added menu accelerators

Wed, 02 Apr 2014 09:59:38 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 02 Apr 2014 09:59:38 +0200
changeset 18
06be29a56f8b
parent 17
db95c0104937
child 19
f8f22eb0b575

added menu accelerators

application/main.c file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/gtk/window.c file | annotate | diff | comparison | revisions
ui/motif/menu.c file | annotate | diff | comparison | revisions
ui/motif/stock.c file | annotate | diff | comparison | revisions
ui/motif/stock.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/application/main.c	Wed Apr 02 09:59:38 2014 +0200
@@ -112,8 +112,8 @@
     ui_list_append(list, "main.c");
     
     ui_menu("File");
-    ui_menuitem("New", action_new, NULL);
-    ui_menuitem("Open", action_open, NULL);
+    ui_menuitem_st(UI_STOCK_NEW, action_new, NULL);
+    ui_menuitem_st(UI_STOCK_OPEN, action_open, NULL);
     ui_menuseparator();
     ui_menuitem("Dokument 1", action_doc1, NULL);
     ui_menuitem("Dokument 2", action_doc2, NULL);
@@ -121,7 +121,7 @@
     ui_menuseparator();
     ui_checkitem_nv("Check", "check1");
     //ui_checkitem("Check", action_open, NULL);
-    ui_menuitem("Close", action_close, NULL);
+    ui_menuitem_st(UI_STOCK_CLOSE, action_close, NULL);
     void ui_menuseparator();
     ui_menuitem_list(list, action_document, list);
     
--- a/ui/common/context.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/common/context.c	Wed Apr 02 09:59:38 2014 +0200
@@ -42,6 +42,11 @@
     ctx->toplevel = toplevel;
     ctx->vars = ucx_map_new_a(mp->allocator, 16);
     
+#ifdef UI_GTK
+    ctx->accel_group = gtk_accel_group_new();
+    gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group);
+#endif
+    
     return ctx;
 }
 
--- a/ui/common/context.h	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/common/context.h	Wed Apr 02 09:59:38 2014 +0200
@@ -40,9 +40,13 @@
 typedef struct UiVar UiVar;
 
 struct UiContext {
-    UiObject     *toplevel;
-    UcxMempool   *mempool;
-    UcxMap       *vars; // key: char*  value: UiVar*
+    UiObject      *toplevel;
+    UcxMempool    *mempool;
+    UcxMap        *vars; // key: char*  value: UiVar*
+    
+#ifdef UI_GTK
+    GtkAccelGroup *accel_group;
+#endif
 };
 
 struct UiVar {
--- a/ui/gtk/menu.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/gtk/menu.c	Wed Apr 02 09:59:38 2014 +0200
@@ -95,6 +95,22 @@
     cm->items = ucx_list_append(cm->items, item);
 }
 
+void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) {
+    if(!current) {
+        return;
+    }
+    
+    UiStMenuItem *item = malloc(sizeof(UiStMenuItem));
+    item->item.add_to = (ui_menu_add_f)add_menuitem_st_widget;
+    
+    item->stockid = stockid;
+    item->userdata = userdata;
+    item->callback = f;
+    
+    UiMenu *cm = current->data;
+    cm->items = ucx_list_append(cm->items, item);
+}
+
 void ui_menuseparator() {
     if(!current) {
         return;
@@ -221,7 +237,7 @@
 {
     UiStMenuItem *i = (UiStMenuItem*)item;
     
-    GtkWidget *widget = gtk_image_menu_item_new_from_stock(i->stockid, NULL);
+    GtkWidget *widget = gtk_image_menu_item_new_from_stock(i->stockid, obj->ctx->accel_group);
     
     if(i->callback != NULL) {
         UiEventData *event = malloc(sizeof(UiEventData));
--- a/ui/gtk/window.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/gtk/window.c	Wed Apr 02 09:59:38 2014 +0200
@@ -56,10 +56,10 @@
 
 UiObject* ui_window(char *title, void *window_data) {
     UcxMempool *mp = ucx_mempool_new(256);
-    UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject));
+    UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject));  
+    obj->widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     obj->ctx = uic_context(obj, mp);
     
-    obj->widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     if(title != NULL) {
         gtk_window_set_title(GTK_WINDOW(obj->widget), title);
     }
--- a/ui/motif/menu.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/motif/menu.c	Wed Apr 02 09:59:38 2014 +0200
@@ -32,6 +32,7 @@
 #include "menu.h"
 #include "button.h"
 #include "toolkit.h"
+#include "stock.h"
 #include "../common/context.h"
 #include "../ui/window.h"
 
@@ -94,6 +95,22 @@
     cm->items = ucx_list_append(cm->items, item);
 }
 
+void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) {
+    if(!current) {
+        return;
+    }
+    
+    UiStMenuItem *item = malloc(sizeof(UiStMenuItem));
+    item->item.add_to = (ui_menu_add_f)add_menuitem_st_widget;
+    
+    item->stockid = stockid;
+    item->userdata = userdata;
+    item->callback = f;
+    
+    UiMenu *cm = current->data;
+    cm->items = ucx_list_append(cm->items, item);
+}
+
 void ui_menuseparator() {
     if(!current) {
         return;
@@ -230,6 +247,61 @@
     return 1;
 }
 
+int add_menuitem_st_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) {
+    UiStMenuItem *mi = (UiStMenuItem*)item;
+    
+    UiStockItem *si = ui_get_stock_item(mi->stockid);
+    if(!si) {
+        fprintf(stderr, "UI Error: unknown stock id: %s\n", mi->stockid);
+        return 0;
+    }
+    
+    int n = 0;
+    Arg args[4];
+    XmString label = XmStringCreateLocalized(si->label);
+    XmString at = NULL;
+    
+    XtSetArg(args[n], XmNlabelString, label);
+    n++;
+    if(si->accelerator) {
+        XtSetArg(args[n], XmNaccelerator, si->accelerator);
+        n++;
+    }
+    if(si->accelerator_label) {
+        at = XmStringCreateLocalized(si->accelerator_label);
+        XtSetArg(args[n], XmNacceleratorText, at);
+        n++;
+    }
+    
+    Widget mitem = XtCreateManagedWidget(
+            "menubutton",
+            xmPushButtonWidgetClass,
+            parent,
+            args,
+            n);
+    XmStringFree(label);
+    if(at) {
+        XmStringFree(at);
+    }
+    
+    if(mi->callback != NULL) {
+        UiEventData *event = ucx_mempool_malloc(
+                obj->ctx->mempool,
+                sizeof(UiEventData));
+        event->obj = obj;
+        event->user_data = mi->userdata;
+        event->callback = mi->callback;
+        event->value = 0;
+        XtAddCallback(
+                mitem,
+                XmNactivateCallback,
+                (XtCallbackProc)ui_push_button_callback,
+                event);
+    }
+    
+    return 1;
+}
+
 int add_menuseparator_widget(
         Widget parent,
         int i,
--- a/ui/motif/stock.c	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/motif/stock.c	Wed Apr 02 09:59:38 2014 +0200
@@ -37,20 +37,22 @@
 void ui_stock_init() {
     stock_items = ucx_map_new(64);
     
-    ui_add_stock_item(UI_STOCK_NEW, "New", NULL);
-    ui_add_stock_item(UI_STOCK_OPEN, "Open", NULL);
-    ui_add_stock_item(UI_STOCK_SAVE, "Save", NULL);
-    ui_add_stock_item(UI_STOCK_SAVE_AS, "Save as ...", NULL);
-    ui_add_stock_item(UI_STOCK_CLOSE, "Close", NULL);
-    ui_add_stock_item(UI_STOCK_UNDO, "Undo", NULL);
-    ui_add_stock_item(UI_STOCK_REDO, "Redo", NULL);
-    ui_add_stock_item(UI_STOCK_GO_BACK, "Back", NULL);
-    ui_add_stock_item(UI_STOCK_GO_FORWARD, "Forward", NULL);
+    ui_add_stock_item(UI_STOCK_NEW, "New", "Ctrl<Key>N", "Ctrl+N", NULL);
+    ui_add_stock_item(UI_STOCK_OPEN, "Open", "Ctrl<Key>O", "Ctrl+O", NULL);
+    ui_add_stock_item(UI_STOCK_SAVE, "Save", "Ctrl<Key>S", "Ctrl+S", NULL);
+    ui_add_stock_item(UI_STOCK_SAVE_AS, "Save as ...", NULL, NULL, NULL);
+    ui_add_stock_item(UI_STOCK_CLOSE, "Close", "Ctrl<Key>W", "Ctrl+W", NULL);
+    ui_add_stock_item(UI_STOCK_UNDO, "Undo", "Ctrl<Key>Z", "Ctrl+Z", NULL);
+    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);
 }
 
-void ui_add_stock_item(char *id, char *label, void *icon) {
+void ui_add_stock_item(char *id, char *label, char *accelerator, char *accelerator_label, void *icon) {
     UiStockItem *i = malloc(sizeof(UiStockItem));
     i->label = label;
+    i->accelerator = accelerator;
+    i->accelerator_label = accelerator_label;
     // TODO: icon
     
     ucx_map_cstr_put(stock_items, id, i);
--- a/ui/motif/stock.h	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/motif/stock.h	Wed Apr 02 09:59:38 2014 +0200
@@ -37,12 +37,14 @@
 
 typedef struct UiStockItem {
     char *label;
+    char *accelerator;
+    char *accelerator_label;
     // TODO: icon
 } UiStockItem;
     
 void ui_stock_init();
 
-void ui_add_stock_item(char *id, char *label, void *icon);
+void ui_add_stock_item(char *id, char *label, char *accelerator, char *accelerator_label, void *icon);
 
 UiStockItem* ui_get_stock_item(char *id);
 
--- a/ui/ui/toolkit.h	Tue Apr 01 13:47:29 2014 +0200
+++ b/ui/ui/toolkit.h	Wed Apr 02 09:59:38 2014 +0200
@@ -42,6 +42,7 @@
 
 #include <gtk/gtk.h>
 #define UIWIDGET GtkWidget*
+#define UI_GTK
 
 #elif UI_MOTIF
 

mercurial