|
From: Mats B. <ma...@pr...> - 2007-08-27 13:49:44
|
Sorry, but this is a bit long...
I have tested various ways to integrate the tk widgets with the ttk themes
and haven't found a robust solution until now. I'd like to have
any comments on this. The example below treats the Menu and its non-ttk
options -activebackground, -activeforeground, and -disabledforeground.
In brief, I add a kind of fake 'style map Menu' for everything that is not
in the themes 'style configure .' or 'style map .'. Then I register
a Menu event handler 'bind Menu <<ThemeChanged>>' which configure
all existing Menus and sets option resources for any new Menus.
Does anyone have a better solution?
I first tried experimenting with -selectbackground and -selectforeground
if set in the themes since they give the right answer on windows themes,
but this generally fails.
/Mats
namespace eval ttk {
foreach name [ttk::availableThemes] {
# @@@ We could be more economical here and load theme only when needed.
if {[catch {package require ttk::theme::$name}]} {
continue
}
# Set only the switches that are not in [style configure .]
# or [style map .].
switch $name {
winnative {
style theme settings $name {
style map Menu \
-background {active SystemHighlight} \
-foreground {active SystemHighlightText disabled SystemGrayText}
}
}
xpnative {
style theme settings $name {
style map Menu \
-background {active SystemHighlight} \
-foreground {active SystemHighlightText disabled SystemGrayText}
}
}
}
}
}
namespace eval ::ttkutils {
# There are two things that need to be set for each class of widget:
# 1) existing widgets need to be configured
# 2) the resources must be set for new widgets
bind Menu <<ThemeChanged>> {ttkutils::MenuThemeChanged %W }
}
proc ttkutils::MenuThemeChanged {win} {
if {[winfo class $win] ne "Menu"} {
return
}
# We configure the resource database here as well since it saves code.
# Seems X11 has some system option db that must be overridden.
if {[tk windowingsystem] eq "x11"} {
set priority 60
} else {
set priority startupFile
}
# Some themes miss this one.
array set style [list -foreground black]
array set style [style configure .]
array set style [style configure Menu]
array set map [style map .]
array set map [style map Menu]
if {[info exists style(-background)]} {
set color $style(-background)
$win configure -background $color
$win configure -activebackground $color
option add *Menu.background $color $priority
option add *Menu.activeBackground $color $priority
if {[info exists map(-background)]} {
foreach {state col} $map(-background) {
if {[lsearch $state active] >= 0} {
$win configure -activebackground $col
option add *Menu.activeBackground $col $priority
break
}
}
}
}
if {[info exists style(-foreground)]} {
set color $style(-foreground)
$win configure -foreground $color
$win configure -activeforeground $color
$win configure -disabledforeground $color
option add *Menu.foreground $color $priority
option add *Menu.activeForeground $color $priority
option add *Menu.disabledForeground $color $priority
if {[info exists map(-foreground)]} {
foreach {state col} $map(-foreground) {
if {[lsearch $state active] >= 0} {
$win configure -activeforeground $col
option add *Menu.activeForeground $col $priority
}
if {[lsearch $state disabled] >= 0} {
$win configure -disabledforeground $col
option add *Menu.disabledForeground $col $priority
}
}
}
}
}
|