tWindows client now supports menu keyboard shortcuts; Win2K "bank" bug (hopefully) fixed - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit c36da537a319cbf1fe6096f8ddf214655a298a66
(DIR) parent 00e4b2e2bdfc603f8ce07ec3b8b98c2cd6af22c1
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Sun, 21 Oct 2001 18:36:03 +0000
Windows client now supports menu keyboard shortcuts; Win2K "bank" bug (hopefully) fixed
Diffstat:
M src/gtkport.c | 133 ++++++++++++++++++++++++++-----
M src/gtkport.h | 9 +++++++--
2 files changed, 119 insertions(+), 23 deletions(-)
---
(DIR) diff --git a/src/gtkport.c b/src/gtkport.c
t@@ -219,6 +219,8 @@ static void gtk_window_set_initial_position(GtkWindow *window,
static void gtk_progress_bar_size_request(GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_progress_bar_realize(GtkWidget *widget);
+static gint gtk_accel_group_add(GtkAccelGroup *accel_group,ACCEL *newaccel);
+static void gtk_accel_group_set_id(GtkAccelGroup *accel_group,gint ind,gint ID);
typedef struct _GdkInput GdkInput;
t@@ -873,7 +875,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) {
gtk_option_menu_update_selection(widget);
} else if (lParam && HIWORD(wParam)==BN_CLICKED) {
gtk_signal_emit(GTK_OBJECT(widget),"clicked");
- } else if (HIWORD(wParam)==0) {
+ } else if (HIWORD(wParam)==0 || HIWORD(wParam)==1) {
window=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA));
widget=gtk_window_get_menu_ID(GTK_WINDOW(window),LOWORD(wParam));
if (widget) gtk_signal_emit(GTK_OBJECT(widget),"activate");
t@@ -1211,6 +1213,8 @@ void gtk_widget_create(GtkWidget *widget) {
void gtk_widget_destroy(GtkWidget *widget) {
if (!widget) return;
gtk_widget_lose_focus(widget);
+ if (widget->hWnd) DestroyWindow(widget->hWnd);
+ widget->hWnd=NULL;
// g_print("gtk_widget_destroy on widget %p\n",widget);
gtk_signal_emit(GTK_OBJECT(widget),"destroy");
// g_print("Freeing widget\n");
t@@ -1778,10 +1782,12 @@ void gtk_window_destroy(GtkWidget *widget) {
// g_print("gtk_window_destroy on widget %p\n",widget);
WindowList=g_slist_remove(WindowList,(gpointer)window);
gtk_container_destroy(widget);
- g_free(GTK_WINDOW(widget)->title);
+ if (window->accel_group) gtk_accel_group_destroy(window->accel_group);
+ if (window->hAccel) DestroyAcceleratorTable(window->hAccel);
+ g_free(window->title);
EnableParent(window);
- if (widget->hWnd) DestroyWindow(widget->hWnd);
- widget->hWnd=NULL;
+// if (widget->hWnd) DestroyWindow(widget->hWnd);
+// widget->hWnd=NULL;
}
void gtk_window_show(GtkWidget *widget) {
t@@ -1987,6 +1993,11 @@ void gtk_window_realize(GtkWidget *widget) {
gtk_set_default_font(widget->hWnd);
/* g_print("Window window %p created\n",widget->hWnd);*/
gtk_container_realize(widget);
+
+ if (win->accel_group && win->accel_group->numaccel) {
+ win->hAccel = CreateAcceleratorTable(win->accel_group->accel,
+ win->accel_group->numaccel);
+ }
// if (win->focus && win->focus->hWnd) SetFocus(win->focus->hWnd);
}
t@@ -2023,7 +2034,9 @@ void gtk_button_realize(GtkWidget *widget) {
GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS);
Parent=gtk_get_parent_hwnd(widget);
widget->hWnd = CreateWindow("BUTTON",but->text,
- WS_CHILD|WS_TABSTOP|BS_PUSHBUTTON,
+ WS_CHILD|WS_TABSTOP|
+ (GTK_WIDGET_FLAGS(widget)>K_IS_DEFAULT ?
+ BS_DEFPUSHBUTTON : BS_PUSHBUTTON),
widget->allocation.x,widget->allocation.y,
widget->allocation.width,widget->allocation.height,
Parent,NULL,hInst,NULL);
t@@ -2867,6 +2880,7 @@ void gtk_radio_button_toggled(GtkRadioButton *radio_button,gpointer data) {
GtkRadioButton *radio;
gboolean is_active = GTK_TOGGLE_BUTTON(radio_button)->toggled;
hWnd=GTK_WIDGET(radio_button)->hWnd;
+g_print("radio_button_toggled\n");
if (hWnd) {
SendMessage(hWnd,BM_SETCHECK,is_active ? BST_CHECKED : BST_UNCHECKED,0);
}
t@@ -2900,23 +2914,27 @@ void gtk_main() {
MSG msg;
GSList *list;
BOOL MsgDone;
- GtkWidget *widget;
+ GtkWidget *widget,*window;
HACCEL hAccel;
RecurseLevel++;
while (GetMessage(&msg,NULL,0,0)) {
MsgDone=FALSE;
- for (list=WindowList;list && !MsgDone;list=g_slist_next(list)) {
+ widget=GTK_WIDGET(GetWindowLong(msg.hwnd,GWL_USERDATA));
+ window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW);
+ if (window) {
+ hAccel=GTK_WINDOW(window)->hAccel;
+ if (hAccel) {
+ MsgDone=TranslateAccelerator(window->hWnd,hAccel,&msg);
+ }
+ }
+ if (!MsgDone) for (list=WindowList;list && !MsgDone;
+ list=g_slist_next(list)) {
widget=GTK_WIDGET(list->data);
if (widget && widget->hWnd &&
(MsgDone=IsDialogMessage(widget->hWnd,&msg))==TRUE) break;
}
- widget=GTK_WIDGET(GetWindowLong(msg.hwnd,GWL_USERDATA));
- if (!MsgDone && widget && GTK_OBJECT(widget)->klass==&GtkWindowClass) {
- hAccel=GTK_WINDOW(widget)->hAccel;
- if (hAccel) MsgDone=TranslateAccelerator(widget->hWnd,hAccel,&msg);
- }
if (!MsgDone) {
TranslateMessage(&msg);
DispatchMessage(&msg);
t@@ -3144,6 +3162,7 @@ GtkItemFactory *gtk_item_factory_new(GtkType container_type,
GtkItemFactory *new_fac;
new_fac=(GtkItemFactory *)GtkNewObject(&GtkItemFactoryClass);
new_fac->path=g_strdup(path);
+ new_fac->accel_group = accel_group;
new_fac->top_widget=gtk_menu_bar_new();
return new_fac;
}
t@@ -3166,14 +3185,14 @@ static gint PathCmp(const gchar *path1,const gchar *path2) {
static void gtk_item_factory_parse_path(GtkItemFactory *ifactory,
gchar *path,
GtkItemFactoryChild **parent,
- gchar **menu_title) {
+ GString *menu_title) {
GSList *list;
GtkItemFactoryChild *child;
- gchar *root,*pt,*title;
+ gchar *root,*pt;
pt=strrchr(path,'/');
if (!pt) return;
- title=g_strdup(pt+1);
+ g_string_assign(menu_title,pt+1);
root=g_strdup(path);
root[pt-path]='\0';
t@@ -3182,22 +3201,60 @@ static void gtk_item_factory_parse_path(GtkItemFactory *ifactory,
child=(GtkItemFactoryChild *)list->data;
if (PathCmp(child->path,root)==1) { *parent=child; break; }
}
- *menu_title=title;
g_free(root);
}
+static gboolean gtk_item_factory_parse_accel(GtkItemFactory *ifactory,
+ gchar *accelerator,
+ GString *menu_title,ACCEL *accel) {
+ gchar *apt;
+
+ if (!accelerator) return FALSE;
+
+ apt=accelerator;
+ accel->fVirt=0;
+ accel->key=0;
+ accel->cmd=0;
+
+ g_string_append(menu_title,"\t");
+
+ if (strncmp(apt,"<control>",9)==0) {
+ accel->fVirt |= FCONTROL;
+ g_string_append(menu_title,"Ctrl+");
+ apt+=9;
+ }
+
+ if (strlen(apt)==1) {
+ g_string_append_c(menu_title,*apt);
+ accel->key = *apt;
+ accel->fVirt |= FVIRTKEY;
+ } else if (strcmp(apt,"F1")==0) {
+ g_string_append(menu_title,apt);
+ accel->fVirt |= FVIRTKEY;
+ accel->key = VK_F1;
+ }
+ return (accel->key!=0);
+}
+
void gtk_item_factory_create_item(GtkItemFactory *ifactory,
GtkItemFactoryEntry *entry,
gpointer callback_data,guint callback_type) {
GtkItemFactoryChild *new_child,*parent=NULL;
- gchar *menu_title=NULL;
+ GString *menu_title;
GtkWidget *menu_item,*menu;
+ ACCEL accel;
+ gboolean haveaccel;
new_child=g_new0(GtkItemFactoryChild,1);
new_child->path=g_strdup(entry->path);
- gtk_item_factory_parse_path(ifactory,new_child->path,&parent,&menu_title);
- menu_item=gtk_menu_item_new_with_label(menu_title);
+ menu_title = g_string_new("");
+
+ gtk_item_factory_parse_path(ifactory,new_child->path,&parent,menu_title);
+ haveaccel = gtk_item_factory_parse_accel(ifactory,entry->accelerator,
+ menu_title,&accel);
+
+ menu_item=gtk_menu_item_new_with_label(menu_title->str);
new_child->widget=menu_item;
if (entry->callback) {
gtk_signal_connect(GTK_OBJECT(menu_item),"activate",
t@@ -3215,7 +3272,12 @@ void gtk_item_factory_create_item(GtkItemFactory *ifactory,
gtk_menu_bar_append(GTK_MENU_BAR(ifactory->top_widget),menu_item);
}
- g_free(menu_title);
+ if (haveaccel && ifactory->accel_group) {
+ GTK_MENU_ITEM(menu_item)->accelind=
+ gtk_accel_group_add(ifactory->accel_group,&accel);
+ }
+
+ g_string_free(menu_title,TRUE);
ifactory->children=g_slist_append(ifactory->children,new_child);
}
t@@ -3304,6 +3366,7 @@ GtkWidget *gtk_menu_item_new_with_label(const gchar *label) {
gint i;
menu_item=GTK_MENU_ITEM(GtkNewObject(&GtkMenuItemClass));
+ menu_item->accelind=-1;
menu_item->text=g_strdup(label);
for (i=0;i<strlen(menu_item->text);i++) {
if (menu_item->text[i]=='_') menu_item->text[i]='&';
t@@ -3357,13 +3420,21 @@ void gtk_menu_bar_realize(GtkWidget *widget) {
void gtk_menu_item_realize(GtkWidget *widget) {
GtkMenuItem *menu_item=GTK_MENU_ITEM(widget);
MENUITEMINFO mii;
- GtkWidget *menu_bar;
+ GtkWidget *menu_bar,*window;
HMENU parent_menu;
gint pos;
menu_bar=gtk_widget_get_ancestor(widget,GTK_TYPE_MENU_BAR);
if (menu_bar) menu_item->ID=GTK_MENU_BAR(menu_bar)->LastID++;
+ if (menu_item->accelind>=0) {
+ window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW);
+ if (window && GTK_WINDOW(window)->accel_group) {
+ gtk_accel_group_set_id(GTK_WINDOW(window)->accel_group,
+ menu_item->accelind,menu_item->ID);
+ }
+ }
+
if (menu_item->submenu) gtk_widget_realize(GTK_WIDGET(menu_item->submenu));
parent_menu=GTK_MENU_SHELL(widget->parent)->menu;
t@@ -3783,9 +3854,28 @@ gpointer gtk_object_get_data(GtkObject *object,const gchar *key) {
GtkAccelGroup *gtk_accel_group_new() {
GtkAccelGroup *new_accel;
new_accel=g_new0(GtkAccelGroup,1);
+ new_accel->accel = NULL;
+ new_accel->numaccel = 0;
return new_accel;
}
+gint gtk_accel_group_add(GtkAccelGroup *accel_group,ACCEL *newaccel) {
+ accel_group->numaccel++;
+ accel_group->accel = g_realloc(accel_group->accel,
+ accel_group->numaccel*sizeof(ACCEL));
+ memcpy(&accel_group->accel[accel_group->numaccel-1],newaccel,sizeof(ACCEL));
+ return (accel_group->numaccel-1);
+}
+
+void gtk_accel_group_set_id(GtkAccelGroup *accel_group,gint ind,gint ID) {
+ if (ind < accel_group->numaccel) accel_group->accel[ind].cmd = ID;
+}
+
+void gtk_accel_group_destroy(GtkAccelGroup *accel_group) {
+ g_free(accel_group->accel);
+ g_free(accel_group);
+}
+
void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory,
GtkTranslateFunc func,
gpointer data,
t@@ -3793,6 +3883,7 @@ void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory,
}
void gtk_widget_grab_default(GtkWidget *widget) {
+ GTK_WIDGET_SET_FLAGS(widget,GTK_IS_DEFAULT);
}
void gtk_widget_grab_focus(GtkWidget *widget) {
(DIR) diff --git a/src/gtkport.h b/src/gtkport.h
t@@ -99,7 +99,8 @@ typedef enum {
GTK_SENSITIVE = 1 << 10,
GTK_CAN_FOCUS = 1 << 11,
GTK_HAS_FOCUS = 1 << 12,
- GTK_CAN_DEFAULT = 1 << 13
+ GTK_CAN_DEFAULT = 1 << 13,
+ GTK_IS_DEFAULT = 1 << 14
} GtkWidgetFlags;
#define GTK_VISIBLE 1
t@@ -135,7 +136,8 @@ typedef struct _GtkHPaned GtkHPaned;
typedef struct _GtkOptionMenu GtkOptionMenu;
struct _GtkAccelGroup {
- GSList *accel;
+ ACCEL *accel; /* list of ACCEL structures */
+ gint numaccel;
};
struct _GtkSignalType {
t@@ -209,6 +211,7 @@ struct _GtkMenuItem {
GtkWidget widget;
GtkMenu *submenu;
gint ID;
+ gint accelind;
gchar *text;
};
t@@ -320,6 +323,7 @@ struct _GtkItemFactory {
GtkObject object;
GSList *children;
gchar *path;
+ GtkAccelGroup *accel_group;
GtkWidget *top_widget;
};
t@@ -640,6 +644,7 @@ GtkWidget *gtk_vseparator_new();
void gtk_object_set_data(GtkObject *object,const gchar *key,gpointer data);
gpointer gtk_object_get_data(GtkObject *object,const gchar *key);
GtkAccelGroup *gtk_accel_group_new();
+void gtk_accel_group_destroy(GtkAccelGroup *accel_group);
void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory,
GtkTranslateFunc func,
gpointer data,