gh-68166: Add support of "vsapi" in ttk.Style.element_create() (GH-111393)

This commit is contained in:
Serhiy Storchaka 2023-11-27 20:57:33 +02:00 committed by GitHub
parent 45d648597b
commit 4dcfd02bed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 204 additions and 32 deletions

View file

@ -95,40 +95,47 @@ def _format_mapdict(mapdict, script=False):
def _format_elemcreate(etype, script=False, *args, **kw):
"""Formats args and kw according to the given element factory etype."""
spec = None
specs = ()
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 = _join(_mapdict_values(args[1:]))
spec = "%s %s" % (iname, imagespec)
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 = (iname, *_mapdict_values(args[1:]))
if script:
specs = (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 = _join(_mapdict_values(args[2:]))
spec = "%s %s %s" % (class_name, part_id, statemap)
specs = (_join(imagespec),)
opts = _format_optdict(kw, script)
if etype == "vsapi":
# 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.
if len(args) < 3:
class_name, part_id = args
statemap = (((), 1),)
else:
class_name, part_id, statemap = args
specs = (class_name, part_id, tuple(_mapdict_values(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
specs = (args[0],) # theme name
if len(args) > 1: # elementfrom specified
opts = (_format_optvalue(args[1], script),)
if script:
spec = '{%s}' % spec
specs = _join(specs)
opts = ' '.join(opts)
return specs, opts
else:
return *specs, opts
return spec, opts
def _format_layoutlist(layout, indent=0, indent_size=2):
"""Formats a layout list so we can pass the result to ttk::style
@ -214,10 +221,10 @@ def _script_from_settings(settings):
elemargs = eopts[1:argc]
elemkw = eopts[argc] if argc < len(eopts) and eopts[argc] else {}
spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw)
specs, eopts = _format_elemcreate(etype, True, *elemargs, **elemkw)
script.append("ttk::style element create %s %s %s %s" % (
name, etype, spec, opts))
name, etype, specs, eopts))
return '\n'.join(script)
@ -434,9 +441,9 @@ class Style(object):
def element_create(self, elementname, etype, *args, **kw):
"""Create a new element in the current theme of given etype."""
spec, opts = _format_elemcreate(etype, False, *args, **kw)
*specs, opts = _format_elemcreate(etype, False, *args, **kw)
self.tk.call(self._name, "element", "create", elementname, etype,
spec, *opts)
*specs, *opts)
def element_names(self):