ui/motif/container.c

changeset 102
64ded9f6a6c6
parent 101
7b3a3130be44
equal deleted inserted replaced
101:7b3a3130be44 102:64ded9f6a6c6
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
37 #include "Grid.h" 39 #include "Grid.h"
40
41
42 UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args) {
43 Arg xargs[64];
44 int n = 0;
45
46 UiContainerPrivate *ctn = ui_obj_container(obj);
47 UI_APPLY_LAYOUT(ctn->layout, args);
48
49 Widget parent = ctn->prepare(ctn, xargs, &n);
50 Widget widget = create_widget(obj, args, userdata, parent, xargs, n);
51 XtManageChild(widget);
52 ctn->add(ctn, widget);
53
54 return widget;
55 }
38 56
39 /* ---------------------------- Box Container ---------------------------- */ 57 /* ---------------------------- Box Container ---------------------------- */
40 58
41 static UIWIDGET box_create(UiObject *obj, UiContainerArgs args, UiBoxOrientation orientation) { 59 static UIWIDGET box_create(UiObject *obj, UiContainerArgs args, UiBoxOrientation orientation) {
42 UiContainerPrivate *ctn = ui_obj_container(obj); 60 UiContainerPrivate *ctn = ui_obj_container(obj);
201 grid->x++; 219 grid->x++;
202 ui_reset_layout(ctn->layout); 220 ui_reset_layout(ctn->layout);
203 } 221 }
204 222
205 223
224 /* -------------------------- TabView Container -------------------------- */
225
226 static void ui_tabbar_resize(Widget widget, XtPointer udata, XtPointer cdata) {
227 UiMotifTabView *tabview = udata;
228
229 if(tabview->tabview == UI_TABVIEW_INVISIBLE) {
230 return;
231 }
232
233 int width = 0;
234 int height = 0;
235 XtVaGetValues(widget, XmNwidth, &width, XmNheight, &height, NULL);
236 int numbuttons = cxListSize(tabview->tabs);
237 if(numbuttons == 0) {
238 return;
239 }
240 int button_width = width / numbuttons;
241 int x = 0;
242
243 CxIterator i = cxListIterator(tabview->tabs);
244 cx_foreach(UiTab *, tab, i) {
245 if(i.index + 1 == numbuttons) {
246 button_width = width - x;
247 }
248 XtVaSetValues(
249 tab->tab_button,
250 XmNx, x,
251 XmNy, 0,
252 XmNwidth,
253 button_width,
254
255 NULL);
256 x += button_width;
257 }
258
259 if(height <= tabview->height) {
260 XtVaSetValues(widget, XmNheight, tabview->height + 4, NULL);
261 }
262 }
263
264 static void ui_tabbar_expose(Widget widget, XtPointer udata, XtPointer cdata) {
265 UiMotifTabView *tabview = udata;
266 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *)cdata;
267 XEvent *event = cbs->event;
268 Display *dpy = XtDisplay(widget);
269
270 if(!tabview->gc_initialized) {
271 XGCValues gcvals;
272 gcvals.foreground = tabview->fg1;
273 tabview->gc = XCreateGC(XtDisplay(tabview->tabbar), XtWindow(tabview->tabbar), (GCForeground), &gcvals);
274 }
275
276 if(tabview->current_tab) {
277 Widget tab = tabview->current_tab->tab_button;
278 XFillRectangle(dpy, XtWindow(widget), tabview->gc, tab->core.x, tab->core.height, tab->core.width, 4);
279 }
280 }
281
282 UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs args) {
283 Arg xargs[16];
284 int n = 0;
285
286 UiContainerPrivate *ctn = ui_obj_container(obj);
287 UI_APPLY_LAYOUT(ctn->layout, args);
288
289 // create widgets
290 // form
291 // - tabbar (Drawing Area)
292 // - content (Frame)
293 UiMotifTabView *tabview = malloc(sizeof(UiMotifTabView));
294 memset(tabview, 0, sizeof(UiMotifTabView));
295 char *name = args.name ? (char*)args.name : "tabview";
296 XtSetArg(xargs[n], XmNuserData, tabview); n++;
297 Widget parent = ctn->prepare(ctn, xargs, &n);
298 Widget form = XmCreateForm(parent, name, xargs, n);
299 XtManageChild(form);
300
301 n = 0;
302 XtSetArg(xargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
303 XtSetArg(xargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
304 XtSetArg(xargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
305 XtSetArg(xargs[n], XmNorientation, XmHORIZONTAL); n++;
306 XtSetArg(xargs[n], XmNpacking, XmPACK_TIGHT); n++;
307 XtSetArg(xargs[n], XmNspacing, 1); n++;
308 XtSetArg(xargs[n], XmNmarginWidth, 0); n++;
309 XtSetArg(xargs[n], XmNmarginHeight, 0); n++;
310 Widget tabbar = XmCreateDrawingArea(form, "ui_test", xargs, n);
311 XtManageChild(tabbar);
312 XtAddCallback(tabbar, XmNresizeCallback , ui_tabbar_resize, tabview);
313 XtAddCallback(tabbar, XmNexposeCallback, ui_tabbar_expose, tabview);
314
315 n = 0;
316 XtSetArg(xargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
317 XtSetArg(xargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
318 XtSetArg(xargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
319 XtSetArg(xargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
320 XtSetArg(xargs[n], XmNtopWidget, tabbar); n++;
321 Widget content = XmCreateFrame(form, "tabviewcontent", xargs, n);
322
323 // setup tabview object, that holds all relevant objects
324 tabview->obj = obj;
325 tabview->form = form;
326 tabview->tabbar = tabbar;
327 tabview->content = content;
328 tabview->tabview = args.tabview;
329 tabview->subcontainer = args.subcontainer;
330 tabview->select = ui_motif_tabview_select;
331 tabview->add = ui_motif_tabview_add_tab;
332 tabview->remove = ui_motif_tabview_remove;
333 tabview->tabs = cxArrayListCreate(obj->ctx->allocator, cx_cmp_ptr, sizeof(UiTab), 8);
334 tabview->current_index = -1;
335
336 UiTabViewContainer *ct = ui_malloc(obj->ctx, sizeof(UiTabViewContainer));
337 ct->container.widget = form;
338 ct->container.type = UI_CONTAINER_TABVIEW;
339 ct->container.prepare = ui_tabview_container_prepare;
340 ct->container.add = ui_tabview_container_add;
341 ct->tabview = tabview;
342
343 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER);
344 if(var) {
345 UiInteger *i = var->value;
346 i->obj = tabview;
347 i->get = ui_tabview_get;
348 i->set = ui_tabview_set;
349 }
350
351 uic_object_push_container(obj, (UiContainerX*)ct);
352
353 return form;
354 }
355
356 int64_t ui_tabview_get(UiInteger *i) {
357 UiMotifTabView *tabview = i->obj;
358 i->value = tabview->current_index;
359 return i->value;
360 }
361
362 void ui_tabview_set(UiInteger *i, int64_t value) {
363 UiMotifTabView *tabview = i->obj;
364 if(value < cxListSize(tabview->tabs)) {
365 ui_motif_tabview_select(tabview, value);
366 i->value = value;
367 }
368 }
369
370 void ui_tab_create(UiObject *obj, const char* title) {
371 UiContainerPrivate *ctn = ui_obj_container(obj);
372 if(ctn->type != UI_CONTAINER_TABVIEW) {
373 fprintf(stderr, "UI Error: container is not a tabview\n");
374 return;
375 }
376
377 UiMotifTabView *tabview = NULL;
378 XtVaGetValues(ctn->widget, XmNuserData, &tabview, NULL);
379 if(!tabview) {
380 fprintf(stderr, "UI Error: no tabview\n");
381 return;
382 }
383
384
385 Widget child = ui_vbox_create(obj, (UiContainerArgs) { 0 });
386 if(tabview->current) {
387 XtUnmanageChild(child);
388 } else {
389 tabview->current = child;
390 }
391
392 tabview->add(tabview, -1, title, child);
393 }
394
395 void ui_tabview_select(UIWIDGET tabview, int tab) {
396 UiMotifTabView *tabviewdata = NULL;
397 XtVaGetValues(tabview, XmNuserData, &tabviewdata, NULL);
398 if(tabviewdata) {
399 ui_motif_tabview_select(tabviewdata, tab);
400 } else {
401 fprintf(stderr, "ui_tabview_select: widget is not a tabview\n");
402 }
403 }
404
405 void ui_tabview_remove(UIWIDGET tabview, int tab) {
406 UiMotifTabView *tabviewdata = NULL;
407 XtVaGetValues(tabview, XmNuserData, &tabviewdata, NULL);
408 if(tabviewdata) {
409 ui_motif_tabview_remove(tabviewdata, tab);
410 } else {
411 fprintf(stderr, "ui_tabview_select: widget is not a tabview\n");
412 }
413 }
414
415 UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index) {
416 UiMotifTabView *tabviewdata = NULL;
417 XtVaGetValues(tabview, XmNuserData, &tabviewdata, NULL);
418 if(tabviewdata) {
419 Arg args[16];
420 int n = 0;
421
422 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
423 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
424 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
425 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
426 XtSetArg(args[n], XmNtopWidget, tabviewdata->tabbar); n++;
427
428 Widget grid = XtCreateManagedWidget("vbox", gridClass, tabviewdata->content, args, n);
429
430 UiObject *newobj = ui_calloc(tabviewdata->obj->ctx, 1, sizeof(UiObject));
431 newobj->ctx = tabviewdata->obj->ctx;
432 newobj->widget = grid;
433 UiContainerX *container = ui_box_container(newobj, grid, UI_BOX_VERTICAL);
434 newobj->container_begin = container;
435 newobj->container_end = container;
436 return newobj;
437 } else {
438 fprintf(stderr, "ui_tabview_select: widget is not a tabview\n");
439 return NULL;
440 }
441 }
442
443 void ui_motif_tabview_select(UiMotifTabView *tabview, int tab) {
444 UiTab *t = cxListAt(tabview->tabs, tab);
445 if(t) {
446 tabview->current_index = tab;
447 ui_motif_tabview_change_tab(tabview, t);
448 }
449 }
450
451 static void ui_tab_button_callback(Widget widget, UiTab *tab, XtPointer d) {
452 UiMotifTabView *tabview = NULL;
453 XtVaGetValues(widget, XmNuserData, &tabview, NULL);
454 ui_motif_tabview_change_tab(tabview, tab);
455 }
456
457 void ui_motif_tabview_add_tab(UiMotifTabView *tabview, int index, const char *name, Widget child) {
458 UiTab tab;
459
460 Arg args[16];
461 int n = 0;
462
463 XmString label = XmStringCreateLocalized((char*)name);
464 XtSetArg(args[n], XmNlabelString, label); n++;
465 XtSetArg(args[n], XmNshadowThickness, 0); n++;
466 XtSetArg(args[n], XmNhighlightThickness, 0); n++;
467 XtSetArg(args[n], XmNuserData, tabview); n++;
468
469 Widget button = XmCreatePushButton(tabview->tabbar, "tab_button", args, n);
470 if(tabview->tabview != UI_TABVIEW_INVISIBLE) {
471 XtManageChild(button);
472 }
473
474 if(tabview->height == 0) {
475 Dimension h;
476 XtVaGetValues(
477 button,
478 XmNarmColor,
479 &tabview->bg1,
480 XmNbackground,
481 &tabview->bg2,
482 XmNhighlightColor,
483 &tabview->fg1,
484 XmNheight,
485 &h,
486 NULL);
487 tabview->height = h + 2; // border
488
489 XtVaSetValues(tabview->tabbar, XmNbackground, tabview->bg1, NULL);
490 }
491
492 tab.tab_button = button;
493 tab.child = child;
494 size_t newtab_index = cxListSize(tabview->tabs);
495 cxListAdd(tabview->tabs, &tab);
496 UiTab *newtab = cxListAt(tabview->tabs, newtab_index);
497
498 XtAddCallback(
499 button,
500 XmNactivateCallback,
501 (XtCallbackProc)ui_tab_button_callback,
502 newtab);
503
504 if(newtab_index == 0) {
505 ui_motif_tabview_change_tab(tabview, newtab);
506 } else {
507 XtVaSetValues(button, XmNbackground, tabview->bg1, NULL);
508 }
509 }
510
511 void ui_motif_tabview_remove(UiMotifTabView *tabview, int index) {
512 UiTab *tab = cxListAt(tabview->tabs, index);
513 if(tab) {
514 if(tab == tabview->current_tab) {
515 if(index > 0) {
516 ui_motif_tabview_select(tabview, index-1);
517 } else {
518 if(index < cxListSize(tabview->tabs)) {
519 ui_motif_tabview_select(tabview, index+1);
520 } else {
521 tabview->current_tab = NULL;
522 tabview->current_index = -1;
523 }
524 }
525 }
526 XtDestroyWidget(tab->tab_button);
527 XtDestroyWidget(tab->child);
528 cxListRemove(tabview->tabs, index);
529 }
530 }
531
532 void ui_motif_tabview_change_tab(UiMotifTabView *tabview, UiTab *tab) {
533 if(tabview->current_tab) {
534 XtVaSetValues(tabview->current_tab->tab_button, XmNshadowThickness, 0, XmNbackground, tabview->bg1, NULL);
535 XtUnmanageChild(tabview->current_tab->child);
536 }
537 XtVaSetValues(tab->tab_button, XmNshadowThickness, 1, XmNbackground, tabview->bg2, NULL);
538 tabview->current_tab = tab;
539 tabview->current_index = (int)cxListFind(tabview->tabs, tab);;
540 XtManageChild(tab->child);
541 }
542
543 Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n) {
544 UiTabViewContainer *ct = (UiTabViewContainer*)ctn;
545 UiMotifTabView *tabview = ct->tabview;
546 int a = *n;
547 XtSetArg(args[a], XmNleftAttachment, XmATTACH_FORM); a++;
548 XtSetArg(args[a], XmNrightAttachment, XmATTACH_FORM); a++;
549 XtSetArg(args[a], XmNbottomAttachment, XmATTACH_FORM); a++;
550 XtSetArg(args[a], XmNtopAttachment, XmATTACH_WIDGET); a++;
551 XtSetArg(args[a], XmNtopWidget, tabview->tabbar); a++;
552 *n = a;
553 return tabview->form;
554 }
555
556 void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget) {
557 ui_reset_layout(ctn->layout);
558 }
559
560
561
206 /* -------------------- Container Helper Functions -------------------- */ 562 /* -------------------- Container Helper Functions -------------------- */
207 563
208 void ui_container_begin_close(UiObject *obj) { 564 void ui_container_begin_close(UiObject *obj) {
209 UiContainerPrivate *ct = ui_obj_container(obj); 565 UiContainerPrivate *ct = ui_obj_container(obj);
210 ct->container.close = 1; 566 ct->container.close = 1;

mercurial