textarea automatically sets selection group (GTK, Motif)

Thu, 03 Apr 2014 14:16:41 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 03 Apr 2014 14:16:41 +0200
changeset 22
bcf880b29bc3
parent 21
012418e7dc90
child 23
decc6bf584aa

textarea automatically sets selection group (GTK, Motif)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/text.c file | annotate | diff | comparison | revisions
ui/gtk/text.h file | annotate | diff | comparison | revisions
ui/motif/stock.c file | annotate | diff | comparison | revisions
ui/motif/text.c file | annotate | diff | comparison | revisions
ui/motif/text.h file | annotate | diff | comparison | revisions
ui/ui/stock.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Thu Apr 03 11:12:22 2014 +0200
+++ b/application/main.c	Thu Apr 03 14:16:41 2014 +0200
@@ -104,6 +104,22 @@
     printf("selected document: %d\n", event->intval);
 }
 
+void action_cut(UiEvent *event, void *data) {
+    printf("cut\n");
+}
+
+void action_copy(UiEvent *event, void *data) {
+    printf("copy\n");
+}
+
+void action_paste(UiEvent *event, void *data) {
+    printf("paste\n");
+}
+
+void action_delete(UiEvent *event, void *data) {
+    printf("delete\n");
+}
+
 
 int main(int argc, char** argv) {
     ui_init("app1", argc, argv);
@@ -132,6 +148,12 @@
     ui_menuseparator();
     ui_menuitem_st(UI_STOCK_CLOSE, action_close, NULL);
     
+    ui_menu("Edit");
+    ui_menuitem_stgr(UI_STOCK_CUT, action_cut, NULL, UI_GROUP_SELECTION, -1);
+    ui_menuitem_stgr(UI_STOCK_COPY, action_copy, NULL, UI_GROUP_SELECTION, -1);
+    ui_menuitem_st(UI_STOCK_PASTE, action_paste, NULL);
+    ui_menuitem_stgr(UI_STOCK_DELETE, action_delete, NULL, UI_GROUP_SELECTION, -1);
+    
     
     ui_toolitem_st("new", UI_STOCK_NEW, action_new, NULL);
     ui_toolitem_st("open", UI_STOCK_GO_BACK, action_open, NULL);
--- a/ui/gtk/text.c	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/gtk/text.c	Thu Apr 03 14:16:41 2014 +0200
@@ -33,14 +33,47 @@
 #include "text.h"
 #include "container.h"
 
+static void selection_handler(
+        GtkTextBuffer *buf,
+        GtkTextIter *location,
+        GtkTextMark *mark,
+        UiTextArea *textview)
+{
+    const char *mname = gtk_text_mark_get_name(mark);
+    if(mname) {
+        GtkTextIter begin;
+        GtkTextIter end;
+        int sel = gtk_text_buffer_get_selection_bounds (buf, &begin, &end);
+        if(sel != textview->last_selection_state) {
+            if(sel) {
+                ui_set_group(textview->ctx, UI_GROUP_SELECTION);
+            } else {
+                ui_unset_group(textview->ctx, UI_GROUP_SELECTION);
+            }
+        }
+        textview->last_selection_state = sel;
+    }
+}
+
 UIWIDGET ui_textarea(UiObject *obj, UiText *value) {
     GtkWidget *text_area = gtk_text_view_new();
     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR);
     g_signal_connect(
-                text_area,
-                "realize",
-                G_CALLBACK(ui_textarea_realize_event),
-                NULL);
+            text_area,
+            "realize",
+            G_CALLBACK(ui_textarea_realize_event),
+            NULL);
+    g_signal_connect(
+            text_area,
+            "selection-clear-event",
+            G_CALLBACK(selection_handler),
+            NULL);
+    
+    UiTextArea *uitext = ucx_mempool_malloc(
+            obj->ctx->mempool,
+            sizeof(UiTextArea));
+    uitext->ctx = obj->ctx;
+    uitext->last_selection_state = 0;
     
     GtkWidget *scroll_area = gtk_scrolled_window_new (NULL, NULL);
     gtk_scrolled_window_set_policy(
@@ -86,6 +119,12 @@
                 "delete-range",
                 G_CALLBACK(ui_textbuf_delete),
                 value);
+        
+        g_signal_connect(
+                buf,
+                "mark-set",
+                G_CALLBACK(selection_handler),
+                uitext);
     }
     
     return scroll_area;
--- a/ui/gtk/text.h	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/gtk/text.h	Thu Apr 03 14:16:41 2014 +0200
@@ -54,6 +54,11 @@
     int     event;
 } UiUndoMgr;
 
+typedef struct UiTextArea {
+    UiContext *ctx;
+    int last_selection_state;
+} UiTextArea;
+
 char* ui_textarea_get(UiText *text);
 void ui_textarea_set(UiText *text, char *str);
 char* ui_textarea_getsubstr(UiText *text, int begin, int end);
--- a/ui/motif/stock.c	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/motif/stock.c	Thu Apr 03 14:16:41 2014 +0200
@@ -46,6 +46,10 @@
     ui_add_stock_item(UI_STOCK_REDO, "Redo", NULL, NULL, NULL);
     ui_add_stock_item(UI_STOCK_GO_BACK, "Back", NULL, NULL, NULL);
     ui_add_stock_item(UI_STOCK_GO_FORWARD, "Forward", NULL, NULL, NULL);
+    ui_add_stock_item(UI_STOCK_CUT, "Cut", "Ctrl<Key>X", "Ctrl+X", NULL);
+    ui_add_stock_item(UI_STOCK_COPY, "Copy", "Ctrl<Key>C", "Ctrl+C", NULL);
+    ui_add_stock_item(UI_STOCK_PASTE, "Paste", "Ctrl<Key>V", "Ctrl+V", NULL);
+    ui_add_stock_item(UI_STOCK_DELETE, "Delete", NULL, NULL, NULL);
 }
 
 void ui_add_stock_item(char *id, char *label, char *accelerator, char *accelerator_label, void *icon) {
--- a/ui/motif/text.c	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/motif/text.c	Thu Apr 03 14:16:41 2014 +0200
@@ -46,6 +46,17 @@
     Widget text_area = XmCreateScrolledText(parent, "text_area", args, n);
     XtManageChild(text_area);
     
+    UiTextArea *uitext = ucx_mempool_malloc(
+            obj->ctx->mempool,
+            sizeof(UiTextArea));
+    uitext->ctx = obj->ctx;
+    uitext->last_selection_state = 0;
+    XtAddCallback(
+                text_area,
+                XmNmotionVerifyCallback,
+                (XtCallbackProc)ui_text_selection_callback,
+                uitext);
+    
     // bind value
     if(value) {
         value->set = ui_textarea_set;
@@ -114,6 +125,25 @@
     return mgr;
 }
 
+void ui_text_selection_callback(
+        Widget widget,
+        UiTextArea *textarea,
+        XtPointer data)
+{
+    long left = 0;
+    long right = 0;
+    XmTextGetSelectionPosition(widget, &left, &right);
+    int sel = left < right ? 1 : 0;
+    if(sel != textarea->last_selection_state) {
+        if(sel) {
+            ui_set_group(textarea->ctx, UI_GROUP_SELECTION);
+        } else {
+            ui_unset_group(textarea->ctx, UI_GROUP_SELECTION);
+        }
+    }
+    textarea->last_selection_state = sel;
+}
+
 void ui_text_modify_callback(Widget widget, UiText *value, XtPointer data) {
     XmTextVerifyCallbackStruct *txv = (XmTextVerifyCallbackStruct*)data;
     int type = txv->text->length > 0 ? UI_TEXTBUF_INSERT : UI_TEXTBUF_DELETE;
--- a/ui/motif/text.h	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/motif/text.h	Thu Apr 03 14:16:41 2014 +0200
@@ -53,6 +53,11 @@
     int     length;
     int     event;
 } UiUndoMgr;
+
+typedef struct UiTextArea {
+    UiContext *ctx;
+    int last_selection_state;
+} UiTextArea;
     
 char* ui_textarea_get(UiText *text);
 void ui_textarea_set(UiText *text, char *str);
@@ -60,6 +65,10 @@
 void ui_textarea_insert(UiText *text, int pos, char *str);
 
 UiUndoMgr* ui_create_undomgr();
+void ui_text_selection_callback(
+        Widget widget,
+        UiTextArea *textarea,
+        XtPointer data);
 void ui_text_modify_callback(Widget widget, UiText *value, XtPointer data);
 int ui_check_insertstr(char *oldstr, int oldlen, char *newstr, int newlen);
 void ui_free_textbuf_op(UiTextBufOp *op);
--- a/ui/ui/stock.h	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/ui/stock.h	Thu Apr 03 14:16:41 2014 +0200
@@ -43,13 +43,18 @@
 #define UI_STOCK_SAVE                   "uiSave"
 #define UI_STOCK_SAVE_AS                "uiSaveAs"
 #define UI_STOCK_REVERT_TO_SAVED        "uiRevertToSaved"
-#define UI_STOCK_UNDO                   "uiUndo"
-#define UI_STOCK_REDO                   "uiRedo"
 #define UI_STOCK_GO_BACK                "uiGoBack"
 #define UI_STOCK_GO_FORWARD             "uiGoForward"
 #define UI_STOCK_ADD                    "uiAdd"
 #define UI_STOCK_CLOSE                  "uiClose"
     
+#define UI_STOCK_UNDO                   "uiUndo"
+#define UI_STOCK_REDO                   "uiRedo"
+#define UI_STOCK_CUT                    "uiCut"
+#define UI_STOCK_COPY                   "uiCopy"
+#define UI_STOCK_PASTE                  "uiPaste"
+#define UI_STOCK_DELETE                 "uiDelete"
+    
 #endif
     
 #if UI_GTK2 || UI_GTK3
--- a/ui/ui/toolkit.h	Thu Apr 03 11:12:22 2014 +0200
+++ b/ui/ui/toolkit.h	Thu Apr 03 14:16:41 2014 +0200
@@ -55,6 +55,8 @@
 extern "C" {
 #endif
 
+#define UI_GROUP_SELECTION     20000
+    
 /* public types */
 typedef struct UiObject   UiObject;
 typedef struct UiEvent    UiEvent;

mercurial