[gnome-contacts/new-design] Separate out the common row stuff into rowgroup
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-contacts/new-design] Separate out the common row stuff into rowgroup
- Date: Mon, 12 Dec 2011 15:33:08 +0000 (UTC)
commit 416a6fc9f4d7415f2aa14a108e4e1433a3cdf315
Author: Alexander Larsson <alexl redhat com>
Date: Mon Dec 12 11:11:01 2011 +0100
Separate out the common row stuff into rowgroup
src/contacts-contact-pane.vala | 29 ++--
src/contacts-row.vala | 354 +++++++++++++++++++++-------------------
2 files changed, 204 insertions(+), 179 deletions(-)
---
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 5417e74..47d8836 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -416,17 +416,10 @@ public class Contacts.AvatarMenu : Menu {
public class Contacts.FieldRow : Contacts.Row {
int start;
- public FieldRow(ContactPane pane) {
- base (3);
+ public FieldRow(RowGroup group) {
+ base (group);
start = 0;
-
- set_column_min_width (0, 32);
- set_column_min_width (1, 400);
- set_column_max_width (1, 450);
- set_column_min_width (2, 32);
- set_column_spacing (0, 8);
- set_column_spacing (1, 8);
}
public void pack (Widget w) {
@@ -514,7 +507,7 @@ public class Contacts.PersonaSheet : Grid {
construct {
this.set_orientation (Orientation.VERTICAL);
- label_row = new FieldRow (sheet.pane);
+ label_row = new FieldRow (sheet.pane.row_group);
this.add (label_row);
label_row.label (label_name);
}
@@ -536,7 +529,7 @@ public class Contacts.PersonaSheet : Grid {
}
public FieldRow new_row () {
- var row = new FieldRow (sheet.pane);
+ var row = new FieldRow (sheet.pane.row_group);
this.add (row);
return row;
}
@@ -733,7 +726,7 @@ public class Contacts.PersonaSheet : Grid {
Contact.persona_has_writable_property (persona, "postal-addresses");
if (!persona.store.is_primary_store) {
- header = new FieldRow (pane);
+ header = new FieldRow (pane.row_group);
this.attach (header, 0, row_nr++, 1, 1);
header.header (Contact.format_persona_store_name (persona.store));
@@ -756,7 +749,7 @@ public class Contacts.PersonaSheet : Grid {
}
if (editable) {
- footer = new FieldRow (pane);
+ footer = new FieldRow (pane.row_group);
this.attach (footer, 0, row_nr++, 1, 1);
var b = new Button.with_label ("Add detail...");
@@ -774,6 +767,7 @@ public class Contacts.ContactPane : ScrolledWindow {
private Grid top_grid;
private Grid card_grid;
private Grid personas_grid;
+ public RowGroup row_group;
private Contact? contact;
@@ -912,6 +906,13 @@ public class Contacts.ContactPane : ScrolledWindow {
public ContactPane (Store contacts_store) {
this.contacts_store = contacts_store;
+ row_group = new RowGroup(3);
+ row_group.set_column_min_width (0, 32);
+ row_group.set_column_min_width (1, 400);
+ row_group.set_column_max_width (1, 450);
+ row_group.set_column_min_width (2, 32);
+ row_group.set_column_spacing (0, 8);
+ row_group.set_column_spacing (1, 8);
this.set_hexpand (true);
this.set_vexpand (true);
@@ -927,7 +928,7 @@ public class Contacts.ContactPane : ScrolledWindow {
this.get_child().get_style_context ().add_class ("contact-pane");
- var top_row = new FieldRow (this);
+ var top_row = new FieldRow (row_group);
top_grid.add (top_row);
card_grid = new Grid ();
card_grid.set_vexpand (false);
diff --git a/src/contacts-row.vala b/src/contacts-row.vala
index 3361105..4851606 100644
--- a/src/contacts-row.vala
+++ b/src/contacts-row.vala
@@ -18,49 +18,53 @@
using Gtk;
-public class Contacts.Row : Container {
- struct RowInfo {
- int min_height;
- int nat_height;
- bool expand;
- }
-
- struct ColumnInfo {
+public class Contacts.RowGroup : Object {
+ public struct ColumnInfo {
int min_width;
int nat_width;
int max_width;
int prio;
int spacing;
}
- struct Child {
- Widget? widget;
- }
- int n_columns;
- int n_rows;
- ColumnInfo[] column_info;
- Child[,] row_children;
+ public int n_columns;
+ private ColumnInfo[] column_info;
int[] cached_widths;
int cached_widths_for_width;
- public Row (int n_columns) {
- int i;
-
- set_has_window (false);
- set_redraw_on_allocate (false);
- set_hexpand (true);
+ Gee.ArrayList<unowned Row> rows;
+ public RowGroup (int n_columns) {
this.n_columns = n_columns;
- n_rows = 1;
- row_children = new Child[n_columns, n_rows];
+
column_info = new ColumnInfo[n_columns];
- for (i = 0; i < n_columns; i++) {
+ for (int i = 0; i < n_columns; i++) {
column_info[i].min_width = 0;
column_info[i].nat_width = -1;
column_info[i].max_width = -1;
column_info[i].prio = 0;
}
+
+ rows = new Gee.ArrayList<Row>();
+ }
+
+ public unowned ColumnInfo? get_column_info (int col) {
+ return column_info[col];
+ }
+
+ public void add (Row row) {
+ rows.add (row);
+ row.destroy.connect ( (widget) => {
+ rows.remove (row);
+ });
+ }
+
+ private void queue_resize () {
+ foreach (unowned Row row in rows) {
+ if (row.get_visible ())
+ row.queue_resize ();
+ }
}
public void set_column_priority (int column, int priority) {
@@ -70,8 +74,7 @@ public class Contacts.Row : Container {
column_info[column].prio = priority;
cached_widths = null;
- if (this.get_visible ())
- this.queue_resize ();
+ queue_resize ();
}
public void set_column_min_width (int column, int min_width) {
@@ -80,8 +83,7 @@ public class Contacts.Row : Container {
column_info[column].min_width = min_width;
cached_widths = null;
- if (this.get_visible ())
- this.queue_resize ();
+ queue_resize ();
}
public void set_column_max_width (int column, int max_width) {
@@ -90,8 +92,7 @@ public class Contacts.Row : Container {
column_info[column].max_width = max_width;
cached_widths = null;
- if (this.get_visible ())
- this.queue_resize ();
+ queue_resize ();
}
public void set_column_spacing (int column, int spacing) {
@@ -100,43 +101,167 @@ public class Contacts.Row : Container {
column_info[column].spacing = spacing;
cached_widths = null;
- if (this.get_visible ())
- this.queue_resize ();
+ queue_resize ();
}
- public void attach (Widget widget, int attach_col, int attach_row) {
- if (attach_col >= n_columns || attach_row >= n_rows) {
- int old_n_columns = n_columns;
- int old_n_rows = n_rows;
+ public int[] distribute_widths (int width) {
+ if (cached_widths != null &&
+ cached_widths_for_width == width)
+ return cached_widths;
+
+ int max_prio = 0;
+ var widths = new int[n_columns];
+
+ /* First distribute the min widths */
+ for (int i = 0; i < n_columns; i++) {
+ var info = &column_info[i];
+
+ if (info->prio > max_prio)
+ max_prio = info->prio;
+
+ if (width > info.min_width) {
+ widths[i] = info.min_width;
+ width -= info.min_width;
+ } else if (width > 0) {
+ widths[i] = width;
+ width = 0;
+ } else {
+ widths[i] = 0;
+ }
+ width -= info.spacing;
+ }
- if (attach_col >= n_columns) {
- n_columns = attach_col + 1;
+ /* Distribute remaining width equally among
+ children with same priority, up to max */
+ for (int prio = max_prio; width > 0 && prio >= 0; prio--) {
+ int n_children;
- var old_column_info = (owned)column_info;
- column_info = new ColumnInfo[n_columns];
+ while (width > 0) {
+ n_children = 0;
+ int max_extra = width;
for (int i = 0; i < n_columns; i++) {
- if (i < old_n_columns)
- column_info[i] = old_column_info[i];
- else {
- column_info[i].min_width = 0;
- column_info[i].nat_width = -1;
- column_info[i].max_width = -1;
- column_info[i].prio = 0;
+ var info = &column_info[i];
+
+ if (info.prio == prio &&
+ (info.max_width < 0 ||
+ widths[i] < info.max_width)) {
+ n_children++;
+
+ if (info.max_width >= 0 &&
+ info.max_width - widths[i] < max_extra)
+ max_extra = info.max_width - widths[i];
+ }
+ }
+
+ if (n_children == 0)
+ break; // No more unsatisfied children on this prio
+
+ int distribute = int.min (width, max_extra * n_children);
+ width -= distribute;
+
+ int per_child = distribute / n_children;
+ int per_child_extra = distribute % n_children;
+ int per_child_extra_sum = 0;
+
+ for (int i = 0; i < n_columns; i++) {
+ var info = &column_info[i];
+
+ if (info.prio == prio &&
+ (info.max_width < 0 ||
+ widths[i] < info.max_width)) {
+ widths[i] += per_child;
+ per_child_extra_sum += per_child_extra;
+ if (per_child_extra_sum > distribute) {
+ widths[i] += 1;
+ per_child_extra_sum -= distribute;
+ }
}
}
}
+ }
+
+ cached_widths = widths;
+ cached_widths_for_width = width;
+ return widths;
+ }
+
+ public void get_width (out int minimum_width, out int natural_width) {
+ minimum_width = 0;
+ natural_width = 0;
+
+ for (int i = 0; i < n_columns; i++) {
+ minimum_width += column_info[i].min_width;
+ if (column_info[i].nat_width >= 0)
+ natural_width += column_info[i].nat_width;
+ else if (column_info[i].max_width >= 0)
+ natural_width += column_info[i].max_width;
+ else
+ natural_width += column_info[i].min_width;
+ minimum_width += column_info[i].spacing;
+ natural_width += column_info[i].spacing;
+ }
+ }
+
+ public bool is_expanding () {
+ for (int i = 0; i < n_columns; i++) {
+ var info = &column_info[i];
+ if (info.max_width == -1 &&
+ info.max_width != info.min_width) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+public class Contacts.Row : Container {
+ struct RowInfo {
+ int min_height;
+ int nat_height;
+ bool expand;
+ }
+
+ struct Child {
+ Widget? widget;
+ }
+
+ RowGroup group;
+ int n_rows;
+ Child[,] row_children;
+
+ public Row (RowGroup group) {
+ int i;
+
+ this.group = group;
+ group.add (this);
- if (attach_row >= n_rows)
- n_rows = attach_row + 1;
+ set_has_window (false);
+ set_redraw_on_allocate (false);
+ set_hexpand (true);
+
+ n_rows = 1;
+ row_children = new Child[group.n_columns, n_rows];
+ }
+
+ public void attach (Widget widget, int attach_col, int attach_row) {
+ if (attach_col >= group.n_columns) {
+ warning ("Tryint to attach widget to non-existing column");
+ return;
+ }
+
+ if (attach_row >= n_rows) {
+ int old_n_rows = n_rows;
+
+ n_rows = attach_row + 1;
var old_row_children = (owned)row_children;
- row_children = new Child[n_columns, n_rows];
+ row_children = new Child[group.n_columns, n_rows];
for (int row = 0; row < n_rows; row++) {
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
if (row < old_n_rows &&
- col < old_n_columns) {
+ col < group.n_columns) {
row_children[col, row] = (owned)old_row_children[col, row];
}
}
@@ -154,7 +279,7 @@ public class Contacts.Row : Container {
public override void add (Widget widget) {
for (int row = 0; row < n_rows; row++) {
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget == null) {
attach (widget, col, row);
@@ -167,7 +292,7 @@ public class Contacts.Row : Container {
public override void remove (Widget widget) {
for (int row = 0; row < n_rows; row++) {
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget == widget) {
bool was_visible = widget.get_visible ();
@@ -188,7 +313,7 @@ public class Contacts.Row : Container {
public override void forall_internal (bool include_internals,
Gtk.Callback callback) {
for (int row = 0; row < n_rows; row++) {
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget != null) {
callback (child_info.widget);
@@ -198,19 +323,11 @@ public class Contacts.Row : Container {
}
public override void compute_expand_internal (out bool hexpand, out bool vexpand) {
- hexpand = false;
- for (int i = 0; i < n_columns; i++) {
- var info = &column_info[i];
- if (info.max_width == -1 &&
- info.max_width != info.min_width) {
- hexpand = true;
- break;
- }
- }
+ hexpand = group.is_expanding ();
vexpand = false;
for (int row = 0; row < n_rows; row++) {
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget != null) {
vexpand |= child_info.widget.compute_expand (Orientation.VERTICAL);
@@ -233,87 +350,6 @@ public class Contacts.Row : Container {
get_preferred_height_for_width (natural_width, out minimum_height, out natural_height);
}
- int[] distribute_widths (int width) {
- if (cached_widths != null &&
- cached_widths_for_width == width)
- return cached_widths;
-
- int max_prio = 0;
- var widths = new int[n_columns];
-
- /* First distribute the min widths */
- for (int i = 0; i < n_columns; i++) {
- ColumnInfo *info = &column_info[i];
-
- if (info->prio > max_prio)
- max_prio = info->prio;
-
- if (width > info.min_width) {
- widths[i] = info.min_width;
- width -= info.min_width;
- } else if (width > 0) {
- widths[i] = width;
- width = 0;
- } else {
- widths[i] = 0;
- }
- width -= info.spacing;
- }
-
- /* Distribute remaining width equally among
- children with same priority, up to max */
- for (int prio = max_prio; width > 0 && prio >= 0; prio--) {
- int n_children;
-
- while (width > 0) {
- n_children = 0;
- int max_extra = width;
-
- for (int i = 0; i < n_columns; i++) {
- ColumnInfo *info = &column_info[i];
-
- if (info.prio == prio &&
- (info.max_width < 0 ||
- widths[i] < info.max_width)) {
- n_children++;
-
- if (info.max_width >= 0 &&
- info.max_width - widths[i] < max_extra)
- max_extra = info.max_width - widths[i];
- }
- }
-
- if (n_children == 0)
- break; // No more unsatisfied children on this prio
-
- int distribute = int.min (width, max_extra * n_children);
- width -= distribute;
-
- int per_child = distribute / n_children;
- int per_child_extra = distribute % n_children;
- int per_child_extra_sum = 0;
-
- for (int i = 0; i < n_columns; i++) {
- ColumnInfo *info = &column_info[i];
-
- if (info.prio == prio &&
- (info.max_width < 0 ||
- widths[i] < info.max_width)) {
- widths[i] += per_child;
- per_child_extra_sum += per_child_extra;
- if (per_child_extra_sum > distribute) {
- widths[i] += 1;
- per_child_extra_sum -= distribute;
- }
- }
- }
- }
- }
-
- cached_widths = widths;
- cached_widths_for_width = width;
- return widths;
- }
int[] distribute_heights (int height, RowInfo[] row_info) {
var heights = new int[n_rows];
@@ -389,7 +425,7 @@ public class Contacts.Row : Container {
bool first = true;
bool expand = false;
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget != null) {
int child_min, child_nat;
@@ -416,8 +452,8 @@ public class Contacts.Row : Container {
}
public override void get_preferred_height_for_width (int width, out int minimum_height, out int natural_height) {
- var widths = distribute_widths (width);
- var row_info = get_row_heights_for_widths (widths);
+ var widths = group.distribute_widths (width);
+ var row_info = get_row_heights_for_widths (widths);
minimum_height = 0;
natural_height = 0;
@@ -429,19 +465,7 @@ public class Contacts.Row : Container {
}
public override void get_preferred_width (out int minimum_width, out int natural_width) {
- minimum_width = 0;
- natural_width = 0;
- for (int i = 0; i < n_columns; i++) {
- minimum_width += column_info[i].min_width;
- if (column_info[i].nat_width >= 0)
- natural_width += column_info[i].nat_width;
- else if (column_info[i].max_width >= 0)
- natural_width += column_info[i].max_width;
- else
- natural_width += column_info[i].min_width;
- minimum_width += column_info[i].spacing;
- natural_width += column_info[i].spacing;
- }
+ group.get_width (out minimum_width, out natural_width);
}
public override void get_preferred_width_for_height (int height, out int minimum_width, out int natural_width) {
@@ -449,7 +473,7 @@ public class Contacts.Row : Container {
}
public override void size_allocate (Gtk.Allocation allocation) {
- var widths = distribute_widths (allocation.width);
+ var widths = group.distribute_widths (allocation.width);
var row_info = get_row_heights_for_widths (widths);
var heights = distribute_heights (allocation.height, row_info);
@@ -458,7 +482,7 @@ public class Contacts.Row : Container {
int y = 0;
for (int row = 0; row < n_rows; row ++) {
int x = 0;
- for (int col = 0; col < n_columns; col++) {
+ for (int col = 0; col < group.n_columns; col++) {
Child *child_info = &row_children[col, row];
if (child_info.widget != null) {
Allocation child_allocation = { 0, 0, 0, 0};
@@ -473,7 +497,7 @@ public class Contacts.Row : Container {
child_allocation.y = allocation.y + y;
child_info.widget.size_allocate (child_allocation);
}
- x += widths[col] + column_info[col].spacing;
+ x += widths[col] + group.get_column_info (col).spacing;
}
y += heights[row];
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]