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)
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
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())
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
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)
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 = {}
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 = []
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 = {}
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)