Beispiel #1
0
 def handle_button_press(self, cr, rect, event_x, event_y):
     if self.is_expandable:
         if not self.in_animation:
             if self.has_expand:
                 text_width, text_height = self.shrink_button_width, self.shrink_button_height
             else:
                 text_width, text_height = self.expand_button_width, self.expand_button_height
             if is_in_rect((event_x, event_y), 
                           (rect.width - (rect.width - self.label_wrap_width) / 2 - text_width,
                            rect.height - text_height,
                            text_width,
                            text_height)):
                 
                 if self.has_expand:
                     start_position = self.expand_height
                     animation_distance = self.init_height - self.expand_height
                 else:
                     start_position = self.init_height
                     animation_distance = self.expand_height - self.init_height
                 
                 self.in_animation = True    
                     
                 timeline = Timeline(self.animation_time, CURVE_SINE)
                 timeline.connect('update', lambda source, status: 
                                  self.update(source,
                                              status, 
                                              start_position,
                                              animation_distance))
                 timeline.connect("completed", self.completed)
                 timeline.run()
     else:
         print "no expand button"
Beispiel #2
0
    def handle_button_press(self, cr, rect, event_x, event_y):
        if self.is_expandable:
            if not self.in_animation:
                if self.has_expand:
                    text_width, text_height = self.shrink_button_width, self.shrink_button_height
                else:
                    text_width, text_height = self.expand_button_width, self.expand_button_height
                if is_in_rect((event_x, event_y),
                              (rect.width - (rect.width - self.label_wrap_width) / 2 - text_width,
                               rect.height - text_height,
                               text_width,
                               text_height)):

                    if self.has_expand:
                        start_position = self.expand_height
                        animation_distance = self.init_height - self.expand_height
                    else:
                        start_position = self.init_height
                        animation_distance = self.expand_height - self.init_height

                    self.in_animation = True

                    timeline = Timeline(self.animation_time, CURVE_SINE)
                    timeline.connect('update', lambda source, status:
                                     self.update(source,
                                                 status,
                                                 start_position,
                                                 animation_distance))
                    timeline.connect("completed", self.completed)
                    timeline.run()
        else:
            print "no expand button"
Beispiel #3
0
    def graph_package_deps(self, p, pngname):
    
        tl = Timeline()
        
        def epoch(t): return t.toordinal() #float(t.strftime("%s"))
       
        def authColor(p): return hashColor(self.author(p))

        #depbar = "LightSkyBlue"
        #focalbar = "Yellow"
        reflbar = "PaleGoldenrod"
        

        vers_names = self.versions(p)

        # extend each version until the end of hte subsequent version
        for v,w in zip(vers_names[:-1], vers_names[1:]):     # Lost author for author color
            tl.span(p, epoch(self.dc[p][v]), epoch(self.dc[p][w]), p + ":" + v, v, authColor(p), None)
        vlast = vers_names[-1]
        tl.span(p, epoch(self.dc[p][vlast]), epoch(self.end_of_time), p + ":" + vlast, vlast, authColor(p), None)
    
        for dep in self.dependencies(p):
            for (ref,st,en) in self.dep_version_spans(p, dep):
                tl.span(dep, epoch(st), epoch(en), dep + "::" + ref, ref, reflbar, "bottom")
    
            depvers = self.dep_versions(p, dep)
            try:
                vn2 = self.versions(dep)
                for vv,ww in zip(vn2[:-1], vn2[1:]):
                    self.logwith( "deploop", vv,ww, self.dc[dep].keys())
                    tl.span(dep, epoch(self.dc[dep][vv]), epoch(self.dc[dep][ww]),
                            dep + ":" + vv, vv, authColor(dep), "top") 
                vvlast = vn2[-1]
                tl.span(dep, epoch(self.dc[dep][vvlast]), epoch(self.end_of_time),
                       dep + ":" + vvlast, vvlast, authColor(dep), "top") 
            except Exception, e:
                self.logwith("Exception processing dependency", dep, e)
            for vn in vers_names:
                if vn in depvers:
                    dep_ver = self.extractVersionLimiter(depvers[vn])
                    self.logwith( dep_ver)
                    destrec = tl.findByKey(dep + ":" + dep_ver)
                    srcrec = tl.findByKey(p + ":" + vn)
                    if len(destrec) > 0 and len(srcrec) > 0:
                        tl.connect(destrec[0], srcrec[0])
                        self.logwith( "version", vn, "of", p, "did link to dependency", dep, "version", dep_ver)
                    else:
                        self.logwith( "version", vn, "of", p, "***can't*** find dependency", \
                               dep, "version", dep_ver, "lendestrec=", len(destrec), "lensrcrec=", len(srcrec))
                else:
                    self.logwith(vn,"is not in",list(depvers))
                    self.logwith( "version", vn, "of", p, "did not update dependency on", dep)
Beispiel #4
0
 def start_animation(self, index, tab_start_x):
     if not self.in_animiation:
         self.in_animiation = True
         
         source_tab_x = tab_start_x + self.tab_index * self.tab_width
         target_tab_x = tab_start_x + index * self.tab_width
         
         timeline = Timeline(self.tab_animation_time, CURVE_SINE)
         timeline.connect('update', lambda source, status: self.update_animation(source, status, source_tab_x, (target_tab_x - source_tab_x)))
         timeline.connect("completed", lambda source: self.completed_animation(source, index))
         timeline.run()
         
         self.emit("tab-switch-start", index)
Beispiel #5
0
    def graph_package_downstreams(self, p, pngname):
    
        tl = Timeline()
        
        def epoch(t): return t.toordinal() #float(t.strftime("%s"))
       
        def authColor(p): return hashColor(self.author(p))

        reflbar = "PaleGoldenrod"
        
        vers_names = self.versions(p)

        # Just show the first 20; the image gets too big otherwise
        for dep in list(self.reverse_dependencies(p))[:20]:
            for (ref,st,en) in self.dep_version_spans(dep, p):
                try:
                    vname = str(ref).strip()
                    if vname == "": vname = "*"
                except:
                    self.logwith("Could not correct version name ", ref)
                    vname = ref
                tl.span(dep, epoch(st), epoch(en), dep + "::" + ref, "-->" + vname, reflbar, "bottom", invisibleBar=True)
    
            depvers = self.dep_versions(dep, p)
            try:
                vn2 = self.versions(dep)
                for vv,ww in zip(vn2[:-1], vn2[1:]):
                    self.logwith( "deploop", vv,ww, self.dc[dep].keys())
                    tl.span(dep, epoch(self.dc[dep][vv]), epoch(self.dc[dep][ww]),
                            dep + ":" + vv, vv, authColor(dep), "top") 
                vvlast = vn2[-1]
                tl.span(dep, epoch(self.dc[dep][vvlast]), epoch(self.end_of_time),
                       dep + ":" + vvlast, vvlast, authColor(dep), "top") 
            except Exception, e:
                self.logwith("Exception processing dependency", dep, e)
            for vn in vers_names:
                if vn in depvers:
                    dep_ver = self.extractVersionLimiter(depvers[vn])
                    self.logwith( dep_ver)
                    destrec = tl.findByKey(dep + ":" + dep_ver)
                    srcrec = tl.findByKey(p + ":" + vn)
                    if len(destrec) > 0 and len(srcrec) > 0:
                        tl.connect(destrec[0], srcrec[0])
                        self.logwith( "version", vn, "of", p, "did link to dependency", dep, "version", dep_ver)
                    else:
                        self.logwith( "version", vn, "of", p, "***can't*** find dependency", \
                               dep, "version", dep_ver, "lendestrec=", len(destrec), "lensrcrec=", len(srcrec))
                else:
                    self.logwith(vn,"is not in",list(depvers))
                    self.logwith( "version", vn, "of", p, "did not update dependency on", dep)
Beispiel #6
0
    def start_animation(self, animation_time, index=None):
        # Update ticker with active index if option index is None.
        if index == None:
            if self.active_index >= self.image_number - 1:
                index = 0
            else:
                index = self.active_index + 1

        if not self.in_animiation:
            self.in_animiation = True
            self.target_index = index

            timeline = Timeline(animation_time, CURVE_SINE)
            timeline.connect("update", self.update_animation)
            timeline.connect("completed", lambda source: self.completed_animation(source, index))
            timeline.run()

        return True
Beispiel #7
0
    def start_animation(self, animation_time, index=None):
        # Update ticker with active index if option index is None.
        if index == None:
            if self.active_index >= self.image_number - 1:
                index = 0
            else:
                index = self.active_index + 1

        if not self.in_animiation:
            self.in_animiation = True
            self.target_index = index

            timeline = Timeline(animation_time, CURVE_SINE)
            timeline.connect('update', self.update_animation)
            timeline.connect("completed", lambda source: self.completed_animation(source, index))
            timeline.run()

        return True
Beispiel #8
0
    def slide_to(self, widget):

        self.active_widget = widget

        def update(source, status):
            pos = end_position - start_position
            adjustment.set_value(start_position + int(round(status * pos)))

        adjustment = self.get_hadjustment()
        start_position = adjustment.get_value()
        end_position = widget.get_allocation().x

        if start_position != end_position:
            timeline = Timeline(500, CURVE_SINE)
            timeline.connect('update', update)
            timeline.run()
            
        if self.slide_callback:    
            self.slide_callback(self.layout.get_children().index(widget), widget)
Beispiel #9
0
 def set_value(self, value):
     if (not self.in_animation) and value != self.value:
         self.start_value = self.value
         self.range = value - self.value
         times = int(abs(self.range)) * 10
         from timeline import Timeline, CURVE_SINE
         timeline = Timeline(times * 10, CURVE_SINE)
         timeline.connect("start", self.start_animation)
         timeline.connect("stop", self.stop_animation)
         timeline.connect("update", self.update_animation)
         timeline.run()
         
     return False    
Beispiel #10
0
    def set_value(self, value):
        if (not self.in_animation) and value != self.value:
            self.start_value = self.value
            self.range = value - self.value
            times = int(abs(self.range)) * 10
            if times != 0:
                from timeline import Timeline, CURVE_SINE
                timeline = Timeline(times * 10, CURVE_SINE)
                timeline.connect("start", self.start_animation)
                timeline.connect("stop", self.stop_animation)
                timeline.connect("update", self.update_animation)
                timeline.run()
            else:
                self.value = value
                self.queue_draw()

        return False
Beispiel #11
0
class HSlider(gtk.Viewport):
    '''
    HSlider class.
    
    @undocumented: slide_to_page
    @undocumented: set_to_page
    @undocumented: append_page
    '''
    
    __gsignals__ = {
            "start_slide" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
            "completed_slide" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
            }
    
    def __init__(self, 
                 slide_time=200,
                 ):
        '''
        Initialize HSlider class.
        
        @param slide_time: The animation of slide time, default is 200ms.
        '''
        gtk.Viewport.__init__(self)
        self.set_shadow_type(gtk.SHADOW_NONE)
        self.fixed = gtk.Fixed()
        self.add(self.fixed)
        self.slide_time = slide_time
        self.pre_widget = None
        self.active_widget = None
        self.connect("realize", self._update_size)
        self.connect("size_allocate", self._update_size)
        self.page_width = 0
        self.page_height = 0
        self.in_sliding = False

    def _update_size(self, w=None, _w=None):
        self.page_width = self.allocation.width
        self.page_height = self.allocation.height
        if self.active_widget:
            self.active_widget.set_size_request(self.page_width, self.page_height)
        if self.pre_widget:
            self.pre_widget.set_size_request(self.page_width, self.page_height)
        self.show_all()

    def _to_right(self, percent):
        self.offset = int(round(percent * self.page_width)) 
        
        if self.pre_widget:
            self.fixed.move(self.pre_widget, - self.offset, 0)
        
        self.fixed.move(self.active_widget, self.page_width - self.offset, 0)
        
    def _to_left(self, percent):
        self.offset = int(round(percent * self.page_width))
        
        if self.pre_widget:
            self.fixed.move(self.pre_widget, self.offset, 0)
        
        self.fixed.move(self.active_widget, self.offset - self.page_width, 0)

    def _no_effect(self):
        self.offset = self.page_width

        if self.pre_widget:
            self.fixed.remove(self.pre_widget)
        self.fixed.move(self.active_widget, 0, 0)

    def to_page(self, w, direction):
        '''
        Slide to given page.
        
        @param w: gtk.Widget to slide.
        @param direction: The direction of slide animation, can use below value:
         - \"right\"    slide from right to left
         - \"left\"     slide from left to right
         - None         no animation effect, slide directly
        '''
        if self.in_sliding:
            return

        if w != self.active_widget:
            w.set_size_request(self.page_width, self.page_height)
            if w.parent != self.fixed:
                self.fixed.put(w, self.page_width, 0)
            self.active_widget = w

            self.timeline = Timeline(self.slide_time, CURVE_SINE)
            if direction == "right":
                self.timeline.connect('update', lambda source, status: self._to_right(status))
            elif direction == "left":
                self.timeline.connect('update', lambda source, status: self._to_left(status))
            else:
                self._no_effect()

            self.timeline.connect("start", lambda source: self._start())
            self.timeline.connect("completed", lambda source: self._completed())
            self.timeline.run()
            self.in_sliding = True

            self.show_all()
            
    def _start(self):
        self.emit("start_slide")

    def _completed(self):
        if self.pre_widget and self.pre_widget.parent == self.fixed:
            self.fixed.remove(self.pre_widget)
        self.pre_widget = self.active_widget
        #print "Pre: " +  str(self.pre_widget)  + "  act: " + str(self.active_widget) + "children: " + str(self.get_children())
        self.show_all()
        self.in_sliding = False
        self.emit("completed_slide")

    def to_page_now(self, w, d=None):
        '''
        Slide to given page immediately.

        @param w: gtk.Widget to slide.
        '''
        self.to_page(w, d)

    def slide_to_page(self, w, d):
        self.to_page(w, d)
        
    def set_to_page(self, w):
        self.to_page_now(w)
        
    def append_page(self, w):
        pass
Beispiel #12
0
class WizardBox(gtk.EventBox):
    '''
    WizardBox class.
    
    @undocumented: init_size
    @undocumented: on_expose_event
    @undocumented: handle_animation
    @undocumented: on_motion_notify
    @undocumented: on_enter_notify
    @undocumented: on_leave_notify
    @undocumented: on_button_press
    @undocumented: auto_animation
    @undocumented: start_animation
    @undocumented: update_animation
    @undocumented: completed_animation
    '''
    
    __gsignals__ = {
        'close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        }
    
    def __init__(self, 
                 slider_images=None, 
                 pointer_images=None, 
                 button_images=None, 
                 show_button=True, 
                 slide_delay=10000,
                 ):
        '''
        Initialize WizardBox class.
        
        @param slider_images: Slider images, default is None.
        @param pointer_images: Pointer images, default is None.
        @param pointer_images: Button images, default is None.
        @param show_button: Set as True to show button.
        @param slide_delay: The time of delay between slider image, default is 10000ms.
        '''
        gtk.EventBox.__init__(self)
        self.set_visible_window(False)
        
        self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
                        gtk.gdk.BUTTON_RELEASE_MASK |
                        gtk.gdk.POINTER_MOTION_MASK |
                        gtk.gdk.ENTER_NOTIFY_MASK |
                        gtk.gdk.LEAVE_NOTIFY_MASK
                        )
        
        self.connect("expose-event", self.on_expose_event)                
        self.connect("motion-notify-event", self.on_motion_notify)
        self.connect("button-press-event", self.on_button_press)
        
        # Init images.
        self.slider_pixbufs = map(gtk.gdk.pixbuf_new_from_file, slider_images)
        self.slider_numuber = len(slider_images)
        self.dot_normal_pixbuf, self.dot_active_pixbuf = map(gtk.gdk.pixbuf_new_from_file, pointer_images)
        self.button_normal_pixbuf, self.button_press_pixbuf = map(gtk.gdk.pixbuf_new_from_file, button_images)
        self.close_dpixbuf = ui_theme.get_pixbuf("button/window_close_normal.png")
        
        self.show_button = show_button
        
        # Init sizes.
        self.init_size()
        self.pointer_coords = {}
        
        # Move animation.
        self.active_index = 0
        self.target_index = None
        
        self.active_alpha = 1.0
        self.target_index = 0.0
        
        self.active_x = 0
        self.target_x = None
        self.slider_y = 0
        self.auto_animation_id = None
        self.auto_animation_timeout = slide_delay  # millisecond.
        self.slider_timeout = 1000 # millisecond.
        self.in_animation = False
        self.motion_index = None
        self.auto_animation()
        
    def init_size(self):    
        slider_pixbuf = self.slider_pixbufs[0]
        self.slider_width = slider_pixbuf.get_width()
        self.slider_height = slider_pixbuf.get_height()
        self.set_size_request(self.slider_width, self.slider_height)
        
        self.dot_width = self.dot_normal_pixbuf.get_width()
        self.dot_height = self.dot_normal_pixbuf.get_height()
        
        dot_spacing = 10        
        self.dot_width_offset = self.dot_width + dot_spacing
        dot_area_width = self.dot_width * self.slider_numuber + dot_spacing * (self.slider_numuber - 1)
        dot_offset_y = 40
        self.dot_start_x =  (self.slider_width - dot_area_width) / 2
        self.dot_y = self.slider_height - dot_offset_y
        
        close_spacing = 0
        close_x = self.slider_width - self.close_dpixbuf.get_pixbuf().get_width() - close_spacing
        close_y = close_spacing
        self.close_rect = gtk.gdk.Rectangle(close_x, close_y,
                                            self.close_dpixbuf.get_pixbuf().get_width(),
                                            self.close_dpixbuf.get_pixbuf().get_height())    
        
        button_bottom_size = 55
        button_width = self.button_normal_pixbuf.get_width()
        button_height = self.button_normal_pixbuf.get_height()
        button_x = (self.slider_width - button_width) / 2
        button_y = self.slider_height - button_height - button_bottom_size        
        self.button_rect = gtk.gdk.Rectangle(button_x,  button_y, button_width, button_height)
        
    def on_expose_event(self, widget, event):    
        cr = widget.window.cairo_create()        
        rect = widget.allocation
        
        cr.save()
        draw_pixbuf(cr, self.slider_pixbufs[self.active_index], rect.x + self.active_x, 
                    rect.x + self.slider_y, self.active_alpha)
        
        if self.target_index != None and self.target_x != None:
            draw_pixbuf(cr, self.slider_pixbufs[self.target_index], rect.x + self.target_x, 
                        rect.y + self.slider_y, self.target_alpha)
        cr.restore()    
        
        # Draw select pointer.
        dot_start_x = rect.x + self.dot_start_x
        
        for index in range(self.slider_numuber):
            if self.target_index == None:
                if self.active_index == index:
                    dot_pixbuf = self.dot_active_pixbuf
                else:    
                    dot_pixbuf = self.dot_normal_pixbuf
            else:        
                if self.target_index == index:
                    dot_pixbuf = self.dot_active_pixbuf
                else:    
                    dot_pixbuf = self.dot_normal_pixbuf
                    
            pointer_rect = gtk.gdk.Rectangle(
                dot_start_x, rect.y + self.dot_y,
                self.dot_width, self.dot_height)        
            self.pointer_coords[index] = pointer_rect
            draw_pixbuf(cr, dot_pixbuf, dot_start_x, rect.y + self.dot_y)
            dot_start_x += self.dot_width_offset
            
        # Draw close pixbuf.    
        draw_pixbuf(cr, self.close_dpixbuf.get_pixbuf(), 
                    rect.x + self.close_rect.x, rect.y + self.close_rect.y)    
        
        if self.show_button and self.target_index == self.slider_numuber - 1:
            if self.button_hover_flag:
                pixbuf = self.button_press_pixbuf
            else:    
                pixbuf = self.button_normal_pixbuf
            draw_pixbuf(cr, pixbuf, rect.x + self.button_rect.x, rect.y + self.button_rect.y)    
        return True    
    
    def handle_animation(self, widget, event):    
        self.motion_index = None
        for index, rect in self.pointer_coords.items():
            if rect.x <= event.x <= rect.x + rect.width and rect.y <= event.y <= rect.y + rect.height:
                set_cursor(widget, gtk.gdk.HAND2)
                self.motion_index = index
                break    
        else:    
            self.motion_index = None
            set_cursor(widget, None)
    
    def on_motion_notify(self, widget, event):
        self.handle_animation(widget, event)
        if is_in_rect((event.x, event.y), self.button_rect):    
            self.button_hover_flag = True
        else:    
            self.button_hover_flag = False
        self.queue_draw()    
    
    def on_enter_notify(self, widget, event):
        if self.auto_animation_id is not None:
            gobject.source_remove(self.auto_animation_id)
            self.auto_animation_id = None
    
    def on_leave_notify(self, widget, event):
        self.auto_animation()
        set_cursor(widget, None)
    
    def on_button_press(self, widget, event):
        if self.motion_index != None:
            self.start_animation(self.slider_timeout, self.motion_index)
            
        if is_in_rect((event.x, event.y), self.close_rect):
            self.emit("close")
            
        if is_in_rect((event.x, event.y), self.button_rect):    
            self.emit("close")
                            
    
    def auto_animation(self):
        self.auto_animation_id = gobject.timeout_add(self.auto_animation_timeout, 
                                                 lambda : self.start_animation(self.slider_timeout))
    
    def start_animation(self, animation_time, target_index=None, direction="left"):
        if target_index is None:
            if self.active_index >= self.slider_numuber - 1:
                return False
                target_index = 0
            else:    
                target_index = self.active_index + 1
        else:        
            if target_index < self.active_index:
                direction = "right"
                
        if not self.in_animation:        
            self.in_animation = True
            self.target_index = target_index
            
            self.timeline = Timeline(animation_time, CURVE_SINE)
            self.timeline.connect("update", lambda source, status: self.update_animation(source, status, direction))
            self.timeline.connect("completed", lambda source: self.completed_animation(source, target_index))
            self.timeline.run()
        return True    
    
    def update_animation(self, source, status, direction):
        self.active_alpha = 1.0 - status
        self.target_alpha = status
        
        if direction == "right":
            self._to_right(status)
        else:    
            self._to_left(status)
            
        self.queue_draw()    
        
    def completed_animation(self, source, index):    
        self.active_index = index
        self.active_alpha = 1.0
        # self.target_index = None
        self.target_alpha = 0.0
        self.in_animation = False
        self.active_x = 0
        self.target_x = None
        self.queue_draw()
        
    def _to_right(self, status):    
        self.active_x = self.slider_width * status
        self.target_x = 0
        
    def _to_left(self, status):    
        self.active_x = 0 - (self.slider_width * status)
        self.target_x = 0
Beispiel #13
0
class HSlider(gtk.Viewport):
    '''
    HSlider class.

    @undocumented: slide_to_page
    @undocumented: set_to_page
    @undocumented: append_page
    '''

    __gsignals__ = {
        "start_slide": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        "completed_slide": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }

    def __init__(
        self,
        slide_time=200,
    ):
        '''
        Initialize HSlider class.

        @param slide_time: The animation of slide time, default is 200ms.
        '''
        gtk.Viewport.__init__(self)
        self.set_shadow_type(gtk.SHADOW_NONE)
        self.fixed = gtk.Fixed()
        self.add(self.fixed)
        self.slide_time = slide_time
        self.pre_widget = None
        self.active_widget = None
        self.connect("realize", self._update_size)
        self.connect("size_allocate", self._update_size)
        self.page_width = 0
        self.page_height = 0
        self.in_sliding = False

    def _update_size(self, w=None, _w=None):
        self.page_width = self.allocation.width
        self.page_height = self.allocation.height
        if self.active_widget:
            self.active_widget.set_size_request(self.page_width,
                                                self.page_height)
        if self.pre_widget:
            self.pre_widget.set_size_request(self.page_width, self.page_height)
        self.show_all()

    def _to_right(self, percent):
        self.offset = int(round(percent * self.page_width))

        if self.pre_widget:
            self.fixed.move(self.pre_widget, -self.offset, 0)

        self.fixed.move(self.active_widget, self.page_width - self.offset, 0)

    def _to_left(self, percent):
        self.offset = int(round(percent * self.page_width))

        if self.pre_widget:
            self.fixed.move(self.pre_widget, self.offset, 0)

        self.fixed.move(self.active_widget, self.offset - self.page_width, 0)

    def _no_effect(self):
        self.offset = self.page_width

        if self.pre_widget:
            self.fixed.remove(self.pre_widget)
        self.fixed.move(self.active_widget, 0, 0)

    def to_page(self, w, direction):
        '''
        Slide to given page.

        @param w: gtk.Widget to slide.
        @param direction: The direction of slide animation, can use below value:
         - \"right\"    slide from right to left
         - \"left\"     slide from left to right
         - None         no animation effect, slide directly
        '''
        if self.in_sliding:
            return

        if w != self.active_widget:
            w.set_size_request(self.page_width, self.page_height)
            if w.parent != self.fixed:
                self.fixed.put(w, self.page_width, 0)
            self.active_widget = w

            self.timeline = Timeline(self.slide_time, CURVE_SINE)
            if direction == "right":
                self.timeline.connect(
                    'update', lambda source, status: self._to_right(status))
            elif direction == "left":
                self.timeline.connect(
                    'update', lambda source, status: self._to_left(status))
            else:
                self._no_effect()

            self.timeline.connect("start", lambda source: self._start())
            self.timeline.connect("completed",
                                  lambda source: self._completed())
            self.timeline.run()
            self.in_sliding = True

            self.show_all()

    def _start(self):
        self.emit("start_slide")

    def _completed(self):
        if self.pre_widget and self.pre_widget.parent == self.fixed:
            self.fixed.remove(self.pre_widget)
        self.pre_widget = self.active_widget
        #print "Pre: " +  str(self.pre_widget)  + "  act: " + str(self.active_widget) + "children: " + str(self.get_children())
        self.show_all()
        self.in_sliding = False
        self.emit("completed_slide")

    def to_page_now(self, w, d=None):
        '''
        Slide to given page immediately.

        @param w: gtk.Widget to slide.
        '''
        self.to_page(w, d)

    def slide_to_page(self, w, d):
        self.to_page(w, d)

    def set_to_page(self, w):
        self.to_page_now(w)

    def append_page(self, w):
        pass
Beispiel #14
0
class WizardBox(gtk.EventBox):
    '''
    WizardBox class.

    @undocumented: init_size
    @undocumented: on_expose_event
    @undocumented: handle_animation
    @undocumented: on_motion_notify
    @undocumented: on_enter_notify
    @undocumented: on_leave_notify
    @undocumented: on_button_press
    @undocumented: auto_animation
    @undocumented: start_animation
    @undocumented: update_animation
    @undocumented: completed_animation
    '''

    __gsignals__ = {
        'close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }

    def __init__(
        self,
        slider_images=None,
        pointer_images=None,
        button_images=None,
        show_button=True,
        slide_delay=10000,
    ):
        '''
        Initialize WizardBox class.

        @param slider_images: Slider images, default is None.
        @param pointer_images: Pointer images, default is None.
        @param pointer_images: Button images, default is None.
        @param show_button: Set as True to show button.
        @param slide_delay: The time of delay between slider image, default is 10000ms.
        '''
        gtk.EventBox.__init__(self)
        self.set_visible_window(False)

        self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK
                        | gtk.gdk.POINTER_MOTION_MASK
                        | gtk.gdk.ENTER_NOTIFY_MASK
                        | gtk.gdk.LEAVE_NOTIFY_MASK)

        self.connect("expose-event", self.on_expose_event)
        self.connect("motion-notify-event", self.on_motion_notify)
        self.connect("button-press-event", self.on_button_press)

        # Init images.
        self.slider_pixbufs = map(gtk.gdk.pixbuf_new_from_file, slider_images)
        self.slider_numuber = len(slider_images)
        self.dot_normal_pixbuf, self.dot_active_pixbuf = map(
            gtk.gdk.pixbuf_new_from_file, pointer_images)
        self.button_normal_pixbuf, self.button_press_pixbuf = map(
            gtk.gdk.pixbuf_new_from_file, button_images)
        self.close_dpixbuf = ui_theme.get_pixbuf(
            "button/window_close_normal.png")

        self.show_button = show_button

        # Init sizes.
        self.init_size()
        self.pointer_coords = {}

        # Move animation.
        self.active_index = 0
        self.target_index = None

        self.active_alpha = 1.0
        self.target_index = 0.0

        self.active_x = 0
        self.target_x = None
        self.slider_y = 0
        self.auto_animation_id = None
        self.auto_animation_timeout = slide_delay  # millisecond.
        self.slider_timeout = 1000  # millisecond.
        self.in_animation = False
        self.motion_index = None
        self.auto_animation()

    def init_size(self):
        slider_pixbuf = self.slider_pixbufs[0]
        self.slider_width = slider_pixbuf.get_width()
        self.slider_height = slider_pixbuf.get_height()
        self.set_size_request(self.slider_width, self.slider_height)

        self.dot_width = self.dot_normal_pixbuf.get_width()
        self.dot_height = self.dot_normal_pixbuf.get_height()

        dot_spacing = 10
        self.dot_width_offset = self.dot_width + dot_spacing
        dot_area_width = self.dot_width * self.slider_numuber + dot_spacing * (
            self.slider_numuber - 1)
        dot_offset_y = 40
        self.dot_start_x = (self.slider_width - dot_area_width) / 2
        self.dot_y = self.slider_height - dot_offset_y

        close_spacing = 0
        close_x = self.slider_width - self.close_dpixbuf.get_pixbuf(
        ).get_width() - close_spacing
        close_y = close_spacing
        self.close_rect = gtk.gdk.Rectangle(
            close_x, close_y,
            self.close_dpixbuf.get_pixbuf().get_width(),
            self.close_dpixbuf.get_pixbuf().get_height())

        button_bottom_size = 55
        button_width = self.button_normal_pixbuf.get_width()
        button_height = self.button_normal_pixbuf.get_height()
        button_x = (self.slider_width - button_width) / 2
        button_y = self.slider_height - button_height - button_bottom_size
        self.button_rect = gtk.gdk.Rectangle(button_x, button_y, button_width,
                                             button_height)

    def on_expose_event(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.save()
        draw_pixbuf(cr, self.slider_pixbufs[self.active_index],
                    rect.x + self.active_x, rect.x + self.slider_y,
                    self.active_alpha)

        if self.target_index != None and self.target_x != None:
            draw_pixbuf(cr, self.slider_pixbufs[self.target_index],
                        rect.x + self.target_x, rect.y + self.slider_y,
                        self.target_alpha)
        cr.restore()

        # Draw select pointer.
        dot_start_x = rect.x + self.dot_start_x

        for index in range(self.slider_numuber):
            if self.target_index == None:
                if self.active_index == index:
                    dot_pixbuf = self.dot_active_pixbuf
                else:
                    dot_pixbuf = self.dot_normal_pixbuf
            else:
                if self.target_index == index:
                    dot_pixbuf = self.dot_active_pixbuf
                else:
                    dot_pixbuf = self.dot_normal_pixbuf

            pointer_rect = gtk.gdk.Rectangle(dot_start_x, rect.y + self.dot_y,
                                             self.dot_width, self.dot_height)
            self.pointer_coords[index] = pointer_rect
            draw_pixbuf(cr, dot_pixbuf, dot_start_x, rect.y + self.dot_y)
            dot_start_x += self.dot_width_offset

        # Draw close pixbuf.
        draw_pixbuf(cr, self.close_dpixbuf.get_pixbuf(),
                    rect.x + self.close_rect.x, rect.y + self.close_rect.y)

        if self.show_button and self.target_index == self.slider_numuber - 1:
            if self.button_hover_flag:
                pixbuf = self.button_press_pixbuf
            else:
                pixbuf = self.button_normal_pixbuf
            draw_pixbuf(cr, pixbuf, rect.x + self.button_rect.x,
                        rect.y + self.button_rect.y)
        return True

    def handle_animation(self, widget, event):
        self.motion_index = None
        for index, rect in self.pointer_coords.items():
            if rect.x <= event.x <= rect.x + rect.width and rect.y <= event.y <= rect.y + rect.height:
                set_cursor(widget, gtk.gdk.HAND2)
                self.motion_index = index
                break
        else:
            self.motion_index = None
            set_cursor(widget, None)

    def on_motion_notify(self, widget, event):
        self.handle_animation(widget, event)
        if is_in_rect((event.x, event.y), self.button_rect):
            self.button_hover_flag = True
        else:
            self.button_hover_flag = False
        self.queue_draw()

    def on_enter_notify(self, widget, event):
        if self.auto_animation_id is not None:
            gobject.source_remove(self.auto_animation_id)
            self.auto_animation_id = None

    def on_leave_notify(self, widget, event):
        self.auto_animation()
        set_cursor(widget, None)

    def on_button_press(self, widget, event):
        if self.motion_index != None:
            self.start_animation(self.slider_timeout, self.motion_index)

        if is_in_rect((event.x, event.y), self.close_rect):
            self.emit("close")

        if is_in_rect((event.x, event.y), self.button_rect):
            self.emit("close")

    def auto_animation(self):
        self.auto_animation_id = gobject.timeout_add(
            self.auto_animation_timeout,
            lambda: self.start_animation(self.slider_timeout))

    def start_animation(self,
                        animation_time,
                        target_index=None,
                        direction="left"):
        if target_index is None:
            if self.active_index >= self.slider_numuber - 1:
                return False
                target_index = 0
            else:
                target_index = self.active_index + 1
        else:
            if target_index < self.active_index:
                direction = "right"

        if not self.in_animation:
            self.in_animation = True
            self.target_index = target_index

            self.timeline = Timeline(animation_time, CURVE_SINE)
            self.timeline.connect(
                "update", lambda source, status: self.update_animation(
                    source, status, direction))
            self.timeline.connect(
                "completed",
                lambda source: self.completed_animation(source, target_index))
            self.timeline.run()
        return True

    def update_animation(self, source, status, direction):
        self.active_alpha = 1.0 - status
        self.target_alpha = status

        if direction == "right":
            self._to_right(status)
        else:
            self._to_left(status)

        self.queue_draw()

    def completed_animation(self, source, index):
        self.active_index = index
        self.active_alpha = 1.0
        # self.target_index = None
        self.target_alpha = 0.0
        self.in_animation = False
        self.active_x = 0
        self.target_x = None
        self.queue_draw()

    def _to_right(self, status):
        self.active_x = self.slider_width * status
        self.target_x = 0

    def _to_left(self, status):
        self.active_x = 0 - (self.slider_width * status)
        self.target_x = 0