diff --git a/qwerty.py b/qwerty.py
index 231bca8..1e40a9c 100755
--- a/qwerty.py
+++ b/qwerty.py
@@ -7,13 +7,20 @@ import re
from Xlib import X,display
import Xlib.protocol.event
import gtk
+from gtk import gdk
+import cairo
-ICON_PATHS = ["/usr/share/pixmaps", "/usr/share/icons/hicolor/48x48/apps", "/usr/share/icons/hicolor/scalable/apps"]
+ICON_PATHS = ["/usr/share/pixmaps", "/usr/share/icons/hicolor/48x48/apps", "/usr/share/icons/hicolor/scalable/apps", "/usr/share/icons"]
GLOBAL = 0
SECTION = 1
KEY = 2
+BUTTON_BORDER = (0.7,0.7,0.7)
+BUTTON_BORDER_ACTIVE = (0,0,0)
+BUTTON_FILL = (0.9, 0.9, 0.9)
+BUTTON_FILL_RUNNING = (0.7, 0.7, 0.7)
+
config_file = os.path.expanduser('~/.config/qwerty.conf')
sections = []
@@ -25,42 +32,102 @@ def find_icon(name):
if os.path.exists(p):
return p
-class SuperButton(gtk.Button):
- def __init__(self,key,label=None,icon=None):
- gtk.Button.__init__(self)
- self.vbox = gtk.VBox()
- self.label = gtk.Label()
- if label:
- self.label.set_text(label)
+class SuperButton(gtk.DrawingArea):
+ def __init__(self,key, label=None, icon=None):
+ gtk.DrawingArea.__init__(self)
+
self.key = key
- self.keyl = gtk.Label()
- self.keyl.set_markup("<b>" + key + "</b>")
- self.icon = gtk.Image()
- if icon:
- self.set_icon(icon)
- self.vbox.pack_start(self.label)
- self.vbox.pack_start(self.icon)
- self.vbox.pack_start(self.keyl)
- self.add(self.vbox)
- self.vbox.show_all()
+ self.label = label
+ self.active = False
self.running = False
self.cls = None
+ if icon:
+ self.icon = find_icon(icon)
+ else:
+ self.icon = None
+
+ self.connect("expose-event",self.on_expose)
+ self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)
+ self.callback = None
+ self.connect('enter-notify-event', self.on_mouse_over)
+ self.connect('leave-notify-event', self.on_mouse_out)
+
+ self.set_size_request(90,120)
+
+ self.fg = BUTTON_BORDER
+
+ def on_expose(self,widget,event):
+ x,y,self.width,self.height,b = widget.window.get_geometry()
+ cr = widget.window.cairo_create()
+
+ if self.running:
+ cr.set_source_rgb(*BUTTON_FILL_RUNNING)
+ else:
+ cr.set_source_rgb(*BUTTON_FILL)
+ cr.rectangle(4,4,self.width-8,self.height-8)
+ cr.fill()
+ cr.set_source_rgb(*self.fg)
+ cr.rectangle(4,4,self.width-8,self.height-8)
+ cr.stroke()
+
+ if self.active:
+ cr.set_source_rgb(*BUTTON_BORDER_ACTIVE)
+
+ cr.move_to(20, self.height-50)
+ cr.set_font_size(40)
+ cr.show_text(self.key)
+
+ if not self.active:
+ return
+
+ cr.move_to(20,30)
+ cr.set_font_size(16)
+ cr.show_text(self.label)
+
+ if self.icon:
+ pb = gdk.pixbuf_new_from_file(self.icon)
+
+ w = pb.get_width()
+ h = pb.get_height()
+
+ IS = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h)
+ cr2 = cairo.Context(IS)
+ cr2 = gdk.CairoContext(cr2)
+ cr2.set_source_pixbuf(pb,0,0)
+ cr2.paint()
+
+ x = (self.width - w)/2
+ y = 45
+
+ cr.set_source_surface(IS,x,y)
+ cr.paint()
+
+ def on_mouse_over(self,widget,event):
+ if self.active:
+ self.fg = BUTTON_BORDER_ACTIVE
+ self.queue_draw()
+
+ def on_mouse_out(self,widget,event):
+ self.fg = BUTTON_BORDER
+ self.queue_draw()
+
+ def set_label(self,label):
+ self.label = label
+ self.queue_draw()
+
+ def set_icon(self,icon):
+ self.active = True
+ self.icon = find_icon(icon)
+ self.queue_draw()
def mark_running(self,cls):
- l = self.label.get_text()
- self.label.set_markup("<b>[" + l + "]</b>")
self.running = True
self.cls = cls
+ self.queue_draw()
def clear(self):
- self.label.set_text('')
- self.icon.clear()
-
- def set_icon(self,icon):
- self.icon.set_from_file(find_icon(icon))
-
- def set_label(self,label):
- self.label.set_text(label)
+ self.active = False
+ self.queue_draw()
class Section(object):
def __init__(self,title):
@@ -180,10 +247,10 @@ class GUI(object):
for row in self.rows:
for btn in row:
- btn.connect("clicked",self.on_button)
+ btn.connect("button-press-event",self.on_button)
for btn in self.sbuttons:
- btn.connect("clicked",self.on_section)
+ btn.connect("button-press-event",self.on_section)
for i,S in enumerate(sections):
btn = self.sbuttons[i]
@@ -197,8 +264,8 @@ class GUI(object):
self.window.connect('destroy', self.exit)
self.window.connect('key-release-event', self.on_key)
- self.window.fullscreen()
-# self.window.resize(800,600)
+# self.window.fullscreen()
+ self.window.resize(800,600)
self.collect_windows()
@@ -254,13 +321,13 @@ class GUI(object):
# self.send_event(wnd, self.NET_ACTIVE_WINDOW, [X.CurrentTime])
# wnd.map()
- def on_button(self,widget):
+ def on_button(self,widget,event=None):
if widget.running:
print "Activating", widget.label.get_text()
self.activate_window(widget.cls)
else:
self.key_exec(widget.key)
-# self.exit()
+ self.exit()
def on_section(self,widget):
self.show_section(widget.key)