]> uap-core.de Git - note.git/commitdiff
implement paragraph style changes via dropdown menu
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 17 Mar 2025 11:23:18 +0000 (12:23 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 17 Mar 2025 11:23:18 +0000 (12:23 +0100)
15 files changed:
application/editor.h
application/gtk-text.c
application/note.c
application/note.h
application/window.c
application/window.h
ui/cocoa/container.m
ui/cocoa/objs.mk
ui/cocoa/text.h [new file with mode: 0644]
ui/cocoa/text.m [new file with mode: 0644]
ui/common/types.c
ui/gtk/list.c
ui/motif/button.c
ui/motif/list.c
ui/ui/tree.h

index 11c798f81e314c2fe51b5f155a4c3305d3dc4825..bab1836fa05e963ca0b550155eb4381d1f8c797b 100644 (file)
@@ -128,6 +128,7 @@ void editor_apply_styles(UiText *text, CxList /* MDDocStyleSection */ *styles);
 cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a);
 
 UiBool editor_set_style(UiText *text, const char *style, UiBool enabled);
+void editor_set_paragraph_style(UiText *text, const char *style);
 
 #ifdef __cplusplus
 }
index 4702038b8094739f460ec9cb63d6ad0d81d3a819..fb55168d654503faf22bbfbbf23f18da92a6d1a9 100644 (file)
@@ -123,17 +123,9 @@ static void editor_button_released_cb(
     }
 }
 
-static void editor_set_cursor_cb(
-        GtkTextBuffer *buffer,
-        const GtkTextIter *location,
-        GtkTextMark *mark,
-        NoteEditor *editor)
-{
-    const char *mark_name = gtk_text_mark_get_name(mark);
-    if(!mark_name || strcmp(mark_name, "insert")) {
-        return;
-    }
-    
+// update the paragraph style dropdown list to the style of the current
+// cursor position
+static void update_cursor_paragraph_style(NoteEditor *editor, GtkTextBuffer *buffer) {
     GtkTextIter pos;
     // get current tags
     // when the buffer has a selection, get the tags from the selection start
@@ -163,6 +155,20 @@ static void editor_set_cursor_cb(
     }
 }
 
+static void editor_set_cursor_cb(
+        GtkTextBuffer *buffer,
+        const GtkTextIter *location,
+        GtkTextMark *mark,
+        NoteEditor *editor)
+{
+    const char *mark_name = gtk_text_mark_get_name(mark);
+    if(!mark_name || strcmp(mark_name, "insert")) {
+        return;
+    }
+    
+    update_cursor_paragraph_style(editor, buffer);
+}
+
 void editor_try_follow_link(NoteEditor *editor, GtkTextIter *pos) {
     GSList *tags = gtk_text_iter_get_tags(pos);
     while(tags) {
@@ -316,7 +322,7 @@ void init_tagtable(GtkTextTagTable *table) {
     gtk_text_tag_table_add(table, tag);
     
     tag = gtk_text_tag_new(EDITOR_STYLE_CODE_BLOCK);
-    g_object_set(tag, "family", "Monospace", "paragraph-background", "#080808", NULL);
+    g_object_set(tag, "family", "Monospace", "paragraph-background", "#efefef", NULL);
     g_object_set_data(G_OBJECT(tag), "set_style", (void*)tagstyle_codeblock);
     gtk_text_tag_table_add(table, tag);
     
@@ -514,3 +520,48 @@ UiBool editor_set_style(UiText *text, const char *style, UiBool enabled) {
     
     return TRUE;
 }
+
+static void remove_paragraph_styles(GtkTextBuffer *buffer, GtkTextIter *begin, GtkTextIter *end) {
+    char *para[] = {
+        EDITOR_STYLE_PARAGRAPH,
+        EDITOR_STYLE_HEADING1,
+        EDITOR_STYLE_HEADING2,
+        EDITOR_STYLE_HEADING3,
+        EDITOR_STYLE_HEADING4,
+        EDITOR_STYLE_HEADING5,
+        EDITOR_STYLE_HEADING6,
+        EDITOR_STYLE_QUOTE,
+        EDITOR_STYLE_CODE_BLOCK,
+        NULL
+    };
+    
+    for(int i=0;para[i] != NULL;i++) {
+        gtk_text_buffer_remove_tag_by_name(buffer, para[i], begin, end);
+    }
+}
+
+void editor_set_paragraph_style(UiText *text, const char *style) {
+    GtkTextBuffer *buffer = text->data1;
+    NoteEditor *editor = g_object_get_data(text->obj, "editor");
+    
+    // currently changing the selection's paragraph style is not supported
+    if(gtk_text_buffer_get_has_selection(buffer)) {
+        update_cursor_paragraph_style(editor, buffer);
+        return;
+    }
+    
+    GtkTextMark *cursor = gtk_text_buffer_get_insert(buffer);
+    if(!cursor) {
+        fprintf(stderr, "Error: no insert mark\n");
+        return;
+    }
+    GtkTextIter pos;
+    gtk_text_buffer_get_iter_at_mark(buffer, &pos, cursor);
+    GtkTextIter begin = pos;
+    GtkTextIter end = pos;
+    gtk_text_iter_set_line_offset(&begin, 0);
+    gtk_text_iter_forward_to_line_end(&end);
+    
+    remove_paragraph_styles(buffer, &begin, &end);
+    gtk_text_buffer_apply_tag_by_name(buffer, style, &begin, &end);
+}
index 4f3bd3cd0f7e3fb87ce3cf09b9db141042da5baa..24ae291a98e7557cc511ea9a6c9fe3a08cb09df0 100644 (file)
 #include "store.h"
 #include "editor.h"
 
+static TextNoteParagraphStyles paragraph_styles[] = {
+    { "Paragraph", EDITOR_STYLE_PARAGRAPH },
+    { "Code", EDITOR_STYLE_CODE_BLOCK },
+    { "Blockquote", EDITOR_STYLE_QUOTE },
+    { "Heading 1", EDITOR_STYLE_HEADING1 },
+    { "Heading 2", EDITOR_STYLE_HEADING2 },
+    { "Heading 3", EDITOR_STYLE_HEADING3 },
+    { "Heading 4", EDITOR_STYLE_HEADING4 },
+    { "Heading 5", EDITOR_STYLE_HEADING5 },
+    { "Heading 6", EDITOR_STYLE_HEADING6 }
+};
+
+static size_t num_paragraph_styles = 9;
+
 NoteModel *notemodel_current(UiObject *obj) {
     MainWindow *win = obj->window;
     if(win->current_notebook && win->current_notebook->current_note) {
@@ -55,15 +69,9 @@ NoteModel* notemodel_create(const CxAllocator *note_allocator) {
     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");
+    for(int i=0;i<num_paragraph_styles;i++) {
+        ui_list_append(model->textnote_para, (void*)paragraph_styles[i].label);
+    }
     
     model->textnote_strong = ui_int_new(model->ctx, "note_textnote_strong");
     model->textnote_emphasis = ui_int_new(model->ctx, "note_textnote_emphasis");
@@ -137,6 +145,16 @@ void note_update_current_style(NoteModel *note, MDActiveStyles *style) {
     ui_set(note->textnote_code, style->code);
 }
 
+void note_set_paragraph_type(NoteModel *note, int style) {
+    if(style < 0 || style >= num_paragraph_styles) {
+        fprintf(stderr, "Invalid paragraph style %d\n", style);
+        return;
+    }
+    
+    const char *style_name = paragraph_styles[style].style;
+    editor_set_paragraph_style(note->text, style_name);
+}
+
 void note_text_style_set_strong(NoteModel *note, UiBool enabled) {
     if(!editor_set_style(note->text, EDITOR_STYLE_STRONG, enabled)) {
         ui_set(note->textnote_strong, !enabled);
index 8e2bce86166c27a6bd066629e7bb35d8b2ab4661..fcaab320b9d7cc29ddd39a0eb24ca95a90e2e87d 100644 (file)
 extern "C" {
 #endif
 
+typedef struct TextNoteParagraphStyles {
+    const char *label;
+    const char *style;
+} TextNoteParagraphStyles;
+    
 NoteModel *notemodel_current(UiObject *obj);
     
 NoteModel* notemodel_create(const CxAllocator *note_allocator);
@@ -48,6 +53,7 @@ void note_save(UiObject *obj, NotebookModel *notebook, Note *note);
 
 void note_update_current_style(NoteModel *note, MDActiveStyles *style);
 
+void note_set_paragraph_type(NoteModel *note, int style);
 void note_text_style_set_strong(NoteModel *note, UiBool enabled);
 void note_text_style_set_emphasis(NoteModel *note, UiBool enabled);
 void note_text_style_set_underline(NoteModel *note, UiBool enabled);
index 6a4d0e305a1737696c11de3cb6594b188b5fa448..779a6cc3d9432d1bebbe4abcac93fd395a75b955 100644 (file)
@@ -75,7 +75,7 @@ void window_create() {
                         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_combobox(obj, .varname = "note_textnote_para", .onactivate = action_textnote_paragraph);
                         ui_togglebutton(obj, .icon = "format-text-bold", .varname = "note_textnote_strong", .onchange = action_textnote_style_strong);
                         ui_togglebutton(obj, .icon = "format-text-italic", .varname = "note_textnote_emphasis", .onchange = action_textnote_style_emphasis);
                         ui_togglebutton(obj, .icon = "format-text-underline", .varname = "note_textnote_underline", .onchange = action_textnote_style_underline);
@@ -343,3 +343,14 @@ void action_textnote_style_code(UiEvent *event, void *userdata) {
         note_text_style_set_code(notebook->current_note->model, event->intval);
     }
 }
+
+void action_textnote_paragraph(UiEvent *event, void *userdata) {
+    if(event->set) {
+        return;
+    }
+    MainWindow *window = event->window;
+    NotebookModel *notebook = window->current_notebook;
+    if(notebook && notebook->current_note && notebook->current_note->model) {
+        note_set_paragraph_type(notebook->current_note->model, event->intval);
+    }
+}
index ed470acbc5fb6551f66671455cbe5a38499c45d6..bb21ee1a30a126f6f3e9644f18591e574558ed68 100644 (file)
@@ -56,6 +56,7 @@ void action_notebook_selected(UiEvent *event, void *userdata);
 void action_note_selected(UiEvent *event, void *userdata);
 void action_note_activated(UiEvent *event, void *userdata);
 
+void action_textnote_paragraph(UiEvent *event, void *userdata);
 void action_textnote_style_strong(UiEvent *event, void *userdata);
 void action_textnote_style_emphasis(UiEvent *event, void *userdata);
 void action_textnote_style_underline(UiEvent *event, void *userdata);
index 9dc596544f68863411cdbfae2b9636bfe328160a..99b18c937ed00ab442ad94e49d3311456a072759 100644 (file)
     if(self.orientation == NSUserInterfaceLayoutOrientationHorizontal) {
         [view.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = YES;
         if(!fill) {
-            [view.widthAnchor constraintEqualToConstant:view.intrinsicContentSize.width].active = YES;
+            NSSize isize = view.intrinsicContentSize;
+            [view.widthAnchor constraintEqualToConstant:isize.width].active = YES;
         }
     } else {
         [view.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
         if(!fill) {
-            [view.heightAnchor constraintEqualToConstant:view.intrinsicContentSize.height].active = YES;
+            NSSize isize = view.intrinsicContentSize;
+            NSRect frame = view.frame;
+            CGFloat height = isize.height > 0 ? isize.height : frame.size.height;
+            if(height == 0) {
+                printf("debug");
+            }
+            if(height > 0) {
+                [view.heightAnchor constraintEqualToConstant:height].active = YES;
+            }
         }
     }
     
index 80f882a9d83934c424c1f6c38149ead76f9c6988..9324579ceda02dc59e1491fccf6db3a7af9a0c6b 100644 (file)
@@ -39,6 +39,7 @@ COCOAOBJ += WindowManager.o
 COCOAOBJ += window.o
 COCOAOBJ += Container.o
 COCOAOBJ += button.o
+COCOAOBJ += text.o
 
 TOOLKITOBJS += $(COCOAOBJ:%=$(COCOA_OBJPRE)%)
 TOOLKITSOURCE += $(COCOAOBJ:%.o=cocoa/%.m)
diff --git a/ui/cocoa/text.h b/ui/cocoa/text.h
new file mode 100644 (file)
index 0000000..9bd685f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 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.
+ */
+
+#import "toolkit.h"
+
+#import "../ui/text.h"
+
diff --git a/ui/cocoa/text.m b/ui/cocoa/text.m
new file mode 100644 (file)
index 0000000..74d6a79
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 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.
+ */
+
+#import "text.h"
+#import "EventData.h"
+#import "Container.h"
+#import <objc/runtime.h>
+
+UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) {
+    //NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:(NSRect){ 0, 0, 40, 40}];
+    NSTextView *textview = [[NSTextView alloc] initWithFrame:(NSRect){ 0, 0, 40, 40}];
+    //scrollview.documentView = textview;
+    
+    UiLayout layout = UI_INIT_LAYOUT(args);
+    ui_container_add(obj, textview, &layout, TRUE);
+    
+    return (__bridge void*)textview;
+}
index 1fdb1b9d13c98bcac663968540d4c69e9b781a5b..dc8d5c3fca3551f49b9e57cbbd58979ea744d126 100644 (file)
@@ -625,7 +625,6 @@ void uic_list_register_observer_destructor(UiContext *ctx, UiList *list, UiObser
     cxMempoolSetDestructor(destr, (cx_destructor_func)observer_destructor);
 }
 
-
 static int ui_set_op = 0;
 
 void ui_setop_enable(int set) {
@@ -635,4 +634,3 @@ void ui_setop_enable(int set) {
 int ui_get_setop(void) {
     return ui_set_op;
 }
-
index 5d7f5191fc83eb92c7fbbdcae84d562d6ed5348e..cd276386e2dc6ea07b3899f296f43c34da10054a 100644 (file)
@@ -352,6 +352,15 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
     return view;
 }
 
+void ui_listview_select(UIWIDGET listview, int index) {
+    GtkSelectionModel *model = gtk_list_view_get_model(GTK_LIST_VIEW(listview));
+    gtk_selection_model_select_item(model, index, TRUE);
+}
+    
+void ui_combobox_select(UIWIDGET dropdown, int index) {
+    gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), index);
+}
+
 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
     UiObject* current = uic_current_obj(obj);
     
@@ -465,6 +474,7 @@ static void listview_event(ui_callback cb, void *cbdata, UiListView *view) {
     event.window = event.obj->window;
     event.intval = view->selection.count;
     event.eventdata = &view->selection;
+    event.set = ui_get_setop();
     if(cb) {
         cb(&event, cbdata);
     }
@@ -507,6 +517,7 @@ void ui_dropdown_notify(GtkWidget *dropdown, GObject *pspec, gpointer userdata)
         event.window = event.obj->window;
         event.intval = index;
         event.eventdata = eventdata->data;
+        event.set = ui_get_setop();
         view->onactivate(&event, view->onactivatedata);
     }
 }
@@ -543,6 +554,7 @@ void ui_dropdown_activate(GtkDropDown* self, gpointer userdata) {
         event.window = event.obj->window;
         event.intval = view->selection.count;
         event.eventdata = &view->selection;
+        event.set = ui_get_setop();
         view->onactivate(&event, view->onactivatedata);
     }
 }
@@ -580,6 +592,7 @@ UiListSelection ui_listview_getselection2(UiList *list) {
 }
 
 void ui_listview_setselection2(UiList *list, UiListSelection selection) {
+    ui_setop_enable(TRUE);
     UiListView *view = list->obj;
     UiListSelection newselection;
     newselection.count = view->selection.count;
@@ -598,6 +611,7 @@ void ui_listview_setselection2(UiList *list, UiListSelection selection) {
             gtk_selection_model_select_item(view->selectionmodel, selection.rows[i], FALSE);
         }
     }
+    ui_setop_enable(FALSE);
 }
 
 UiListSelection ui_combobox_getselection(UiList *list) {
@@ -613,12 +627,14 @@ UiListSelection ui_combobox_getselection(UiList *list) {
 }
 
 void ui_combobox_setselection(UiList *list, UiListSelection selection) {
+    ui_setop_enable(TRUE);
     UiListView *view = list->obj;
     if(selection.count > 0) {
         gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), selection.rows[0]);
     } else {
         gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), GTK_INVALID_LIST_POSITION);
     }
+    ui_setop_enable(FALSE);
 }
 
 #else
@@ -842,6 +858,17 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs args) {
     return scroll_area;
 }
 
+void ui_listview_select(UIWIDGET listview, int index) {
+    GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview));
+    GtkTreePath *path = gtk_tree_path_new_from_indicesv(&index, 1);
+    gtk_tree_selection_select_path(sel, path);
+    //g_object_unref(path);
+}
+    
+void ui_combobox_select(UIWIDGET dropdown, int index) {
+    gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), index);
+}
+
 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
     UiObject* current = uic_current_obj(obj);
     
@@ -1026,11 +1053,13 @@ UiListSelection ui_listview_getselection(UiList *list) {
 }
 
 void ui_listview_setselection(UiList *list, UiListSelection selection) {
+    ui_setop_enable(TRUE);
     UiListView *view = list->obj;
     GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view->widget));
     GtkTreePath *path = gtk_tree_path_new_from_indicesv(selection.rows, selection.count);
     gtk_tree_selection_select_path(sel, path);
     //g_object_unref(path);
+    ui_setop_enable(FALSE);
 }
 
 
@@ -1117,6 +1146,7 @@ GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **
         event->callback = f;
         event->value = 0;
         event->customdata = uicbox;
+        event.set = ui_get_setop();
 
         g_signal_connect(
                 combobox,
@@ -1145,6 +1175,7 @@ void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e) {
     event.document = event.obj->ctx->document;
     event.eventdata = eventdata;
     event.intval = index;
+    event.set = ui_get_setop();
     e->callback(&event, e->userdata);
 }
 
@@ -1165,10 +1196,12 @@ UiListSelection ui_combobox_getselection(UiList *list) {
 }
 
 void ui_combobox_setselection(UiList *list, UiListSelection selection) {
+    ui_setop_enable(TRUE);
     UiListView *combobox = list->obj;
     if(selection.count > 0) {
         gtk_combo_box_set_active(GTK_COMBO_BOX(combobox->widget), selection.rows[0]);
     }
+    ui_setop_enable(FALSE);
 }
 
 
@@ -1190,6 +1223,7 @@ void ui_listview_activate_event(
     e.document = event->obj->ctx->document;
     e.eventdata = &selection;
     e.intval = selection.count > 0 ? selection.rows[0] : -1;
+    e.set = ui_get_setop();
     event->activate(&e, event->activatedata);
     
     if(selection.count > 0) {
@@ -1209,6 +1243,7 @@ void ui_listview_selection_event(
     e.document = event->obj->ctx->document;
     e.eventdata = &selection;
     e.intval = selection.count > 0 ? selection.rows[0] : -1;
+    e.set = ui_get_setop();
     event->selection(&e, event->selectiondata);
     
     if(selection.count > 0) {
@@ -1267,6 +1302,7 @@ static GdkContentProvider *ui_listview_dnd_prepare(GtkDragSource *source, double
         event.document = event.obj->ctx->document;
         event.eventdata = dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondragstart(&event, listview->ondragstartdata);
     }
     
@@ -1302,6 +1338,7 @@ static void ui_listview_drag_end(GtkDragSource *self, GdkDrag *drag, gboolean de
         event.document = event.obj->ctx->document;
         event.eventdata = &dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondragcomplete(&event, listview->ondragcompletedata);
     }
 }
@@ -1330,6 +1367,7 @@ static gboolean ui_listview_drop(
         event.document = event.obj->ctx->document;
         event.eventdata = &dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondrop(&event, listview->ondropdata);
     }
     
@@ -1392,6 +1430,7 @@ static void ui_listview_drag_getdata(
         event.document = event.obj->ctx->document;
         event.eventdata = &dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondragstart(&event, listview->ondragstartdata);
     }
 }
@@ -1416,6 +1455,7 @@ static void ui_listview_drag_end(
         event.document = event.obj->ctx->document;
         event.eventdata = &dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondragcomplete(&event, listview->ondragcompletedata);
     }
 }
@@ -1461,6 +1501,7 @@ static void ui_listview_drag_data_received(
         event.document = event.obj->ctx->document;
         event.eventdata = &dnd;
         event.intval = 0;
+        event.set = ui_get_setop();
         listview->ondrop(&event, listview->ondropdata);
     }
 }
@@ -1933,6 +1974,7 @@ void ui_listbox_row_activate(GtkListBox *self, GtkListBoxRow *row, gpointer user
     event.document = event.obj->ctx->document;
     event.eventdata = &eventdata;
     event.intval = data->value0;
+    event.set = ui_get_setop();
     
     if(data->callback) {
         data->callback(&event, data->userdata);
index ff5421cf56d40ca33ab8d31cd1deb95a1d3e18e8..6ca74adf6c2c90de3b5ec68e1f0826d936f80195 100644 (file)
@@ -92,6 +92,7 @@ void ui_push_button_callback(Widget widget, UiEventData *event, XtPointer d) {
     e.window = event->obj->window;
     e.document = event->obj->ctx->document;
     e.intval = event->value;
+    e.set = 0;
     event->callback(&e, event->userdata);
 }
 
@@ -173,6 +174,7 @@ static void togglebutton_changed(Widget w, UiVarEventData *event, XmToggleButton
     e.document = e.obj->ctx->document;
     e.eventdata = NULL;
     e.intval = XmToggleButtonGetState(w);
+    e.set = ui_get_setop();
     
     if(event->callback) {
         event->callback(&e, event->userdata);
@@ -281,6 +283,7 @@ static void radiobutton_changed(Widget w, UiVarEventData *event, XmToggleButtonC
     e.document = e.obj->ctx->document;
     e.eventdata = value;
     e.intval = v;
+    e.set = ui_get_setop();
     
     if(event->callback) {
         event->callback(&e, event->userdata);
index 2bdc35f77dc117147a500519627b34f64b9172a3..5da5a0b4d38c5d3d369a37fd268e39c9ec9d8646 100644 (file)
@@ -186,11 +186,13 @@ UiListSelection ui_listview_getselection(UiList *list) {
 }
 
 void ui_listview_setselection(UiList *list, UiListSelection selection) {
+    ui_setop_enable(TRUE);
     UiListView *listview = list->obj;
     XmListDeselectAllItems(listview->widget);
     for(int i=0;i<selection.count;i++) {
         XmListSelectPos(listview->widget, selection.rows[i]+1, False);
     }
+    ui_setop_enable(FALSE);
 }
 
 void* ui_strmodel_getvalue(void *elm, int column) {
index 9d8ebba64b5e91728d8edc06ff373fef5fcaf76b..8217cf601512b023957c91817430d0cbfbc483d1 100644 (file)
@@ -251,6 +251,9 @@ UIEXPORT UIWIDGET ui_table_create(UiObject* obj, UiListArgs args);
 UIEXPORT UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args);
 UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args);
 
+UIEXPORT void ui_listview_select(UIWIDGET listview, int index);
+UIEXPORT void ui_combobox_select(UIWIDGET dropdown, int index);
+
 UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs args);