50 return 0; |
50 return 0; |
51 } |
51 } |
52 return 1; |
52 return 1; |
53 } |
53 } |
54 |
54 |
|
55 UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args) { |
|
56 UiObject* current = uic_current_obj(obj); |
|
57 |
|
58 UIWIDGET widget = create_widget(obj, args, userdata); |
|
59 |
|
60 UI_APPLY_LAYOUT1(current, args); |
|
61 current->container->add(current->container, widget, FALSE); |
|
62 |
|
63 return widget; |
|
64 } |
|
65 |
55 GtkWidget* ui_gtk_vbox_new(int spacing) { |
66 GtkWidget* ui_gtk_vbox_new(int spacing) { |
56 #if GTK_MAJOR_VERSION >= 3 |
67 #if GTK_MAJOR_VERSION >= 3 |
57 return gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing); |
68 return gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing); |
58 #else |
69 #else |
59 return gtk_vbox_new(FALSE, spacing); |
70 return gtk_vbox_new(FALSE, spacing); |
94 break; |
105 break; |
95 } |
106 } |
96 case UI_CONTAINER_GRID: { |
107 case UI_CONTAINER_GRID: { |
97 sub = ui_create_grid_widget(columnspacing, rowspacing); |
108 sub = ui_create_grid_widget(columnspacing, rowspacing); |
98 add = ui_box_set_margin(sub, margin); |
109 add = ui_box_set_margin(sub, margin); |
99 newobj->container = ui_grid_container(newobj, sub); |
110 newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE); |
100 newobj->widget = sub; |
111 newobj->widget = sub; |
101 break; |
112 break; |
102 } |
113 } |
103 case UI_CONTAINER_NO_SUB: { |
114 case UI_CONTAINER_NO_SUB: { |
104 break; |
115 break; |
154 |
165 |
155 ui_reset_layout(ct->layout); |
166 ui_reset_layout(ct->layout); |
156 ct->current = widget; |
167 ct->current = widget; |
157 } |
168 } |
158 |
169 |
159 UiContainer* ui_grid_container(UiObject *obj, GtkWidget *grid) { |
170 UiContainer* ui_grid_container( |
|
171 UiObject *obj, |
|
172 GtkWidget *grid, |
|
173 UiBool def_hexpand, |
|
174 UiBool def_vexpand, |
|
175 UiBool def_hfill, |
|
176 UiBool def_vfill) |
|
177 { |
160 UiGridContainer *ct = cxCalloc( |
178 UiGridContainer *ct = cxCalloc( |
161 obj->ctx->allocator, |
179 obj->ctx->allocator, |
162 1, |
180 1, |
163 sizeof(UiGridContainer)); |
181 sizeof(UiGridContainer)); |
|
182 ct->def_hexpand = def_hexpand; |
|
183 ct->def_vexpand = def_vexpand; |
|
184 ct->def_hfill = def_hfill; |
|
185 ct->def_vfill = def_vfill; |
164 ct->container.widget = grid; |
186 ct->container.widget = grid; |
165 ct->container.add = ui_grid_container_add; |
187 ct->container.add = ui_grid_container_add; |
166 UI_GTK_V2(ct->width = 0); |
188 UI_GTK_V2(ct->width = 0); |
167 UI_GTK_V2(ct->height = 1); |
189 UI_GTK_V2(ct->height = 1); |
168 return (UiContainer*)ct; |
190 return (UiContainer*)ct; |
180 |
202 |
181 int hexpand = FALSE; |
203 int hexpand = FALSE; |
182 int vexpand = FALSE; |
204 int vexpand = FALSE; |
183 int hfill = FALSE; |
205 int hfill = FALSE; |
184 int vfill = FALSE; |
206 int vfill = FALSE; |
|
207 if(!ct->layout.override_defaults) { |
|
208 if(grid->def_hexpand) { |
|
209 hexpand = TRUE; |
|
210 hfill = TRUE; |
|
211 } else if(grid->def_hfill) { |
|
212 hfill = TRUE; |
|
213 } |
|
214 if(grid->def_vexpand) { |
|
215 vexpand = TRUE; |
|
216 vfill = TRUE; |
|
217 } else if(grid->def_vfill) { |
|
218 vfill = TRUE; |
|
219 } |
|
220 } |
|
221 |
185 if(ct->layout.fill != UI_LAYOUT_UNDEFINED) { |
222 if(ct->layout.fill != UI_LAYOUT_UNDEFINED) { |
186 fill = ui_lb2bool(ct->layout.fill); |
223 fill = ui_lb2bool(ct->layout.fill); |
187 } |
224 } |
188 if(ct->layout.hexpand != UI_LAYOUT_UNDEFINED) { |
225 if(ct->layout.hexpand) { |
189 hexpand = ct->layout.hexpand; |
226 hexpand = TRUE; |
190 hfill = TRUE; |
227 hfill = TRUE; |
191 } |
228 } else if(ct->layout.hfill) { |
192 if(ct->layout.vexpand != UI_LAYOUT_UNDEFINED) { |
229 hfill = TRUE; |
193 vexpand = ct->layout.vexpand; |
230 } |
|
231 if(ct->layout.vexpand) { |
|
232 vexpand = TRUE; |
|
233 vfill = TRUE; |
|
234 } else if(ct->layout.vfill) { |
194 vfill = TRUE; |
235 vfill = TRUE; |
195 } |
236 } |
196 if(fill) { |
237 if(fill) { |
197 hfill = TRUE; |
238 hfill = TRUE; |
198 vfill = TRUE; |
239 vfill = TRUE; |
228 ct->layout.newline = FALSE; |
269 ct->layout.newline = FALSE; |
229 } |
270 } |
230 |
271 |
231 int hexpand = FALSE; |
272 int hexpand = FALSE; |
232 int vexpand = FALSE; |
273 int vexpand = FALSE; |
233 if(ct->layout.hexpand != UI_LAYOUT_UNDEFINED) { |
274 int hfill = FALSE; |
234 hexpand = ct->layout.hexpand; |
275 int vfill = FALSE; |
235 } |
276 if(!ct->layout.override_defaults) { |
236 if(ct->layout.vexpand != UI_LAYOUT_UNDEFINED) { |
277 if(grid->def_hexpand) { |
237 vexpand = ct->layout.vexpand; |
278 hexpand = TRUE; |
238 } |
279 hfill = TRUE; |
239 GtkAttachOptions xoptions = hexpand ? GTK_FILL | GTK_EXPAND : GTK_FILL; |
280 } else if(grid->def_hfill) { |
240 GtkAttachOptions yoptions = vexpand ? GTK_FILL | GTK_EXPAND : GTK_FILL; |
281 hfill = TRUE; |
|
282 } |
|
283 if(grid->def_vexpand) { |
|
284 vexpand = TRUE; |
|
285 vfill = TRUE; |
|
286 } else if(grid->def_vfill) { |
|
287 vfill = TRUE; |
|
288 } |
|
289 } |
|
290 |
|
291 if(ct->layout.fill != UI_LAYOUT_UNDEFINED) { |
|
292 fill = ui_lb2bool(ct->layout.fill); |
|
293 } |
|
294 if(ct->layout.hexpand) { |
|
295 hexpand = TRUE; |
|
296 hfill = TRUE; |
|
297 } else if(ct->layout.hfill) { |
|
298 hfill = TRUE; |
|
299 } |
|
300 if(ct->layout.vexpand) { |
|
301 vexpand = TRUE; |
|
302 vfill = TRUE; |
|
303 } else if(ct->layout.vfill) { |
|
304 vfill = TRUE; |
|
305 } |
|
306 if(fill) { |
|
307 hfill = TRUE; |
|
308 vfill = TRUE; |
|
309 } |
|
310 |
|
311 GtkAttachOptions xoptions = 0; |
|
312 GtkAttachOptions yoptions = 0; |
|
313 if(hexpand) { |
|
314 xoptions = GTK_EXPAND; |
|
315 } |
|
316 if(hfill) { |
|
317 xoptions |= GTK_FILL; |
|
318 } |
|
319 if(vexpand) { |
|
320 yoptions = GTK_EXPAND; |
|
321 } |
|
322 if(vfill) { |
|
323 yoptions |= GTK_FILL; |
|
324 } |
241 |
325 |
242 int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; |
326 int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; |
243 int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; |
327 int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; |
244 // TODO: use colspan/rowspan |
328 // TODO: use colspan/rowspan |
245 |
329 |
394 ui_set_name_and_style(grid, args.name, args.style_class); |
478 ui_set_name_and_style(grid, args.name, args.style_class); |
395 widget = ui_box_set_margin(grid, args.margin); |
479 widget = ui_box_set_margin(grid, args.margin); |
396 current->container->add(current->container, widget, TRUE); |
480 current->container->add(current->container, widget, TRUE); |
397 |
481 |
398 UiObject *newobj = uic_object_new(obj, grid); |
482 UiObject *newobj = uic_object_new(obj, grid); |
399 newobj->container = ui_grid_container(obj, grid); |
483 newobj->container = ui_grid_container(obj, grid, args.def_hexpand, args.def_vexpand, args.def_hfill, args.def_vfill); |
400 uic_obj_add(obj, newobj); |
484 uic_obj_add(obj, newobj); |
401 |
485 |
402 return widget; |
486 return widget; |
403 } |
487 } |
404 |
488 |
753 newobj->container = ui_box_container(newobj, sub, data->subcontainer); |
837 newobj->container = ui_box_container(newobj, sub, data->subcontainer); |
754 break; |
838 break; |
755 } |
839 } |
756 case UI_CONTAINER_GRID: { |
840 case UI_CONTAINER_GRID: { |
757 sub = ui_create_grid_widget(data->columnspacing, data->rowspacing); |
841 sub = ui_create_grid_widget(data->columnspacing, data->rowspacing); |
758 newobj->container = ui_grid_container(newobj, sub); |
842 newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE); |
759 break; |
843 break; |
760 } |
844 } |
761 } |
845 } |
762 newobj->widget = sub; |
846 newobj->widget = sub; |
763 GtkWidget *widget = ui_box_set_margin(sub, data->margin); |
847 GtkWidget *widget = ui_box_set_margin(sub, data->margin); |
943 #endif |
1027 #endif |
944 return NULL; |
1028 return NULL; |
945 } |
1029 } |
946 |
1030 |
947 |
1031 |
|
1032 |
|
1033 static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs args) { |
|
1034 UiObject* current = uic_current_obj(obj); |
|
1035 |
|
1036 GtkWidget *pane0 = create_paned(orientation); |
|
1037 |
|
1038 UI_APPLY_LAYOUT1(current, args); |
|
1039 current->container->add(current->container, pane0, TRUE); |
|
1040 |
|
1041 int max = args.max_panes == 0 ? 2 : args.max_panes; |
|
1042 |
|
1043 UiObject *newobj = uic_object_new(obj, pane0); |
|
1044 newobj->container = ui_splitpane_container(obj, pane0, orientation, max); |
|
1045 uic_obj_add(obj, newobj); |
|
1046 |
|
1047 return pane0; |
|
1048 } |
|
1049 |
|
1050 UIWIDGET ui_hsplitpane_create(UiObject *obj, UiSplitPaneArgs args) { |
|
1051 return splitpane_create(obj, UI_HORIZONTAL, args); |
|
1052 } |
|
1053 |
|
1054 UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs args) { |
|
1055 return splitpane_create(obj, UI_VERTICAL, args); |
|
1056 } |
|
1057 |
|
1058 UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max) { |
|
1059 UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer)); |
|
1060 ct->container.widget = pane; |
|
1061 ct->container.add = ui_splitpane_container_add; |
|
1062 ct->current_pane = pane; |
|
1063 ct->orientation = orientation; |
|
1064 ct->max = max; |
|
1065 return (UiContainer*)ct; |
|
1066 } |
|
1067 |
|
1068 void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) { |
|
1069 UiSplitPaneContainer *s = (UiSplitPaneContainer*)ct; |
|
1070 |
|
1071 if(s->nchildren >= s->max) { |
|
1072 fprintf(stderr, "splitpane: maximum number of children reached\n"); |
|
1073 return; |
|
1074 } |
|
1075 |
|
1076 if(s->pos == 0) { |
|
1077 gtk_paned_set_start_child(GTK_PANED(s->current_pane), widget); |
|
1078 s->pos++; |
|
1079 s->nchildren++; |
|
1080 } else { |
|
1081 if(s->nchildren+1 == s->max) { |
|
1082 gtk_paned_set_end_child(GTK_PANED(s->current_pane), widget); |
|
1083 } else { |
|
1084 GtkWidget *pane = create_paned(s->orientation); |
|
1085 gtk_paned_set_start_child(GTK_PANED(pane), widget); |
|
1086 gtk_paned_set_end_child(GTK_PANED(s->current_pane), pane); |
|
1087 s->current_pane = pane; |
|
1088 } |
|
1089 |
|
1090 s->pos = 0; |
|
1091 s->nchildren++; |
|
1092 } |
|
1093 } |
948 |
1094 |
949 /* -------------------- ItemList Container -------------------- */ |
1095 /* -------------------- ItemList Container -------------------- */ |
950 |
1096 |
951 static void remove_item(void *data, void *item) { |
1097 static void remove_item(void *data, void *item) { |
952 UiGtkItemListContainer *ct = data; |
1098 UiGtkItemListContainer *ct = data; |
995 if(item_obj) { |
1141 if(item_obj) { |
996 // re-add previously created widget |
1142 // re-add previously created widget |
997 ui_box_container_add(ct->container, item_obj->widget, FALSE); |
1143 ui_box_container_add(ct->container, item_obj->widget, FALSE); |
998 } else { |
1144 } else { |
999 // create new widget and object for this list element |
1145 // create new widget and object for this list element |
1000 CxMempool *mp = cxBasicMempoolCreate(256); |
1146 CxMempool *mp = cxMempoolCreateSimple(256); |
1001 const CxAllocator *a = mp->allocator; |
1147 const CxAllocator *a = mp->allocator; |
1002 UiObject *obj = cxCalloc(a, 1, sizeof(UiObject)); |
1148 UiObject *obj = cxCalloc(a, 1, sizeof(UiObject)); |
1003 obj->ctx = uic_context(obj, mp); |
1149 obj->ctx = uic_context(obj, mp); |
1004 obj->window = NULL; |
1150 obj->window = NULL; |
1005 obj->widget = ui_subcontainer_create( |
1151 obj->widget = ui_subcontainer_create( |
1100 void ui_layout_vfill(UiObject *obj, UiBool fill) { |
1246 void ui_layout_vfill(UiObject *obj, UiBool fill) { |
1101 UiContainer *ct = uic_get_current_container(obj); |
1247 UiContainer *ct = uic_get_current_container(obj); |
1102 ct->layout.vfill = fill; |
1248 ct->layout.vfill = fill; |
1103 } |
1249 } |
1104 |
1250 |
|
1251 UIEXPORT void ui_layout_override_defaults(UiObject *obj, UiBool d) { |
|
1252 UiContainer *ct = uic_get_current_container(obj); |
|
1253 ct->layout.override_defaults = d; |
|
1254 } |
|
1255 |
1105 void ui_layout_colspan(UiObject* obj, int cols) { |
1256 void ui_layout_colspan(UiObject* obj, int cols) { |
1106 UiContainer* ct = uic_get_current_container(obj); |
1257 UiContainer* ct = uic_get_current_container(obj); |
1107 ct->layout.colspan = cols; |
1258 ct->layout.colspan = cols; |
1108 } |
1259 } |
1109 |
1260 |