[Python-checkins] r63406 - in sandbox/trunk/ttk-gsoc: Doc/library/ttk.rst src/2.x/ttk.py src/3.x/ttk.py

guilherme.polo python-checkins at python.org
Sat May 17 16:10:19 CEST 2008


Author: guilherme.polo
Date: Sat May 17 16:10:18 2008
New Revision: 63406

Log:
Added support for 'element create' for theme_settings/theme_create;

_format_mapdict supports an iterable as state value now, which may
appear in some styling code;

Updated docs to match this new addition and also added some options at
Layouts which are not documented in Tk yet.


Modified:
   sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst
   sandbox/trunk/ttk-gsoc/src/2.x/ttk.py
   sandbox/trunk/ttk-gsoc/src/3.x/ttk.py

Modified: sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst
==============================================================================
--- sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst	(original)
+++ sandbox/trunk/ttk-gsoc/Doc/library/ttk.rst	Sat May 17 16:10:18 2008
@@ -1240,9 +1240,10 @@
       *settings* and then restore the previous theme.
       
       Each key in *settings* is a style and each value may contain the keys 
-      'configure', 'map' and 'layout' and they are expected to have the same 
-      format as specified by the methods :meth:`Style.configure`, 
-      :meth:`Style.map` and :meth:`Style.layout` respectively.
+      'configure', 'map', 'layout' and 'element create' and they are expected 
+      to have the same format as specified by the methods 
+      :meth:`Style.configure`, :meth:`Style.map`, :meth:`Style.layout` and
+      :meth:`Style.element_create` respectively.
       
       As an example, lets change the Combobox for the default theme a bit::
 
@@ -1296,6 +1297,12 @@
  * sticky: nswe
     Specifies where the element is placed inside its allocated parcel.
 
+ * expand: 1 or 0 XXX
+
+ * border: XXX
+
+ * unit: XXX
+
  * children: [sublayout... ]
     Specifies a list of elements to place inside the element. Each 
     element is a tuple (or other sequence type) where the first item is

Modified: sandbox/trunk/ttk-gsoc/src/2.x/ttk.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/2.x/ttk.py	(original)
+++ sandbox/trunk/ttk-gsoc/src/2.x/ttk.py	Sat May 17 16:10:18 2008
@@ -101,12 +101,53 @@
                 # be used to indicate the "normal" state
                 state = "{}"
 
+            if not isinstance(val, basestring):
+                # val may also be a sequence which needs to be grouped
+                val = "{%s}" % ' '.join(map(str, val))
+
             opt_val.append("%s %s" % (state, val))
 
         opts.append(("-%s" % opt, format % ' '.join(opt_val)))
     
     return Tkinter._flatten(opts)
 
+def _format_elemcreate(etype, script=False, *args, **kw):
+    """Formats args and kw according to the given element factory etype."""
+    spec = None
+    opts = ()
+    if etype in ("image", "vsapi"): 
+        if etype == "image": # define an element based on an image
+            # first arg should be the default image name
+            iname = args[0]
+            # next args, if any, are statespec/value pairs which is almost
+            # a mapdict, but we just need the value
+            imagespec = _format_mapdict({None: args[1:]})[1]
+            spec = "%s %s" % (iname, imagespec)
+
+        else: 
+            # define an element whose visual appearance is drawn using the
+            # Microsoft Visual Styles API which is responsible for the 
+            # themed styles on Windows XP and Vista. 
+            # Availability: Tk 8.6, Windows XP and Vista.
+            class_name, part_id = args[:2]
+            statemap = _format_mapdict({None: args[2:]})[1]
+            spec = "%s %s %s" % (class_name, part_id, statemap)
+
+        opts = _format_optdict(kw, script)
+
+    elif etype == "from": # clone an element
+        # it expects a themename and optionally an element to clone from,
+        # otherwise it will clone {} (empty element)
+        spec = args[0] # theme name
+        if len(args) > 1: # elementfrom specified
+            opts = (args[1], )
+    
+    if script:
+        spec = '{%s}' % spec
+        opts = ' '.join(map(str, opts))
+
+    return spec, opts
+
 def _format_layoutdict(layout, indent=2, child=False):
     """Formats a layout dict so we can pass the result to ttk::style 
     layout and ttk::style settings.
@@ -165,23 +206,39 @@
     # a script will be generated according to settings passed, which
     # will then be evaluated by Tcl
     for name, opts in settings.iteritems():
-        # format 'configure' according to Tcl code
-        if opts.get('configure'):
+        # will format specific keys according to Tcl code 
+        if opts.get('configure'): # format 'configure'
             s = ' '.join(map(str, _format_optdict(opts['configure'], True)))
             script.append("ttk::style configure %s %s;" % (name, s))
 
-        # format 'map' according to Tcl code
-        if opts.get('map'):
+        if opts.get('map'): # format 'map'
             s = ' '.join(map(str, _format_mapdict(opts['map'], True)))
             script.append("ttk::style map %s %s;" % (name, s))
 
-        # format 'layout' according to Tcl code
-        if 'layout' in opts: # layout may be empty
+        if 'layout' in opts: # format 'layout' which may be empty
             if not opts['layout']:
                 s = 'null' # could be any other word, but this one makes sense
             else:
-                s = _format_layoutdict(opts['layout'])
-            script.append("ttk::style layout %s {\n%s}" % (name, s))
+                s, _ = _format_layoutdict(opts['layout'])
+            script.append("ttk::style layout %s {\n%s\n}" % (name, s))
+
+        if opts.get('element create'): # format 'element create'
+            eopts = opts['element create']
+            etype = eopts[0]
+
+            # find where args end, and where kwargs start
+            argc = 1 # etype was the first one
+            while argc < len(eopts) and not hasattr(eopts[argc], 'iteritems'):
+                argc += 1
+
+            elemargs = eopts[1:argc]
+            elemkw = {}
+            if argc < len(eopts) and eopts[argc]:
+                elemkw = eopts[argc]
+            spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw)
+
+            script.append("ttk::style element create %s %s %s %s" % (
+                name, etype, spec, opts))
 
     return '\n'.join(script)
 
@@ -332,8 +389,7 @@
                     Specifies a list of elements to place inside the 
                     element. Each element is a tuple (or other sequence)
                     where the first item is the layout name, and the other
-                    is a LAYOUT.
-        """
+                    is a LAYOUT."""
         lspec = None
         if layoutspec:
             lspec = _format_layoutdict(layoutspec)[0]
@@ -347,36 +403,7 @@
 
     def element_create(self, elementname, etype, *args, **kw): 
         """Create a new element in the current theme of given etype."""
-        spec = None
-        opts = ()
-
-        if etype in ("image", "vsapi"): 
-            if etype == "image": # define an element based on an image
-                # first arg should be the default image name
-                iname = args[0]
-                # next args, if any, are statespec/value pairs which is almost
-                # a mapdict, but we just need the value
-                imagespec = _format_mapdict({None: args[1:]})[1]
-                spec = "%s %s" % (iname, imagespec)
-
-            else: 
-                # define an element whose visual appearance is drawn using the
-                # Microsoft Visual Styles API which is responsible for the 
-                # themed styles on Windows XP and Vista. 
-                # Availability: Tk 8.6, Windows XP and Vista.
-                class_name, part_id = args[:2]
-                statemap = _format_mapdict({None: args[2:]})[1]
-                spec = "%s %s %s" % (class_name, part_id, statemap)
-
-            opts = _format_optdict(kw)
-
-        elif etype == "from": # clone an element
-            # it expects a themename and optionally an element to clone from,
-            # otherwise it will clone {} (empty element)
-            spec = args[0] # theme name
-            if len(args) > 1: # elementfrom specified
-                opts = (args[1], )
-
+        spec, opts = _format_elemcreate(etype, False, *args, **kw)
         self.tk.call(self._name, "element", "create", elementname, etype,
                      spec, *opts)
 
@@ -413,9 +440,9 @@
         settings and then restore the previous theme.
 
         Each key in settings is a style and each value may contain the 
-        keys 'configure', 'map' and 'layout' and they are expected to have
-        the same format as specified by the methods configure, map and
-        layout respectively."""
+        keys 'configure', 'map', 'layout' and 'element create' and they 
+        are expected to have the same format as specified by the methods 
+        configure, map, layout and element_create respectively."""
         script = _script_from_settings(settings)
         self.tk.call(self._name, "theme", "settings", themename, script)
 

Modified: sandbox/trunk/ttk-gsoc/src/3.x/ttk.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/3.x/ttk.py	(original)
+++ sandbox/trunk/ttk-gsoc/src/3.x/ttk.py	Sat May 17 16:10:18 2008
@@ -68,7 +68,7 @@
             # value is expected to be a sequence
             value = format % ' '.join(map(str, value))
 
-        if script and isinstance(value, str) and not value: 
+        if script and isinstance(value, str) and not value:
             value = '{}' # empty string in Python is equivalent to {} in Tcl
 
         opts.append(("-%s" % opt, value))
@@ -101,12 +101,53 @@
                 # be used to indicate the "normal" state
                 state = "{}"
 
+            if not isinstance(val, str):
+                # val may also be a sequence which needs to be grouped
+                val = "{%s}" % ' '.join(map(str, val))
+
             opt_val.append("%s %s" % (state, val))
 
         opts.append(("-%s" % opt, format % ' '.join(opt_val)))
     
     return Tkinter._flatten(opts)
 
+def _format_elemcreate(etype, script=False, *args, **kw):
+    """Formats args and kw according to the given element factory etype."""
+    spec = None
+    opts = ()
+    if etype in ("image", "vsapi"): 
+        if etype == "image": # define an element based on an image
+            # first arg should be the default image name
+            iname = args[0]
+            # next args, if any, are statespec/value pairs which is almost
+            # a mapdict, but we just need the value
+            imagespec = _format_mapdict({None: args[1:]})[1]
+            spec = "%s %s" % (iname, imagespec)
+
+        else: 
+            # define an element whose visual appearance is drawn using the
+            # Microsoft Visual Styles API which is responsible for the 
+            # themed styles on Windows XP and Vista. 
+            # Availability: Tk 8.6, Windows XP and Vista.
+            class_name, part_id = args[:2]
+            statemap = _format_mapdict({None: args[2:]})[1]
+            spec = "%s %s %s" % (class_name, part_id, statemap)
+
+        opts = _format_optdict(kw, script)
+
+    elif etype == "from": # clone an element
+        # it expects a themename and optionally an element to clone from,
+        # otherwise it will clone {} (empty element)
+        spec = args[0] # theme name
+        if len(args) > 1: # elementfrom specified
+            opts = (args[1], )
+    
+    if script:
+        spec = '{%s}' % spec
+        opts = ' '.join(map(str, opts))
+
+    return spec, opts
+
 def _format_layoutdict(layout, indent=2, child=False):
     """Formats a layout dict so we can pass the result to ttk::style 
     layout and ttk::style settings.
@@ -165,23 +206,39 @@
     # a script will be generated according to settings passed, which
     # will then be evaluated by Tcl
     for name, opts in settings.items():
-        # format 'configure' according to Tcl code
-        if opts.get('configure'):
+        # will format specific keys according to Tcl code 
+        if opts.get('configure'): # format 'configure'
             s = ' '.join(map(str, _format_optdict(opts['configure'], True)))
             script.append("ttk::style configure %s %s;" % (name, s))
 
-        # format 'map' according to Tcl code
-        if opts.get('map'):
+        if opts.get('map'): # format 'map'
             s = ' '.join(map(str, _format_mapdict(opts['map'], True)))
             script.append("ttk::style map %s %s;" % (name, s))
 
-        # format 'layout' according to Tcl code
-        if 'layout' in opts: # layout may be empty
+        if 'layout' in opts: # format 'layout' which may be empty
             if not opts['layout']:
                 s = 'null' # could be any other word, but this one makes sense
             else:
-                s = _format_layoutdict(opts['layout'])
-            script.append("ttk::style layout %s {\n%s}" % (name, s))
+                s, _ = _format_layoutdict(opts['layout'])
+            script.append("ttk::style layout %s {\n%s\n}" % (name, s))
+
+        if opts.get('element create'): # format 'element create'
+            eopts = opts['element create']
+            etype = eopts[0]
+
+            # find where args end, and where kwargs start
+            argc = 1 # etype was the first one
+            while argc < len(eopts) and not hasattr(eopts[argc], 'iteritems'):
+                argc += 1
+
+            elemargs = eopts[1:argc]
+            elemkw = {}
+            if argc < len(eopts) and eopts[argc]:
+                elemkw = eopts[argc]
+            spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw)
+
+            script.append("ttk::style element create %s %s %s %s" % (
+                name, etype, spec, opts))
 
     return '\n'.join(script)
 
@@ -332,8 +389,7 @@
                     Specifies a list of elements to place inside the 
                     element. Each element is a tuple (or other sequence)
                     where the first item is the layout name, and the other
-                    is a LAYOUT.
-        """
+                    is a LAYOUT."""
         lspec = None
         if layoutspec:
             lspec = _format_layoutdict(layoutspec)[0]
@@ -347,36 +403,7 @@
 
     def element_create(self, elementname, etype, *args, **kw): 
         """Create a new element in the current theme of given etype."""
-        spec = None
-        opts = ()
-
-        if etype in ("image", "vsapi"): 
-            if etype == "image": # define an element based on an image
-                # first arg should be the default image name
-                iname = args[0]
-                # next args, if any, are statespec/value pairs which is almost
-                # a mapdict, but we just need the value
-                imagespec = _format_mapdict({None: args[1:]})[1]
-                spec = "%s %s" % (iname, imagespec)
-
-            else: 
-                # define an element whose visual appearance is drawn using the
-                # Microsoft Visual Styles API which is responsible for the 
-                # themed styles on Windows XP and Vista. 
-                # Availability: Tk 8.6, Windows XP and Vista.
-                class_name, part_id = args[:2]
-                statemap = _format_mapdict({None: args[2:]})[1]
-                spec = "%s %s %s" % (class_name, part_id, statemap)
-
-            opts = _format_optdict(kw)
-
-        elif etype == "from": # clone an element
-            # it expects a themename and optionally an element to clone from,
-            # otherwise it will clone {} (empty element)
-            spec = args[0] # theme name
-            if len(args) > 1: # elementfrom specified
-                opts = (args[1], )
-
+        spec, opts = _format_elemcreate(etype, False, *args, **kw)
         self.tk.call(self._name, "element", "create", elementname, etype,
                      spec, *opts)
 
@@ -413,9 +440,9 @@
         settings and then restore the previous theme.
 
         Each key in settings is a style and each value may contain the 
-        keys 'configure', 'map' and 'layout' and they are expected to have
-        the same format as specified by the methods configure, map and
-        layout respectively."""
+        keys 'configure', 'map', 'layout' and 'element create' and they 
+        are expected to have the same format as specified by the methods 
+        configure, map, layout and element_create respectively."""
         script = _script_from_settings(settings)
         self.tk.call(self._name, "theme", "settings", themename, script)
 


More information about the Python-checkins mailing list