From: Philipp Zabel Date: Fri, 2 Jul 2010 16:24:00 +0000 (+0200) Subject: Add VBox cell renderer to display driver name in lift list X-Git-Url: http://vcs.maemo.org/git/?p=beifahrer;a=commitdiff_plain;h=d69d4f2f3289dbb1489a1f3ccec4c95dbc50d69a Add VBox cell renderer to display driver name in lift list --- diff --git a/Makefile.am b/Makefile.am index 5bb0c5e..16c3fcc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,6 +30,7 @@ icon64_DATA = \ beifahrer_SOURCES = \ src/beifahrer.c \ src/adac-mitfahrclub.c \ + src/cell-renderer-vbox.c \ src/city-button.c \ src/orientation.c \ src/query-window.c \ @@ -43,6 +44,7 @@ beifahrer_SOURCES = \ beifahrer_VALASOURCES = \ src/beifahrer.vala \ src/adac-mitfahrclub.vala \ + src/cell-renderer-vbox.vala \ src/city-button.vala \ src/orientation.vala \ src/query-window.vala \ diff --git a/src/cell-renderer-vbox.vala b/src/cell-renderer-vbox.vala new file mode 100644 index 0000000..659db86 --- /dev/null +++ b/src/cell-renderer-vbox.vala @@ -0,0 +1,149 @@ +/* This file is part of Cinaest. + * + * Copyright (C) 2009 Philipp Zabel + * + * Cinaest is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cinaest is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cinaest. If not, see . + */ + +using Gtk; + +class CellRendererVBox : CellRenderer { + private List children; + + public CellRendererVBox () { + } + + construct { + children = null; + } + + public void append (CellRenderer cell, bool expand) { + children.append (cell); + cell.set_data ("box-expand", (void*) (long) expand); + } + + public override void get_size (Widget widget, Gdk.Rectangle? rectangle, out int x_offset, out int y_offset, out int width, out int height) { + int calc_width = 0; + int calc_height = 0; + + foreach (CellRenderer child in children) { + int renderer_width, renderer_height; + + child.get_size (widget, null, null, null, out renderer_width, out renderer_height); + if ((renderer_width > 0) && (renderer_height > 0)) { + calc_width = int.max (calc_width, renderer_width); + calc_height += renderer_height; + } + } + + int full_width = (int) xpad * 2 + calc_width; + int full_height = (int) ypad * 2 + calc_height; + + if ((rectangle != null) && calc_width > 0 && calc_height > 0) { + if (&x_offset != null) { + x_offset = (int) (((widget.get_direction () == TextDirection.RTL) ? (1.0 - xalign) : xalign) * (rectangle.width - full_width)); + x_offset = int.max (x_offset, 0); + } + if (&y_offset != null) { + y_offset = (int) (yalign * (rectangle.height - full_height)); + y_offset = int.max (y_offset, 0); + } + } else { + if (&x_offset != null) + x_offset = 0; + if (&y_offset != null) + y_offset = 0; + } + + if (&width != null) + width = full_width; + if (&height != null) + height = full_height; + } + + public override void render (Gdk.Window window, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { + int nvis_children = 0; + int nexpand_children = 0; + int height, extra; + + // Counts visible and expandable children cell renderers + foreach (CellRenderer child in children) { + bool visible, expand; + + child.get ("visible", out visible); + expand = child.get_data ("box-expand"); + + if (visible) { + nvis_children += 1; + if (expand) + nexpand_children += 1; + } + } + + if (nvis_children > 0) { + int x_pad, y_pad; + int y; + var child_alloc = Gdk.Rectangle (); + + if (nexpand_children > 0) { + var req = Requisition (); + + get_size (widget, null, null, null, out req.width, out req.height); + height = cell_area.height - req.height; + extra = height / nexpand_children; + } else { + height = 0; + extra = 0; + } + + get ("xpad", out x_pad, "ypad", out y_pad); + y = cell_area.y + y_pad; + child_alloc.x = cell_area.x + x_pad; + child_alloc.width = int.max (1, cell_area.width - x_pad * 2); + + foreach (CellRenderer child in children) { + bool visible, expand; + + child.get ("visible", out visible); + expand = child.get_data ("box-expand"); + + if (visible) { + var child_req = Requisition (); + int child_xpad, child_ypad; + var child_expose_area = Gdk.Rectangle (); + + child.get_size (widget, null, null, null, out child_req.width, out child_req.height); + child.get ("xpad", out child_xpad, "ypad", out child_ypad); + + if (expand) { + if (nexpand_children == 1) + child_req.height += height; + else + child_req.height += extra; + nexpand_children -= 1; + height -= extra; + } + + child_alloc.height = int.max (1, child_req.height); + child_alloc.y = y; + + if (child_alloc.intersect (expose_area, child_expose_area)) { + child.render (window, widget, background_area, child_alloc, child_expose_area, flags); + } + y += child_req.height; + } + } + } + } +} diff --git a/src/lift-list-window.vala b/src/lift-list-window.vala index c1a2611..4c59c5e 100644 --- a/src/lift-list-window.vala +++ b/src/lift-list-window.vala @@ -22,6 +22,16 @@ using Hildon; public class LiftListWindow : StackableWindow { public const string GCONF_KEY_PRELOAD = "/apps/beifahrer/preload"; + enum Columns { + ROUTE, + SECONDARY, + DATETIME, + PLACES, + PRICE, + SMOKER, + LIFT + } + AdacMitfahrclub adac; ListStore store; TreeSortable sortable; @@ -56,7 +66,7 @@ public class LiftListWindow : StackableWindow { set_main_menu (menu); gconf = GConf.Client.get_default (); - store = new ListStore (6, typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (Lift)); + store = new ListStore (7, typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (Lift)); sortable = new TreeModelSort.with_model (store); alignment = new Alignment (0.0f, 0.0f, 1.0f, 1.0f); @@ -74,36 +84,69 @@ public class LiftListWindow : StackableWindow { var selection = tree.get_selection (); selection.set_mode (SelectionMode.SINGLE); - // Source and destination column - route_column = new TreeViewColumn.with_attributes ("Route", new CellRendererText (), "markup", 0); + // Source - destination / driver column + var route_column = new TreeViewColumn (); + route_column.set_title (_("Route")); route_column.set_reorderable (false); route_column.set_sizing (TreeViewColumnSizing.AUTOSIZE); route_column.set_expand (true); tree.append_column (route_column); + var vbox_renderer = new CellRendererVBox (); + + var renderer = new CellRendererText (); + renderer.yalign = 1.0f; + renderer.set_fixed_size (-1, 32); + vbox_renderer.append (renderer, true); + vbox_renderer.set_data ("route-renderer", renderer); + + // Add secondary text to column (driver name, route details) + renderer = new CellRendererText (); + renderer.yalign = 0; + renderer.set_fixed_size (-1, 32); + renderer.ellipsize = Pango.EllipsizeMode.END; + Pango.AttrList attr_list = new Pango.AttrList (); + var style = Gtk.rc_get_style_by_paths (Gtk.Settings.get_default (), "SmallSystemFont", null, typeof (void)); + if (style != null) { + var attr_font_desc = new Pango.AttrFontDesc (style.font_desc.copy ()); + attr_list.insert ((owned) attr_font_desc); + } + Gdk.Color color; + this.ensure_style (); + if (this.style.lookup_color ("SecondaryTextColor", out color)) { + Pango.Attribute attr_color = Pango.attr_foreground_new (color.red, color.green, color.blue); + attr_list.insert ((owned) attr_color); + } + renderer.attributes = attr_list; + vbox_renderer.append (renderer, true); + vbox_renderer.set_data ("secondary-renderer", renderer); + + route_column.pack_start (vbox_renderer, true); + route_column.set_cell_data_func (vbox_renderer, vbox_data_func); + // Date and time column - var datetime_column = new TreeViewColumn.with_attributes ("DateTime", new CellRendererText (), "text", 1); + var datetime_column = new TreeViewColumn.with_attributes ("DateTime", new CellRendererText (), "text", Columns.DATETIME); datetime_column.set_reorderable (false); datetime_column.set_sizing (TreeViewColumnSizing.AUTOSIZE); datetime_column.set_expand (true); tree.append_column (datetime_column); // Free places column - var places_column = new TreeViewColumn.with_attributes ("Places", new CellRendererText (), "text", 2); + var places_column = new TreeViewColumn.with_attributes ("Places", new CellRendererText (), "text", Columns.PLACES); places_column.set_reorderable (false); places_column.set_sizing (TreeViewColumnSizing.AUTOSIZE); places_column.set_expand (true); tree.append_column (places_column); // Price column - var price_column = new TreeViewColumn.with_attributes ("Price", new CellRendererText (), "text", 3); + var price_column = new TreeViewColumn.with_attributes ("Price", new CellRendererText (), "text", Columns.PRICE); price_column.set_reorderable (false); price_column.set_sizing (TreeViewColumnSizing.AUTOSIZE); price_column.set_expand (true); tree.append_column (price_column); // Smoker/Non-smoker column - var smoke_column = new TreeViewColumn.with_attributes ("Smoker", new CellRendererPixbuf (), "icon-name", 4); + var smoke_column = new TreeViewColumn.with_attributes ("Smoker", new CellRendererPixbuf (), "icon-name", Columns.SMOKER); smoke_column.set_reorderable (false); smoke_column.set_sizing (TreeViewColumnSizing.AUTOSIZE); smoke_column.set_expand (false); @@ -134,14 +177,27 @@ public class LiftListWindow : StackableWindow { goto_website.clicked.connect (on_goto_website_clicked); sort_by_time.toggled.connect (button => { if (button.get_active ()) - sortable.set_sort_column_id (1, Gtk.SortType.ASCENDING); + sortable.set_sort_column_id (Columns.DATETIME, Gtk.SortType.ASCENDING); }); sort_by_price.toggled.connect (button => { if (button.get_active ()) - sortable.set_sort_column_id (3, Gtk.SortType.ASCENDING); + sortable.set_sort_column_id (Columns.PRICE, Gtk.SortType.ASCENDING); }); } + private void vbox_data_func (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter) { + unowned string text; + CellRendererText renderer; + + model.get (iter, Columns.ROUTE, out text); + renderer = cell.get_data ("route-renderer"); + renderer.text = text; + + model.get (iter, Columns.SECONDARY, out text); + renderer = cell.get_data ("secondary-renderer"); + renderer.text = text; + } + public async void find_lifts (string city_from, int radius_from, string city_to, int radius_to, Date date, int tolerance = 0) { TreeIter iter; set_title ("%s - %s".printf (city_from, city_to)); @@ -161,12 +217,13 @@ public class LiftListWindow : StackableWindow { string datetime = "%02d.%02d.%04d".printf (lift.time.day, lift.time.month, lift.time.year); if (lift.time.hour >= 0) datetime += ", %d:%02d".printf (lift.time.hour, lift.time.minute); - store.insert_with_values (out iter, -1, 0, lift.city_from + " - " + lift.city_to, - 1, datetime, - 2, _("%d pl.").printf (lift.places), - 3, lift.price, - 4, icon_name, - 5, lift); + store.insert_with_values (out iter, -1, Columns.ROUTE, lift.city_from + " - " + lift.city_to, + Columns.SECONDARY, "", + Columns.DATETIME, datetime, + Columns.PLACES, _("%d pl.").printf (lift.places), + Columns.PRICE, lift.price, + Columns.SMOKER, icon_name, + Columns.LIFT, lift); // (LiftFlags.WOMEN_ONLY,ADAC_MEMBER in lift.flags) } if (lift_list.length () > 6) @@ -182,12 +239,12 @@ public class LiftListWindow : StackableWindow { if (preload) { if (store.get_iter_first (out iter)) do { Lift lift2; - store.@get (iter, 5, out lift2); + store.@get (iter, Columns.LIFT, out lift2); if (lift2 == null) continue; if (lift2.description == null) { yield adac.update_lift_details (lift2); - store.@set (iter, 0, lift2.city_from + " - " + lift2.city_to + "\n" + lift2.name + ""); + store.@set (iter, Columns.SECONDARY, lift2.name); } } while (store.iter_next (ref iter)); } @@ -205,7 +262,7 @@ public class LiftListWindow : StackableWindow { Lift lift; if (model.get_iter (out iter, path)) { - model.get (iter, 5, out lift); + model.get (iter, Columns.LIFT, out lift); var window = new LiftDetailWindow (adac, lift); window.show ();