I just found out, after an hour of searcing, how to get "system colors" in gtk. Only tried with pygtk, but I guess bindings does it the same.
First you have to get a GtkStyle object. If you extend GtkWidget you can get it using self.get_style(), else you can get it from e.g. a button: gtk.Button().get_style()
The GtkStyle object contains a lot of GtkStyleHelper objects. More precisely it has: ['base', 'base_gc', 'bg', 'bg_gc', 'bg_pixmap', 'dark', 'dark_gc', 'fg', 'fg_gc', 'light', 'light_gc', 'mid', 'mid_gc', 'text', 'text_aa', 'text_aa_gc', 'text_gc']
Each of these has different colors depending on the state. The states are ['STATE_ACTIVE', 'STATE_INSENSITIVE', 'STATE_NORMAL', 'STATE_PRELIGHT', 'STATE_SELECTED']
When you know that, you should be able to draw with a system color, e.g. with cairo.
context = widget.window.cairo_create()
context.rectangle(0,0,10,10)
context.set_source_color(self.get_style().dark[gtk.STATE_NORMAL])
context.fill_preserve()
Some other code:
>>> [m for m in dir(gtk) if m.startswith("STATE")]
['STATE_ACTIVE', 'STATE_INSENSITIVE', 'STATE_NORMAL', 'STATE_PRELIGHT', 'STATE_SELECTED']
>>> [m for m in dir(gtk.Button().get_style()) if type(getattr(gtk.Button().get_style(), m)) == type(gtk.Button().get_style().light)]
['base', 'base_gc', 'bg', 'bg_gc', 'bg_pixmap', 'dark', 'dark_gc', 'fg', 'fg_gc', 'light', 'light_gc', 'mid', 'mid_gc', 'text', 'text_aa', 'text_aa_gc', 'text_gc']
Update:
I've crafted a small pygtk script bringing up a palete of the colors of the current gtktheme.
Code is:
#!/usr/bin/python
import pygtk
pygtk.require("2.0")
import gtk, pango
w = gtk.Button()
states = [m for m in dir(gtk) if m.startswith("STATE_")]
styles = [m for m in dir(w.get_style()) if type(getattr(w.get_style(), m)) == type(w.get_style().light)]
styles = [m for m in styles if not m.endswith("_gc")]
class CairoBoard(gtk.DrawingArea):
def __init__(self):
gtk.DrawingArea.__init__(self)
self.connect("expose_event", self.expose)
def expose(self, widget, event):
context = widget.window.cairo_create()
context.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
context.clip()
self.draw(context)
return False
def draw (self, context):
for x in range(len(states)):
for y in range(len(styles)):
style = getattr(self.get_style(), styles[y])
state = getattr(gtk, states[x])
color = style[state]
if color == None or type(color) != gtk.gdk.Color:
color = gtk.gdk.Color(0,0,0)
context.set_source_color(color)
context.rectangle(x*150,y*50,150,50)
context.fill_preserve()
context.new_path()
if color.red + color.green + color.blue < 65535:
context.set_source_color(gtk.gdk.Color(65535,65535,65535))
else: context.set_source_color(gtk.gdk.Color(0,0,0))
cstring = "#"
for col in color.red, color.green, color.blue:
h = hex(col/256)[2:]
if len(h) == 1:
h = "0"+h
cstring += h
layout = self.create_pango_layout ("%s\n%s\n%s" % \
(styles[y], states[x][6:], cstring))
layout.set_font_description(pango.FontDescription("Sans Serif 10"))
context.move_to(x*150,y*50)
context.show_layout(layout)
context.fill_preserve()
context.new_path()
window = gtk.Window()
window.connect("destroy", gtk.main_quit)
window.add(CairoBoard())
window.set_default_size(len(states)*150, len(styles)*50)
window.show_all()
gtk.main()