From: Stefanos Harhalakis Date: Mon, 2 Aug 2010 21:46:34 +0000 (+0000) Subject: Added animation for icon rotation. X-Git-Url: https://vcs.maemo.org/git/?p=drlaunch;a=commitdiff_plain;h=97ecd4b9fdb91f797b6a6ddbac335e52326845e0 Added animation for icon rotation. --- diff --git a/src/icon.py b/src/icon.py index aafe320..df559cc 100755 --- a/src/icon.py +++ b/src/icon.py @@ -82,6 +82,8 @@ class Icon(gobject.GObject): self.clickcount=0 + self.angle=0 + def timePressed(self): """ return how much time a button is pressed """ dt=time.time() - self.lastpress @@ -100,7 +102,20 @@ class Icon(gobject.GObject): def getSize(self): return(self.config.iconsize+self.config.iconspace) - def draw(self, cr, x, y, mode): + def setAngle(self, angle): + if self.angle==angle: + print "Same angle" + return + + self.angle=angle + + # The caller should be responsible for redrawing. + # If we call invalidate() here there is the risk of having + # icons rotate individually using different angles +# self.invalidate() + + def draw(self, cr, x, y): + self.draw_queued=False self.x=x self.y=y @@ -108,6 +123,7 @@ class Icon(gobject.GObject): return cr.save() + cr.set_source_rgba(0.1, 0.1, 0.1, 1) cr.set_line_width(5) @@ -143,15 +159,54 @@ class Icon(gobject.GObject): icon=self.icon - if mode=='l': - icon2=icon - else: - icon2=icon.rotate_simple(gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE) + icon2=icon + +# Old method. Faster rotation but without support for rotation +# animation + +# if mode=='l': +# icon2=icon +# else: +# icon2=icon.rotate_simple(gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE) + +# cr.save() +# x3=x + (self.config.iconspace/2) +# y3=y + (self.config.iconspace/2) +# cr.set_source_pixbuf(icon2, x3, y3) +# +# cr.paint() +# cr.restore() + + # Width is the iconsize plus the empty border around the icon + w=self.config.iconsize + self.config.iconspace + + # This is used to locate the center of the surface + dx=int(w/2) + + # This is the delta from the center where icons are drawn + dx2=int(self.config.iconsize/2) + + # A surface to draw on + t_s=cairo.ImageSurface(cairo.FORMAT_ARGB32, w, w) + + # And a context to draw + t_cr0=cairo.Context(t_s) + t_cr=gtk.gdk.CairoContext(t_cr0) + + # A transformation matrix with dx/dy set to point to the center + m=cairo.Matrix(1, 0, 0, 1, dx, dx) + t_cr.set_matrix(m) + # Transform degrees to rads + rot=-1 * pi * 2 * self.angle / 360 + t_cr.rotate(rot) + # Draw the icon + t_cr.set_source_pixbuf(icon2, -dx2, -dx2) + t_cr.paint() + + # Draw the rotated icon on the main cairo context cr.save() - x3=x + (self.config.iconspace/2) - y3=y + (self.config.iconspace/2) - cr.set_source_pixbuf(icon2, x3, y3) + cr.set_source_surface(t_s, x, y) cr.paint() cr.restore() @@ -198,6 +253,9 @@ class Icon(gobject.GObject): def doCancel(self): self.ispressed=False + def setWindow(self, window): + self.window=window + def invalidate(self, window=None): if window==None: window=self.window @@ -207,6 +265,10 @@ class Icon(gobject.GObject): if window==None: return + if self.draw_queued: + print "queued" + return + self.draw_queued=True w=self.config.iconsize + self.config.iconspace rect=gdk.Rectangle(self.x, self.y, w, w) gdk.Window.invalidate_rect(window, rect, True) diff --git a/src/icongrid.py b/src/icongrid.py index ffe098d..0278dde 100755 --- a/src/icongrid.py +++ b/src/icongrid.py @@ -51,6 +51,8 @@ class IconGrid(object): #(gobject.GObject): def __init__(self, isconfig=False): # self.__gobject_init__() + self.init_done=False + self.size=(0,0) self.isconfig=isconfig @@ -60,6 +62,8 @@ class IconGrid(object): #(gobject.GObject): self.draw_pending=False + self.mode=None + def do_realize(self, config): self.config=config @@ -83,18 +87,60 @@ class IconGrid(object): #(gobject.GObject): return(ret) def setMode(self, mode): + if self.mode==mode: + print "same mode" + return + self.mode=mode if not isinstance(self, gtk.Widget): return + do_draw=False + try: v=self.get_property('is-on-current-desktop') if v: - self.queue_draw() + do_draw=True else: self.draw_pending=True except TypeError: - self.queue_draw() + do_draw=True + + if do_draw: + #self.queue_draw() + self.angle_timer_start=time.time() + gobject.timeout_add(20, self.timerAngle) + + def timerAngle(self): + self.queue_draw() + + if self.angle_timer_start==0: + self.angle_timer_start=time.time() + + dt=time.time()-self.angle_timer_start + + da=90.0*dt/0.5 + + if self.mode=='l': + angle=90-da + else: + angle=da + + if angle>=90: + angle=90 + ret=False + elif angle<0: + angle=0 + ret=False + else: + ret=True + + self.setAngle(angle) + + if ret==False: + self.angle_timer_start=0 + + return(ret) def iconAt(self, x, y): """ Get icon at coordinates x,y. X and Y are in pixels """ @@ -137,7 +183,12 @@ class IconGrid(object): #(gobject.GObject): continue ico=self.icons.get(x,y) - ico.draw(cr, x2, y2, self.mode) + ico.draw(cr, x2, y2) + + def setAngle(self, angle): + for x,y in self.icons: + ic=self.icons.get(x,y) + ic.setAngle(angle) def do_expose_event(self, event): cr=self.window.cairo_create() @@ -147,6 +198,10 @@ class IconGrid(object): #(gobject.GObject): cr.clip() + if not self.init_done: + self.icons.setWindow(self.window) + self.init_done=True + self._draw(cr, event) def setLastIcon(self, icon): diff --git a/src/icons.py b/src/icons.py index 015273b..3f663d7 100755 --- a/src/icons.py +++ b/src/icons.py @@ -116,6 +116,13 @@ class Icons(gobject.GObject): def getSize(self): return(self.size) + def setWindow(self, win): + """ Set the window for all icons """ + + for i in self.icons: + ic=self.icons[i] + ic.setWindow(win) + def signalLongpress(self, icon): #print "signalLongpress()", icon self.emit('long-press', icon)