Exemplo n.º 1
0
    def __init__(self, parent=None, **kwargs):
        """
        :type parent: DivNode
        :param kwargs: All other parameter for the div node.
        """
        super(ChartAxisBase, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)

        self._marking_div = InteractiveDivNode(parent=self)
        self._marking_div.start_listening(clicked=self._on_tap,
                                          drag_started=self._on_drag_start,
                                          dragged=self._on_drag,
                                          drag_ended=self._on_drag_end)
        self._label_and_unit_div = InteractiveDivNode(parent=self)
        self._label_and_unit_div.start_listening(
            clicked=self._on_tap,
            drag_started=self._on_drag_start,
            dragged=self._on_drag,
            drag_ended=self._on_drag_end)
        self._axis_and_tick_div = InteractiveDivNode(parent=self)
        self._axis_and_tick_div.start_listening(
            clicked=self._on_tap,
            drag_started=self._on_drag_start,
            dragged=self._on_drag,
            drag_ended=self._on_drag_end)
Exemplo n.º 2
0
    def __init__(self,
                 obj_id,
                 attributes,
                 color=DataDefaults.COLOR,
                 pos_x=0,
                 pos_y=0,
                 width=20,
                 height=20,
                 level_of_detail=0):
        """
        :param obj_id: The name of this data object.
        :type obj_id: object
        :param attributes: The list of all different data this object holds.
        :type attributes: list[Attribute]
        :param color: The color for this data object.
        :type color: Color
        """
        EventDispatcher.__init__(self)

        self.__pos_x = pos_x
        self.__pos_y = pos_y
        self.__width = width
        self.__height = height
        self.__level_of_detail = level_of_detail

        self.__value_length = None
        self.__attributes = {}
        self.__obj_id = obj_id
        self.__color = color
        self.__selection_state = DataSelectionState.Nothing

        for attribute in attributes:
            self.__attributes[attribute.data_name] = attribute
Exemplo n.º 3
0
    def __init__(self, parent, event):
        """
        This class uses an initial touch event to track subsequent moves draw a line between them in a div node.
        It is mainly used to draw a selection lasso and record a polygon of it. This polygon can later be used to check
        for if the lasso contains nodes.

        Args:
            parent (avg.DivNode): Parent node that should contain the drawn line.
            event (Event): Initial event that is used to track touches / mouse moves.
        """
        EventDispatcher.__init__(self)

        self.__parent = parent
        self.__node = avg.PolygonNode(
            strokewidth=2,
            parent=self.__parent,
            color=vs_config.SELECTION_FEEDBACK_COLOR,
            fillopacity=0.5,
            opacity=0.5,
            fillcolor='ccc',
            sensitive=False,
            pos=[self.__parent.getRelPos((event.x, event.y))])
        self.__event = event
        self.__touch_id = event.cursorid

        self.__event.contact.subscribe(avg.Contact.CURSOR_MOTION,
                                       self.__on_move)
        self.__event.contact.subscribe(avg.Contact.CURSOR_UP, self.__on_up)
    def initialize(self, controller, on_web_socket_opened=None, on_web_socket_closed=None):
        """
        :type controller: WebClientController
        :param on_web_socket_opened: Called when a new websocket has opened.
        :type on_web_socket_opened: function(sender:DataWebSocketHandler)
        :param on_web_socket_closed: Called when this open websocket has closed.
        :type on_web_socket_closed: function(sender:DataWebSocketHandler)
        """
        super(ConnectionWebSocket, self).initialize(controller=controller)
        EventDispatcher.__init__(self)

        if not IpMapper.is_ip_already_known(self.request.remote_ip):
            self._connection_id = IpMapper.get_id_from_ip(self.request.remote_ip)

        self.bind(self.__WEB_SOCKET_OPENED, on_web_socket_opened)
        self.bind(self.__WEB_SOCKET_CLOSED, on_web_socket_closed)
    def __init__(self, data_keys):
        """
        :param data_keys: The list of all data keys that this data holder observes.
        :type data_keys: list[str]
        """
        EventDispatcher.__init__(self)

        self.__data_keys = data_keys
        SelectionDataHolder.__KEY_IDS.update(
            {key: -1
             for key in self.__data_keys})

        # key -> selection set id     value -> selection set (list)
        self.__selection_sets = {}

        self._last_selection = LastSelection("", True, time.time())
Exemplo n.º 6
0
    def __init__(self, divico_controller):
        """
        :type divico_controller: DivicoControl
        """
        self.__thread_name = "TornadoServer-Thread"

        super(TornadoServer, self).__init__()
        EventDispatcher.__init__(self)
        self.setName(self.__thread_name)
        self.setDaemon(True)

        self.__started = False

        self.__controller = divico_controller

        self.__data_web_sockets = []
        self.__data_web_sockets_id_counter = 0

        # Get the right paths to the files.
        working_directory = os.getcwd()
        if "tornado_server" not in working_directory:
            working_directory += "/tornado_server"
        web_path = "{}/{}".format(working_directory, "web")

        self.__touchpad_webSocket_parameters = {
            "controller": self.__controller,
            "on_web_socket_opened": self.__on_data_web_socket_opened,
            "on_web_socket_closed": self.__on_data_web_socket_closed,
        }

        self.__handlers = [
            (r"/js/(.*)", JsStaticFileHandler, dict(path="{}/{}".format(working_directory, "web/js"))),
            (r"/css/(.*)", CssStaticFileHandler, dict(path="{}/{}".format(working_directory, "web/css"))),
            (r"/assets/(.*)", StaticFileHandler, dict(path="{}/{}".format(working_directory, "web/assets"))),
            (r"/", IndexHandler, dict(web_path=web_path)),
            (r"/ws/touch_pad", ConnectionWebSocket, self.__touchpad_webSocket_parameters),
        ]
        self.__settings = {
            "debug": True,
            "autoreload": False,
        }

        self.__tornado_web_app = Application(self.__handlers, **self.__settings)
        self.__http_server = HTTPServer(self.__tornado_web_app)
        self.__io_loop = None
Exemplo n.º 7
0
    def __init__(self, parent=None, **kwargs):
        super(TouchTestView, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)

        self.__touch_count = 0
        self.__rect_nodes = []
        rect_size = self.size[0] / 4, self.size[1] / 3
        for y in range(3):
            y = rect_size[1] * y
            for x in range(4):
                x = rect_size[0] * x
                rect_node = avg.RectNode(parent=self,
                                         pos=(x, y),
                                         size=rect_size,
                                         fillcolor="8c0707",
                                         fillopacity=1,
                                         strokewidth=0)
                rect_node.subscribe(avg.Node.CURSOR_DOWN,
                                    self.__on_cursor_down)
Exemplo n.º 8
0
    def __init__(self,
                 map_model,
                 size,
                 parent,
                 map_provider,
                 country_list=None,
                 **kwargs):
        """
        :param map_model: The model this view is based on.
        :type map_model: MapModel
        :param parent: The parent this view should be shown in.
        :type parent: DivNode
        :param geo_cord_border: Border for the data points of the map. (left, top, right, bottom)
        :type geo_cord_border: tuple
        """
        super(MapView, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)
        self.subscribe(avg.Node.KILLED, self.__on_self_killed)

        self.__map_model = map_model
        self.__map_model.start_listening(
            points_changed=self.__on_points_changed)

        self.__map_provider = map_provider
        if isinstance(self.__map_provider, ImageMapProvider):
            self.__map_provider.start_listening(
                image_moved=self.__on_background_resized)
        self.__geo_coord_mapper = GeoCoordMapper()

        self.__size = size
        self.__background_div = avg.DivNode(parent=self, size=size)
        self.__point_div = avg.DivNode(parent=self)
        self.__point_detail_div = avg.DivNode(parent=self)
        self.__point_views = []

        self.__country_list = [] if not country_list else country_list
        self.update(country_list=country_list)

        self.size = size
        self.crop = True
    def __init__(self, parent=None, **kwargs):
        super(InteractiveDivNode, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)

        self.__drag_recognizer = gesture.DragRecognizer(
            eventNode=self,
            minDragDist=CommonRecognizerDefaults.DRAG_MIN_DIST,
            detectedHandler=self._on_drag_started,
            moveHandler=self._on_drag,
            upHandler=self._on_drag_ended,
            friction=-1
        )
        self.subscribe(avg.Node.CURSOR_DOWN, self.__on_cursor_down)
        self.subscribe(avg.Node.CURSOR_UP, self.__on_cursor_up)

        self._drag_start_pos = 0, 0
        self._last_drag_change = 0, 0

        # key -> event id     value -> start time
        self.__down_events = {}
Exemplo n.º 10
0
    def __init__(self,
                 grid_element,
                 grid_element_div_config=None,
                 parent=None,
                 **kwargs):
        """
        :param grid_element: The grid element that is the base for this div.
        :type grid_element: GridElement
        :param grid_element_div_config: The configuration that is used to create this grid element div.
        :type grid_element_div_config: GridElementDivConfigurations
        :param parent: The parent of this div.
        :type parent: DivNode
        :param kwargs: All other parameters that are possible for the DivNode.
        """
        super(GridElementDiv, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)

        self._grid_element = grid_element
        self._grid_element_div_config = grid_element_div_config if grid_element_div_config else GridElementDivConfigurations(
        )

        avg.RectNode(
            parent=self,
            pos=(self._grid_element_div_config.margin,
                 self._grid_element_div_config.margin),
            size=(self.size[0] - 2 * self._grid_element_div_config.margin,
                  self.size[1] - 2 * self._grid_element_div_config.margin),
            strokewidth=self._grid_element_div_config.border_width,
            color=self._grid_element_div_config.border_color,
            fillcolor=self._grid_element_div_config.background_color,
            fillopacity=1)
        self._internal_div = avg.DivNode(
            parent=self,
            pos=(self._grid_element_div_config.margin,
                 self._grid_element_div_config.margin),
            size=(self.size[0] - 2 * self._grid_element_div_config.margin,
                  self.size[1] - 2 * self._grid_element_div_config.margin),
            crop=True)
        self._child_nodes = []
Exemplo n.º 11
0
    def __init__(self,
                 data,
                 data_keys_for_selection,
                 label,
                 view_id=-1,
                 chart_config=None,
                 selection_label_text_config=None,
                 parent=None,
                 **kwargs):
        """
        :param data: A dictionary with data objects. Each entry has a key (the name of the data object) and a dict with all
                     values for all the axis in the chart. This value dicts key is a string with the label of the data descriptor
                     and the value is a list with all values on the specified axis.
        :type data: list[DataObject]
        :param data_keys_for_selection: The keys for the attributes of this data object that are important for the selection.
        :type data_keys_for_selection: list[str]
        :param label: The name of this chart.
        :type label: str
        :param chart_config: The configuration used to create this chart.
        :type chart_config: ChartConfiguration
        :param selection_label_text_config: The configuration used to create labels for selected data objects.
        :type: TextLabelConfiguration
        :type parent: DivNode
        :param kwargs: All other parameter for the div node.
        """
        super(ChartBase, self).__init__(**kwargs)
        self.registerInstance(self, parent)
        EventDispatcher.__init__(self)

        self._chart_config = chart_config or ChartConfiguration()
        self._selection_label_text_config = selection_label_text_config or TextMarkingConfiguration(
        )
        self._label = label
        self._view_id = view_id

        # dict: key -> label of the axis     value -> the view of the axis
        self._axis_views = {}

        self._grid_lines_div = avg.DivNode(parent=self)
        self._background_div = avg.DivNode(parent=self)
        self._axis_div = avg.DivNode(parent=self)
        self._data_div = avg.DivNode(parent=self)
        self._selection_label_div = avg.DivNode(parent=self, sensitive=False)
        self._label_node = None

        self._background_tap_recognizer = gesture.DoubletapRecognizer(
            node=self._background_div,
            maxTime=CommonRecognizerDefaults.DOUBLE_TAP_MAX_TIME,
            maxDist=CommonRecognizerDefaults.DOUBLE_TAP_MAX_DIST,
            detectedHandler=self._on_background_tap)

        self._padding_size = (self.size[0] - self._chart_config.padding_left -
                              self._chart_config.padding_right,
                              self.size[1] - self._chart_config.padding_top -
                              self._chart_config.padding_bottom)
        # dict: key -> aid line type     value -> aid line controller
        self._aid_line_controllers = {}

        self._data_objects = {d.obj_id: d for d in data}
        # dict: key -> object name     value -> Node
        self._data_object_nodes = {}
        self._data_object_tap_recognizer = {}
        self._data_keys_for_selection = data_keys_for_selection
        self._selection_data_holder = SelectionDataHolder(
            data_keys_for_selection)

        # key -> object name     value -> WordNode
        self._data_object_label_nodes = {}
Exemplo n.º 12
0
    def __init__(self, device, device_pointer_config, **kwargs):
        """

        :param device: The device this view should represent.
        :type device: Device
        :param device_pointer_config: The configuration for the pointer device.
        :type device_pointer_config: DevicePointerConfigurations
        :param kwargs:
        """
        super(PointerDeviceView, self).__init__(**kwargs)
        EventDispatcher.__init__(self)
        self.registerInstance(self, device.canvas)

        self.__device = device
        self.__device_pointer_config = None
        self.__internal_div = avg.DivNode()

        self.change_configuration(device_pointer_config)

        self.__swipe_rec_right = SwipeRecognizer(
            node=self.__internal_div,
            direction=SwipeRecognizer.RIGHT,
            directionTolerance=self.__device_pointer_config.
            swipe_direction_tolerance,
            detectedHandler=self.__on_swipe_right,
            minDist=self.__device_pointer_config.swipe_min_dist)
        self.__swipe_rec_left = SwipeRecognizer(
            node=self.__internal_div,
            direction=SwipeRecognizer.LEFT,
            directionTolerance=self.__device_pointer_config.
            swipe_direction_tolerance,
            detectedHandler=self.__on_swipe_left,
            minDist=self.__device_pointer_config.swipe_min_dist)
        self.__swipe_rec_right = SwipeRecognizer(
            node=self.__internal_div,
            direction=SwipeRecognizer.UP,
            directionTolerance=self.__device_pointer_config.
            swipe_direction_tolerance,
            detectedHandler=self.__on_swipe_up,
            minDist=self.__device_pointer_config.swipe_min_dist)
        self.__swipe_rec_left = SwipeRecognizer(
            node=self.__internal_div,
            direction=SwipeRecognizer.DOWN,
            directionTolerance=self.__device_pointer_config.
            swipe_direction_tolerance,
            detectedHandler=self.__on_swipe_down,
            minDist=self.__device_pointer_config.swipe_min_dist)
        self.__drag_recognizer = DragRecognizer(
            eventNode=self.__internal_div,
            minDragDist=self.__device_pointer_config.min_drag_dist,
            direction=DragRecognizer.ANY_DIRECTION,
            moveHandler=self.__on_drag,
            endHandler=self.__on_drag_end,
            friction=-1)
        self.__tap_recognizer = TapRecognizer(
            node=self.__internal_div,
            maxDist=self.__device_pointer_config.tap_max_dist,
            maxTime=self.__device_pointer_config.tap_max_time,
            detectedHandler=self.__on_tap)

        self.__event_id = None
        self.__event = None
        self.__event_time = None
        self.__event_movement_dist = None

        self.__last_drag_offset = (0, 0)
        self.__last_tap_time = 0
        self.__double_tap_hold_active = False
        self.__hold_active = False

        self.subscribe(avg.Node.CURSOR_DOWN, self.__on_cursor_down)
        self.subscribe(avg.Node.CURSOR_MOTION, self.__on_cursor_motion)
        self.subscribe(avg.Node.CURSOR_UP, self.__on_cursor_up)
    def __init__(self,
                 chart,
                 aid_line_area,
                 use_tick_snapping=False,
                 use_data_point_snapping=False,
                 remove_intersection_on_selection=True,
                 labels_only_at_data_points=False,
                 aid_line_config=None,
                 intersection_config=None):
        """
        :param chart: The chart that should be watched through this controller.
        :type chart: ChartBase
        :param aid_line_area: The area the axis is allowed to be in.
        :type aid_line_area: tuple
        :param use_tick_snapping: Should the aid line be snapping to the next tick? Only one snapping can be activated at a time.
        :type use_tick_snapping: bool
        :param use_data_point_snapping: Should the aid line be snapping to the next data point? Only one snapping can be activated at a time.
        :type use_data_point_snapping: bool
        :param remove_intersection_on_selection: Should the intersections be removed if the data object, the intersection are coupled with, is selected.
        :type remove_intersection_on_selection: bool
        :param aid_line_config: The container that holds all values necessary for aid lines.
        :type aid_line_config: AidLineConfiguration
        :param intersection_config: The container that holds all values necessary for intersections.
        :type intersection_config: IntersectionConfiguration
        """
        EventDispatcher.__init__(self)

        if chart.view_id not in AidLineControllerBase.__aid_line_controller_instances:
            AidLineControllerBase.__aid_line_controller_instances[
                chart.view_id] = []
        AidLineControllerBase.__aid_line_controller_instances[
            chart.view_id].append(self)

        self._chart = chart
        self._chart.selection_data_holder.start_listening(
            selection_set_added=self._on_selection_set_changed,
            selection_set_removed=self._on_selection_set_changed)
        for data_object in self._chart.data_objects.values():
            data_object.start_listening(
                color_changed=self._on_data_object_color_changed)

        self._internal_div = avg.DivNode(parent=self._chart)
        self._intersection_div = avg.DivNode(parent=self._internal_div)
        self._aid_lines_div = avg.DivNode(parent=self._internal_div)
        # key -> object ids     value -> dict: (key -> position of the intersection     value -> Node for the label)
        self._intersection_nodes = {}

        self._aid_line_area = aid_line_area
        self._use_tick_snapping = use_tick_snapping
        self._use_data_point_snapping = use_data_point_snapping if not use_tick_snapping else False
        self._remove_intersection_on_selection = remove_intersection_on_selection
        # TODO: Currently this only affects the line charts (through the intersections). The other possibilities could be added if wished.
        self._labels_only_at_data_points = labels_only_at_data_points
        self._aid_line_config = aid_line_config if aid_line_config else AidLineConfiguration(
        )
        self._intersection_config = intersection_config if intersection_config else IntersectionConfiguration(
        )
        if not intersection_config:
            self._intersection_config.marking_text_config = TextMarkingConfiguration(
                offset_to_other_element=self._intersection_config.radius)

        self.bind(self.STEP_FORWARD, self._on_step_forward)
        self.bind(self.STEP_BACKWARD, self._on_step_backward)