diff --git a/mitterlib/ui/ui_pygtk.py b/mitterlib/ui/ui_pygtk.py
index 89d9004..178bc20 100644
--- a/mitterlib/ui/ui_pygtk.py
+++ b/mitterlib/ui/ui_pygtk.py
@@ -99,7 +99,7 @@ class _WorkerThread(threading.Thread, _IdleObject):
def run(self):
# call the function
- _log.debug('Thread %s calling %s', self.ident, str(self._function))
+ _log.debug('Thread %s calling %s', self.name, str(self._function))
args = self._args
kwargs = self._kwargs
@@ -183,6 +183,76 @@ class _ThreadManager(object):
self._thread_id += 1
return
+# ----------------------------------------------------------------------
+# Custom cell renderer
+# ----------------------------------------------------------------------
+class CellRendererNetworkData(gtk.GenericCellrenderer):
+ """A customized cell renderer for messages."""
+
+ __gproperties__ = {
+ 'message': (gobject.TYPE_PYOBJECT,
+ 'message',
+ 'A NetworkData object to be rendered',
+ '',
+ gobject.PARAM_WRITABLE)
+ }
+
+ def __init__(self):
+ super(CellrendererNetworkData, self).__init__(self)
+ self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ return
+
+ def on_render(self, window, widget, bg_area, cell_area, exp_area, flags):
+ """The render() method invokes the virtual render function of the
+ gtk.CellRenderer. The three passed-in rectangles are areas of window.
+ Most renderers will draw within cell_area; the xalign, yalign, xpad,
+ and ypad properties of the gtk.CellRenderer should be honored with
+ respect to cell_area. background_area includes the blank space around
+ the cell, and also the area containing the tree expander; so the
+ background_area rectangles for all cells tile to cover the entire
+ window. expose_area is a clip rectangle.
+
+ The flags value is one of: gtk.CELL_RENDERER_SELECTED,
+ gtk.CELL_RENDERER_PRELIT, gtk.CELL_RENDERER_INSENSITIVE or
+ gtk.CELL_RENDERER_SORTED"""
+
+ layout = self.get_layout(widget)
+
+ if flags & gtk.CELL_RENDERER_SELECTED:
+ if widget.get_property('has-focus'):
+ state = gtk.STATE_SELECTED
+ else:
+ satte = gtk.STATE_ACTIVE
+ else:
+ state = gtk.STATE_NORMAL
+
+ widget.style.paint_layout(
+ window,
+ state,
+ True,
+ cell_area,
+ widget,
+ 'foo',
+ cell_area.x + x_offset,
+ cell_area.y + y_offset,
+ layout
+ )
+ return
+
+ def on_get_size(sel, widget, cell_area):
+ """The get_size() method obtains the width and height needed to render
+ the cell. These values are returned as part of a tuple containing the
+ x_offset, y_offset, width and height. get_size() is used by view
+ widgets to determine the appropriate size for the cell_area to be
+ passed to the gtk.CellRenderer.render() method. If cell_area is not
+ None, the x and y offsets of the cell relative to this location are
+ returned. Please note that the values set in the returned width and
+ height, as well as those in x_offset and y_offset are inclusive of the
+ xpad and ypad properties."""
+ return (x_offset, y_offset, width, height)
+
+gobject.type_register(CellRendererNetworkData)
+
# ----------------------------------------------------------------------
# Mitter interface object
# ----------------------------------------------------------------------
@@ -230,7 +300,7 @@ class Interface(object):
main_window.connect('destroy', self._quit_app)
main_window.connect('delete-event', self._quit_app)
- main_window.connect('size-request', self._window_resize)
+ main_window.connect('size-request', self._grid_resize)
grid = self._create_grid()
(menu, toolbar, accelerators) = self._create_menu_and_toolbar()
@@ -263,19 +333,31 @@ class Interface(object):
user_renderer = gtk.CellRendererPixbuf()
user_column = gtk.TreeViewColumn('User', user_renderer)
+ user_column.set_fixed_width(48) # avatar size (we resize to 48x48)
+ user_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
user_column.set_cell_data_func(user_renderer,
self._cell_renderer_user)
- self._grid.append_column(user_column)
message_renderer = gtk.CellRendererText()
message_renderer.set_property('wrap-mode', gtk.WRAP_WORD)
message_renderer.set_property('wrap-width', 200)
- message_renderer.set_property('width', 10)
-
message_column = gtk.TreeViewColumn('Message',
message_renderer)
message_column.set_cell_data_func(message_renderer,
self._cell_renderer_message)
+
+ options_renderer = gtk.CellRendererPixbuf()
+ options_renderer.set_fixed_size(16, 16)
+ options_column = gtk.TreeViewColumn('Options', options_renderer)
+ options_column.set_cell_data_func(options_renderer,
+ self._cell_renderer_options)
+ #options_column.set_fixed_width(16) # icon size
+ #options_column.set_max_width(16)
+ #options_column.set_expand(False)
+ #options_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+
+ self._grid.append_column(user_column)
+ self._grid.append_column(options_column)
self._grid.append_column(message_column)
self._grid.set_resize_mode(gtk.RESIZE_IMMEDIATE)
@@ -498,14 +580,13 @@ class Interface(object):
# unescape escaped entities that pango is not okay with
message = re.sub(r'&', r'&', message)
- #_log.debug('Rendering message: %s', message)
+ _log.debug('Rendering message: %s', message)
# highlight URLs
mask = r'\1' % (
self._options[self.NAMESPACE]['link_colour'])
message = URL_RE.sub(mask, message)
-
# use a different highlight for the current user
#message = re.sub(r'(@'+self.twitter.username+')',
# r'\1',
@@ -517,6 +598,13 @@ class Interface(object):
return
+ def _cell_renderer_options(self, column, cell, store, position):
+ """Callback for the options renderer. Adds the delete icon if the
+ message belongs to the user or reply if not."""
+ data = store.get_value(position, 0)
+ cell.set_property('pixbuf', self._reply_pixbuf)
+ return
+
# ------------------------------------------------------------
# Helper functions
# ------------------------------------------------------------
@@ -577,26 +665,34 @@ class Interface(object):
gtk.main_quit()
return
- def _window_resize(self, widget, request, data=None):
+ def _grid_resize(self, widget, allocation, data=None):
"""Called when the window is resized. We use it to set the proper
word-wrapping in the message column."""
- (width, height) = widget.get_size()
model = self._grid.get_model()
-
if len(model) == 0:
# nothing in the list, so we don't have what to set proper word
# wrapping
return
- column = self._grid.get_column(1)
+ _log.debug('Widget size: %d', allocation.width)
+
+ column = self._grid.get_column(2)
iter = model.get_iter_first()
path = model.get_path(iter)
- column_rectangle = self._grid.get_cell_area(path, column)
+ cell_rectangle = self._grid.get_cell_area(path, column)
+ # x_padding
+
+ # focus-line-width
+ focus_line_width = self._grid.style_get_property('focus-line-width')
+ #rectangle_width = column_rectangle.width
+
+ width = cell_rectangle.width - focus_line_width
for renderer in column.get_cell_renderers():
- renderer.set_property('wrap-width', column_rectangle.width)
+ renderer.set_property('wrap-width', width)
+ renderer.set_property('width', width)
while iter:
path = model.get_path(iter)
@@ -711,6 +807,9 @@ class Interface(object):
# Load images
self._app_icon = find_image('mitter.png')
self._app_icon_alert = find_image('mitter-new.png')
+ self._reply_pixbuf = gtk.gdk.pixbuf_new_from_file(
+ find_image('reply.png'))
+ #self._delete_icon = find_image('icon_trash.gif')
unknown_pixbuf = find_image('unknown.png')
if unknown_pixbuf: