deskbar-applet r2099 - in trunk: . deskbar/ui/cuemiac
- From: sebp svn gnome org
- To: svn-commits-list gnome org
- Subject: deskbar-applet r2099 - in trunk: . deskbar/ui/cuemiac
- Date: Fri, 11 Apr 2008 18:22:39 +0100 (BST)
Author: sebp
Date: Fri Apr 11 18:22:38 2008
New Revision: 2099
URL: http://svn.gnome.org/viewvc/deskbar-applet?rev=2099&view=rev
Log:
Added CuemiacCellRendererAction class that renders either a categories match count or an arrow for a match that has more than one action.
Replaced CuemiacCellRendererCategory with CuemiacCellRendererMatch that either renders category's title or the description of a match.
Added CuemiacCellRenderer: base class for CuemiacCellRendererAction and CuemiacCellRendererCategory.
Added:
trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py
trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py
trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py
- copied, changed from r2098, /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py
Removed:
trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py
Modified:
trunk/ChangeLog
trunk/deskbar/ui/cuemiac/CuemiacTreeView.py
trunk/deskbar/ui/cuemiac/Makefile.am
Added: trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py
==============================================================================
--- (empty file)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py Fri Apr 11 18:22:38 2008
@@ -0,0 +1,62 @@
+import gtk
+import gobject
+import pango
+
+class CuemiacCellRenderer (gtk.CellRendererText):
+ """
+ Base class for CuemiacCellRendererAction and CuemiacCellRendererMatch
+ """
+
+ __gsignals__ = {
+ "activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
+ }
+
+ def __init__ (self):
+ gtk.CellRendererText.__init__ (self)
+
+ self.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ self.__relative_header_size = -0.2 # Make header 20% smaller than normal fonts
+
+ # Grab some default theme settings
+ # they are probably incorrect, but we reset
+ # them on each render anyway.
+ style = gtk.Style ()
+ self.header_font_desc = style.font_desc
+ self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
+ self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
+ self.header_bg = style.base [gtk.STATE_NORMAL]
+
+ def set_style (self, widget):
+ """
+ Apply the style from widget, to this cellrenderer
+ """
+ self.header_font_desc = widget.style.font_desc
+ self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
+ self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
+ self.header_bg = widget.style.base [gtk.STATE_NORMAL]
+
+ def renderer_state_to_widget_state(self, flags):
+ state = 0
+
+ if (gtk.CELL_RENDERER_SELECTED & flags) == gtk.CELL_RENDERER_SELECTED:
+ state |= gtk.STATE_SELECTED
+ if (gtk.CELL_RENDERER_PRELIT & flags) == gtk.CELL_RENDERER_PRELIT:
+ state |= gtk.STATE_PRELIGHT
+ if (gtk.CELL_RENDERER_INSENSITIVE & flags) == gtk.CELL_RENDERER_INSENSITIVE:
+ state |= gtk.STATE_INSENSITIVE
+ if state == 0:
+ state= gtk.STATE_NORMAL
+ return state
+
+ def do_activate(self, event, widget, path_string, background_area, cell_area, flags):
+ if not isinstance(widget, gtk.TreeView):
+ # Not a treeview
+ return False
+
+ if event == None or event.type != gtk.gdk.BUTTON_PRESS:
+ # Event type not GDK_BUTTON_PRESS
+ return True
+
+ path = tuple([int(i) for i in path_string.split(':')])
+ self.emit("activated", path)
+ return True
Added: trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py
==============================================================================
--- (empty file)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py Fri Apr 11 18:22:38 2008
@@ -0,0 +1,170 @@
+import gtk
+import gobject
+import pango
+from deskbar.ui.cuemiac.CuemiacCellRenderer import CuemiacCellRenderer
+
+class CuemiacCellRendererAction (CuemiacCellRenderer):
+ """
+ Special cell renderer for the CuemiacTreeView.
+
+ If the cell to be rendered is a normal Match that has
+ more than one action an arrow is displayed.
+ If it's CuemiacCategory the match-count is displayed.
+ """
+
+ __gproperties__ = {
+ 'is-header' : (gobject.TYPE_BOOLEAN, 'whether we render a category header',
+ 'Render the header of a category, i.e. display the match-count',
+ False, gobject.PARAM_READWRITE),
+ 'match-count' : (gobject.TYPE_INT, 'number of hits in the category',
+ 'the number of hits for the CuemiacCategory to be rendered',
+ 0, 1000, 0, gobject.PARAM_READWRITE),
+ 'has-more-actions' : (gobject.TYPE_BOOLEAN, 'whether the match has more than one action',
+ 'If set to True a symbol will be displayed on the right',
+ False, gobject.PARAM_READWRITE),
+ }
+
+ def __init__ (self):
+ CuemiacCellRenderer.__init__ (self)
+ self.__match_count = 0
+ self.__has_more_actions = False
+ self.__is_header = False
+
+ def do_get_property(self, property):
+ if property.name == 'match-count':
+ return self.__match_count
+ elif property.name == 'has-more-actions':
+ return self.__has_more_actions
+ elif property.name == 'is-header':
+ return self.__is_header
+ else:
+ raise AttributeError, 'unknown property %s' % property.name
+
+ def do_set_property(self, property, value):
+ if property.name == 'match-count':
+ self.__match_count = value
+ elif property.name == 'has-more-actions':
+ self.__has_more_actions = value
+ elif property.name == 'is-header':
+ self.__is_header = value
+ else:
+ raise AttributeError, 'unknown property %s' % property.name
+
+ def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
+ self.set_style(widget)
+ if self.get_property ("is-header"):
+ self.render_category (window, widget, background_area, cell_area, expose_area, flags)
+ elif self.get_property ("has-more-actions"):
+ self.render_match (window, widget, background_area, cell_area, expose_area, flags)
+
+ def do_get_size(self, widget, cell_area):
+ """
+ Calculate size that is required to display
+ """
+ (xoffset, yoffset, w, h) = gtk.CellRendererText.do_get_size (self, widget, cell_area)
+
+ context = widget.get_pango_context()
+ metrics = context.get_metrics(self.header_font_desc, context.get_language())
+ char_width = metrics.get_approximate_char_width()
+
+ if self.get_property("is-header"):
+ num_chars = len(str(self.get_property("match-count"))) + 2
+ else:
+ num_chars = 1
+
+ width = self.get_property("xpad") * 2 + ((char_width/pango.SCALE) * num_chars);
+
+ return (xoffset, yoffset, width, h)
+
+ def _calculate_arrow_geometry (self, x, y, width, height):
+ """
+ Stolen from calculate_arrow_geometry at
+ http://svn.gnome.org/svn/gtk+/trunk/gtk/gtkstyle.c
+ """
+ # For right arrows only
+ h = height + (height % 2) - 1
+ w = (h / 2 + 1)
+
+ if w > width:
+ w = width
+ h = 2 * w - 1
+
+ if (width % 2 == 1 or w % 2 == 0):
+ w += 1
+
+ new_x = x + (width - w) / 2;
+ new_y = y + (height - h) / 2;
+ return (new_x, new_y, w, h)
+
+
+ def _draw_arrow_right(self, window, color, state, area, x, y, width, height):
+ (x, y, width, height) = self._calculate_arrow_geometry(x, y, width, height)
+
+ cr = window.cairo_create()
+ cr.set_source_color (color)
+
+ if area:
+ cr.rectangle (area)
+ cr.clip()
+
+ # Draw right arrow
+ cr.move_to(x,y)
+ cr.line_to(x + width, y + height / 2)
+ cr.line_to(x, y + height)
+
+ cr.close_path()
+
+ cr.fill()
+
+ def _shift_color (self, color, amount):
+ """
+ @type color: gtk.gdk.Color
+ """
+ r = color.red + amount
+ g = color.green + amount
+ b = color.blue + amount
+
+ return gtk.gdk.Color (r, g, b, color.pixel)
+
+ def render_match (self, window, widget, background_area, cell_area, expose_area, flags):
+ """
+ Renders an arrow
+ """
+ state = self.renderer_state_to_widget_state(flags)
+
+ if state & gtk.STATE_PRELIGHT:
+ color = color = widget.style.bg[state]
+ else:
+ color = color = widget.style.fg[state]
+
+ arrow_width = cell_area.width / 2
+ arrow_height = cell_area.height / 2
+
+ self._draw_arrow_right(window, color, state, cell_area,
+ cell_area.x + cell_area.width / 2,
+ cell_area.y + ((cell_area.height - arrow_height) / 2) + 1,
+ arrow_width,
+ arrow_height)
+
+ def render_category (self, window, widget, background_area, cell_area, expose_area, flag):
+ """
+ Renders the hit count (read from the "match-count" property).
+ """
+ ctx = window.cairo_create ()
+
+ # Set up a pango.Layout for the hit count
+ count_layout = ctx.create_layout ()
+ count_layout.set_text ("(" + str(self.get_property("match-count")) + ")")
+ count_layout.set_font_description (self.header_font_desc)
+
+ count_layout_width, count_layout_height = count_layout.get_pixel_size()
+
+ state = self.renderer_state_to_widget_state(flag)
+
+ mod_gc = widget.get_style().text_gc[state]
+
+ window.draw_layout(mod_gc,
+ cell_area.x + (cell_area.width - count_layout_width) / 2,
+ cell_area.y + ( (cell_area.height - count_layout_height) / 2) + 1,
+ count_layout)
+
\ No newline at end of file
Copied: trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py (from r2098, /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py)
==============================================================================
--- /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py (original)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py Fri Apr 11 18:22:38 2008
@@ -1,8 +1,9 @@
import gtk
import gobject
import pango
+from deskbar.ui.cuemiac.CuemiacCellRenderer import CuemiacCellRenderer
-class CuemiacCellRendererCategory (gtk.CellRendererText):
+class CuemiacCellRendererMatch (CuemiacCellRenderer):
"""
Special cell renderer for the CuemiacTreeView.
If the cell to be rendered is a normal Match, it falls back to the normal
@@ -17,114 +18,36 @@
'category-header' : (gobject.TYPE_STRING, 'markup for category title string',
'markup for category title string, None if this is not a category header',
None, gobject.PARAM_READWRITE),
-
- 'match-count' : (gobject.TYPE_INT, 'number of hits in the category',
- 'the number of hits for the CuemiacCategory to be rendered',
- 0,1000,0, gobject.PARAM_READWRITE),
- 'has-more-actions' : (gobject.TYPE_BOOLEAN, 'whether the match has more than one action',
- 'If set to True a symbol will be displayed on the right',
- False, gobject.PARAM_READWRITE),
}
- __gsignals__ = {
- # This signal will be emited when '>' on the right is clicked
- "show-actions-activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
- # This signal will be emited then an area that's not the '>' from above is clicked
- "do-action-activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
- }
def __init__ (self):
- gtk.CellRendererText.__init__ (self)
+ CuemiacCellRenderer.__init__ (self)
self.__category_header = None
- self.__match_count = 0
- self.__has_more_actions = False
- self.__match_markup = ""
- self.__button_x = 0
- self.__button_y = 0
- self.__button_width = 0
- self.__button_height = 0
- self.__relative_header_size = -0.2 # Make header 20% smaller than normal fonts
-
- self.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
-
- # Grab some default theme settings
- # they are probably incorrect, but we reset
- # them on each render anyway.
- style = gtk.Style ()
- self.header_font_desc = style.font_desc
- self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
- self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
- self.header_bg = style.base [gtk.STATE_NORMAL]
-
- def set_style (self, widget):
- """
- Apply the style from widget, to this cellrenderer
- """
- self.header_font_desc = widget.style.font_desc
- self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
- self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
- self.header_bg = widget.style.base [gtk.STATE_NORMAL]
-
- def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
- if not self.get_property ("category-header"):
- self.render_match (window, widget, background_area, cell_area, expose_area, flags)
- else:
- self.render_category (window, widget, background_area, cell_area, expose_area, flags)
-
- def render_match (self, window, widget, background_area, cell_area, expose_area, flags):
- ctx = window.cairo_create ()
- # Set up a pango.Layout
- more_actions_layout = ctx.create_layout ()
- if self.get_property("has-more-actions"):
- more_actions_layout.set_markup ("<b>></b>")
-
- more_actions_layout.set_font_description (self.header_font_desc)
-
- more_actions_layout_width, more_actions_layout_height = more_actions_layout.get_pixel_size()
-
- state = self.renderer_state_to_widget_state(flags)
-
- self.__button_width = more_actions_layout_width + 2
- self.__button_height = cell_area.height
-
- # Draw the actual text in the remaining area
- cell_area_width = cell_area.width
- cell_area.width -= self.__button_width
- gtk.CellRendererText.do_render (self, window, widget, background_area, cell_area, expose_area, flags)
-
- mod_gc = widget.get_style().text_gc[state]
-
- self.__button_x = (cell_area.x + cell_area_width) - more_actions_layout_width - 2
- self.__button_y = cell_area.y + ( (cell_area.height - more_actions_layout_height) / 2 ) + 1
-
- window.draw_layout(mod_gc,
- self.__button_x,
- self.__button_y,
- more_actions_layout)
-
- if self.get_property("has-more-actions"):
- # Add some additional area around the '>' to activate it
- self.__button_x -= 3
- self.__button_y = cell_area.y
- self.__button_width += 3
+ def do_get_property(self, property):
+ if property.name == 'category-header':
+ return self.__category_header
+ else:
+ raise AttributeError, 'unknown property %s' % property.name
+
+ def do_set_property(self, property, value):
+ if property.name == 'category-header':
+ self.__category_header = value
else:
- self.__button_height = 0
- self.__button_width = 0
- self.__button_x = 0
- self.__button_y = 0
-
- #window.draw_rectangle(mod_gc, False, self.__button_x, self.__button_y,
- # self.__button_width, self.__button_height
- # )
+ raise AttributeError, 'unknown property %s' % property.name
+ def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
+ self.set_style(widget)
+ if self.get_property ("category-header"):
+ self.render_category (window, widget, background_area, cell_area, expose_area, flags)
+ else:
+ gtk.CellRendererText.do_render (self, window, widget, background_area, cell_area, expose_area, flags)
+
def render_category (self, window, widget, background_area, cell_area, expose_area, flag):
"""
Renders the category title from the "category-header" property and displays a rigth aligned
hit count (read from the "match-count" property).
"""
- # Ensure we have fresh style settings
- self.set_style (widget)
-
ctx = window.cairo_create ()
# Set up a pango.Layout for the category title
@@ -138,28 +61,7 @@
cat_text = self.get_property("category-header")
cat_layout.set_markup(cat_text)
cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
-
- # Set up a pango.Layout for the hit count
- count_layout = ctx.create_layout ()
- count_layout.set_text ("(" + str(self.get_property("match-count")) + ")")
- count_layout.set_font_description (self.header_font_desc)
-
- count_layout_width, count_layout_height = count_layout.get_pixel_size()
-
- max_cat_layout_width = cell_area.width - count_layout_width - 10
-
- if cat_layout_width > max_cat_layout_width:
- ratio = float(max_cat_layout_width - ellipsise_size)/cat_layout_width;
- characters = int( ratio * len(cat_text) )
- while (cat_layout_width > max_cat_layout_width):
- if characters > 0:
- cat_layout.set_markup( cat_text[0:characters].strip() + "..." )
- characters -= 1
- cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
- else:
- cat_layout.set_markup(cat_text.strip())
- break
-
+
state = self.renderer_state_to_widget_state(flag)
main_gc = widget.get_style().text_gc[state]
@@ -167,63 +69,4 @@
18,
cell_area.y + ( (cell_area.height - cat_layout_height) / 2) + 1,
cat_layout)
-
- mod_gc = widget.get_style().text_gc[state]
- window.draw_layout(mod_gc,
- (cell_area.x + cell_area.width) - count_layout_width - 2,
- cell_area.y + ( (cell_area.height - count_layout_height) / 2 ) + 1,
- count_layout)
-
- def renderer_state_to_widget_state(self, flags):
- state = gtk.STATE_NORMAL
- if (gtk.CELL_RENDERER_SELECTED & flags) == gtk.CELL_RENDERER_SELECTED:
- state = gtk.STATE_SELECTED
- return state
-
- def do_activate(self, event, widget, path_string, background_area, cell_area, flags):
- if not isinstance(widget, gtk.TreeView):
- # Not a treeview
- return False
-
- if event == None or event.type != gtk.gdk.BUTTON_PRESS:
- # Event type not GDK_BUTTON_PRESS
- return True
-
- ex = event.x
- ey = event.y
- bx = self.__button_x
- # Otherwise, we get problems when the cell
- # is at the top of the visible part of the treeview
- by = cell_area.y
- bw = self.__button_width
- bh = self.__button_height
-
- path = tuple([int(i) for i in path_string.split(':')])
- if (ex < bx or ex > (bx+bw) or ey < by or ey > (by+bh)):
- # Click wasn't on the icon
- self.emit("do-action-activated", path)
- return True
- else:
- self.emit("show-actions-activated", path)
- return False
-
- def do_get_property(self, property):
- if property.name == 'category-header':
- return self.__category_header
- elif property.name == 'match-count':
- return self.__match_count
- elif property.name == 'has-more-actions':
- return self.__has_more_actions
- else:
- raise AttributeError, 'unknown property %s' % property.name
-
- def do_set_property(self, property, value):
- if property.name == 'category-header':
- self.__category_header = value
- elif property.name == 'match-count':
- self.__match_count = value
- elif property.name == 'has-more-actions':
- self.__has_more_actions = value
- else:
- raise AttributeError, 'unknown property %s' % property.name
\ No newline at end of file
Modified: trunk/deskbar/ui/cuemiac/CuemiacTreeView.py
==============================================================================
--- trunk/deskbar/ui/cuemiac/CuemiacTreeView.py (original)
+++ trunk/deskbar/ui/cuemiac/CuemiacTreeView.py Fri Apr 11 18:22:38 2008
@@ -5,7 +5,8 @@
import logging
from deskbar.ui.cuemiac.CuemiacItems import CuemiacCategory
-from deskbar.ui.cuemiac.CuemiacCellRendererCategory import CuemiacCellRendererCategory
+from deskbar.ui.cuemiac.CuemiacCellRendererMatch import CuemiacCellRendererMatch
+from deskbar.ui.cuemiac.CuemiacCellRendererAction import CuemiacCellRendererAction
from deskbar.interfaces import Match
LOGGER = logging.getLogger(__name__)
@@ -34,17 +35,22 @@
self.connect ("key-press-event", self.__on_key_press)
icon = gtk.CellRendererPixbuf ()
- icon.set_property("xpad", 10)
- hit_title = CuemiacCellRendererCategory ()
- hit_title.connect("show-actions-activated", self.__on_show_actions_activated)
- hit_title.connect("do-action-activated", self.__on_do_action_activated)
+ #icon.set_property("xpad", 10)
+
+ hit_title = CuemiacCellRendererMatch ()
+ hit_title.connect("activated", self.__on_do_action_activated)
hit_title.set_property ("ellipsize", pango.ELLIPSIZE_END)
-
+
+ action = CuemiacCellRendererAction ()
+ action.connect("activated", self.__on_show_actions_activated)
+
self._hits_column = gtk.TreeViewColumn ("Hits")
self._hits_column.pack_start (icon, expand=False)
self._hits_column.pack_start (hit_title)
+ self._hits_column.pack_end (action, expand=False)
self._hits_column.set_cell_data_func(hit_title, self.__get_match_title_for_cell)
self._hits_column.set_cell_data_func(icon, self.__get_match_icon_for_cell)
+ self._hits_column.set_cell_data_func(action, self.__get_match_action_for_cell)
self.append_column (self._hits_column)
#self.set_reorderable(True)
@@ -157,7 +163,6 @@
cell.set_property ("cell-background-gdk", self.style.bg[gtk.STATE_NORMAL])
cell.set_property ("height", 20)
cell.set_property ("category-header", match.get_name())
- cell.set_property ("match-count", match.get_count ())
return
cell.set_property ("category-header", None)
@@ -166,11 +171,20 @@
if match == None:
LOGGER.error("See bug 359251 or 471672 and report this output: Match object of unexpected type: %r - %r" % (match.__class__, match))
- cell.set_property ("has-more-actions", False)
cell.set_property ("markup", "")
else:
- cell.set_property ("has-more-actions", len(match.get_actions()) > 1)
cell.set_property ("markup", model[iter][model.ACTIONS])
+
+ def __get_match_action_for_cell (self, column, cell, model, iter, data=None):
+ match = model[iter][model.MATCHES]
+ if isinstance(match, CuemiacCategory):
+ cell.set_property ("is-header", True)
+ cell.set_property ("match-count", match.get_count ())
+ cell.set_property ("cell-background-gdk", self.style.bg[gtk.STATE_NORMAL])
+ else:
+ cell.set_property ("is-header", False)
+ cell.set_property ("has-more-actions", len(match.get_actions()) > 1)
+ cell.set_property ("cell-background-gdk", self.style.base[gtk.STATE_NORMAL])
def __on_show_actions_activated(self, widget, path):
col = self.get_model().ACTIONS
Modified: trunk/deskbar/ui/cuemiac/Makefile.am
==============================================================================
--- trunk/deskbar/ui/cuemiac/Makefile.am (original)
+++ trunk/deskbar/ui/cuemiac/Makefile.am Fri Apr 11 18:22:38 2008
@@ -2,7 +2,9 @@
deskbar_cuemiac_PYTHON = \
__init__.py \
CuemiacActionsTreeView.py \
- CuemiacCellRendererCategory.py \
+ CuemiacCellRenderer.py \
+ CuemiacCellRendererAction.py \
+ CuemiacCellRendererMatch.py \
CuemiacEntry.py \
CuemiacHeader.py \
CuemiacHistory.py \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]