r6995 - in bigboard/trunk: . bigboard bigboard/libbig bigboard/stocks/self bigboard/themes
- From: commits mugshot org
- To: online-desktop-list gnome org
- Subject: r6995 - in bigboard/trunk: . bigboard bigboard/libbig bigboard/stocks/self bigboard/themes
- Date: Fri, 7 Dec 2007 18:37:43 -0600 (CST)
Author: walters
Date: 2007-12-07 18:37:43 -0600 (Fri, 07 Dec 2007)
New Revision: 6995
Added:
bigboard/trunk/bigboard/libbig/signalobject.py
Modified:
bigboard/trunk/bigboard/big_widgets.py
bigboard/trunk/bigboard/stocks/self/SelfStock.py
bigboard/trunk/bigboard/themes/default.py
bigboard/trunk/bigboard/themes/fedora.py
bigboard/trunk/main.py
Log:
More theming infrastructure.
Modified: bigboard/trunk/bigboard/big_widgets.py
===================================================================
--- bigboard/trunk/bigboard/big_widgets.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/bigboard/big_widgets.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -1,4 +1,4 @@
-import os, code, sys, traceback, logging, StringIO, threading, urlparse
+import os, code, sys, traceback, logging, StringIO, threading, urlparse, weakref
import cairo
import pango
@@ -11,8 +11,12 @@
from libgimmie import DockWindow
from libbig.imagecache import URLImageCache
import libbig, stock, globals, bigboard
+from bigboard.libbig.signalobject import SignalObject
+from bigboard.libbig.singletonmixin import Singleton
from table_layout import TableLayout
+_logger = logging.getLogger("bigboard.BigWidgets")
+
class CanvasVBox(hippo.CanvasBox):
def __init__(self, **kwargs):
kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
@@ -29,6 +33,74 @@
self.spinner = gtk.SpinButton()
self.set_property('widget', self.spinner)
+class ThemeManager(gobject.GObject):
+ __gsignals__ = {
+ 'theme-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+ }
+ def __init__(self):
+ super(ThemeManager, self).__init__()
+ self.__class__.instance = weakref.ref(self)
+ self.__theme = None
+ gconf.client_get_default().notify_add('/apps/bigboard/theme', self.__sync_theme)
+ self.__sync_theme()
+
+ @staticmethod
+ def getInstance():
+ needinst = False
+ if not hasattr(ThemeManager, 'instance'):
+ instvalue = None
+ else:
+ instref = getattr(ThemeManager, 'instance')
+ instvalue = instref()
+ needinst = instvalue is None
+ if instvalue is None:
+ inst = ThemeManager()
+ else:
+ inst = instvalue
+ return inst
+
+ def get_theme(self):
+ return self.__theme
+
+ def __sync_theme(self, *args):
+ _logger.debug("doing theme sync")
+ themename = gconf.client_get_default().get_string('/apps/bigboard/theme')
+ if themename == 'fedora':
+ from bigboard.themes.fedora import FedoraTheme
+ self.__theme = FedoraTheme.getInstance()
+ else:
+ from bigboard.themes.default import DefaultTheme
+ self.__theme = DefaultTheme.getInstance()
+ self.emit('theme-changed')
+
+class ThemedWidgetMixin(object):
+ def __init__(self):
+ super(ThemedWidgetMixin, self).__init__()
+ mgr = ThemeManager.getInstance()
+ self.__boundprops = {}
+ mgr.connect('theme-changed', self.__sync_theme)
+
+ def get_theme(self):
+ return ThemeManager.getInstance().get_theme()
+
+ def _theme_bind(self, bindings):
+ self.__boundprops.update(bindings)
+ self._on_theme_change(ThemeManager.getInstance())
+
+ def _on_theme_change(self, tm):
+ print "tc, bindings: %s" % (self.__boundprops)
+ for binding,func in self.__boundprops.iteritems():
+ self.set_property(binding, func(tm.get_theme()))
+
+ def __sync_theme(self, tm):
+ self._on_theme_change(tm)
+
+class ThemedText(hippo.CanvasText, ThemedWidgetMixin):
+ def __init__(self, **kwargs):
+ super(ThemedText, self).__init__(**kwargs)
+ ThemedWidgetMixin.__init__(self)
+ self._theme_bind({'color': lambda t: t.foreground})
+
class CanvasCheckbox(hippo.CanvasWidget):
def __init__(self, label):
super(CanvasCheckbox, self).__init__()
@@ -52,7 +124,7 @@
self.__layout.set_row_expand(row, expand)
-class GradientHeader(hippo.CanvasGradient):
+class GradientHeader(hippo.CanvasGradient, ThemedWidgetMixin):
def __init__(self, **kwargs):
hippo.CanvasGradient.__init__(self,
orientation=hippo.ORIENTATION_HORIZONTAL,
Added: bigboard/trunk/bigboard/libbig/signalobject.py
===================================================================
--- bigboard/trunk/bigboard/libbig/signalobject.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/bigboard/libbig/signalobject.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -0,0 +1,77 @@
+import weakref
+
+## Adapted from:
+## http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/87056
+## by Patrick O'Brien, under the Python License
+
+class SignalObject(object):
+ """An object which can emit signals, similar in style
+ to GObject but usable as a non-meta class. Not threadsafe."""
+ def __init__(self):
+ self.__weakmethods = weakref.WeakKeyDictionary()
+ self.__signal_handlers = {}
+
+ def connect(self, signame, handler, *args):
+ if signame not in self.__class__.pysignals:
+ raise ValueError("Unknown signal %s", signame)
+ try:
+ handlers = self.__signal_handlers.get(signame)
+ except KeyError, e:
+ handlers = []
+ self.__signal_handlers[signame] = handlers
+ funcref = self.__get_method_ref(handler)
+ argref = weakref.ref(args)
+ handlers.append((funcref, argref))
+
+ def emit(self, signame, *args):
+ dead = []
+ handlers = self.__signal_handlers.get(signame, [])
+ for funcref, argref in handlers:
+ func = funcref()
+ fargs = argref()
+ if (func is None) or (fargs is None):
+ dead.append((funcref, argref))
+ continue
+ func(self, *(args + fargs))
+ for pair in dead:
+ handlers.remove(pair)
+
+ def __get_method_ref(self, obj):
+ """Return a *safe* weak reference to a callable object."""
+ if hasattr(object, 'im_self'):
+ if object.im_self is not None:
+ # Turn a bound method into a BoundMethodWeakref instance.
+ # Keep track of these instances for lookup by disconnect().
+ selfkey = object.im_self
+ funckey = object.im_func
+ if selfkey not in self.__weakmethods:
+ self.__weakmethods[selfkey] = weakref.WeakKeyDictionary()
+ if funckey not in self.__weakmethods[selfkey]:
+ self.__weakmethods[selfkey][funckey] = BoundMethodWeakref(boundMethod=obj)
+ return self.__weakmethods[selfkey][funckey]
+ return weakref.ref(object)
+
+class BoundMethodWeakref:
+ """BoundMethodWeakref class."""
+ def __init__(self, boundMethod):
+ """Return a weak-reference-like instance for a bound method."""
+ self.isDead = False
+ self.weakSelf = weakref.ref(boundMethod.im_self, self.__set_dead)
+ self.weakFunc = weakref.ref(boundMethod.im_func, self.__set_dead)
+
+ def __set_dead(self):
+ self.isDead = True
+
+ def __repr__(self):
+ """Return the closest representation."""
+ return repr(self.weakFunc)
+ def __call__(self):
+ """Return a strong reference to the bound method."""
+ if self.isDead:
+ return None
+ else:
+ object = self.weakSelf()
+ method = self.weakFunc().__name__
+ return getattr(object, method)
+
+__all__ = ['SignalObject']
Modified: bigboard/trunk/bigboard/stocks/self/SelfStock.py
===================================================================
--- bigboard/trunk/bigboard/stocks/self/SelfStock.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/bigboard/stocks/self/SelfStock.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -13,7 +13,8 @@
import bigboard.libbig as libbig
from bigboard.workboard import WorkBoard
from bigboard.stock import Stock, AbstractMugshotStock
-from bigboard.big_widgets import CanvasMugshotURLImage, PhotoContentItem, CanvasVBox, CanvasHBox, ActionLink, IconLink, Separator
+from bigboard.big_widgets import CanvasMugshotURLImage, PhotoContentItem, CanvasVBox, CanvasHBox
+from bigboard.big_widgets import ActionLink, IconLink, Separator, ThemedText
import bigboard.google
import portfoliomanager
@@ -257,7 +258,7 @@
self._namephoto_box.set_photo(self._photo)
self._namephoto_box_child = CanvasHBox()
- self._name = hippo.CanvasText(text="Nobody", size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
+ self._name = ThemedText(text="Nobody", size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
self._name.set_property("font", "14px Bold")
self._namephoto_box_child.append(self._name)
Modified: bigboard/trunk/bigboard/themes/default.py
===================================================================
--- bigboard/trunk/bigboard/themes/default.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/bigboard/themes/default.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -6,6 +6,8 @@
super(DefaultTheme, self).__init__()
self.background = 0xFFFFFFFF
self.foreground = 0x000000FF
+ self.header_start = 0xF4F4F4FF
+ self.header_end = 0xC7C7C7FF
def draw_header(self, cr, area):
cr.set_source_rgb(1.0, 1.0, 1.0)
Modified: bigboard/trunk/bigboard/themes/fedora.py
===================================================================
--- bigboard/trunk/bigboard/themes/fedora.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/bigboard/themes/fedora.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -5,9 +5,11 @@
class FedoraTheme(DefaultTheme):
def __init__(self):
- super(DefaultTheme, self).__init__()
+ super(FedoraTheme, self).__init__()
self.background = 0x345B75FF
self.foreground = 0xFFFFFFFF
+ self.header_start = 0x436A85FF
+ self.header_end = 0x59809CFF
def draw_header(self, cr, area):
cr.set_source_rgb(1.0, 1.0, 1.0)
Modified: bigboard/trunk/main.py
===================================================================
--- bigboard/trunk/main.py 2007-12-08 00:04:48 UTC (rev 6994)
+++ bigboard/trunk/main.py 2007-12-08 00:37:43 UTC (rev 6995)
@@ -18,7 +18,8 @@
import bigboard
import bigboard.big_widgets
-from bigboard.big_widgets import Sidebar, CanvasHBox, CanvasVBox, ActionLink, Button, GradientHeader
+from bigboard.big_widgets import Sidebar, CanvasHBox, CanvasVBox, ActionLink
+from bigboard.big_widgets import Button, GradientHeader, ThemedWidgetMixin, ThemeManager
from bigboard.stock import Stock
import bigboard.libbig
try:
@@ -273,21 +274,29 @@
self.widget = ggadget.Gadget(metainfo, env)
self.widget.show_all()
self.set_property('widget', self.widget)
+
+class ThemedGradient(hippo.CanvasGradient, ThemedWidgetMixin):
+ def __init__(self):
+ super(ThemedGradient, self).__init__()
+ self._on_theme_change()
+ def _on_theme_change(self, *args):
+ theme = self.get_theme()
+ _logger.debug("changing gradient %s %s", theme.header_start, theme.header_end)
+ self.set_property('start-color', theme.header_start)
+ self.set_property('end-color', theme.header_end)
-class Exchange(hippo.CanvasBox):
+class Exchange(hippo.CanvasBox, ThemedWidgetMixin):
"""A renderer for stocks."""
def __init__(self, metainfo, env, pymodule=None, is_notitle=False, panel=None):
hippo.CanvasBox.__init__(self,
orientation=hippo.ORIENTATION_VERTICAL,
- spacing=4)
+ spacing=4)
self.__size = None
self.__metainfo = metainfo
self.__env = env
self.__pymodule = pymodule
self.__panel = panel
- self.__themehandler = self.__sync_theme
- self.__panel.add_theme_listener(self.__themehandler)
self.__ticker_text = None
self.__ticker_container = None
self.__mini_more_button = None
@@ -295,7 +304,7 @@
self.append(self.__sep)
self.__expanded = True
if not is_notitle:
- self.__ticker_container = GradientHeader()
+ self.__ticker_container = ThemedGradient()
self.__ticker_text = hippo.CanvasText(text=metainfo.title, font="14px", xalign=hippo.ALIGNMENT_START)
self.__ticker_text.connect("button-press-event", lambda text, event: self.__toggle_expanded())
self.__ticker_container.append(self.__ticker_text, hippo.PACK_EXPAND)
@@ -313,15 +322,15 @@
self.append(self.__ticker_container)
self.__stockbox = hippo.CanvasBox()
self.append(self.__stockbox)
- self.__sync_theme()
+ self._on_theme_change()
if pymodule:
pymodule.connect('visible', self.__render_pymodule)
self.__render_pymodule()
else:
self.__render_google_gadget()
- def __sync_theme(self, *args):
- theme = self.__panel.get_theme()
+ def _on_theme_change(self, *args):
+ theme = self.get_theme()
self.set_property('background-color', theme.background)
def on_delisted(self):
@@ -425,8 +434,8 @@
self._main_box.append(self._stocks_box)
- gconf_client.notify_add(GCONF_PREFIX + 'theme', self.__sync_theme)
- self.__theme_listeners = []
+ self.__theme_mgr = ThemeManager.getInstance()
+ self.__theme_mgr.connect('theme-changed', self.__sync_theme)
self.__sync_theme()
gconf_client.notify_add(GCONF_PREFIX + 'expand', self._sync_size)
@@ -558,24 +567,8 @@
_logger.debug("queuing strut complete")
def __sync_theme(self, *args):
- _logger.debug("doing theme sync")
- themename = gconf.client_get_default().get_string(GCONF_PREFIX + 'theme')
- if themename == 'fedora':
- from bigboard.themes.fedora import FedoraTheme
- self.__theme = FedoraTheme.getInstance()
- else:
- from bigboard.themes.default import DefaultTheme
- self.__theme = DefaultTheme.getInstance()
-
- self._canvas.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#%6X" % (self.__theme.background >> 8,)))
- for ref in self.__theme_listeners:
- listener = ref()
- if listener:
- listener()
-
- # We have manual signals here because we can't subclass GObject
- def add_theme_listener(self, listener):
- self.__theme_listeners.append(weakref.ref(listener))
+ theme = self.__theme_mgr.get_theme()
+ self._canvas.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#%6X" % (theme.background >> 8,)))
def get_theme(self):
return self.__theme
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]