Faster icon rotation using various cachings
[drlaunch] / src / icongrid.py
index 1308bb0..3571736 100755 (executable)
@@ -32,44 +32,44 @@ import cairo
 import time
 
 from portrait import FremantleRotation
-from xdg.IconTheme import getIconPath
+#from xdg.IconTheme import getIconPath
 
-import config
+#import config
 import apps
 import icon
 from icon import Icon
 from icons import Icons
 
-def getIcon(name):
-    ico=getIconPath(name, config.iconsize)
-    ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, config.iconsize,
-       config.iconsize)
-
-    return(ret)
+#def getIcon(name, iconsize):
+#    ico=getIconPath(name, iconsize)
+#    ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, iconsize, iconsize)
+#
+#    return(ret)
 
 #class IconGrid(gtk.Widget, FremantleRotation):
 class IconGrid(object):        #(gobject.GObject):
     def __init__(self, isconfig=False):
 #      self.__gobject_init__()
 
-       self.size=0
+       self.init_done=False
 
-       self.isconfig=isconfig
+       self.size=(0,0)
 
-       self.icons=Icons(isconfig)
+       self.isconfig=isconfig
 
-       self.setMode('l')
+       self.icons=None
+       self.lasticon=None  # The last icon that got selected
 
-       # Maybe fix those:
-#      w=(config.getSize() * config.iconsize) + \
-#          (config.getSize()) * config.iconspace
-       #self.set_size_request(w, w)
+       self.draw_pending=False
 
-#      self.setSize(config.getSize())
-       self.setSize(4)
+       self.mode=None
 
-       self.lasticon=None  # The last icon that got selected
+    def do_realize(self, config):
+       self.config=config
 
+       self.icons=Icons(self.isconfig, self.config)
+       self.setMode('l')
+       self.setSize((4,4))
        self.reloadIcons()
 
     def connect(self, what, *args):
@@ -79,29 +79,88 @@ class IconGrid(object):     #(gobject.GObject):
            super(IconGrid, self).connect(what, *args)
 
     def setSize(self, size):
-       print "igw::setSize", size
-#      config.setSize(size)
        self.size=size
        self.icons.setSize(size)
 
+    def getSize(self):
+       ret=self.icons.getSize()
+       return(ret)
+
     def setMode(self, mode):
+       if self.mode==mode:
+           print "same mode"
+           return
+
        self.mode=mode
-       if isinstance(self, gtk.Widget):
+       if not isinstance(self, gtk.Widget):
+           return
+
+       do_draw=False
+
+       try:
+           v=self.get_property('is-on-current-desktop')
+           if v:
+               do_draw=True
+           else:
+               self.draw_pending=True
+       except TypeError:
+           do_draw=True
+
+       if do_draw:
+           #self.queue_draw()
+           self.angle_timer_start=time.time()
+           gobject.timeout_add(20, self.timerAngle)
+        else:
+            if self.mode=='l':
+                self.setAngle(0)
+            else:
+                self.setAngle(90)
+                
+    def timerAngle(self):
+       if self.angle_timer_start==0:
+           self.angle_timer_start=time.time()-0.05
+
+       dt=time.time()-self.angle_timer_start
+
+       # Duration of the rotation effect
+       rotation_time=0.5
+
+       da=90.0*dt/rotation_time
+
+       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
+
+       if self.setAngle(angle):
            self.queue_draw()
 
+       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 """
 
-       w=config.iconsize + config.iconspace
+       w=self.config.iconsize + self.config.iconspace
 
-       if self.mode=='l':
+       if self.mode=='l' or self.config.getIndiv():
            x2=int(x / w)
            y2=int(y / w)
        else:
-           x2=self.size - int(y/w) - 1
+           x2=self.size[1] - int(y/w) - 1
            y2=int(x/w)
 
-       print "x2,y2", x2, y2
        ret=self.get(x2,y2)
 
        return(ret)
@@ -112,19 +171,17 @@ class IconGrid(object):   #(gobject.GObject):
        return(ret)
 
     def _draw(self, cr, event):
-#      print "mode:", self.mode
-#      print "icons", len(self.icons)
+       self.draw_pending=False
 
-       w=config.iconsize + config.iconspace
+       w=self.config.iconsize + self.config.iconspace
        for x,y in self.icons:
-#          print x, y
-
-           if self.mode=='l':
-               x2=x * (config.iconsize + config.iconspace)
-               y2=y * (config.iconsize + config.iconspace)
+           if self.mode=='l' or self.config.getIndiv():
+               x2=x * (self.config.iconsize + self.config.iconspace)
+               y2=y * (self.config.iconsize + self.config.iconspace)
            else:
-               x2=y * (config.iconsize + config.iconspace)
-               y2=(self.size-x-1) * (config.iconsize + config.iconspace)
+               x2=y * (self.config.iconsize + self.config.iconspace)
+               y2=(self.size[1]-x-1) * \
+                       (self.config.iconsize + self.config.iconspace)
 
            # Only repaint the needed icons
            rect=gdk.Rectangle(x2, y2, w, w)
@@ -132,9 +189,18 @@ class IconGrid(object):    #(gobject.GObject):
            if t.width==0 and t.height==0:
                continue
 
-#          print "draw:", x, y
            ico=self.icons.get(x,y)
-           ico.draw(cr, x2, y2, self.mode)
+           ico.draw(cr, x2, y2)
+
+    def setAngle(self, angle):
+       """ Return True/False indicating that angle has changed """
+       ret=False
+       for x,y in self.icons:
+           ic=self.icons.get(x,y)
+           if ic.setAngle(angle):
+               ret=True
+
+       return(ret)
 
     def do_expose_event(self, event):
        cr=self.window.cairo_create()
@@ -144,6 +210,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):
@@ -156,7 +226,6 @@ class IconGrid(object):     #(gobject.GObject):
        self.lasticon=icon
 
     def do_button_press_event(self, event):
-       print "press", event.type
        icon=self.iconAt(event.x, event.y)
        if icon==None:
            return
@@ -171,7 +240,6 @@ class IconGrid(object):     #(gobject.GObject):
        return(True)
 
     def do_button_release_event(self, event):
-       print "release"
        if self.lasticon!=None:
            self.lasticon.invalidate(self.window)
            self.lasticon.doRelease()
@@ -181,13 +249,10 @@ class IconGrid(object):   #(gobject.GObject):
        return(True)
 
     def do_leave_notify_event(self, event):
-       print "leave"
-       #print "leave", event.x, event.y
        self.setLastIcon(None)
        return(True)
 
     def do_pproperty_notify_event(self, event):
-       print "property"
        icon=self.iconAt(event.x, event.y)
        if icon==None:
            return
@@ -196,7 +261,6 @@ class IconGrid(object):     #(gobject.GObject):
        return(True)
 
     def do_motion_notify_event(self, event):
-       print "motion"
        icon=self.iconAt(event.x, event.y)
        if self.lasticon==icon:
            return(True)
@@ -207,9 +271,7 @@ class IconGrid(object):     #(gobject.GObject):
        return(True)
 
     def do_button_press_event_old(self, event):
-       #print "press"
        if event.type==gdk.BUTTON_PRESS:
-           print "press", event.type
            if self.mode=='p':
                self.setMode('l')
            else:
@@ -221,9 +283,6 @@ class IconGrid(object):     #(gobject.GObject):
     def do_event1(self, event):
        print "event:", event, event.type
 
-    def butTest(self, arg):
-       print "but", arg
-
     def reloadIcons(self):
        self.icons.load()
 
@@ -233,16 +292,23 @@ class IconGrid(object):   #(gobject.GObject):
 #      self.setMode(o)
 
 class IconGridWidget(IconGrid, gtk.Widget):
-    def __init__(self, isconfig):
+    def __init__(self, isconfig, config):
        IconGrid.__init__(self, isconfig)
        gtk.Widget.__init__(self)
 
+       self.config=config
+
+       IconGrid.do_realize(self, self.config)
+
        if isconfig:
-           w=4 * (config.iconsize + config.iconspace)
+           maxsz=self.config.getMaxSize()
+           w=maxsz[0] * (self.config.iconsize + self.config.iconspace)
+           h=maxsz[1] * (self.config.iconsize + self.config.iconspace)
        else:
-           w=self.size * (config.iconsize + config.iconspace)
+           w=self.size[0] * (self.config.iconsize + self.config.iconspace)
+           h=self.size[1] * (self.config.iconsize + self.config.iconspace)
 
-       self.set_size_request(w, w)
+       self.set_size_request(w, h)
 
     def do_realize(self):
        screen=self.get_screen()