Remove debug from qtable.
[gmpc.git] / src / Widgets / gmpc-widgets-qtable.vala
blobcfaf616be3c7457133d90af95472218a946891db
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 using Config;
21 using Gtk;
22 using Gmpc;
24 private const bool use_transition_gav = Gmpc.use_transition;
25 private const string some_unique_name_gav = Config.VERSION;
26 [compact]
27 private class QtableEntry
29 public enum Type
31 HEADER,
32 ITEM
34 public Type type;
35 public weak Gtk.Widget widget;
39 public class Gmpc.Widgets.Qtable : Gtk.Container, Gtk.Buildable
41 private int item_width_real = 0;
42 private int item_height_real = 0;
43 private int header_height_real = 0;
44 private int max_columns_real = 0;
45 private int num_items = 0;
46 private int columns = 3;
47 public int spacing {get; set; default=8;}
48 public int padding_left {get; set; default=0;}
49 public int padding_right {get; set; default=0;}
51 public int max_columns
53 get {
54 return max_columns_real;
56 set {
57 max_columns_real = value;
58 this.queue_resize();
62 public int item_width
64 get {
65 return item_width_real;
67 set {
68 item_width_real = value;
69 this.queue_resize();
73 public int item_height
75 get {
76 return item_height_real;
78 set {
79 item_height_real = value;
80 this.queue_resize();
83 public int header_height
85 get {
86 return header_height_real;
88 set {
89 header_height_real = value;
90 this.queue_resize();
95 private List<QtableEntry> children = null;
96 /* GtkBuildable override */
97 public void add_child(Gtk.Builder build, GLib.Object child, string? type)
99 if(!(child is Gtk.Widget))
101 GLib.warning("Trying to add non widget");
102 return;
104 if(type != null && type == "header")
106 add_header(child as Gtk.Widget);
108 else
110 add(child as Gtk.Widget);
115 construct
117 this.set_has_window(false);
118 this.set_redraw_on_allocate(false);
121 public Qtable()
123 // Set resize mode.
124 this.resize_mode = Gtk.ResizeMode.QUEUE;
128 * Calculates the size of the widget.
130 public override void get_preferred_height_for_width(int actual_width, out int min_height, out int nat_height)
132 int cover_width = item_width_real;
133 int cover_height= item_height_real;
134 int header_height = header_height_real;
135 int items = 0, width=0;
138 actual_width -= padding_left;
139 actual_width -= padding_right;
140 /* determine max width/height */
141 foreach ( var child in children)
143 if(child.widget.get_visible())
145 int w,h;
146 if(child.type == QtableEntry.Type.ITEM)
148 Gtk.Requisition cr = {0,0};
149 child.widget.get_preferred_size(out cr,null);
150 cover_width = int.max(cr.width,cover_width);
151 cover_height = int.max(cr.height,cover_height);
153 else
155 Gtk.Requisition cr = {0,0};
156 child.widget.get_preferred_size(out cr,null);
157 width = int.max(cr.width,width);
158 header_height = int.max(cr.height,header_height);
162 if(spacing>0)
164 cover_width += spacing;
165 cover_height += spacing;
166 header_height += spacing;
168 columns = int.max(actual_width/cover_width,1);
169 if(max_columns_real > 0)
171 columns = int.min(columns,max_columns_real);
173 int rows = 0;
174 foreach ( var child in children)
176 if(child.widget.get_visible())
178 if(child.type == QtableEntry.Type.ITEM)
180 items++;
182 else
184 if(items != 0)
186 int nrows = items/columns;
187 int remain = (items%columns >0)?1:0;
188 rows += (nrows+remain)*cover_height;
190 items = 0;
191 rows+=header_height;
195 if(items != 0)
197 int nrows = items/columns;
198 int remain = (items%columns >0)?1:0;
199 rows = rows + (nrows+remain)*cover_height;
202 /* Width of one column */
203 min_height = rows;
204 nat_height = rows;
207 public override void add(Gtk.Widget widget)
209 if(widget != null)
211 QtableEntry a = new QtableEntry();
212 a.type = QtableEntry.Type.ITEM;
213 a.widget = widget;
214 children.append(a);
215 widget.set_parent(this);
216 num_items++;
217 this.queue_resize();
220 public void add_header(Gtk.Widget widget)
222 if(widget != null)
224 QtableEntry a = new QtableEntry();
225 a.type = QtableEntry.Type.HEADER;
226 a.widget = widget;
227 children.append(a);
228 widget.set_parent(this);
229 num_items++;
230 this.queue_resize();
234 public override GLib.Type child_type()
236 return typeof(Gtk.Widget);
238 public override void remove(Gtk.Widget widget)
240 if(widget != null )
242 QtableEntry a = null;
244 if((a = children.find_custom(widget,compare)) == null) {
245 GLib.error("Failed to find widget in container");
248 foreach(QtableEntry f in this.children)
250 if(f.widget == widget)
252 a = f;
253 break;
256 if(a == null)
257 GLib.error("Failed to find widget in container");
258 bool visible = widget.get_visible();
259 widget.unparent();
261 /* owned is needed to avoid leak */
262 children.remove((owned)a);
263 num_items--;
264 if(visible)
265 this.queue_resize();
268 public override void size_allocate(Gtk.Allocation alloc)
270 int cover_width = item_width_real;
271 int cover_height= item_height_real;
272 int header_height = header_height_real;
273 /* Hack to avvoid pointless resizes,
274 * I get this "1" size when a child widget changes */
275 if(alloc.width == 1) return;
276 int width = alloc.width;
277 int new_columns = 0;
278 int rows = 0;
279 int item = 0;
280 // This fixes it so the correct taborder is calculated.
281 this.set_allocation(alloc);
282 foreach ( var child in children)
284 if(child.widget.get_visible())
287 if(child.type == QtableEntry.Type.ITEM)
289 Gtk.Requisition cr = {0,0};
290 child.widget.get_preferred_size(out cr, null);
291 cover_width = int.max(cr.width,cover_width);
292 cover_height = int.max(cr.height,cover_height);
293 item++;
295 else
297 Gtk.Requisition cr = {0,0};
298 child.widget.get_preferred_size(out cr,null);
299 item = 0;
301 width = int.max(cr.width,width);
302 header_height = int.max(cr.height,header_height);
306 if(spacing>0)
308 cover_width += spacing;
309 cover_height += spacing;
310 header_height += spacing;
312 new_columns = int.max((width-padding_left - padding_right+spacing)/cover_width, 1);
313 if(max_columns_real > 0)
315 new_columns = int.min(new_columns,max_columns_real);
318 item = 0;
319 foreach ( var child in children)
321 if(child.widget.get_visible())
323 if(child.type == QtableEntry.Type.ITEM)
325 Gtk.Allocation ca = {0,0,0,0};
326 ca.x = alloc.x + (item%new_columns)*cover_width+padding_left;
327 ca.y = rows+alloc.y + (item/new_columns)*cover_height;
328 ca.width = cover_width - spacing;
329 ca.height = cover_height - spacing;
331 child.widget.size_allocate(ca);
332 item++;
334 else
336 if(item != 0)
338 int nrows = item/new_columns;
339 int remain = (item%new_columns >0)?1:0;
340 rows = rows + (nrows+remain)*cover_height;
342 item = 0;
344 Gtk.Allocation ca = {0,0,0,0};
345 ca.x = alloc.x-padding_left;
346 ca.y = alloc.y+rows;
347 ca.width = cover_width*new_columns;
348 ca.height = header_height - spacing;
350 child.widget.size_allocate(ca);
351 rows+=header_height;
355 if(new_columns != columns)
357 columns = new_columns;
358 this.queue_resize();
361 public override void forall_internal(bool include_internals,
362 Gtk.Callback callback)
364 weak List<QtableEntry> iter = children.first();
365 /* Somehow it fails when doing a foreach() construction,
366 weird vala bug I guess */
367 /* would be nice if I could filter out say only the visible ones */
368 while(iter != null)
370 weak QtableEntry child = iter.data;
371 iter = iter.next;
372 callback(child.widget);
375 public void clear()
377 foreach(var a in children)
379 a.widget.unparent();
380 num_items--;
382 children = null;
383 this.queue_resize();
387 public override Gtk.SizeRequestMode get_request_mode ()
389 return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;