diff -r a7f18dda6baf -r 0ebf9d7b23e8 ui/motif/tree.c --- a/ui/motif/tree.c Wed Dec 04 08:57:35 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,328 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2014 Olaf Wintermann. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "tree.h" - -#include "container.h" -#include "../common/object.h" -#include "../common/context.h" -#include -#include -#include - -UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModel *model, UiListCallbacks cb) { - // TODO: check if modelinfo is complete - - Arg args[32]; - int n = 0; - - // create scrolled window - UiContainer *ct = uic_get_current_container(obj); - Widget parent = ct->prepare(ct, args, &n, TRUE); - - XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); - n++; - XtSetArg(args[n], XmNshadowThickness, 0); - n++; - Widget scrollw = XmCreateScrolledWindow(parent, "scroll_win", args, n); - ct->add(ct, scrollw); - XtManageChild(scrollw); - - // create table headers - XmStringTable header = (XmStringTable)XtMalloc( - model->columns * sizeof(XmString)); - for(int i=0;icolumns;i++) { - header[i] = XmStringCreateLocalized(model->titles[i]); - } - n = 0; - XtSetArg(args[n], XmNdetailColumnHeading, header); - n++; - XtSetArg(args[n], XmNdetailColumnHeadingCount, model->columns); - n++; - - // set res - XtSetArg(args[n], XmNlayoutType, XmDETAIL); - n++; - XtSetArg(args[n], XmNentryViewType, XmSMALL_ICON); - n++; - XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); - n++; - XtSetArg(args[n], XmNwidth, 600); - n++; - - // create widget - //UiContainer *ct = uic_get_current_container(obj); - //Widget parent = ct->add(ct, args, &n); - - Widget container = XmCreateContainer(scrollw, "table", args, n); - XtManageChild(container); - - // add callbacks - UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData)); - event->obj = obj; - event->activate = cb.activate; - event->selection = cb.selection; - event->userdata = cb.userdata; - event->last_selection = NULL; - if(cb.selection) { - XtAddCallback( - container, - XmNselectionCallback, - (XtCallbackProc)ui_table_select_callback, - event); - } - if(cb.activate) { - XtAddCallback( - container, - XmNdefaultActionCallback, - (XtCallbackProc)ui_table_action_callback, - event); - } - - // add initial data - UiList *list = var->value; - void *data = list->first(list); - int width = 0; - while(data) { - int w = ui_add_icon_gadget(container, model, data); - if(w > width) { - width = w; - } - data = list->next(list); - } - - UiTableView *tableview = cxMalloc(obj->ctx->allocator, sizeof(UiTableView)); - tableview->widget = container; - tableview->var = var; - tableview->model = model; - - // set new XmContainer width - XtVaSetValues(container, XmNwidth, width, NULL); - - // cleanup - for(int i=0;icolumns;i++) { - XmStringFree(header[i]); - } - XtFree((char*)header); - - return scrollw; -} - -UIWIDGET ui_table(UiObject *obj, UiList *data, UiModel *model, UiListCallbacks cb) { - UiVar *var = malloc(sizeof(UiVar)); - var->value = data; - var->type = UI_VAR_SPECIAL; - return ui_table_var(obj, var, model, cb); -} - -void ui_table_update(UiEvent *event, UiTableView *view) { - // clear container - Widget *children; - int nc; - - XtVaGetValues( - view->widget, - XmNchildren, - &children, - XmNnumChildren, - &nc, - NULL); - - for(int i=0;ivar->value; - - void *data = list->first(list); - int width = 0; - while(data) { - int w = ui_add_icon_gadget(view->widget, view->model, data); - if(w > width) { - width = w; - } - data = list->next(list); - } - -} - -#define UI_COL_CHAR_WIDTH 12 - -int ui_add_icon_gadget(Widget container, UiModel *model, void *data) { - int width = 50; - - if(model->columns == 0) { - return width; - } - - XmString label = NULL; - Arg args[8]; - Boolean f; - // first column - if(model->types[0] != 12345678) { // TODO: icon/label type - char *str = ui_type_to_string( - model->types[0], - model->getvalue(data, 0), - &f); - - // column width - width += strlen(str) * UI_COL_CHAR_WIDTH; - - - XmString label = XmStringCreateLocalized(str); - XtSetArg(args[0], XmNlabelString, label); - if(f) { - free(str); - } - } else { - // TODO - } - - // remaining columns are the icon gadget details - XmStringTable details = (XmStringTable)XtMalloc( - (model->columns - 1) * sizeof(XmString)); - for(int i=1;icolumns;i++) { - char *str = ui_type_to_string( - model->types[i], - model->getvalue(data, i), - &f); - - // column width - width += strlen(str) * UI_COL_CHAR_WIDTH; - - details[i - 1] = XmStringCreateLocalized(str); - if(f) { - free(str); - } - } - XtSetArg(args[1], XmNdetail, details); - XtSetArg(args[2], XmNdetailCount, model->columns - 1); - XtSetArg(args[3], XmNshadowThickness, 0); - // create widget - Widget item = XmCreateIconGadget(container, "table_item", args, 4); - XtManageChild(item); - - // cleanup - XmStringFree(label); - for(int i=0;icolumns-1;i++) { - XmStringFree(details[i]); - } - XtFree((char*)details); - - return width; -} - -char* ui_type_to_string(UiModelType type, void *data, Boolean *free) { - switch(type) { - case UI_STRING: *free = FALSE; return data; - case UI_INTEGER: { - *free = TRUE; - int *val = data; - cxmutstr str = cx_asprintf("%d", *val); - return str.ptr; - } - case UI_ICON: break; // TODO - case UI_ICON_TEXT: break; // TODO - } - *free = FALSE; - return NULL; -} - -void ui_table_action_callback( - Widget widget, - UiTreeEventData *event, - XmContainerSelectCallbackStruct *sel) -{ - UiListSelection *selection = ui_list_selection(sel); - - UiEvent e; - e.obj = event->obj; - e.window = event->obj->window; - e.document = event->obj->ctx->document; - e.eventdata = selection; - e.intval = selection->count > 0 ? selection->rows[0] : -1; - event->activate(&e, event->userdata); - - free(event->last_selection->rows); - free(event->last_selection); - event->last_selection = selection; -} - -void ui_table_select_callback( - Widget widget, - UiTreeEventData *event, - XmContainerSelectCallbackStruct *sel) -{ - UiListSelection *selection = ui_list_selection(sel); - if(!ui_compare_list_selection(selection, event->last_selection)) { - UiEvent e; - e.obj = event->obj; - e.window = event->obj->window; - e.document = event->obj->ctx->document; - e.eventdata = selection; - e.intval = selection->count > 0 ? selection->rows[0] : -1; - event->selection(&e, event->userdata); - } - if(event->last_selection) { - free(event->last_selection->rows); - free(event->last_selection); - } - event->last_selection = selection; -} - -UiListSelection* ui_list_selection(XmContainerSelectCallbackStruct *xs) { - UiListSelection *selection = malloc(sizeof(UiListSelection)); - selection->count = xs->selected_item_count; - selection->rows = calloc(selection->count, sizeof(int)); - for(int i=0;icount;i++) { - int index; - XtVaGetValues(xs->selected_items[i], XmNpositionIndex, &index, NULL); - selection->rows[i] = index; - } - return selection; -} - -Boolean ui_compare_list_selection(UiListSelection *s1, UiListSelection *s2) { - if(!s1 || !s2) { - return FALSE; - } - if(s1->count != s2->count) { - return FALSE; - } - for(int i=0;icount;i++) { - if(s1->rows[i] != s2->rows[i]) { - return FALSE; - } - } - return TRUE; -}