vim line
[drlaunch] / src / win_config.py
index 124dbe8..4639e2b 100755 (executable)
@@ -26,45 +26,240 @@ import gtk
 import gobject
 import hildon
 import time
+import copy
 
 from hildon import StackableWindow
 #from portrait import FremantleRotation
 #from xdg.IconTheme import getIconPath
 
-#import config
+import config
 import apps
 from icon import Icon, getIcon
+from iconw import IconWidget
 from icongrid import IconGridWidget
+from about import DlgAbout
+from portrait import FremantleRotation
+from sig import Disconnector
 
-class WinConfig(StackableWindow):
+class DialogIconSize(gtk.Dialog):
+    def __init__(self, config):
+       gtk.Dialog.__init__(self, "Adjust icon size")
+
+       # Operate on copy of config
+       self.config=copy.copy(config)
+       # And keep another copy to be able to undo
+       self.config0=copy.copy(config)
+
+       vbox=self.vbox
+
+       self.pa=hildon.PannableArea()
+       vbox.add(self.pa)
+       self.pa.set_property('mov-mode', hildon.MOVEMENT_MODE_VERT)
+
+       vbox=gtk.VBox()
+       self.pa.add_with_viewport(vbox)
+       self.pa.set_size_request(-1, 1000)
+
+       self.labelDim=gtk.Label("koko")
+       vbox.add(self.labelDim)
+
+       vbox.add(gtk.Label("Icon size:"))
+       scale=gtk.HScale()
+       scale.set_digits(0)
+       scale.set_value_pos(gtk.POS_RIGHT)
+       scale.set_range(*self.config.getIconSizeRange())
+       scale.set_increments(8, 16)
+       self.scaleIconSize=scale
+       vbox.add(scale)
+
+       hbox=gtk.HBox()
+       vbox.add(hbox)
+
+       vbox2=gtk.VBox()
+       vbox2.add(gtk.Label("Padding:"))
+       scale=gtk.HScale()
+       scale.set_digits(0)
+       scale.set_value_pos(gtk.POS_RIGHT)
+       scale.set_range(*self.config.getIconPaddingRange())
+       scale.set_increments(2,2)
+       self.scaleIconPadding=scale
+       vbox2.add(scale)
+       hbox.add(vbox2)
+
+       vbox2=gtk.VBox()
+       vbox2.add(gtk.Label("Margin:"))
+       scale=gtk.HScale()
+       scale.set_digits(0)
+       scale.set_value_pos(gtk.POS_RIGHT)
+       scale.set_range(*self.config.getIconMarginRange())
+       scale.set_increments(2,2)
+       self.scaleIconMargin=scale
+       vbox2.add(scale)
+       hbox.add(vbox2)
+
+       self.icon=IconWidget(False, self.config)
+       self.icon.setApp('osso-addressbook')
+       vbox.add(self.icon)
+
+       self.scaleIconSize.set_value(self.config.getIconSize())
+       self.scaleIconPadding.set_value(self.config.getIconPadding())
+       self.scaleIconMargin.set_value(self.config.getIconMargin())
+
+       # Set thos after settings initial values to avoid unwanted effects
+       self.scaleIconSize.connect('value-changed', self.slotSzChangeSize)
+       self.scaleIconPadding.connect('value-changed', self.slotSzChangePadding)
+       self.scaleIconMargin.connect('value-changed', self.slotSzChangeMargin)
+
+       hbox=gtk.HBox()
+       vbox.add(hbox)
+
+       but=hildon.Button(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
+               hildon.BUTTON_ARRANGEMENT_VERTICAL)
+       but.set_title("OK")
+       but.connect("clicked", self.slotButtonOK)
+       #hbox.add(but)
+       self.action_area.pack_start(but)
+       self.buttonOK=but
+
+       but=hildon.Button(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
+               hildon.BUTTON_ARRANGEMENT_VERTICAL)
+       but.set_title("Undo")
+       but.connect("clicked", self.slotButtonUndo)
+       #hbox.add(but)
+       self.action_area.pack_start(but)
+       self.buttonUndo=but
+
+       but=hildon.Button(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
+               hildon.BUTTON_ARRANGEMENT_VERTICAL)
+       but.set_title("Restore defaults")
+       but.connect("clicked", self.slotButtonDefaults)
+       #hbox.add(but)
+       self.action_area.pack_start(but)
+       self.buttonDefaults=but
+
+       self.show_all()
+
+       self.recalc()
+
+    def setWH(self, w, h):
+       self.labelDim.set_text("Grid size: %d x %d icons" % (w, h))
+       #self.labelWidth.set_text("Width: %d icons" % w)
+       #self.labelHeight.set_text("Height: %d icons" % h)
+
+    def recalc(self):
+       maxsz=self.config.getMaxSize()
+       self.setWH(maxsz[0], maxsz[1])
+       self.icon.refresh()
+
+    def getIconSize(self):
+       return(self.scaleIconSize.get_value())
+
+    def setIconSize(self, iconsize):
+       self.scaleIconSize.set_value(iconsize)
+
+    def getIconPadding(self):
+       return(self.scaleIconPadding.get_value())
+
+    def setIconPadding(self, pad):
+       self.scaleIconPadding.set_value(pad)
+
+    def getIconMargin(self):
+       return(self.scaleIconMargin.get_value())
+
+    def setIconMargin(self, margin):
+       self.scaleIconMargin.set_value(margin)
+
+    def slotSzChangeSize(self, sender):
+       self.config.setIconSize(int(self.getIconSize()))
+       self.recalc()
+
+    def slotSzChangeMargin(self, sender):
+       self.config.setIconMargin(int(self.getIconMargin()))
+       self.recalc()
+
+    def slotSzChangePadding(self, sender):
+       self.config.setIconPadding(int(self.getIconPadding()))
+       self.recalc()
+
+    def slotButtonUndo(self, sender):
+       self.config=copy.copy(self.config0)
+       self.recalc()
+       self.resetSliders()
+
+    def slotButtonDefaults(self, sender):
+       self.config.setDefaultSizes()
+       self.recalc()
+       self.resetSliders()
+
+    def slotButtonOK(self, sender):
+       self.response(gtk.RESPONSE_OK)
+
+    def resetSliders(self):
+       self.scaleIconSize.set_value(self.config.getIconSize())
+       self.scaleIconPadding.set_value(self.config.getIconPadding())
+       self.scaleIconMargin.set_value(self.config.getIconMargin())
+
+    def getData(self):
+       ret={
+           'size':     self.config.getIconSize(),
+           'padding':  self.config.getIconPadding(),
+           'margin':   self.config.getIconMargin()
+           }
+
+       return(ret)
+
+
+class WinConfig(StackableWindow, Disconnector): #, FremantleRotation):
     def __init__(self, config, *args):
        StackableWindow.__init__(self)
+       Disconnector.__init__(self)
+#      FremantleRotation.__init__(self, "DrlaunchPlugin",
+#          mode=FremantleRotation.AUTOMATIC)
 
-       self.config=config
+       self.config=copy.copy(config)
 
        self.setupUi()
 
+#      h=self.c(self, 'delete-event', self.slotDeleteEvent)
+
+# This is a nice test. If it is displayed then the window is actually
+# destroyed and there is no memory leak
+#    def __del__(self):
+#      print "wc-del"
+
     def setupUi(self):
-       self.igw=IconGridWidget(True, self.config)
-#      self.igw.do_realize()
-#      self.igw.setSize(config.getSize())
+       """
+       self.pa         Main Pannable Area
+       self.col1       A VBox for the first column
+       self.col2       A VBox for the second column
+       self.w_igw      The IGW in an alignment
+       """
+       self.set_title("DrLaunch v" + config.version)
 
-       hbox=gtk.HBox()
-       self.add(hbox)
+       self.pa=hildon.PannableArea()
+#      self.add(self.pa)
+       self.pa.set_property('mov-mode', hildon.MOVEMENT_MODE_HORIZ)
 
-       # Add the icongrid
-       hbox.add(self.igw)
+       self.add(self.pa)
 
-       # Now go for the right side
-       al=gtk.Alignment(yscale=0)
-       hbox.add(al)
+#1     hbox=gtk.HBox()
+#1     self.pa.add_with_viewport(hbox)
+
+       # Add the first column of options
+       al=gtk.Alignment(yscale=1)
+#1     hbox.add(al)
 
        vbox=gtk.VBox()
-#      hbox.add(vbox)
        al.add(vbox)
+       self.col1=al
 
        maxsz=self.config.getMaxSize()
 
+       self.maxmaxsz=(16,16)
+
        # ----------------------------------------------
        vbox.add(gtk.Label('Width:'))
 
@@ -72,11 +267,10 @@ class WinConfig(StackableWindow):
        vbox.add(hbox2)
 
        self.butsSizeX=[]
-       self.butsSize=self.butsSizeX # For now
-       for i in xrange(maxsz[0]):
+       for i in xrange(self.maxmaxsz[0]):
            but=hildon.GtkToggleButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
            but.set_label("%s" % (i+1,))
-           but.connect('toggled', self.slotButtonSizeX, i)
+           self.c(but, 'toggled', self.slotButtonSizeX, i)
 
            self.butsSizeX.append(but)
 
@@ -89,19 +283,28 @@ class WinConfig(StackableWindow):
        vbox.add(hbox2)
 
        self.butsSizeY=[]
-       for i in xrange(maxsz[1]):
+       for i in xrange(self.maxmaxsz[1]):
            but=hildon.GtkToggleButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
            but.set_label("%s" % (i+1,))
-           but.connect('toggled', self.slotButtonSizeY, i)
+           self.c(but, 'toggled', self.slotButtonSizeY, i)
 
            self.butsSizeY.append(but)
 
            hbox2.add(but)
 
+       vbox2=gtk.VBox()
+
+       al=gtk.Alignment(xalign=0, yalign=1, xscale=1)
+       al.add(vbox2)
+       self.col11=al
+
+       vbox.add(al)
+       vbox=vbox2
+
        but=hildon.CheckButton(
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
        but.set_label("Rotate icons individually")
-       but.connect('toggled', self.slotButtonRotateIndividually)
+       self.c(but, 'toggled', self.slotButtonRotateIndividually)
        self.buttonRotateIndividually=but
        vbox.add(but)
 
@@ -112,6 +315,62 @@ class WinConfig(StackableWindow):
        self.buttonRequireLongpress=but
        vbox.add(but)
 
+       but=hildon.CheckButton(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
+       but.set_label("Animate rotation")
+       self.buttonAnimateRotation=but
+       vbox.add(but)
+
+       # -----------------------------------------------
+       # Second column of options
+       vbox=gtk.VBox()
+
+       al=gtk.Alignment(xalign=0, yalign=1, xscale=1)
+       al.add(vbox)
+       self.col2=al
+
+       but=hildon.CheckButton(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
+       but.set_label("Theme background")
+       but.connect('toggled', self.slotButtonThemeBackground)
+       self.buttonThemeBackground=but
+       vbox.add(but)
+
+       but=hildon.CheckButton(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
+       but.set_label("No background")
+       self.c(but, 'toggled', self.slotButtonNoBackground)
+       self.buttonNoBackground=but
+       vbox.add(but)
+
+       but=hildon.Button(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
+               hildon.BUTTON_ARRANGEMENT_VERTICAL)
+       but.set_label("Adjust icon size")
+       self.c(but, 'clicked', self.slotButtonIconSize)
+       self.buttonIconSize=but
+       vbox.add(but)
+
+#1     hbox.add(al)
+       but=hildon.Button(
+               gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
+               hildon.BUTTON_ARRANGEMENT_VERTICAL)
+       but.set_title("About")
+       self.c(but, "clicked", self.slotButtonAbout)
+       vbox.add(but)
+       self.buttonAbout=but
+
+       # -----------------------------------------------
+       # Add the icongrid
+       self.igw=IconGridWidget(True, self.config, False)
+#      self.igw.do_realize()
+#      self.igw.setSize(config.getSize())
+       al=gtk.Alignment(xalign=0, xscale=0)
+       al.add(self.igw)
+       al.set_padding(0, 0, 20, 0)
+       self.w_igw=al
+#1     hbox.add(al)
+
        self.igw.connect('long-press', self.slotLongpress)
        self.igw.connect('click', self.slotLongpress)
 
@@ -120,6 +379,118 @@ class WinConfig(StackableWindow):
        self.setSize(self.config.getSize())
        self.setIndiv(self.config.getIndiv())
        self.setLongpress(self.config.getLongpress())
+       self.setAnimate(self.config.getAnimate())
+       self.setNoBg(self.config.getNoBg())
+       self.setThemeBg(self.config.getThemeBg())
+#      self.setIconSize(self.config.getIconSize())
+#      self.setIconPadding(self.config.getIconPadding())
+#      self.setIconMargin(self.config.getIconMargin())
+
+       hbox=gtk.HBox()
+       hbox.add(self.col1)
+       hbox.add(self.col2)
+       hbox.add(self.w_igw)
+       self.pa.add_with_viewport(hbox)
+
+       self.adjustMaxSize()
+
+#    def setupUi(self, orientation):
+#
+#      self.setupUi0()
+#
+#      hbox=gtk.HBox()
+#
+#      if orientation=='l':
+#          hbox.add(self.col1)
+#          hbox.add(self.col2)
+#          hbox.add(self.w_igw)
+#      else:
+#          vbox=gtk.VBox()
+#          hbox.add(vbox)
+#          vbox.add(self.col1)
+#          vbox.add(self.col2)
+#          hbox.add(self.w_igw)
+#
+#      self.pa.add_with_viewport(hbox)
+#
+#      if self.get_child()!=None:
+#          self.remove(self.get_child())
+#      self.add(self.pa)
+#      self.pa.show_all()
+
+    def adjustMaxSize(self):
+       sz=self.config.getMaxSize()
+       maxsz=self.maxmaxsz
+
+       for x in xrange(maxsz[0]):
+           if x<sz[0]:
+               self.butsSizeX[x].show()
+           else:
+               self.butsSizeX[x].hide()
+
+       for y in xrange(maxsz[1]):
+           if y<sz[1]:
+               self.butsSizeY[y].show()
+           else:
+               self.butsSizeY[y].hide()
+
+       osz=self.getSize()
+       nsz=[osz[0], osz[1]]
+
+       if osz[0]>sz[0]:
+           nsz[0]=sz[0]
+       if osz[1]>sz[1]:
+           nsz[1]=sz[1]
+       self.setSize(nsz)
+
+       self.setIndiv(self.getIndiv())
+
+    def setLayoutPortrait(self):
+       print "lo: p"
+       hbox=gtk.HBox()
+       
+       vbox=gtk.VBox()
+       hbox.add(vbox)
+       self.col1.reparent(vbox)
+       self.col2.reparent(vbox)
+       self.w_igw.reparent(hbox)
+
+       r=self.pa.get_children()[0]
+       self.pa.remove(r)
+       r.destroy()
+       self.pa.add_with_viewport(hbox)
+
+       self.pa.show_all()
+
+    def setLayoutLandscape(self):
+       print "lo: l"
+       hbox=gtk.HBox()
+       
+       self.col1.reparent(hbox)
+       self.col2.reparent(hbox)
+       self.w_igw.reparent(hbox)
+
+       r=self.pa.get_children()[0]
+       self.pa.remove(r)
+       r.destroy()
+       self.pa.add_with_viewport(hbox)
+
+       self.pa.show_all()
+
+    def on_orientation_changed(self, orientation):
+       # This is disabled for now since I've not found any reliable
+       # way for supporting orientation changes (#$#%$#*&% GTK)
+       return
+
+       print "orch:", orientation
+       if orientation=='portrait':
+           self.setLayoutPortrait()
+       else:
+           self.setLayoutLandscape()
+
+#    def slotDeleteEvent(self, sender, event):
+#      print "wc-del-event"
+#      return(False)
 
     def slotLongpress(self, sender, icon):
        self.doConfig(icon)
@@ -142,6 +513,48 @@ class WinConfig(StackableWindow):
        but=self.buttonRotateIndividually
        self.setIndiv(but.get_active())
 
+    def slotButtonNoBackground(self, sender):
+       nobg=self.getNoBg()
+       self.setNoBg(nobg)
+
+    def slotButtonThemeBackground(self, sender):
+       themebg=self.getThemeBg()
+       self.setThemeBg(themebg)
+
+    def slotButtonAbout(self, sender):
+       DlgAbout.present2(self)
+
+    def slotButtonIconSize(self, sender):
+       dlg=DialogIconSize(self.config)
+       ret=dlg.run()
+       dt=dlg.getData()
+       dlg.destroy()
+
+       if ret!=gtk.RESPONSE_OK:
+           return
+
+       self.config.setIconSize(dt['size'])
+       self.config.setIconMargin(dt['margin'])
+       self.config.setIconPadding(dt['padding'])
+       self.igw.reconfig()
+       self.adjustMaxSize()
+       self.queue_draw()
+
+    def show_all(self):
+       StackableWindow.show_all(self)
+#      return
+       self.adjustMaxSize()
+       self.queue_draw()
+
+#    def slotScaleIconSzChange(self, sender):
+#      return
+#      self.config.setIconSize(self.getIconSize())
+#      self.config.setIconMargin(self.getIconMargin())
+#      self.config.setIconPadding(self.getIconPadding())
+#      self.igw.reconfig()
+#      self.adjustMaxSize()
+#      self.queue_draw()
+
 #    def slotButtonLongpress(self, sender):
 #      but=self.buttonRequireLongpress
 #      self.set
@@ -171,6 +584,7 @@ class WinConfig(StackableWindow):
        self.igw.setSize(sz)
 
        self.igw.queue_draw()
+       self.queue_draw()
 
     def getSize(self):
        return(self.igw.getSize())
@@ -184,13 +598,28 @@ class WinConfig(StackableWindow):
        if indiv:
            for i in self.butsSizeY:
                i.set_sensitive(True)
+           for i in self.butsSizeX:
+               i.set_sensitive(True)
+
        else:
+           sz=self.config.getMaxSize()
+
            for i in self.butsSizeY:
                i.set_sensitive(False)
+
+           cnt=0
+           for i in self.butsSizeX:
+               cnt+=1
+               # Height is always the narrower, so use that as a limit
+               if cnt>sz[1]:
+                   i.set_sensitive(False)
+               else:
+                   i.set_sensitive(True)
+
            sz=self.getSize()
            szx=sz[0]
-           if szx>4:
-               szx=4
+           if szx>sz[1]:
+               szx=sz[1]
            self.setSize((szx, szx))
 
        self.buttonRotateIndividually.set_active(indiv)
@@ -198,6 +627,29 @@ class WinConfig(StackableWindow):
     def setLongpress(self, lp):
        self.buttonRequireLongpress.set_active(lp)
 
+    def setAnimate(self, ar):
+       self.buttonAnimateRotation.set_active(ar)
+
+    def getNoBg(self):
+       ret=self.buttonNoBackground.get_active()
+       return(ret)
+
+    def setNoBg(self, nobg):
+       self.buttonNoBackground.set_active(nobg)
+
+       self.buttonThemeBackground.set_sensitive(not nobg)
+       self.config.setNoBg(nobg)
+       self.igw.reconfig()
+
+    def getThemeBg(self):
+       ret=self.buttonThemeBackground.get_active()
+       return(ret)
+
+    def setThemeBg(self, themebg):
+       self.buttonThemeBackground.set_active(themebg)
+       self.config.setThemeBg(themebg)
+       self.igw.reconfig()
+
     def doConfig(self, icon):
        aps=apps.scan()
 
@@ -224,7 +676,7 @@ class WinConfig(StackableWindow):
            if app==None:
                continue
            selector.append_text(app)
-           if icon.name!=None and aps[icon.name]['name']==app:
+           if icon.appname!=None and aps[icon.appname]['name']==app:
                idx=cnt
            cnt+=1
 
@@ -237,10 +689,11 @@ class WinConfig(StackableWindow):
        r=dialog.run()
 
        if r==gtk.RESPONSE_OK:
-           cur=selector.get_current_text()
-           if cur=='None':
+           idx2=selector.get_active(0)
+           if idx2<1:
                app=None
            else:
+               cur=lst[idx2-1]
                for i in aps:
                    if aps[i]['name']==cur:
                        app=aps[i]
@@ -256,6 +709,12 @@ class WinConfig(StackableWindow):
 
        dialog.destroy()
 
+#    def finish(self):
+#      print "wc-finish"
+#      self.igw=None
+#
+#      self.dis_finish()
+
     def getData(self):
        szx=0
        szy=0
@@ -280,16 +739,25 @@ class WinConfig(StackableWindow):
            for y in xrange(sz[1]):
                ico=self.igw.get(x,y)
                k=(x,y)
-               wapps[k]=ico.name
+               wapps[k]=ico.appname
 
        indiv=self.buttonRotateIndividually.get_active()
        lp=self.buttonRequireLongpress.get_active()
+       ar=self.buttonAnimateRotation.get_active()
+       nobg=self.buttonNoBackground.get_active()
+       themebg=self.buttonThemeBackground.get_active()
 
        ret={
            'size':         sz,
            'apps':         wapps,
            'indiv':        indiv,
            'longpress':    lp,
+           'animate':      ar,
+           'nobg':         nobg,
+           'themebg':      themebg,
+           'iconsize':     self.config.getIconSize(),
+           'iconpadding':  self.config.getIconPadding(),
+           'iconmargin':   self.config.getIconMargin(),
            }
 
        return(ret)