diff --git a/gb.gtk/src/Makefile.am b/gb.gtk/src/Makefile.am index 35c44537c..46a9b6790 100644 --- a/gb.gtk/src/Makefile.am +++ b/gb.gtk/src/Makefile.am @@ -56,7 +56,7 @@ gb_gtk_la_SOURCES = \ cprinter.h cprinter.cpp \ csvgimage.h csvgimage.cpp \ main.h main.cpp \ - gkey.h \ + gkey.h gkey.cpp \ gcursor.h gcursor.cpp \ gmouse.h gmouse.cpp \ gdesktop.h \ diff --git a/gb.gtk/src/gapplication.cpp b/gb.gtk/src/gapplication.cpp index 2de72e853..7b720a950 100644 --- a/gb.gtk/src/gapplication.cpp +++ b/gb.gtk/src/gapplication.cpp @@ -39,223 +39,8 @@ #include "gprinter.h" #include "gmainwindow.h" -//#define DEBUG_IM 1 //#define DEBUG_ENTER_LEAVE 1 -/************************************************************************* - -gKey - -**************************************************************************/ - -bool gKey::_valid = false; -bool gKey::_no_input_method = false; -GdkEventKey gKey::_event; -GtkIMContext *gKey::_im_context = NULL; -gControl *gKey::_im_control = NULL; -char *_im_text = NULL; - -const char *gKey::text() -{ - if (!_valid) - return 0; - else - return _event.string; -} - -int gKey::code() -{ - if (!_valid) - return 0; - - int code = _event.keyval; - - if (code >= GDK_a && code <= GDK_z) - code += GDK_A - GDK_a; - else if (code == GDK_Alt_L || code == GDK_Alt_R || code == GDK_Control_L || code == GDK_Control_R - || code == GDK_Meta_L || code == GDK_Meta_R || code == GDK_Shift_L || code == GDK_Shift_R) - code = 0; - - return code; -} - -int gKey::state() -{ - if (!_valid) - return 0; - else - return _event.state; -} - -bool gKey::alt() -{ - return state() & GDK_MOD1_MASK || _event.keyval == GDK_Alt_L || _event.keyval == GDK_Alt_R; -} - -bool gKey::control() -{ - return state() & GDK_CONTROL_MASK || _event.keyval == GDK_Control_L || _event.keyval == GDK_Control_R; -} - -bool gKey::meta() -{ - return state() & GDK_MOD2_MASK || _event.keyval == GDK_Meta_L || _event.keyval == GDK_Meta_R; -} - -bool gKey::normal() -{ - return (state() & 0xFF) != 0; -} - -bool gKey::shift() -{ - return state() & GDK_SHIFT_MASK || _event.keyval == GDK_Shift_L || _event.keyval == GDK_Shift_R; -} - -int gKey::fromString(char *str) -{ - char *lstr; - int key; - - if (!str || !*str) - return 0; - - lstr = g_ascii_strup(str, -1); - key = gdk_keyval_from_name(lstr); - g_free(lstr); - if (key) return key; - - lstr = g_ascii_strdown(str, -1); - key = gdk_keyval_from_name(lstr); - g_free(lstr); - if (key) return key; - - key = gdk_keyval_from_name(str); - return key; -} - -void gKey::disable() -{ - if (!_valid) - return; - - _valid = false; - _event.keyval = 0; - _event.state = 0; - g_free(_event.string); -} - -bool gKey::enable(gControl *control, GdkEventKey *event) -{ - bool filter; - - //if (widget != _im_widget) - // return true; - - if (_valid) - disable(); - - _valid = true; - _event = *event; - - if (_event.type == GDK_KEY_PRESS && !_no_input_method && control == _im_control) - { - #if DEBUG_IM - fprintf(stderr, "gKey::enable: event->string = '%s'\n", event->string); - #endif - filter = gtk_im_context_filter_keypress(_im_context, &_event); - #if DEBUG_IM - fprintf(stderr, "gKey::enable: filter -> %d event->string = '%s'\n", filter, event->string); - #endif - } - else - filter = false; - - if (filter && _im_text) - { - _event.string = g_strdup(_im_text); - //_event.keyval = 0; - filter = false; - } - else - _event.string = g_strdup(_event.string); - - if (!filter) - { - //#if DEBUG_IM - //fprintf(stderr, "gKey::enable: gtk_im_context_reset\n"); - //#endif - //gtk_im_context_reset(_im_context); - if (_im_text) - { - g_free(_im_text); - _im_text = NULL; - } - } - - //fprintf(stderr, "gKey::enable: --> %d\n", filter); - return filter; -} - -static void cb_im_commit(GtkIMContext *context, const gchar *str, gpointer pointer) -{ - #if DEBUG_IM - fprintf(stderr, "cb_im_commit: %s\n", str); - #endif - - if (_im_text) - g_free(_im_text); - - _im_text = g_strdup(str); -} - -void gKey::init() -{ - _im_context = gtk_im_multicontext_new(); - g_signal_connect (_im_context, "commit", G_CALLBACK(cb_im_commit), NULL); -} - -void gKey::exit() -{ - disable(); - if (_im_text) - g_free(_im_text); - g_object_unref(_im_context); -} - -void gKey::setActiveControl(gControl *control) -{ - if (_im_control) - { - if (!_no_input_method) - { - #if DEBUG_IM - fprintf(stderr, "gtm_im_context_focus_out\n"); - #endif - gtk_im_context_set_client_window (_im_context, 0); - gtk_im_context_focus_out(_im_context); - } - _im_control = NULL; - _no_input_method = false; - } - - if (control) - { - _im_control = control; - _no_input_method = control->noInputMethod(); - - if (!_no_input_method) - { - gtk_im_context_set_client_window (_im_context, _im_control->widget->window); - gtk_im_context_focus_in(_im_context); - gtk_im_context_reset(_im_context); - #if DEBUG_IM - fprintf(stderr, "gtm_im_context_focus_in\n"); - #endif - } - } -} - /************************************************************************** Global event handler @@ -424,12 +209,12 @@ static void gambas_handle_event(GdkEvent *event) grab = gApplication::_popup_grab; //gdk_window_get_user_data(gApplication::_popup_grab_window, (gpointer *)&grab); - /*if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) + if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) { fprintf(stderr, "widget = %p grab = %p _popup_grab = %p _button_grab = %p\n", widget, grab, gApplication::_popup_grab, gApplication::_button_grab); //fprintf(stderr, "widget = %p (%p) grab = %p (%p)\n", widget, widget ? g_object_get_data(G_OBJECT(widget), "gambas-control") : 0, // grab, grab ? g_object_get_data(G_OBJECT(grab), "gambas-control") : 0); - }*/ + } if (grab && !gApplication::_popup_grab && !gApplication::_button_grab) goto __HANDLE_EVENT; @@ -1193,16 +978,16 @@ void gApplication::exitGroup(GtkWindowGroup *oldGroup) _group = oldGroup; } -void gApplication::enterLoop(void *owner, bool showIt) +void gApplication::enterLoop(void *owner, bool showIt, GtkWindow *modal) { void *old_owner = _loop_owner; int l = _loopLevel; GtkWindowGroup *oldGroup; - oldGroup = enterGroup(); - if (showIt) ((gControl *)owner)->show(); + oldGroup = enterGroup(); + _loopLevel++; _loop_owner = owner; diff --git a/gb.gtk/src/gapplication.h b/gb.gtk/src/gapplication.h index be4075f51..823a8918c 100644 --- a/gb.gtk/src/gapplication.h +++ b/gb.gtk/src/gapplication.h @@ -58,7 +58,7 @@ public: static void setDirty(); static int loopLevel() { return _loopLevel; } - static void enterLoop(void *owner, bool showIt = false); + static void enterLoop(void *owner, bool showIt = false, GtkWindow *modal = NULL); static void enterPopup(gMainWindow *owner); static void exitLoop(void *owner); static bool hasLoop(void *owner) { return _loop_owner == owner; } diff --git a/gb.gtk/src/gdraw.cpp b/gb.gtk/src/gdraw.cpp index ecbbb037a..7e735bb37 100644 --- a/gb.gtk/src/gdraw.cpp +++ b/gb.gtk/src/gdraw.cpp @@ -819,9 +819,12 @@ void gDraw::ellipse(int x, int y, int w, int h, double start, double end) int xs, ys; int xe, ye; - #define CROP_XY(_x, _y) \ - if (_x < x) _x = x; else if (_x >= (x + w)) _x = x + w - 1; \ - if (_y < y) _y = y; else if (_y >= (y + h)) _y = y + h - 1; + x -= _x; + y -= _y; + + #define CROP_XY(__x, __y) \ + if (__x < x) __x = x; else if (__x >= (x + w)) __x = x + w - 1; \ + if (__y < y) __y = y; else if (__y >= (y + h)) __y = y + h - 1; xc = (x + x + w) / 2; //+ cos(start) / 2; yc = (y + y + h) / 2; //- sin(start) / 2; diff --git a/gb.gtk/src/gkey.cpp b/gb.gtk/src/gkey.cpp new file mode 100644 index 000000000..2d04723ad --- /dev/null +++ b/gb.gtk/src/gkey.cpp @@ -0,0 +1,251 @@ +/*************************************************************************** + + gkey.cpp + + (c) 2004-2006 - Daniel Campos Fernández + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#define __GKEY_CPP + +#include +#include +#include + +#include "widgets.h" +#include "widgets_private.h" +#include "gapplication.h" +#include "gtrayicon.h" +#include "gdesktop.h" +#include "gkey.h" + +//#define DEBUG_IM 1 + +/************************************************************************* + +gKey + +**************************************************************************/ + +bool gKey::_valid = false; +bool gKey::_no_input_method = false; +GdkEventKey gKey::_event; +GtkIMContext *gKey::_im_context = NULL; +gControl *gKey::_im_control = NULL; +char *_im_text = NULL; + +const char *gKey::text() +{ + if (!_valid) + return 0; + else + return _event.string; +} + +int gKey::code() +{ + if (!_valid) + return 0; + + int code = _event.keyval; + + if (code >= GDK_a && code <= GDK_z) + code += GDK_A - GDK_a; + else if (code == GDK_Alt_L || code == GDK_Alt_R || code == GDK_Control_L || code == GDK_Control_R + || code == GDK_Meta_L || code == GDK_Meta_R || code == GDK_Shift_L || code == GDK_Shift_R) + code = 0; + + return code; +} + +int gKey::state() +{ + if (!_valid) + return 0; + else + return _event.state; +} + +bool gKey::alt() +{ + return state() & GDK_MOD1_MASK || _event.keyval == GDK_Alt_L || _event.keyval == GDK_Alt_R; +} + +bool gKey::control() +{ + return state() & GDK_CONTROL_MASK || _event.keyval == GDK_Control_L || _event.keyval == GDK_Control_R; +} + +bool gKey::meta() +{ + return state() & GDK_MOD2_MASK || _event.keyval == GDK_Meta_L || _event.keyval == GDK_Meta_R; +} + +bool gKey::normal() +{ + return (state() & 0xFF) != 0; +} + +bool gKey::shift() +{ + return state() & GDK_SHIFT_MASK || _event.keyval == GDK_Shift_L || _event.keyval == GDK_Shift_R; +} + +int gKey::fromString(char *str) +{ + char *lstr; + int key; + + if (!str || !*str) + return 0; + + lstr = g_ascii_strup(str, -1); + key = gdk_keyval_from_name(lstr); + g_free(lstr); + if (key) return key; + + lstr = g_ascii_strdown(str, -1); + key = gdk_keyval_from_name(lstr); + g_free(lstr); + if (key) return key; + + key = gdk_keyval_from_name(str); + return key; +} + +void gKey::disable() +{ + if (!_valid) + return; + + _valid = false; + _event.keyval = 0; + _event.state = 0; + g_free(_event.string); +} + +bool gKey::enable(gControl *control, GdkEventKey *event) +{ + bool filter; + + //if (widget != _im_widget) + // return true; + + if (_valid) + disable(); + + _valid = true; + _event = *event; + + if (_event.type == GDK_KEY_PRESS && !_no_input_method && control == _im_control) + { + #if DEBUG_IM + fprintf(stderr, "gKey::enable: event->string = '%s'\n", event->string); + #endif + filter = gtk_im_context_filter_keypress(_im_context, &_event); + #if DEBUG_IM + fprintf(stderr, "gKey::enable: filter -> %d event->string = '%s'\n", filter, event->string); + #endif + } + else + filter = false; + + if (filter && _im_text) + { + _event.string = g_strdup(_im_text); + //_event.keyval = 0; + filter = false; + } + else + _event.string = g_strdup(_event.string); + + if (!filter) + { + //#if DEBUG_IM + //fprintf(stderr, "gKey::enable: gtk_im_context_reset\n"); + //#endif + //gtk_im_context_reset(_im_context); + if (_im_text) + { + g_free(_im_text); + _im_text = NULL; + } + } + + //fprintf(stderr, "gKey::enable: --> %d\n", filter); + return filter; +} + +static void cb_im_commit(GtkIMContext *context, const gchar *str, gpointer pointer) +{ + #if DEBUG_IM + fprintf(stderr, "cb_im_commit: %s\n", str); + #endif + + if (_im_text) + g_free(_im_text); + + _im_text = g_strdup(str); +} + +void gKey::init() +{ + _im_context = gtk_im_multicontext_new(); + g_signal_connect (_im_context, "commit", G_CALLBACK(cb_im_commit), NULL); +} + +void gKey::exit() +{ + disable(); + if (_im_text) + g_free(_im_text); + g_object_unref(_im_context); +} + +void gKey::setActiveControl(gControl *control) +{ + if (_im_control) + { + if (!_no_input_method) + { + #if DEBUG_IM + fprintf(stderr, "gtm_im_context_focus_out\n"); + #endif + gtk_im_context_set_client_window (_im_context, 0); + gtk_im_context_focus_out(_im_context); + } + _im_control = NULL; + _no_input_method = false; + } + + if (control) + { + _im_control = control; + _no_input_method = control->noInputMethod(); + + if (!_no_input_method) + { + gtk_im_context_set_client_window (_im_context, _im_control->widget->window); + gtk_im_context_focus_in(_im_context); + gtk_im_context_reset(_im_context); + #if DEBUG_IM + fprintf(stderr, "gtm_im_context_focus_in\n"); + #endif + } + } +} diff --git a/gb.gtk/src/gmainwindow.cpp b/gb.gtk/src/gmainwindow.cpp index 35d5c0619..4798c14bf 100644 --- a/gb.gtk/src/gmainwindow.cpp +++ b/gb.gtk/src/gmainwindow.cpp @@ -583,14 +583,17 @@ void gMainWindow::setFullscreen(bool vl) void gMainWindow::center() { - int myx,myy; + GdkRectangle rect; + int x, y; if (!isTopLevel()) return; - myx = (gDesktop::width() - width()) / 2; - myy = (gDesktop::height() - height()) / 2; + gDesktop::availableGeometry(screen(), &rect); - move(myx, myy); + x = rect.x + (rect.width - width()) / 2; + y = rect.y + (rect.height - height()) / 2; + + move(x, y); } bool gMainWindow::isModal() const @@ -607,24 +610,30 @@ void gMainWindow::showModal() if (!isTopLevel()) return; if (isModal()) return; - save = _current; - _current = this; - - gtk_window_set_modal(GTK_WINDOW(border), true); - - center(); //show(); //fprintf(stderr, "showModal: begin %p\n", this); - gApplication::enterLoop(this, true); + gtk_window_set_modal(GTK_WINDOW(border), true); + center(); + show(); + gtk_grab_add(border); - //fprintf(stderr, "showModal: end %p\n", this); + if (_active) + gtk_window_set_transient_for(GTK_WINDOW(border), GTK_WINDOW(_active->border)); + + save = _current; + _current = this; + gApplication::enterLoop(this); + _current = save; + gtk_grab_remove(border); gtk_window_set_modal(GTK_WINDOW(border), false); - + + //fprintf(stderr, "showModal: end %p\n", this); + if (!persistent) destroyNow(); else diff --git a/gb.qt4/src/CWidget.cpp b/gb.qt4/src/CWidget.cpp index bde8f8ac6..37f153464 100644 --- a/gb.qt4/src/CWidget.cpp +++ b/gb.qt4/src/CWidget.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #ifndef NO_X_WINDOW @@ -1465,7 +1466,7 @@ void CWIDGET_reset_color(CWIDGET *_object) w->setPalette(palette); get_viewport(WIDGET)->setPalette(vpalette); } - else if (qobject_cast(w)) + else if (qobject_cast(w) || qobject_cast(w)) { palette = QPalette();