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 = RadialNet.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 is not None and self.__moving is 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 is not 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 = RadialNet.is_in_circle(pointer, self.__rotate_radius, center)

        if result == True:
            return True

        return False


    def __center_is_clicked(self, pointer):
        """
        """
        result = RadialNet.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 = RadialNet.is_in_circle(pointer,
                                           self.__move_radius,
                                           center)

            if result == True:
                return i

        return None