def __draw_move_control(self): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() self.context.set_dash([1, 1]) self.context.arc(xc, yc, 23, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() self.context.set_dash([1, 1]) self.context.move_to(xc, yc) self.context.line_to(xc + x, yc - y) self.context.stroke() self.context.set_dash([1, 0]) self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) if i == self.__moving: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() self.context.arc(xc, yc, 6, 0, 2 * math.pi) if self.__centering == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False
def __draw_move_control(self): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() self.context.set_dash([1,1]) self.context.arc(xc, yc, 23, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() self.context.set_dash([1,1]) self.context.move_to(xc, yc) self.context.line_to(xc + x, yc - y) self.context.stroke() self.context.set_dash([1,0]) self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) if i == self.__moving: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() self.context.arc(xc, yc, 6, 0, 2 * math.pi) if self.__centering == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False
def __move_is_clicked(self, pointer): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() center = (xc + x, yc - y) result = geometry.is_in_circle(pointer, self.__move_radius, center) if result == True: return i return None
class NetNode(Node): """ Node class for radial network widget """ def __init__(self, id=Node): """ """ self.__draw_info = dict() """Hash with draw information""" self.__coordinate = PolarCoordinate() super(NetNode, self).__init__(id) def get_coordinate_theta(self): """ """ return self.__coordinate.get_theta() def get_coordinate_radius(self): """ """ return self.__coordinate.get_radius() def set_coordinate_theta(self, value): """ """ self.__coordinate.set_theta(value) def set_coordinate_radius(self, value): """ """ self.__coordinate.set_radius(value) def set_polar_coordinate(self, r, t): """ Set polar coordinate @type r: number @param r: The radius of coordinate @type t: number @param t: The angle (theta) of coordinate in radians """ self.__coordinate.set_coordinate(r, t) def get_polar_coordinate(self): """ Get cartesian coordinate @rtype: tuple @return: Cartesian coordinates (x, y) """ return self.__coordinate.get_coordinate() def set_cartesian_coordinate(self, x, y): """ Set cartesian coordinate """ cartesian = CartesianCoordinate(x, y) r, t = cartesian.to_polar() self.set_polar_coordinate(r, math.degrees(t)) def get_cartesian_coordinate(self): """ Get cartesian coordinate @rtype: tuple @return: Cartesian coordinates (x, y) """ return self.__coordinate.to_cartesian() def get_draw_info(self, info=None): """ Get draw information about node @type : string @param : Information name @rtype: mixed @return: The requested information """ if info == None: return self.__draw_info if self.__draw_info.has_key(info): return self.__draw_info[info] return None def set_draw_info(self, info): """ Set draw information @type : dict @param : Draw information dictionary """ for key in info: self.__draw_info[key] = info[key] def deep_search_child(self, node): """ """ for child in self.get_draw_info('children'): if child == node: return True elif child.deep_search_child(node): return True return False def set_subtree_info(self, info): """ """ for child in self.get_draw_info('children'): child.set_draw_info(info) if child.get_draw_info('group') != True: child.set_subtree_info(info) def calc_needed_space(self): """ """ number_of_children = len(self.get_draw_info('children')) sum_angle = 0 own_angle = 0 if number_of_children > 0 and self.get_draw_info('group') != True: for child in self.get_draw_info('children'): child.calc_needed_space() sum_angle += child.get_draw_info('space_need') distance = self.get_coordinate_radius() size = self.get_draw_info('radius') * 2 own_angle = geometry.angle_from_object(distance, size) self.set_draw_info({'children_need':sum_angle}) self.set_draw_info({'space_need':max(sum_angle, own_angle)})
class ControlNavigation(gtk.DrawingArea): """ """ def __init__(self, radialnet): """ """ gtk.DrawingArea.__init__(self) self.radialnet = radialnet self.__rotate_node = PolarCoordinate() self.__rotate_node.set_coordinate(40, 90) self.__center_of_widget = (50, 50) self.__moving = None self.__centering = False self.__rotating = False self.__move_pass = 100 self.__move_position = (0, 0) self.__move_addition = [(-1, 0), (-1,-1), ( 0,-1), ( 1,-1), ( 1, 0), ( 1, 1), ( 0, 1), (-1, 1)] self.__move_factor = 1 self.__move_factor_limit = 20 self.__rotate_radius = 6 self.__move_radius = 6 self.__rotate_clicked = False self.__move_clicked = None self.connect('expose_event', self.expose) self.connect('button_press_event', self.button_press) self.connect('button_release_event', self.button_release) self.connect('motion_notify_event', self.motion_notify) self.connect('enter_notify_event', self.enter_notify) self.connect('leave_notify_event', self.leave_notify) self.connect('key_press_event', self.key_press) self.connect('key_release_event', self.key_release) self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY | gtk.gdk.LEAVE_NOTIFY | gtk.gdk.MOTION_NOTIFY | gtk.gdk.NOTHING | gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.POINTER_MOTION_MASK) self.__rotate_node.set_coordinate(40, self.radialnet.get_rotation()) def key_press(self, widget, event): """ """ key = gtk.gdk.keyval_name(event.keyval) self.queue_draw() return True def key_release(self, widget, event): """ """ key = gtk.gdk.keyval_name(event.keyval) self.queue_draw() return True def enter_notify(self, widget, event): """ """ return False def leave_notify(self, widget, event): """ """ self.queue_draw() return False def button_press(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ pointer = self.get_pointer() direction = False if self.__rotate_is_clicked(pointer) == True: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__rotating = True direction = self.__move_is_clicked(pointer) if direction != None and self.__moving == None: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__moving = direction self.__move_in_direction(direction) if self.__center_is_clicked(pointer) == True: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__centering = True self.__move_position = (0, 0) self.radialnet.set_translation(self.__move_position) self.queue_draw() return False def button_release(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ self.__moving = None # stop moving self.__centering = False self.__rotating = False # stop rotate self.__move_factor = 1 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) self.queue_draw() return False def motion_notify(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ xc, yc = self.__center_of_widget x, y = self.get_pointer() status = not self.radialnet.is_in_animation() status = status and not self.radialnet.is_empty() if self.__rotating == True and status: r, t = self.__rotate_node.get_coordinate() t = math.degrees(math.atan2(yc - y, x - xc)) if t < 0: t = 360 + t self.radialnet.set_rotation(t) self.__rotate_node.set_coordinate(r, t) self.queue_draw() return False def expose(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ self.set_size_request(120, 130) self.context = widget.window.cairo_create() self.__draw() return False def __draw_rotate_control(self): """ """ xc, yc = self.__center_of_widget r, t = self.__rotate_node.get_coordinate() x, y = self.__rotate_node.to_cartesian() # draw text self.context.set_font_size(10) self.context.move_to(xc - 49, yc - 48) self.context.show_text(_("Navigation")) width = self.context.text_extents(str(int(t)))[2] self.context.move_to(xc + 49 - width - 2, yc - 48) self.context.show_text(str(round(t, 1))) self.context.set_line_width(1) self.context.stroke() # draw arc self.context.set_dash([1,2]) self.context.arc(xc, yc, 40, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() # draw node self.context.set_dash([1,0]) self.context.arc(xc + x, yc - y, self.__rotate_radius, 0, 2 * math.pi) if self.__rotating == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False def __draw_move_control(self): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() self.context.set_dash([1,1]) self.context.arc(xc, yc, 23, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() self.context.set_dash([1,1]) self.context.move_to(xc, yc) self.context.line_to(xc + x, yc - y) self.context.stroke() self.context.set_dash([1,0]) self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) if i == self.__moving: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() self.context.arc(xc, yc, 6, 0, 2 * math.pi) if self.__centering == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False def __draw(self): """ Drawing method """ # Getting allocation reference allocation = self.get_allocation() self.__center_of_widget = (allocation.width / 2, allocation.height / 2) self.__draw_rotate_control() self.__draw_move_control() return False def __move_in_direction(self, direction): """ """ if self.__moving != None: bx, by = self.__move_position ax, ay = self.__move_addition[direction] self.__move_position = (bx + self.__move_factor * ax, by + self.__move_factor * ay) self.radialnet.set_translation(self.__move_position) if self.__move_factor < self.__move_factor_limit: self.__move_factor += 1 gobject.timeout_add(self.__move_pass, self.__move_in_direction, direction) return False def __rotate_is_clicked(self, pointer): """ """ xn, yn = self.__rotate_node.to_cartesian() xc, yc = self.__center_of_widget center = (xc + xn, yc - yn) result = geometry.is_in_circle(pointer, self.__rotate_radius, center) if result == True: return True return False def __center_is_clicked(self, pointer): """ """ result = geometry.is_in_circle(pointer, self.__move_radius, self.__center_of_widget) if result == True: return True return False def __move_is_clicked(self, pointer): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() center = (xc + x, yc - y) result = geometry.is_in_circle(pointer, self.__move_radius, center) if result == True: return i return None
class ControlNavigation(gtk.DrawingArea): """ """ def __init__(self, radialnet): """ """ gtk.DrawingArea.__init__(self) self.radialnet = radialnet self.__rotate_node = PolarCoordinate() self.__rotate_node.set_coordinate(40, 90) self.__center_of_widget = (50, 50) self.__moving = None self.__centering = False self.__rotating = False self.__move_pass = 100 self.__move_position = (0, 0) self.__move_addition = [(-1, 0), (-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1)] self.__move_factor = 1 self.__move_factor_limit = 20 self.__rotate_radius = 6 self.__move_radius = 6 self.__rotate_clicked = False self.__move_clicked = None self.connect('expose_event', self.expose) self.connect('button_press_event', self.button_press) self.connect('button_release_event', self.button_release) self.connect('motion_notify_event', self.motion_notify) self.connect('enter_notify_event', self.enter_notify) self.connect('leave_notify_event', self.leave_notify) self.connect('key_press_event', self.key_press) self.connect('key_release_event', self.key_release) self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY | gtk.gdk.LEAVE_NOTIFY | gtk.gdk.MOTION_NOTIFY | gtk.gdk.NOTHING | gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.POINTER_MOTION_MASK) self.__rotate_node.set_coordinate(40, self.radialnet.get_rotation()) def key_press(self, widget, event): """ """ key = gtk.gdk.keyval_name(event.keyval) self.queue_draw() return True def key_release(self, widget, event): """ """ key = gtk.gdk.keyval_name(event.keyval) self.queue_draw() return True def enter_notify(self, widget, event): """ """ return False def leave_notify(self, widget, event): """ """ self.queue_draw() return False def button_press(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ pointer = self.get_pointer() direction = False if self.__rotate_is_clicked(pointer) == True: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__rotating = True direction = self.__move_is_clicked(pointer) if direction != None and self.__moving == None: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__moving = direction self.__move_in_direction(direction) if self.__center_is_clicked(pointer) == True: event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) self.__centering = True self.__move_position = (0, 0) self.radialnet.set_translation(self.__move_position) self.queue_draw() return False def button_release(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ self.__moving = None # stop moving self.__centering = False self.__rotating = False # stop rotate self.__move_factor = 1 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) self.queue_draw() return False def motion_notify(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ xc, yc = self.__center_of_widget x, y = self.get_pointer() status = not self.radialnet.is_in_animation() status = status and not self.radialnet.is_empty() if self.__rotating == True and status: r, t = self.__rotate_node.get_coordinate() t = math.degrees(math.atan2(yc - y, x - xc)) if t < 0: t = 360 + t self.radialnet.set_rotation(t) self.__rotate_node.set_coordinate(r, t) self.queue_draw() return False def expose(self, widget, event): """ Drawing callback @type widget: GtkWidget @param widget: Gtk widget superclass @type event: GtkEvent @param event: Gtk event of widget @rtype: boolean @return: Indicator of the event propagation """ self.set_size_request(120, 130) self.context = widget.window.cairo_create() self.__draw() return False def __draw_rotate_control(self): """ """ xc, yc = self.__center_of_widget r, t = self.__rotate_node.get_coordinate() x, y = self.__rotate_node.to_cartesian() # draw text self.context.set_font_size(10) self.context.move_to(xc - 49, yc - 48) self.context.show_text(_("Navigation")) width = self.context.text_extents(str(int(t)))[2] self.context.move_to(xc + 49 - width - 2, yc - 48) self.context.show_text(str(round(t, 1))) self.context.set_line_width(1) self.context.stroke() # draw arc self.context.set_dash([1, 2]) self.context.arc(xc, yc, 40, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() # draw node self.context.set_dash([1, 0]) self.context.arc(xc + x, yc - y, self.__rotate_radius, 0, 2 * math.pi) if self.__rotating == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False def __draw_move_control(self): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() self.context.set_dash([1, 1]) self.context.arc(xc, yc, 23, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() self.context.set_dash([1, 1]) self.context.move_to(xc, yc) self.context.line_to(xc + x, yc - y) self.context.stroke() self.context.set_dash([1, 0]) self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) if i == self.__moving: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() self.context.arc(xc, yc, 6, 0, 2 * math.pi) if self.__centering == True: self.context.set_source_rgb(0.0, 0.0, 0.0) else: self.context.set_source_rgb(1.0, 1.0, 1.0) self.context.fill_preserve() self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() return False def __draw(self): """ Drawing method """ # Getting allocation reference allocation = self.get_allocation() self.__center_of_widget = (allocation.width / 2, allocation.height / 2) self.__draw_rotate_control() self.__draw_move_control() return False def __move_in_direction(self, direction): """ """ if self.__moving != None: bx, by = self.__move_position ax, ay = self.__move_addition[direction] self.__move_position = (bx + self.__move_factor * ax, by + self.__move_factor * ay) self.radialnet.set_translation(self.__move_position) if self.__move_factor < self.__move_factor_limit: self.__move_factor += 1 gobject.timeout_add(self.__move_pass, self.__move_in_direction, direction) return False def __rotate_is_clicked(self, pointer): """ """ xn, yn = self.__rotate_node.to_cartesian() xc, yc = self.__center_of_widget center = (xc + xn, yc - yn) result = geometry.is_in_circle(pointer, self.__rotate_radius, center) if result == True: return True return False def __center_is_clicked(self, pointer): """ """ result = geometry.is_in_circle(pointer, self.__move_radius, self.__center_of_widget) if result == True: return True return False def __move_is_clicked(self, pointer): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() for i in range(8): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() center = (xc + x, yc - y) result = geometry.is_in_circle(pointer, self.__move_radius, center) if result == True: return i return None
class NetNode(Node): """ Node class for radial network widget """ def __init__(self, id=Node): """ """ self.__draw_info = dict() """Hash with draw information""" self.__coordinate = PolarCoordinate() super(NetNode, self).__init__(id) def get_coordinate_theta(self): """ """ return self.__coordinate.get_theta() def get_coordinate_radius(self): """ """ return self.__coordinate.get_radius() def set_coordinate_theta(self, value): """ """ self.__coordinate.set_theta(value) def set_coordinate_radius(self, value): """ """ self.__coordinate.set_radius(value) def set_polar_coordinate(self, r, t): """ Set polar coordinate @type r: number @param r: The radius of coordinate @type t: number @param t: The angle (theta) of coordinate in radians """ self.__coordinate.set_coordinate(r, t) def get_polar_coordinate(self): """ Get cartesian coordinate @rtype: tuple @return: Cartesian coordinates (x, y) """ return self.__coordinate.get_coordinate() def set_cartesian_coordinate(self, x, y): """ Set cartesian coordinate """ cartesian = CartesianCoordinate(x, y) r, t = cartesian.to_polar() self.set_polar_coordinate(r, math.degrees(t)) def get_cartesian_coordinate(self): """ Get cartesian coordinate @rtype: tuple @return: Cartesian coordinates (x, y) """ return self.__coordinate.to_cartesian() def get_draw_info(self, info=None): """ Get draw information about node @type : string @param : Information name @rtype: mixed @return: The requested information """ if info == None: return self.__draw_info if self.__draw_info.has_key(info): return self.__draw_info[info] return None def set_draw_info(self, info): """ Set draw information @type : dict @param : Draw information dictionary """ for key in info: self.__draw_info[key] = info[key] def deep_search_child(self, node): """ """ for child in self.get_draw_info('children'): if child == node: return True elif child.deep_search_child(node): return True return False def set_subtree_info(self, info): """ """ for child in self.get_draw_info('children'): child.set_draw_info(info) if child.get_draw_info('group') != True: child.set_subtree_info(info) def calc_needed_space(self): """ """ number_of_children = len(self.get_draw_info('children')) sum_angle = 0 own_angle = 0 if number_of_children > 0 and self.get_draw_info('group') != True: for child in self.get_draw_info('children'): child.calc_needed_space() sum_angle += child.get_draw_info('space_need') distance = self.get_coordinate_radius() size = self.get_draw_info('radius') * 2 own_angle = geometry.angle_from_object(distance, size) self.set_draw_info({'children_need': sum_angle}) self.set_draw_info({'space_need': max(sum_angle, own_angle)})