[hamster-applet] a kind of better state of the whole layout business. still messy
- From: Toms Baugis <tbaugis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [hamster-applet] a kind of better state of the whole layout business. still messy
- Date: Fri, 14 May 2010 00:11:28 +0000 (UTC)
commit 0fe72f03ab5c2e5af358fc17d3c04136b2225aa9
Author: Toms Bauģis <toms baugis gmail com>
Date: Fri May 14 01:10:54 2010 +0100
a kind of better state of the whole layout business.
still messy
src/hamster/widgets/facttree.py | 352 ++++++++++++++++----------------------
1 files changed, 148 insertions(+), 204 deletions(-)
---
diff --git a/src/hamster/widgets/facttree.py b/src/hamster/widgets/facttree.py
index a4c4ae2..d7d2927 100644
--- a/src/hamster/widgets/facttree.py
+++ b/src/hamster/widgets/facttree.py
@@ -20,9 +20,10 @@
"""beware, this code has some major dragons in it. i'll clean it up one day!"""
import gtk, gobject
+import cairo
import datetime as dt
-from .hamster import stuff
+from .hamster import stuff, graphics
from .hamster.stuff import format_duration, format_activity
from tags import Tag
@@ -81,7 +82,7 @@ class FactTree(gtk.TreeView):
self.connect("row-activated", self._on_row_activated)
self.connect("button-release-event", self._on_button_release_event)
self.connect("key-release-event", self._on_key_released)
- self.connect("configure-event", lambda *args: self.columns_autosize())
+ self.connect("configure-event", lambda *args: self.fix_row_heights())
self.connect("motion-notify-event", self._on_motion)
self.show()
@@ -173,6 +174,9 @@ class FactTree(gtk.TreeView):
# let's save selection too - maybe it will come handy
self.store_selection()
+ #self.parent.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
+
+
# and now do what we were asked to
self.set_model()
@@ -181,6 +185,8 @@ class FactTree(gtk.TreeView):
# attach model is also where we calculate the bounding box widths
self.set_model(self.store_model)
+ #self.parent.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+
if self.stored_selection:
self.restore_selection()
@@ -296,9 +302,8 @@ class FactTree(gtk.TreeView):
if data and "id" in data:
renderer = view.get_column(0).get_cell_renderers()[0]
- label, x, y, w = renderer.labels[data["id"]]["activity"]
- if w != -1:
- self.set_tooltip_text(label)
+ label = data["name"]
+ self.set_tooltip_text(label)
self.trigger_tooltip_query()
@@ -317,24 +322,36 @@ class FactCellRenderer(gtk.GenericCellRenderer):
self.height = 0
self.data = None
+ font = gtk.Style().font_desc
+ default_size = font.get_size() / pango.SCALE
+
+ self.labels = graphics.Sprite()
+
+ self.date_label = graphics.Label(size = default_size)
+
+ self.interval_label = graphics.Label(size = default_size)
+ self.labels.add_child(self.interval_label)
+
+ self.activity_label = graphics.Label(size = default_size)
+ self.labels.add_child(self.activity_label)
+
+ self.category_label = graphics.Label(size = default_size)
+ self.labels.add_child(self.category_label)
+
+ self.description_label = graphics.Label(size = default_size)
+ self.labels.add_child(self.description_label)
+
+ self.duration_label = graphics.Label(size=default_size)
+ self.labels.add_child(self.duration_label)
+
default_font = gtk.Style().font_desc.to_string()
- self.label_font = pango.FontDescription(default_font)
- self.label_font_size = 10
self.selected_color = gtk.Style().text[gtk.STATE_SELECTED]
self.normal_color = gtk.Style().text[gtk.STATE_NORMAL]
- self.tag_font = pango.FontDescription(default_font)
- self.tag_font.set_size(pango.SCALE * 8)
-
- self.layout, self.tag_layout = None, None
-
self.col_padding = 10
self.row_padding = 4
-
- self.labels = {}
-
def do_set_property (self, pspec, value):
setattr(self, pspec.name, value)
@@ -342,12 +359,6 @@ class FactCellRenderer(gtk.GenericCellRenderer):
return getattr (self, pspec.name)
- def set_text(self, text):
- # sets text and returns width and height of the layout
- self.layout.set_text(text)
- w, h = self.layout.get_pixel_size()
- return w, h
-
def on_render (self, window, widget, background_area, cell_area, expose_area, flags):
if not self.data:
return
@@ -355,20 +366,12 @@ class FactCellRenderer(gtk.GenericCellRenderer):
"""
ASCII Art
--------------+--------------------------------------------+-------+---+
- 13:12 - 17:18 | Some activity - category, tag, tag, tag, | 14:44 | E |
- | tag, tag, some description in grey italics | | |
+ 13:12 - 17:18 | Some activity - category tag, tag, tag, | 14:44 | E |
+ | tag, tag, some description | | |
--------------+--------------------------------------------+-------+---+
"""
-
context = window.cairo_create()
- if not self.layout:
- self.layout = context.create_layout()
- self.layout.set_font_description(self.label_font)
-
- self.tag_layout = context.create_layout()
- self.tag_layout.set_font_description(self.tag_font)
-
if "id" in self.data:
fact, parent = self.data, None
@@ -376,14 +379,10 @@ class FactCellRenderer(gtk.GenericCellRenderer):
parent, fact = self.data, None
-
-
- x, y, width, height = self.on_get_size(widget, cell_area)
- width = cell_area.width
+ x, y, width, height = cell_area
context.translate(x, y)
current_fact = widget.get_selected_fact()
-
if parent:
text_color = self.normal_color
# if we are selected, change font color appropriately
@@ -391,97 +390,27 @@ class FactCellRenderer(gtk.GenericCellRenderer):
and current_fact == parent["date"]:
text_color = self.selected_color
- self.set_color(context, text_color)
-
- self.layout.set_width(-1)
-
- self.layout.set_markup("<b>%s</b>" % stuff.escape_pango(parent["label"]))
+ self.date_label.color = text_color
+ self.date_label.text = "<b>%s</b>" % stuff.escape_pango(parent["label"])
+ self.date_label.x = 5
if self.data["first"]:
y = 5
else:
y = 20
- context.move_to(5, y)
- context.show_layout(self.layout)
+ self.date_label.y = y
- self.layout.set_markup("<b>%s</b>" % stuff.format_duration(parent["duration"]))
- label_w, label_h = self.layout.get_pixel_size()
- context.move_to(width - label_w, y)
- context.show_layout(self.layout)
+ self.duration_label.color = text_color
+ self.duration_label.text = "<b>%s</b>" % stuff.format_duration(parent["duration"])
+ self.duration_label.x = width - self.duration_label.width
+ self.duration_label.y = y
+ self.date_label._draw(context)
+ self.duration_label._draw(context)
else:
- text_color = self.normal_color
- selected = False
- # if we are selected, change font color appropriately
- if current_fact and isinstance(current_fact, dt.date) == False \
- and current_fact["id"] == fact["id"]:
- text_color = self.selected_color
- selected = True
-
- def show_label(label_info):
- label, x, y, w = label_info
- self.layout.set_markup(label)
- context.move_to(x, y)
- if w:
- self.layout.set_width(w)
- else:
- self.layout.set_width(-1)
-
- context.show_layout(self.layout)
-
- self.set_color(context, text_color)
-
- labels = self.labels[fact["id"]]
- show_label(labels["interval"])
-
- # for the right-aligned delta with have reserved space for scrollbar
- # but about it's existance we find only on expose, so we realign
- self.layout.set_markup(labels["delta"][0])
- w, h = self.layout.get_pixel_size()
- context.move_to(width - w, labels["delta"][2])
- context.show_layout(self.layout)
-
-
- label, label_x, label_y, label_w = labels["activity"]
- self.layout.set_markup(label)
- self.layout.set_ellipsize(pango.ELLIPSIZE_END)
- context.move_to(label_x, label_y)
- self.layout.set_width(label_w)
- context.show_layout(self.layout)
- self.layout.set_ellipsize(pango.ELLIPSIZE_NONE)
-
-
- if fact["category"]:
- if not selected:
- self.set_color(context, widget.get_style().text[gtk.STATE_INSENSITIVE])
-
- show_label(labels["category"])
-
-
- if fact["tags"]:
- start_x, start_y, cell_end = labels["tags"][1:]
- cur_x, cur_y = start_x, start_y
-
- for i, tag in enumerate(fact["tags"]):
- temp_tag = Tag(tag)
- tag_w, tag_h = temp_tag.width, temp_tag.height
-
- if i > 0 and cur_x + tag_w >= cell_end:
- cur_x = start_x
- cur_y += tag_h + 4
-
- sprite = Tag(tag, False)
- sprite.x, sprite.y = cur_x, cur_y
- sprite._draw(context)
-
- cur_x += tag_w + 4
-
-
- if fact["description"]:
- self.set_color(context, text_color)
- show_label(labels["description"])
+ self.render_cell(context, (x,y,width,height), widget)
@@ -492,46 +421,42 @@ class FactCellRenderer(gtk.GenericCellRenderer):
return c.red/65535.0, c.green/65535.0, c.blue/65535.0, a
- def on_get_size (self, widget, cell_area):
- x_offset, y_offset = 0, 0
- if cell_area:
- x_offset, y_offset = cell_area.x, cell_area.y
-
- if "id" not in self.data:
- if self.data["first"]:
- return (0, y_offset, 0, 25)
- else:
- return (0, y_offset, 0, 40)
-
+ def render_cell(self, context, bounds, widget, really = True):
+ if not bounds:
+ return -1
+ x, y, cell_width, h = bounds
+ g = graphics.Graphics(context)
fact = self.data
- pixmap = gtk.gdk.Pixmap(None, 10, 10, 24)
- context = pixmap.cairo_create()
- layout = context.create_layout()
- layout.set_font_description(self.label_font)
-
- if cell_area:
- x, y, width, height = cell_area
- else:
- x, y, width, height = widget.get_allocation()
+ current_fact = widget.get_selected_fact()
+ text_color = self.normal_color
+ selected = False
+ # if we are selected, change font color appropriately
+ if current_fact and isinstance(current_fact, dt.date) == False \
+ and current_fact["id"] == fact["id"]:
+ text_color = self.selected_color
+ selected = True
- labels = {}
- cell_width = width
""" start time and end time at beginning of column """
interval = fact["start_time"].strftime("%H:%M -")
if fact["end_time"]:
interval = "%s %s" % (interval, fact["end_time"].strftime("%H:%M"))
- labels["interval"] = (interval, self.col_padding, 2, -1)
+
+ self.interval_label.text = interval
+ self.interval_label.color = text_color
+ self.interval_label.x = self.col_padding
+ self.interval_label.y = 2
+
""" duration at the end """
- delta = stuff.format_duration(fact["delta"])
- layout.set_markup(delta)
- duration_w, duration_h = layout.get_pixel_size()
- labels["delta"] = (delta, cell_width - duration_w, 2, -1)
+ self.duration_label.text = stuff.format_duration(fact["delta"])
+ self.duration_label.color = text_color
+ self.duration_label.x = cell_width - self.duration_label.width
+ self.duration_label.y = 2
""" activity, category, tags, description in middle """
@@ -539,102 +464,121 @@ class FactCellRenderer(gtk.GenericCellRenderer):
# both sides, in letter length
cell_start = widget.longest_interval
-
cell_width = cell_width - widget.longest_interval - widget.longest_duration
- layout.set_markup(stuff.escape_pango(fact["name"]))
- label_w, activity_label_height = layout.get_pixel_size()
-
+ # align activity and category (ellipsize activity if it does not fit)
+ category_width = 0
- category_label = " - <small>%s</small>" % stuff.escape_pango(fact["category"])
- layout.set_markup(category_label)
- category_width, label_h = layout.get_pixel_size()
+ self.category_label.text = ""
+ if fact["category"]:
+ self.category_label.text = " - <small>%s</small>" % stuff.escape_pango(fact["category"])
+ if not selected:
+ self.category_label.color = widget.get_style().text[gtk.STATE_INSENSITIVE]
+ else:
+ self.category_label.color = text_color
+ category_width = self.category_label.width
- activity_width = cell_width - category_width - 12
+ self.activity_label.color = text_color
+ self.activity_label.width = None
+ self.activity_label.text = stuff.escape_pango(fact["name"])
+ #activity_label = g.create_layout()
+ #activity_label.set_markup(stuff.escape_pango(fact["name"]))
- if label_w > activity_width:
- activity_width = min(activity_width, label_w)
- labels["activity"] = (stuff.escape_pango(fact["name"]),
- cell_start,
- 2,
- activity_width * pango.SCALE)
+ # if activity label does not fit, we will shrink it
+ if self.activity_label.width > cell_width - category_width:
+ self.activity_label.width = (cell_width - category_width - self.col_padding)
+ self.activity_label.ellipsize = pango.ELLIPSIZE_END
else:
- activity_width = label_w
- labels["activity"] = (stuff.escape_pango(fact["name"]),
- cell_start,
- 2,
- -1)
+ self.activity_label.width = None
+ #self.activity_label.ellipsize = None
+ activity_width = self.activity_label.width
+ y = 2
- labels["category"] = (category_label, cell_start + activity_width, 2, category_width * pango.SCALE)
+ self.activity_label.x = cell_start
+ self.activity_label.y = y
- tag_cell_start = cell_start + activity_width + category_width + 12
- tag_cell_end = cell_start + cell_width
- tag_cell_top = 2
+ self.category_label.x = cell_start + activity_width
+ self.category_label.y = y
- cell_height = label_h + 4
- cur_x, cur_y = tag_cell_start, tag_cell_top
+ current_height = 0
if fact["tags"]:
- layout.set_font_description(self.tag_font)
+ # try putting tags on same line if they fit
+ # otherwise move to the next line
+ tags_end = cell_start + cell_width
+ x = cell_start + activity_width + category_width + 12
+
+ tag = Tag(fact["tags"][0])
- # if we don't fit, jump to the next line
- temp_tag = Tag(fact["tags"][0])
- tag_w, tag_h = temp_tag.width, temp_tag.height
- if tag_cell_start + tag_w >= tag_cell_end:
- tag_cell_start = cell_start
- tag_cell_top = activity_label_height + 4
- cur_x = tag_cell_start
- cur_y = tag_cell_top
+ if x + tag.width > tags_end:
+ x = cell_start
+ y = self.activity_label.height + 4
for i, tag in enumerate(fact["tags"]):
- temp_tag = Tag(tag)
- tag_w, tag_h = temp_tag.width, temp_tag.height
+ tag = Tag(tag)
+
+ if x + tag.width >= tags_end:
+ x = cell_start
+ y += tag.height + 4
- if i > 0 and cur_x + tag_w >= tag_cell_end:
- cur_x = tag_cell_start
- cur_y += tag_h + 4
- cur_x += tag_w + 4
+ tag.x, tag.y = x, y
+ if really:
+ tag._draw(context)
- cell_height = max(cell_height, cur_y + tag_h + 4)
+ x += tag.width + 4
- labels["tags"] = (None, tag_cell_start, tag_cell_top, tag_cell_end)
+ current_height = y + tag.height + 4
- layout.set_font_description(self.label_font)
+
+ current_height = max(self.activity_label.height + 2, current_height)
# see if we can fit in single line
# if not, put description under activity
+ self.description_label.text = ""
if fact["description"]:
- description = "<small>%s</small>" % stuff.escape_pango(fact["description"])
- layout.set_markup(description)
- label_w, label_h = layout.get_pixel_size()
+ self.description_label.text = "<small>%s</small>" % stuff.escape_pango(fact["description"])
+ self.description_label.color = text_color
+ self.description_label.wrap = pango.WRAP_WORD
- x, y = cur_x, cur_y
- width = cell_start + cell_width - x
+ description_width = self.description_label.width
+ width = cell_width - x
- if x + label_w > width:
+ if description_width > width:
x = cell_start
- y = cell_height
- width = cell_width
+ y = current_height
+ self.description_label.width = cell_width
+ else:
+ self.description_label.width = None
+
+ self.description_label.x = x
+ self.description_label.y = y
+
+ current_height = max(current_height, self.description_label.y + self.description_label.height + 5)
- layout.set_width(width * pango.SCALE)
- label_w, label_h = layout.get_pixel_size()
+ self.labels._draw(context)
- labels["description"] = (description, x, y, width * pango.SCALE)
+ return current_height
- cell_height = y + label_h + 4
- self.labels[fact["id"]] = labels
+ def on_get_size(self, widget, cell_area):
+ if "id" not in self.data:
+ if self.data["first"]:
+ return (0, 0, 0, 25)
+ else:
+ return (0, 0, 0, 40)
+
+ context = gtk.gdk.CairoContext(cairo.Context(cairo.ImageSurface(cairo.FORMAT_A1, 0, 0)))
+ area = widget.get_allocation()
- x_offset, y_offset = 0, 0
- if cell_area:
- x_offset, y_offset = cell_area.x, cell_area.y
+ area.width -= 40 # minus the edit column, scrollbar and padding (and the scrollbar part is quite lame)
- return (0, y_offset, 1, cell_height)
+ cell_height = self.render_cell(context, area, widget, False)
+ return (0, 0, -1, cell_height)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]