Browse Source

Starting a custom cell for the messages

master
Julio Biason 15 years ago
parent
commit
73b1712282
  1. 125
      mitterlib/ui/ui_pygtk.py

125
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'<span foreground="%s">\1</span>' % (
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'<span foreground="#FF6633">\1</span>',
@ -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:

Loading…
Cancel
Save