diff -r 9a5f47fbc5c3 -r 458831c574f4 ui/gtk/tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/gtk/tree.c Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,158 @@ +/* + * 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 "../common/context.h" +#include "../common/object.h" +#include "container.h" + +#include "tree.h" + + +void* ui_strmodel_getvalue(void *elm, int column) { + return column == 0 ? elm : NULL; +} + + +UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata) { + return ui_listview(obj, list, ui_strmodel_getvalue, f, udata); +} + +UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + // create treeview + GtkWidget *view = gtk_tree_view_new(); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); + + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); +#ifdef UI_GTK3 + gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE); +#else + +#endif + + UiListModel *model = ui_list_model_new(list, getvalue); + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); + + // add TreeView as observer to the UiList to update the TreeView if the + // data changes + UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView)); + listview->widget = view; + listview->list = list; + listview->getvalue = getvalue; + list->list->observers = ui_add_observer( + list->list->observers, + (ui_callback)ui_listview_update, + listview); + + // add callback + if(f) { + UiEventData *event = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiEventData)); + event->obj = obj; + event->user_data = udata; + event->callback = f; + event->value = 0; + + g_signal_connect( + view, + "row-activated", + G_CALLBACK(ui_listview_selected), + event); + } + + // add widget to the current container + GtkWidget *scroll_area = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(scroll_area), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS + gtk_container_add(GTK_CONTAINER(scroll_area), view); + + UiContainer *ct = uic_get_current_container(obj); + ct->add(ct, scroll_area); + + return scroll_area; +} + +UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); + listptr->list = list; + return ui_listview_var(obj, listptr, getvalue, f, udata); +} + +UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + if(var) { + UiListVar *value = var->value; + return ui_listview_var(obj, value->listptr, getvalue, f, udata); + } else { + // TODO: error + } + return NULL; +} + + +void ui_listview_update(UiEvent *event, UiListView *view) { + UiList *list = view->list->list; + + UiListModel *model = ui_list_model_new(view->list, view->getvalue); + gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model)); +} + +void ui_listview_selected( + GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + UiEventData *event) +{ + int *indices = gtk_tree_path_get_indices(path); + int depth = gtk_tree_path_get_depth(path); + if(depth == 0) { + fprintf(stderr, "UiError: ui_treeview_selected: depth == 0\n"); + return; + } + GtkTreeModel *model = gtk_tree_view_get_model(treeview); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + void *value = NULL; + gtk_tree_model_get(model, &iter, 0, &value, -1); + + UiEvent e; + e.obj = event->obj; + e.window = event->obj->window; + e.document = event->obj->document; + e.eventdata = value; + e.intval = indices[depth-1]; + event->callback(&e, event->user_data); +}