Ignore all generated/compiled files
[gwave-svn.git] / src / GtkTable_indel.c
blobdd243a8cdaaa44c40a8b1d1ae273aead228ed66e
1 /*
2 * Routines to insert and delete rows in a GtkTable.
3 * The table is assumed to have no children that span more than one
4 * row: odd displays may result if this is not true.
6 * Rows are numbered by the value of the top_attach field;
7 * a table with 2 rows has rows numbered 0 and 1, etc.
8 */
10 #include <stdlib.h>
11 #include <gtk/gtk.h>
13 static GtkTableChild *
14 collect_children(GtkTable *table, int row, int *nchp)
16 GtkTableChild *row_children;
17 GtkTableChild *table_child;
18 int nch;
19 int i;
20 GList *list;
22 row_children = g_new0(GtkTableChild, table->ncols);
23 nch = 0;
25 /* locate all of the relevant children, and add an extra reference
26 to them */
27 for (list = table->children; list; list = list->next) {
28 table_child = list->data;
30 if(table_child->top_attach == row) {
31 if(nch == table->ncols) {
32 g_error("collect_children: too many children on row %d\n", row);
33 abort();
35 row_children[nch++] = *table_child;
36 gtk_widget_ref(table_child->widget);
39 if(nchp)
40 *nchp = nch;
41 return row_children;
44 static void
45 reattach_children(GtkTable *table, GtkTableChild *row_children, int nch,
46 int row)
48 int i;
49 GtkAttachOptions xoptions;
50 GtkAttachOptions yoptions;
52 /* add in new position and unref */
53 for(i = 0; i < nch; i++) {
54 xoptions = row_children[i].xexpand
55 | row_children[i].xshrink<<1
56 | row_children[i].xfill<<2;
57 yoptions = row_children[i].yexpand
58 | row_children[i].yshrink<<1
59 | row_children[i].yfill<<2;
61 gtk_table_attach(table, row_children[i].widget,
62 row_children[i].left_attach,
63 row_children[i].right_attach,
64 row,
65 row + (row_children[i].bottom_attach -
66 row_children[i].top_attach),
67 xoptions,
68 yoptions,
69 row_children[i].xpadding,
70 row_children[i].ypadding);
72 gtk_widget_unref(row_children[i].widget);
79 * move a table row to another row position.
81 void
82 gtk_table_move_row(GtkTable *table, int from, int to)
84 GtkTableChild *row_children;
85 int nch;
86 int i;
87 GtkTableChild *table_child;
88 GtkAttachOptions xoptions;
89 GtkAttachOptions yoptions;
90 GList *list;
92 /* printf("move row %d to %d: ", from, to); */
93 row_children = g_new(GtkTableChild, table->ncols);
94 nch = 0;
96 /* locate all of the relevant children, and add an extra reference
97 to them */
98 for (list = table->children; list; list = list->next) {
99 table_child = list->data;
101 if(table_child->top_attach == from) {
102 if(nch == table->ncols) {
103 g_error("gtk_table_move_row: too many children on row %d\n", from);
104 abort();
106 row_children[nch++] = *table_child;
107 gtk_widget_ref(table_child->widget);
111 /* remove from old position */
112 for(i = 0; i < nch; i++) {
113 gtk_container_remove(GTK_CONTAINER(table), row_children[i].widget);
115 /* add in new position and unref */
116 for(i = 0; i < nch; i++) {
117 xoptions = row_children[i].xexpand
118 | row_children[i].xshrink<<1
119 | row_children[i].xfill<<2;
120 yoptions = row_children[i].yexpand
121 | row_children[i].yshrink<<1
122 | row_children[i].yfill<<2;
124 gtk_table_attach(table, row_children[i].widget,
125 row_children[i].left_attach,
126 row_children[i].right_attach,
128 to + (row_children[i].bottom_attach -
129 row_children[i].top_attach),
130 xoptions,
131 yoptions,
132 row_children[i].xpadding,
133 row_children[i].ypadding);
135 gtk_widget_unref(row_children[i].widget);
137 /* printf("%d widgets moved\n", nch); */
139 g_free(row_children);
143 * Insert a new empty row into a GtkTable just before the specified row,
144 * moving subsequent rows down.
145 * - resize the table one larger
146 * - move rows down to put the hole where it belongs
148 void
149 gtk_table_insert_row(GtkWidget *widget, int row)
151 GtkTable *table;
152 int old_nrows, old_ncols;
153 int i;
154 table = GTK_TABLE(widget);
155 old_nrows = table->nrows;
156 old_ncols = table->ncols;
158 gtk_table_resize(table, old_nrows+1, old_ncols);
160 for(i = old_nrows; i > row; i--) {
161 gtk_table_move_row(table, i-1, i);
167 * Delete the indicated row of a GtkTable, moving subsequent rows up.
168 * - remove the specified row
169 * - move other rows
170 * - resize the table one smaller
172 void
173 gtk_table_delete_row(GtkWidget *widget, int row)
175 GtkTable *table;
176 GtkTableChild *table_child;
177 GList *list;
178 GList *del_list = NULL;
179 int old_nrows, old_ncols;
180 int i;
181 table = GTK_TABLE(widget);
182 old_nrows = table->nrows;
183 old_ncols = table->ncols;
185 /* remove widgets from the old row
186 can't delete while walking the list; must make a temporary list
188 for (list = table->children; list; list = list->next) {
189 table_child = list->data;
190 if(table_child->top_attach == row) {
191 del_list = g_list_append(del_list, table_child->widget);
195 while(del_list) {
196 GtkWidget *child;
197 child = del_list->data;
198 /* printf("remove child 0x%lx\n", child); */
199 gtk_container_remove(GTK_CONTAINER(table), child);
200 del_list = g_list_remove(del_list, child);
203 for(i = row; i < old_nrows-1; i++) {
204 gtk_table_move_row(table, i+1, i);
207 gtk_table_resize(table, old_nrows-1, old_ncols);
211 * Reorder a table, moving row FROM to position TO, and shifting
212 * all rows in between up or down one row.
213 * given this arrangement:
218 rotate_rows(, 2, 0) produces this result: ("up" case)
223 while applying rotate_rows(, 1, 3) to the original produces: ("down" case)
229 void
230 gtk_table_rotate_rows(GtkWidget *widget, int from, int to)
232 GtkTable *table = GTK_TABLE(widget);
233 int down; /* does the named "jumping" row move up or down? */
234 GtkTableChild *moving_children;
235 int nch, i;
237 if(to == from) return;
238 else if(to > from) down = 1;
239 else down = 0;
241 /* collect the children in the row that's jumping */
242 moving_children = collect_children(table, from, &nch);
243 /* remove them from their old row */
244 for(i = 0; i < nch; i++) {
245 gtk_container_remove(GTK_CONTAINER(table), moving_children[i].widget);
248 /* now move the other ones one position.
249 * if the "jumping" row moves down, thers move up, etc. */
250 if(down) {
251 for(i = from; i < to; i++) {
252 gtk_table_move_row(table, i+1, i);
254 } else { /* up*/
255 for(i = from; i > to; i--) {
256 gtk_table_move_row(table, i-1, i);
260 /* finally, put those children back down in the vacated target row */
261 reattach_children(table, moving_children, nch, to);
262 g_free(moving_children);
267 * given a pointer to a child widget of a table,
268 * return the (top_attach) row number it is currently on.
271 gtk_table_get_child_row(GtkWidget *widget, GtkWidget *child)
273 GtkTable *table;
274 GtkTableChild *table_child;
275 GList *list;
276 int i;
277 table = GTK_TABLE(widget);
279 for (list = table->children; list; list = list->next) {
280 table_child = list->data;
282 if(table_child->widget == child)
283 return table_child->top_attach;
285 return -1;