]> uap-core.de Git - note.git/commitdiff
add note toolbar
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 7 Mar 2025 21:32:49 +0000 (22:32 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 7 Mar 2025 21:32:49 +0000 (22:32 +0100)
application/application.h
application/note.c
application/window.c
ui/common/context.c
ui/gtk/container.c
ui/gtk/list.c
ui/gtk/list.h
ui/gtk/toolkit.c
ui/gtk/toolkit.h
ui/ui/toolkit.h
ui/ui/tree.h

index 22cd07deed81c82581bd4bdceba480b16971d2f2..d95216cd98a0a3993ea412c8d44bb87f3e3e34d6 100644 (file)
@@ -131,6 +131,11 @@ struct NoteModel {
     UiText *text;
     UiGeneric *html;
     
+    /*
+     * text note paragraph types
+     */
+    UiList *textnote_para;
+    
     bool modified;
 };
    
index b3428656cb114e605840e679c3035f0d13c4b131..1d8fdb3134bf4bd3e2f73731ab4a97f1af9568d1 100644 (file)
@@ -43,6 +43,19 @@ NoteModel* notemodel_create(const CxAllocator *note_allocator) {
     ui_set(model->type, 1);
     //ui_set_group(model->ctx, APP_STATE_NOTE_SELECTED);
     
+    model->textnote_para = ui_list_new(model->ctx, "note_textnote_para");
+    // currently only one type of textnote exists, therefore the 
+    // paragraph types are static
+    ui_list_append(model->textnote_para, "Paragraph");
+    ui_list_append(model->textnote_para, "Code");
+    ui_list_append(model->textnote_para, "Blockquote");
+    ui_list_append(model->textnote_para, "Heading 1");
+    ui_list_append(model->textnote_para, "Heading 2");
+    ui_list_append(model->textnote_para, "Heading 3");
+    ui_list_append(model->textnote_para, "Heading 4");
+    ui_list_append(model->textnote_para, "Heading 5");
+    ui_list_append(model->textnote_para, "Heading 6");
+    
     return model;
 }
 
index 4ab3bc90abed517c7333b8560b112cb9b3b8f6f1..d6faaf31b7b15b32c2f2c2a5577e8ccc41c54948 100644 (file)
@@ -37,6 +37,7 @@
 
 void window_create() {
     UiObject *obj = ui_sidebar_window("note", NULL);
+    ui_window_size(obj, 1600, 1200);
     MainWindow *wdata = window_init_data(obj);
     
     /*
@@ -67,10 +68,20 @@ void window_create() {
             ui_tab(obj, "textnote") {
                 ui_vbox0(obj) {
                     ui_grid(obj, .margin = 10, .columnspacing = 10, .rowspacing = 10, .def_vfill = TRUE, .fill = UI_OFF) {
-                        ui_label(obj, .label = "Title", .vfill = TRUE);
+                        //ui_label(obj, .label = "Title", .vfill = TRUE);
                         ui_textfield(obj, .varname = "note_title", .hexpand = TRUE, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED));
                         ui_newline(obj);
                     }
+                    ui_hbox(obj, .style_class = "note_toolbar", .margin = 10, .spacing = 4, .fill = UI_OFF) {
+                        ui_combobox(obj, .varname = "note_textnote_para");
+                        ui_button(obj, .icon = "format-text-bold");
+                        ui_button(obj, .icon = "format-text-italic");
+                        ui_button(obj, .icon = "format-text-underline");
+                        ui_button(obj, .icon = "view-list-bullet");
+                        ui_button(obj, .icon = "view-list-ordered");
+                        ui_button(obj, .icon = "insert-image");
+                        ui_button(obj, .icon = "insert-link");
+                    }
                     ui_textarea(obj, .varname = "note_text", .vfill = TRUE, .hfill = TRUE, .hexpand = TRUE, .vexpand = TRUE, .colspan = 2, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED), .fill = UI_ON);
                 } 
             }
index 3cc7abce9534693bf4d2bc144fc08facc6d13bb1..585719440a876aff444f73c600815f475547bfb4 100644 (file)
@@ -347,7 +347,10 @@ void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc) {
             *to = tmp;
 
             UiList* t2 = to->value;
-            ui_notify(t2->observers, NULL);
+            if(t->update) {
+                t->update(t, -1);
+            }
+            ui_notify(t2->observers, NULL); // TODO: why not t?
             
             break;
         }
index 9341b8d525340ca72903a430500bcb254b9ae8bf..74d1f6b373d424389f80b1dac76d762ac90ad91e 100644 (file)
@@ -1068,16 +1068,16 @@ void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill)
     cxListAdd(s->children, widget);
     
     if(s->pos == 0) {
-        gtk_paned_set_start_child(GTK_PANED(s->current_pane), widget);
+        PANED_SET_CHILD1(s->current_pane, widget);
         s->pos++;
         s->nchildren++;
     } else {
         if(s->nchildren+1 == s->max) {
-            gtk_paned_set_end_child(GTK_PANED(s->current_pane), widget);
+            PANED_SET_CHILD2(s->current_pane, widget);
         } else {
             GtkWidget *pane = create_paned(s->orientation);
-            gtk_paned_set_start_child(GTK_PANED(pane), widget);
-            gtk_paned_set_end_child(GTK_PANED(s->current_pane), pane);
+            PANED_SET_CHILD1(pane, widget);
+            PANED_SET_CHILD2(s->current_pane, pane);
             s->current_pane = pane;
         }
         
index dc0c47992019273f89bb53867b60499d817b5817..5d7f5191fc83eb92c7fbbdcae84d562d6ed5348e 100644 (file)
@@ -57,6 +57,14 @@ static GtkTargetEntry targetentries[] =
     };
 */
 
+static void listview_copy_static_elements(UiListView *listview, char **elm, size_t nelm) {
+    listview->elements = calloc(nelm, sizeof(char*));
+    listview->nelm = nelm;
+    for(int i=0;i<nelm;i++) {
+        listview->elements[i] = strdup(elm[i]);
+    }
+}
+
 #if GTK_CHECK_VERSION(4, 10, 0)
 
 
@@ -248,6 +256,10 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs args) {
         list->setselection = ui_listview_setselection2;
         
         ui_update_liststore(ls, list);
+    } else if (args.static_elements && args.static_nelm > 0) {
+        listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
+        listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
+        ui_update_liststore_static(ls, listview->elements, listview->nelm);
     }
     
     // event handling
@@ -323,11 +335,15 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
         list->setselection = ui_combobox_setselection;
         
         ui_update_liststore(ls, list);
+    } else if (args.static_elements && args.static_nelm > 0) {
+        listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
+        listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
+        ui_update_liststore_static(ls, listview->elements, listview->nelm);
     }
     
     // event handling
     if(args.onactivate) {
-        g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), listview);
+        g_signal_connect(view, "notify::selected", G_CALLBACK(ui_dropdown_notify), listview);
     }
     
     // add widget to parent 
@@ -478,6 +494,23 @@ static void listview_update_selection(UiListView *view) {
         free(newselection);
     }
 }
+
+void ui_dropdown_notify(GtkWidget *dropdown, GObject *pspec, gpointer userdata) {
+    UiListView *view = userdata;
+    guint index = gtk_drop_down_get_selected(GTK_DROP_DOWN(dropdown));
+    GObject *item = gtk_drop_down_get_selected_item(GTK_DROP_DOWN(dropdown));
+    if(item && view->onactivate) {
+        ObjWrapper *eventdata = (ObjWrapper*)item;
+        UiEvent event;
+        event.obj = view->obj;
+        event.document = event.obj->ctx->document;
+        event.window = event.obj->window;
+        event.intval = index;
+        event.eventdata = eventdata->data;
+        view->onactivate(&event, view->onactivatedata);
+    }
+}
+    
     
 void ui_columnview_activate(void *ignore, guint position, gpointer userdata) {
     UiListView *view = userdata;
@@ -524,6 +557,14 @@ void ui_update_liststore(GListStore *liststore, UiList *list) {
     }
 }
 
+void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) {
+    g_list_store_remove_all(liststore);
+    for(int i=0;i<nelm;i++) {
+        ObjWrapper *obj = obj_wrapper_new(elm[i]);
+        g_list_store_append(liststore, obj);
+    }
+}
+
 void ui_listview_update2(UiList *list, int i) {
     UiListView *view = list->obj;
     ui_update_liststore(view->liststore, list);
@@ -729,6 +770,7 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs args) {
     g_object_unref(listmodel);
     
     UiListView *listview = malloc(sizeof(UiListView));
+    memset(listview, 0, sizeof(UiListView));
     listview->obj = obj;
     listview->widget = view;
     listview->var = var;
@@ -876,6 +918,7 @@ UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
     // add TreeView as observer to the UiList to update the TreeView if the
     // data changes
     UiListView *tableview = malloc(sizeof(UiListView));
+    memset(tableview, 0, sizeof(UiListView));
     tableview->obj = obj;
     tableview->widget = view;
     tableview->var = var;
@@ -1002,7 +1045,7 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
     
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
     
-    GtkWidget *combobox = ui_create_combobox(obj, model, var, args.onactivate, args.onactivatedata);
+    GtkWidget *combobox = ui_create_combobox(obj, model, var, args.static_elements, args.static_nelm, args.onactivate, args.onactivatedata);
     ui_set_name_and_style(combobox, args.name, args.style_class);
     ui_set_widget_groups(obj->ctx, combobox, args.groups);
     UI_APPLY_LAYOUT1(current, args);
@@ -1011,16 +1054,29 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
     return combobox;
 }
 
-GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, ui_callback f, void *udata) {
+GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **elm, size_t nelm, ui_callback f, void *udata) {
     GtkWidget *combobox = gtk_combo_box_new();
        
     UiListView *uicbox = malloc(sizeof(UiListView));
+    memset(uicbox, 0, sizeof(UiListView));
     uicbox->obj = obj;
     uicbox->widget = combobox;
     
     UiList *list = var ? var->value : NULL;
     GtkListStore *listmodel = create_list_store(list, model);
     
+    if(!list && elm && nelm > 0) {
+        listview_copy_static_elements(uicbox, elm, nelm);
+        for(int i=0;i<nelm;i++) {
+            GtkTreeIter iter;
+            GValue value = G_VALUE_INIT;
+            gtk_list_store_insert(listmodel, &iter, -1);
+            g_value_init(&value, G_TYPE_STRING);
+            g_value_set_string(&value, uicbox->elements[i]);
+            gtk_list_store_set_value(listmodel, &iter, 0, &value);
+        }
+    }
+    
     if(listmodel) {
         gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(listmodel));
         g_object_unref(listmodel);
@@ -1060,7 +1116,7 @@ GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, ui_call
         event->userdata = udata;
         event->callback = f;
         event->value = 0;
-        event->customdata = NULL;
+        event->customdata = uicbox;
 
         g_signal_connect(
                 combobox,
@@ -1073,12 +1129,22 @@ GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, ui_call
 }
 
 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e) {
+    int index = gtk_combo_box_get_active(widget);
+    UiListView *listview = e->customdata;
+    void *eventdata = NULL;
+    if(listview->var && listview->var->value) {
+        UiList *list = listview->var->value;
+        eventdata = ui_list_get(list, index);
+    } else if(listview->elements && listview->nelm > index) {
+        eventdata = listview->elements[index];
+    } 
+    
     UiEvent event;
     event.obj = e->obj;
     event.window = event.obj->window;
     event.document = event.obj->ctx->document;
-    event.eventdata = NULL;
-    event.intval = gtk_combo_box_get_active(widget);
+    event.eventdata = eventdata;
+    event.intval = index;
     e->callback(&event, e->userdata);
 }
 
@@ -1496,7 +1562,15 @@ void ui_table_dragdest_a(UIWIDGET tablewidget, int actions, char **targets, int
 
 void ui_listview_destroy(GtkWidget *w, UiListView *v) {
     //gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL);
-    ui_destroy_boundvar(v->obj->ctx, v->var);
+    if(v->var) {
+        ui_destroy_boundvar(v->obj->ctx, v->var);
+    }
+    if(v->elements) {
+        for(int i=0;i<v->nelm;i++) {
+            free(v->elements[i]);
+        }
+        free(v->elements);
+    }
 #if GTK_CHECK_VERSION(4, 10, 0)
     free(v->columns);
 #endif
@@ -1505,7 +1579,15 @@ void ui_listview_destroy(GtkWidget *w, UiListView *v) {
 }
 
 void ui_combobox_destroy(GtkWidget *w, UiListView *v) {
-    ui_destroy_boundvar(v->obj->ctx, v->var);
+    if(v->var) {
+        ui_destroy_boundvar(v->obj->ctx, v->var);
+    }
+    if(v->elements) {
+        for(int i=0;i<v->nelm;i++) {
+            free(v->elements[i]);
+        }
+        free(v->elements);
+    }
     free(v);
 }
 
index 1ff4029e3acd52ab23dd392bf97d2691030b7025..784e6447247cc814ecbdf21e625173499bba5aa4 100644 (file)
@@ -45,6 +45,8 @@ typedef struct UiListView {
     GtkWidget         *widget;
     UiVar             *var;
     UiModel           *model;
+    char              **elements;
+    size_t            nelm;
 #if GTK_CHECK_VERSION(4, 10, 0)
     GListStore        *liststore;
     GtkSelectionModel *selectionmodel;
@@ -100,7 +102,6 @@ struct UiListBox {
     void                     *onactivatedata;
     ui_callback              onbuttonclick;
     void                     *onbuttonclickdata;
-    
     GtkListBoxRow            *first_row;
 };
 
@@ -108,11 +109,13 @@ struct UiListBox {
 #if GTK_CHECK_VERSION(4, 10, 0)
 
 void ui_update_liststore(GListStore *liststore, UiList *list);
+void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm);
 
 void ui_listview_update2(UiList *list, int i);
 UiListSelection ui_listview_getselection2(UiList *list);
 void ui_listview_setselection2(UiList *list, UiListSelection selection);
 
+void ui_dropdown_notify(GtkWidget *dropdown, GObject *pspec, gpointer userdata);
 void ui_columnview_activate(void *ignore, guint position, gpointer userdata);
 void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer user_data);
 
@@ -155,7 +158,7 @@ void ui_listview_add_dnd(UiListView *listview, UiListArgs *args);
 void ui_listview_enable_drop(UiListView *listview, UiListArgs *args);
 
 UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata);
-GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, ui_callback f, void *udata);
+GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **elm, size_t nelm, ui_callback f, void *udata);
 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e);
 void ui_combobox_modelupdate(UiList *list, int i);
 UiListSelection ui_combobox_getselection(UiList *list);
index 19a099092a589bad2c51bd65b08591b7986c90c9..2f28c2b256de482f8398042b53e9d955c86fd51e 100644 (file)
@@ -327,8 +327,6 @@ UiObject *ui_get_active_window() {
 
 #if GTK_MAJOR_VERSION >= 3
 
-static GtkCssProvider* ui_gtk_css_provider;
-
 #if GTK_MAJOR_VERSION == 4
 static const char *ui_gtk_css = 
 "#path-textfield-box {\n"
@@ -415,15 +413,19 @@ static const char *ui_gtk_css =
 #endif
 
 void ui_css_init(void) {
-    ui_gtk_css_provider = gtk_css_provider_new();
+    ui_add_styledata(ui_gtk_css, -1);
+}
+
+void ui_add_styledata(const char *styledata, int len) {
+    GtkCssProvider *css = gtk_css_provider_new();
     
 #ifdef UI_GTK3
-    gtk_css_provider_load_from_data(ui_gtk_css_provider, ui_gtk_css, -1, NULL);
+    gtk_css_provider_load_from_data(css, styledata, len, NULL);
     
     GdkScreen *screen = gdk_screen_get_default();
     gtk_style_context_add_provider_for_screen(
             screen,
-            GTK_STYLE_PROVIDER(ui_gtk_css_provider),
+            GTK_STYLE_PROVIDER(css),
             GTK_STYLE_PROVIDER_PRIORITY_USER);
 #endif /* UI_GTK3 */
     
@@ -431,13 +433,20 @@ void ui_css_init(void) {
     
     
 #if GTK_MINOR_VERSION < 12
-    gtk_css_provider_load_from_data(ui_gtk_css_provider, ui_gtk_css, -1);
+    gtk_css_provider_load_from_data(css, styledata, len);
 #else
-    gtk_css_provider_load_from_string(ui_gtk_css_provider, ui_gtk_css);
+    if(len < 0) {
+        gtk_css_provider_load_from_string(css, ui_gtk_css);
+    } else {
+        GBytes *style_data = g_bytes_new(styledata, len);
+        gtk_css_provider_load_from_bytes(css, style_data);
+        g_bytes_unref(style_data);
+        
+    }
 #endif /* GTK_MINOR_VERSION < 12 */
     
     GdkDisplay *display = gdk_display_get_default();
-    gtk_style_context_add_provider_for_display(display, GTK_STYLE_PROVIDER(ui_gtk_css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    gtk_style_context_add_provider_for_display(display, GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
     
 #endif /* UI_GTK4 */
 }
index 62e82bcc3fc5951ef54172f1baa0b3d4e0578905..b98bb25fd6b3187b87e55af753e9ed57275290db 100644 (file)
@@ -74,6 +74,8 @@ extern "C" {
 #define ICON_IMAGE(icon) gtk_image_new_from_icon_name(icon)
 #define LISTBOX_REMOVE(listbox, row) gtk_list_box_remove(GTK_LIST_BOX(listbox), row)
 #define LISTBOX_ROW_SET_CHILD(row, child) gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(row), child)
+#define PANED_SET_CHILD1(paned, child) gtk_paned_set_start_child(GTK_PANED(paned), child)
+#define PANED_SET_CHILD2(paned, child) gtk_paned_set_end_child(GTK_PANED(paned), child)
 #else
 #define WINDOW_SHOW(window) gtk_widget_show_all(window)
 #define WINDOW_DESTROY(window) gtk_widget_destroy(window)
@@ -94,6 +96,8 @@ extern "C" {
 #define ICON_IMAGE(icon) gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_BUTTON)
 #define LISTBOX_REMOVE(listbox, row) gtk_container_remove(GTK_CONTAINER(listbox), row)
 #define LISTBOX_ROW_SET_CHILD(row, child) gtk_container_add(GTK_CONTAINER(row), child)
+#define PANED_SET_CHILD1(paned, child) gtk_paned_pack1(GTK_PANED(paned), child, TRUE, TRUE)
+#define PANED_SET_CHILD2(paned, child) gtk_paned_pack2(GTK_PANED(paned), child, TRUE, TRUE)
 #endif
     
 #ifdef UI_GTK2
index 437e36084e27740b2d4c5c7a699f1557615e0047..f3d3c62cb6928649c7c81bdda4bafbb5facd4fd7 100644 (file)
@@ -447,6 +447,8 @@ typedef struct UiCondVar {
 UIEXPORT void ui_init(const char *appname, int argc, char **argv);
 UIEXPORT const char* ui_appname();
 
+UIEXPORT void ui_add_styledata(const char *styledata, int len);
+
 UIEXPORT UiContext* ui_global_context(void);
 
 UIEXPORT void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);
index 589d2a1fddd10daff42f17e080a61f06f2e92801..9d8ebba64b5e91728d8edc06ff373fef5fcaf76b 100644 (file)
@@ -118,6 +118,8 @@ struct UiListArgs {
     UiList* list;
     const char* varname;
     UiModel* model;
+    char **static_elements;
+    size_t static_nelm;
     ui_getvaluefunc getvalue;
     ui_callback onactivate;
     void* onactivatedata;