Add VBox cell renderer to display driver name in lift list
[beifahrer] / src / cell-renderer-vbox.vala
diff --git a/src/cell-renderer-vbox.vala b/src/cell-renderer-vbox.vala
new file mode 100644 (file)
index 0000000..659db86
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+
+class CellRendererVBox : CellRenderer {
+       private List<CellRenderer> 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;
+                               }
+                       }
+               }
+       }
+}