32 |
32 |
33 #include "container.h" |
33 #include "container.h" |
34 #include "../common/context.h" |
34 #include "../common/context.h" |
35 #include "../common/object.h" |
35 #include "../common/object.h" |
36 |
36 |
|
37 #include <cx/array_list.h> |
|
38 #include <cx/linked_list.h> |
|
39 #include <cx/compare.h> |
|
40 |
37 #define UI_GRID_MAX_COLUMNS 512 |
41 #define UI_GRID_MAX_COLUMNS 512 |
38 |
42 |
39 static UiBool ui_lb2bool(UiLayoutBool b) { |
43 static UiBool ui_lb2bool(UiLayoutBool b) { |
40 return b == UI_LAYOUT_TRUE ? TRUE : FALSE; |
44 return b == UI_LAYOUT_TRUE ? TRUE : FALSE; |
41 } |
45 } |
44 return b ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE; |
48 return b ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE; |
45 } |
49 } |
46 |
50 |
47 |
51 |
48 UiContainer* ui_frame_container(UiObject *obj, Widget frame) { |
52 UiContainer* ui_frame_container(UiObject *obj, Widget frame) { |
49 UiContainer *ct = ucx_mempool_calloc( |
53 UiContainer *ct = cxCalloc( |
50 obj->ctx->mempool, |
54 obj->ctx->allocator, |
51 1, |
55 1, |
52 sizeof(UiContainer)); |
56 sizeof(UiContainer)); |
53 ct->widget = frame; |
57 ct->widget = frame; |
54 ct->prepare = ui_frame_container_prepare; |
58 ct->prepare = ui_frame_container_prepare; |
55 ct->add = ui_frame_container_add; |
59 ct->add = ui_frame_container_add; |
65 ct->current = widget; |
69 ct->current = widget; |
66 } |
70 } |
67 |
71 |
68 |
72 |
69 UiContainer* ui_box_container(UiObject *obj, Widget box, int margin, int spacing, UiBoxOrientation orientation) { |
73 UiContainer* ui_box_container(UiObject *obj, Widget box, int margin, int spacing, UiBoxOrientation orientation) { |
70 UiBoxContainer *ct = ucx_mempool_calloc( |
74 UiBoxContainer *ct = cxCalloc( |
71 obj->ctx->mempool, |
75 obj->ctx->allocator, |
72 1, |
76 1, |
73 sizeof(UiBoxContainer)); |
77 sizeof(UiBoxContainer)); |
74 ct->container.widget = box; |
78 ct->container.widget = box; |
75 ct->container.prepare = ui_box_container_prepare; |
79 ct->container.prepare = ui_box_container_prepare; |
76 ct->container.add = ui_box_container_add; |
80 ct->container.add = ui_box_container_add; |
191 ui_reset_layout(ct->layout); |
195 ui_reset_layout(ct->layout); |
192 ct->current = widget; |
196 ct->current = widget; |
193 } |
197 } |
194 |
198 |
195 UiContainer* ui_grid_container(UiObject *obj, Widget form, int columnspacing, int rowspacing) { |
199 UiContainer* ui_grid_container(UiObject *obj, Widget form, int columnspacing, int rowspacing) { |
196 UiGridContainer *ct = ucx_mempool_calloc( |
200 UiGridContainer *ct = cxCalloc( |
197 obj->ctx->mempool, |
201 obj->ctx->allocator, |
198 1, |
202 1, |
199 sizeof(UiGridContainer)); |
203 sizeof(UiGridContainer)); |
200 ct->container.widget = form; |
204 ct->container.widget = form; |
201 ct->container.prepare = ui_grid_container_prepare; |
205 ct->container.prepare = ui_grid_container_prepare; |
202 ct->container.add = ui_grid_container_add; |
206 ct->container.add = ui_grid_container_add; |
203 ct->columnspacing = columnspacing; |
207 ct->columnspacing = columnspacing; |
204 ct->rowspacing = rowspacing; |
208 ct->rowspacing = rowspacing; |
|
209 ct->lines = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
205 return (UiContainer*)ct; |
210 return (UiContainer*)ct; |
206 } |
211 } |
207 |
212 |
208 void ui_grid_newline(UiGridContainer *grid) { |
213 void ui_grid_newline(UiGridContainer *grid) { |
209 if(grid->current) { |
214 if(grid->current) { |
222 |
227 |
223 void ui_grid_container_add(UiContainer *ct, Widget widget) { |
228 void ui_grid_container_add(UiContainer *ct, Widget widget) { |
224 UiGridContainer *grid = (UiGridContainer*)ct; |
229 UiGridContainer *grid = (UiGridContainer*)ct; |
225 |
230 |
226 if(grid->current) { |
231 if(grid->current) { |
227 grid->current = ucx_list_append(grid->current, widget); |
232 cxListAdd(grid->current, widget); |
228 } else { |
233 } else { |
229 grid->current = ucx_list_append(grid->current, widget); |
234 grid->current = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
230 grid->lines = ucx_list_append(grid->lines, grid->current); |
235 cxListAdd(grid->current, widget); |
|
236 cxListAdd(grid->lines, grid->current); |
231 } |
237 } |
232 |
238 |
233 ui_reset_layout(ct->layout); |
239 ui_reset_layout(ct->layout); |
234 ct->current = widget; |
240 ct->current = widget; |
235 } |
241 } |
236 |
242 |
237 static void ui_grid_resize(Widget widget, XtPointer udata, XtPointer cdata) { |
243 static void ui_grid_resize(Widget widget, XtPointer udata, XtPointer cdata) { |
238 UiGridContainer *grid = udata; |
244 UiGridContainer *grid = udata; |
239 |
245 |
240 UcxList *rowdim = NULL; |
246 CxList *rowdim = cxArrayListCreateSimple(sizeof(int), grid->lines->size); |
241 int coldim[UI_GRID_MAX_COLUMNS]; |
247 int coldim[UI_GRID_MAX_COLUMNS]; |
242 memset(coldim, 0, UI_GRID_MAX_COLUMNS*sizeof(int)); |
248 memset(coldim, 0, UI_GRID_MAX_COLUMNS*sizeof(int)); |
243 int numcol = 0; |
249 int numcol = 0; |
244 |
250 |
245 // get the minimum size of the columns and rows |
251 // get the minimum size of the columns and rows |
246 int sumw = 0; |
252 int sumw = 0; |
247 int sumh = 0; |
253 int sumh = 0; |
248 UCX_FOREACH(row, grid->lines) { |
254 CxIterator lineIterator = cxListIterator(grid->lines); |
|
255 cx_foreach(CxList *, row, lineIterator) { |
249 int rheight = 0; |
256 int rheight = 0; |
250 int i=0; |
257 int i=0; |
251 int sum_width = 0; |
258 int sum_width = 0; |
252 UCX_FOREACH(elm, row->data) { |
259 CxIterator colIterator = cxListIterator(row); |
253 Widget w = elm->data; |
260 cx_foreach(Widget, w, colIterator) { |
254 int widget_width = 0; |
261 int widget_width = 0; |
255 int widget_height = 0; |
262 int widget_height = 0; |
256 XtVaGetValues( |
263 XtVaGetValues( |
257 w, |
264 w, |
258 XmNwidth, |
265 XmNwidth, |
278 i++; |
285 i++; |
279 if(i > numcol) { |
286 if(i > numcol) { |
280 numcol = i; |
287 numcol = i; |
281 } |
288 } |
282 } |
289 } |
283 rowdim = ucx_list_append(rowdim, (void*)(intptr_t)rheight); |
290 cxListAdd(rowdim, &rheight); |
284 sumh += rheight; |
291 sumh += rheight; |
285 } |
292 } |
286 |
293 |
287 // check container size |
294 // check container size |
288 int gwidth = 0; |
295 int gwidth = 0; |
289 int gheight = 0; |
296 int gheight = 0; |
290 XtVaGetValues(widget, XmNwidth, &gwidth, XmNheight, &gheight, NULL); |
297 XtVaGetValues(widget, XmNwidth, &gwidth, XmNheight, &gheight, NULL); |
291 if(gwidth < sumw || gheight < sumh) { |
298 if(gwidth < sumw || gheight < sumh) { |
292 XtVaSetValues(widget, XmNwidth, sumw, XmNheight, sumh, NULL); |
299 XtVaSetValues(widget, XmNwidth, sumw, XmNheight, sumh, NULL); |
293 ucx_list_free(rowdim); |
300 cxListDestroy(rowdim); |
294 return; |
301 return; |
295 } |
302 } |
296 |
303 |
297 |
304 |
298 // adjust the positions of all children |
305 // adjust the positions of all children |
299 int y = 0; |
306 int y = 0; |
300 UCX_FOREACH(row, grid->lines) { |
307 lineIterator = cxListIterator(grid->lines); |
|
308 cx_foreach(CxList *, row, lineIterator) { |
301 int x = 0; |
309 int x = 0; |
302 int i=0; |
310 int i=0; |
303 UCX_FOREACH(elm, row->data) { |
311 int *rowheight = cxListAt(rowdim, lineIterator.index); |
304 Widget w = elm->data; |
312 CxIterator colIterator = cxListIterator(row); |
|
313 cx_foreach(Widget, w, colIterator) { |
305 XtVaSetValues( |
314 XtVaSetValues( |
306 w, |
315 w, |
307 XmNx, x, |
316 XmNx, x, |
308 XmNy, y, |
317 XmNy, y, |
309 XmNwidth, coldim[i], |
318 XmNwidth, coldim[i], |
310 XmNheight, rowdim->data, |
319 XmNheight, *rowheight, |
311 NULL); |
320 NULL); |
312 |
321 |
313 x += coldim[i]; |
322 x += coldim[i]; |
314 i++; |
323 i++; |
315 } |
324 } |
316 y += (intptr_t)rowdim->data; |
325 y += *rowheight; |
317 rowdim = rowdim->next; |
326 } |
318 } |
327 |
319 |
328 cxListDestroy(rowdim); |
320 ucx_list_free(rowdim); |
|
321 } |
329 } |
322 |
330 |
323 UiContainer* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) { |
331 UiContainer* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) { |
324 UiContainer *ct = ucx_mempool_calloc( |
332 UiContainer *ct = cxCalloc( |
325 obj->ctx->mempool, |
333 obj->ctx->allocator, |
326 1, |
334 1, |
327 sizeof(UiContainer)); |
335 sizeof(UiContainer)); |
328 ct->widget = scrolledwindow; |
336 ct->widget = scrolledwindow; |
329 ct->prepare = ui_scrolledwindow_container_prepare; |
337 ct->prepare = ui_scrolledwindow_container_prepare; |
330 ct->add = ui_scrolledwindow_container_add; |
338 ct->add = ui_scrolledwindow_container_add; |
340 ct->current = widget; |
348 ct->current = widget; |
341 } |
349 } |
342 |
350 |
343 |
351 |
344 UiContainer* ui_tabview_container(UiObject *obj, Widget frame) { |
352 UiContainer* ui_tabview_container(UiObject *obj, Widget frame) { |
345 UiTabViewContainer *ct = ucx_mempool_calloc( |
353 UiTabViewContainer *ct = cxCalloc( |
346 obj->ctx->mempool, |
354 obj->ctx->allocator, |
347 1, |
355 1, |
348 sizeof(UiTabViewContainer)); |
356 sizeof(UiTabViewContainer)); |
349 ct->context = obj->ctx; |
357 ct->context = obj->ctx; |
350 ct->container.widget = frame; |
358 ct->container.widget = frame; |
351 ct->container.prepare = ui_tabview_container_prepare; |
359 ct->container.prepare = ui_tabview_container_prepare; |
352 ct->container.add = ui_tabview_container_add; |
360 ct->container.add = ui_tabview_container_add; |
|
361 ct->tabs = cxArrayListCreate(cxDefaultAllocator, cx_cmp_uintptr, CX_STORE_POINTERS, 16); |
353 return (UiContainer*)ct; |
362 return (UiContainer*)ct; |
354 } |
363 } |
355 |
364 |
356 Widget ui_tabview_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { |
365 Widget ui_tabview_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { |
357 int a = *n; |
366 int a = *n; |
369 if(tabview->current) { |
378 if(tabview->current) { |
370 XtUnmanageChild(tabview->current); |
379 XtUnmanageChild(tabview->current); |
371 } |
380 } |
372 |
381 |
373 tabview->current = widget; |
382 tabview->current = widget; |
374 tabview->tabs = ucx_list_append(tabview->tabs, widget); |
383 cxListAdd(tabview->tabs, widget); |
375 |
384 |
376 ui_select_tab(ct->widget, 0); |
385 ui_select_tab(ct->widget, 0); |
377 ui_reset_layout(ct->layout); |
386 ui_reset_layout(ct->layout); |
378 ct->current = widget; |
387 ct->current = widget; |
379 } |
388 } |
524 void ui_select_tab(UIWIDGET tabview, int tab) { |
533 void ui_select_tab(UIWIDGET tabview, int tab) { |
525 UiTabViewContainer *ct = NULL; |
534 UiTabViewContainer *ct = NULL; |
526 XtVaGetValues(tabview, XmNuserData, &ct, NULL); |
535 XtVaGetValues(tabview, XmNuserData, &ct, NULL); |
527 if(ct) { |
536 if(ct) { |
528 XtUnmanageChild(ct->current); |
537 XtUnmanageChild(ct->current); |
529 UcxList *elm = ucx_list_get(ct->tabs, tab); |
538 Widget w = cxListAt(ct->tabs, tab); |
530 if(elm) { |
539 if(w) { |
531 XtManageChild(elm->data); |
540 XtManageChild(w); |
532 ct->current = elm->data; |
541 ct->current = w; |
533 } else { |
542 } else { |
534 fprintf(stderr, "UiError: front tab index: %d\n", tab); |
543 fprintf(stderr, "UiError: front tab index: %d\n", tab); |
535 } |
544 } |
536 } else { |
545 } else { |
537 fprintf(stderr, "UiError: widget is not a tabview\n"); |
546 fprintf(stderr, "UiError: widget is not a tabview\n"); |
547 int width = 0; |
556 int width = 0; |
548 int height = 0; |
557 int height = 0; |
549 XtVaGetValues(widget, XmNwidth, &width, XmNheight, &height, NULL); |
558 XtVaGetValues(widget, XmNwidth, &width, XmNheight, &height, NULL); |
550 int button_width = width / 4; |
559 int button_width = width / 4; |
551 int x = 0; |
560 int x = 0; |
552 UCX_FOREACH(elm, v->tabs) { |
561 CxIterator tabIterator = cxListIterator(v->tabs); |
553 UiTab *tab = elm->data; |
562 cx_foreach(UiTab*, tab, tabIterator) { |
554 XtVaSetValues( |
563 XtVaSetValues( |
555 tab->tab_button, |
564 tab->tab_button, |
556 XmNx, x, |
565 XmNx, x, |
557 XmNy, 0, |
566 XmNy, 0, |
558 XmNwidth, |
567 XmNwidth, |
629 MotifTabbedPane *tabbedpane = ui_malloc(obj->ctx, sizeof(MotifTabbedPane)); |
638 MotifTabbedPane *tabbedpane = ui_malloc(obj->ctx, sizeof(MotifTabbedPane)); |
630 tabbedpane->view.ctx = uic_current_obj(obj)->ctx; |
639 tabbedpane->view.ctx = uic_current_obj(obj)->ctx; |
631 tabbedpane->view.widget = tabct; |
640 tabbedpane->view.widget = tabct; |
632 tabbedpane->view.document = NULL; |
641 tabbedpane->view.document = NULL; |
633 tabbedpane->tabbar = tabbar; |
642 tabbedpane->tabbar = tabbar; |
634 tabbedpane->tabs = NULL; |
643 tabbedpane->tabs = cxArrayListCreate(obj->ctx->allocator, cx_cmp_uintptr, CX_STORE_POINTERS, 16); |
635 tabbedpane->current = NULL; |
644 tabbedpane->current = NULL; |
636 tabbedpane->height = 0; |
645 tabbedpane->height = 0; |
637 |
646 |
638 XtAddCallback(tabbar, XmNresizeCallback , ui_tabbar_resize, tabbedpane); |
647 XtAddCallback(tabbar, XmNresizeCallback , ui_tabbar_resize, tabbedpane); |
639 XtAddCallback(tabbar, XmNexposeCallback, ui_tabbar_expose, tabbedpane); |
648 XtAddCallback(tabbar, XmNexposeCallback, ui_tabbar_expose, tabbedpane); |
663 Widget frame = XmCreateFrame(view->widget, "tab", args, 6); |
672 Widget frame = XmCreateFrame(view->widget, "tab", args, 6); |
664 XtManageChild(frame); |
673 XtManageChild(frame); |
665 |
674 |
666 UiObject *content = ui_malloc(view->ctx, sizeof(UiObject)); |
675 UiObject *content = ui_malloc(view->ctx, sizeof(UiObject)); |
667 content->widget = NULL; // initialization for uic_context() |
676 content->widget = NULL; // initialization for uic_context() |
668 content->ctx = uic_context(content, view->ctx->mempool); |
677 content->ctx = uic_context(content, view->ctx->allocator); |
669 content->ctx->parent = view->ctx; |
678 content->ctx->parent = view->ctx; |
670 content->ctx->attach_document = uic_context_attach_document; |
679 content->ctx->attach_document = uic_context_attach_document; |
671 content->ctx->detach_document2 = uic_context_detach_document2; |
680 content->ctx->detach_document2 = uic_context_detach_document2; |
672 content->widget = frame; |
681 content->widget = frame; |
673 content->window = view->ctx->obj->window; |
682 content->window = view->ctx->obj->window; |
674 content->container = ui_frame_container(content, frame); |
683 content->container = ui_frame_container(content, frame); |
675 content->next = NULL; |
684 content->next = NULL; |
676 |
685 |
677 // add tab button |
686 // add tab button |
678 v->tabs = ucx_list_append_a(view->ctx->mempool->allocator, v->tabs, tab); |
687 cxListAdd(v->tabs, tab); |
679 |
688 |
680 XmString label = XmStringCreateLocalized("tab"); |
689 XmString label = XmStringCreateLocalized("tab"); |
681 XtSetArg(args[0], XmNlabelString, label); |
690 XtSetArg(args[0], XmNlabelString, label); |
682 XtSetArg(args[1], XmNshadowThickness, 0); |
691 XtSetArg(args[1], XmNshadowThickness, 0); |
683 XtSetArg(args[2], XmNhighlightThickness, 0); |
692 XtSetArg(args[2], XmNhighlightThickness, 0); |
733 XtVaSetValues(pane->current->tab_button, XmNshadowThickness, 0, XmNbackground, pane->bg1, NULL); |
742 XtVaSetValues(pane->current->tab_button, XmNshadowThickness, 0, XmNbackground, pane->bg1, NULL); |
734 } |
743 } |
735 XtVaSetValues(tab->tab_button, XmNshadowThickness, 1, XmNbackground, pane->bg2, NULL); |
744 XtVaSetValues(tab->tab_button, XmNshadowThickness, 1, XmNbackground, pane->bg2, NULL); |
736 |
745 |
737 pane->current = tab; |
746 pane->current = tab; |
738 pane->index = ucx_list_find(pane->tabs, tab, NULL, NULL); |
747 pane->index = cxListFind(pane->tabs, tab); |
739 printf("index: %d\n", pane->index); |
748 printf("index: %d\n", pane->index); |
740 |
749 |
741 // redraw tabbar |
750 // redraw tabbar |
742 Display *dpy = XtDisplay(pane->tabbar); |
751 Display *dpy = XtDisplay(pane->tabbar); |
743 Window window = XtWindow(pane->tabbar); |
752 Window window = XtWindow(pane->tabbar); |