# HG changeset patch # User Olaf Wintermann # Date 1396527401 -7200 # Node ID bcf880b29bc363fd82842268dd7b78fd7113b805 # Parent 012418e7dc9046107ec7e405745b7283bd4e0a24 textarea automatically sets selection group (GTK, Motif) diff -r 012418e7dc90 -r bcf880b29bc3 application/main.c --- 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); diff -r 012418e7dc90 -r bcf880b29bc3 ui/gtk/text.c --- 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; diff -r 012418e7dc90 -r bcf880b29bc3 ui/gtk/text.h --- 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); diff -r 012418e7dc90 -r bcf880b29bc3 ui/motif/stock.c --- 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", "CtrlX", "Ctrl+X", NULL); + ui_add_stock_item(UI_STOCK_COPY, "Copy", "CtrlC", "Ctrl+C", NULL); + ui_add_stock_item(UI_STOCK_PASTE, "Paste", "CtrlV", "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) { diff -r 012418e7dc90 -r bcf880b29bc3 ui/motif/text.c --- 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; diff -r 012418e7dc90 -r bcf880b29bc3 ui/motif/text.h --- 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); diff -r 012418e7dc90 -r bcf880b29bc3 ui/ui/stock.h --- 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 diff -r 012418e7dc90 -r bcf880b29bc3 ui/ui/toolkit.h --- 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;