From e7e67654e2a50ed46b910b1f049fa9432426f5c3 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 18 Dec 2012 19:22:43 +0000 Subject: [PATCH] .developing Gtk git-svn-id: svn://ultimatepp.org/upp/trunk@5651 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/Gtk/App.cpp | 3 +- rainbow/Gtk/Ctrl.cpp | 20 +--- rainbow/Gtk/Ctrl.h | 26 ++++-- rainbow/Gtk/DrawImage.cpp | 2 +- rainbow/Gtk/GdkImage.cpp | 4 + rainbow/Gtk/Gtk.h | 2 + rainbow/Gtk/Gtk.upp | 3 +- rainbow/Gtk/Msg.i | 126 ------------------------- rainbow/Gtk/Proc.cpp | 160 +++++++++++++++++++++++++++---- rainbow/Gtk/Top.cpp | 12 ++- rainbow/Gtk/Util.cpp | 6 ++ rainbow/Gtk/Wnd.cpp | 182 ++++++++++++++++++++++++++---------- rainbow/GtkMain/GtkMain.upp | 3 +- rainbow/GtkMain/main.cpp | 68 ++++++++++++-- 14 files changed, 388 insertions(+), 229 deletions(-) delete mode 100644 rainbow/Gtk/Msg.i diff --git a/rainbow/Gtk/App.cpp b/rainbow/Gtk/App.cpp index 985d5a65e..0192c6e11 100644 --- a/rainbow/Gtk/App.cpp +++ b/rainbow/Gtk/App.cpp @@ -6,9 +6,10 @@ NAMESPACE_UPP void InitGtkApp(int argc, char **argv, const char **envptr) { - gtk_init(0, NULL); + gtk_init(0, NULL); // TODO? Ctrl::GlobalBackBuffer(); SetStdFont(Arial(12)); + g_timeout_add(10, (GSourceFunc) Ctrl::TimeHandler, NULL); } END_UPP_NAMESPACE diff --git a/rainbow/Gtk/Ctrl.cpp b/rainbow/Gtk/Ctrl.cpp index ce72c6cbe..13198ee2e 100644 --- a/rainbow/Gtk/Ctrl.cpp +++ b/rainbow/Gtk/Ctrl.cpp @@ -40,10 +40,6 @@ bool Ctrl::GuiPlatformSetFullRefreshSpecial() return false; } -void Ctrl::PaintCaret(SystemDraw& w) -{ -} - String GuiPlatformGetKeyDesc(dword key) { return Null; @@ -64,6 +60,7 @@ bool GuiPlatformHasSizeGrip() void GuiPlatformGripResize(TopWindow *q) { + // TODO } Color GuiPlatformGetScreenPixel(int x, int y) @@ -75,21 +72,6 @@ void GuiPlatformAfterMenuPopUp() { } -void Ctrl::SetCaret(int x, int y, int cx, int cy) -{ - GuiLock __; - caretx = x; - carety = y; - caretcx = cx; - caretcy = cy; - SyncCaret(); -} - -void Ctrl::SyncCaret() { - GuiLock __; - -} - String Ctrl::Name() const { GuiLock __; #ifdef CPU_64 diff --git a/rainbow/Gtk/Ctrl.h b/rainbow/Gtk/Ctrl.h index cf65a495c..ef4cf2e5c 100644 --- a/rainbow/Gtk/Ctrl.h +++ b/rainbow/Gtk/Ctrl.h @@ -4,26 +4,40 @@ static gboolean GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data); static void IMCommit(GtkIMContext *context, gchar *str, gpointer user_data); + + void GtkMouseEvent(int action, GdkEvent *event); + void GtkKeyEvent(GdkEventKey *key, bool pressed); + virtual bool Proc(GdkEvent *event); - void GtkMouseEvent(int action, GdkEvent *event); + static gboolean GtkEvent(GtkWidget *widget, GdkEvent *key, gpointer user_data); - GdkWindow *gdk() { return top->window->window; } - GtkWindow *gtk() { return (GtkWindow *)top->window; } + void GtkConnect(); + + GdkWindow *gdk() const { return top->window->window; } + GtkWindow *gtk() const { return (GtkWindow *)top->window; } struct Win : Moveable { GtkWidget *gtk; GdkWindow *gdk; - Ctrl *ctrl; + Ptr ctrl; }; - static Vector wins; - + static Vector wins; + static int WndCaretTime; + static bool WndCaretVisible; + static Ptr grabwindow; + int FindCtrl(Ctrl *ctrl); int FindGtkWindow(GtkWidget *gtk); int FindGdkWindow(GdkWindow *gdk); static void FocusSync(); + static void AnimateCaret(); + static gboolean TimeHandler(GtkWidget *); + static void InvalidateMousePos(); + + friend void InitGtkApp(int argc, char **argv, const char **envptr); public: static void EndSession() {} diff --git a/rainbow/Gtk/DrawImage.cpp b/rainbow/Gtk/DrawImage.cpp index fdb81974b..f124e63e2 100644 --- a/rainbow/Gtk/DrawImage.cpp +++ b/rainbow/Gtk/DrawImage.cpp @@ -54,7 +54,7 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color) GuiLock __; if(img.GetLength() == 0) return; - DLOG("SysDrawImageOp " << img.GetSerialId() << ' ' << x << ", " << y << ", "<< img.GetSize()); + LLOG("SysDrawImageOp " << img.GetSerialId() << ' ' << x << ", " << y << ", "<< img.GetSize()); ImageSysDataMaker m; static LRUCache cache; LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount()); diff --git a/rainbow/Gtk/GdkImage.cpp b/rainbow/Gtk/GdkImage.cpp index 68601fd61..d9c4371b4 100644 --- a/rainbow/Gtk/GdkImage.cpp +++ b/rainbow/Gtk/GdkImage.cpp @@ -1,5 +1,7 @@ #include +#ifdef GUI_GTK + NAMESPACE_UPP void ImageGdk::Free() @@ -56,3 +58,5 @@ ImageGdk::~ImageGdk() } END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Gtk/Gtk.h b/rainbow/Gtk/Gtk.h index f534823bf..2c93c2bb2 100644 --- a/rainbow/Gtk/Gtk.h +++ b/rainbow/Gtk/Gtk.h @@ -171,6 +171,8 @@ public: ~PrinterJob() {} }; +int rmsecs(); + END_UPP_NAMESPACE #define GUIPLATFORM_INCLUDE_AFTER diff --git a/rainbow/Gtk/Gtk.upp b/rainbow/Gtk/Gtk.upp index 34d77df5f..fc75a10a9 100644 --- a/rainbow/Gtk/Gtk.upp +++ b/rainbow/Gtk/Gtk.upp @@ -18,6 +18,5 @@ file Top.cpp, Clip.cpp, DnD.cpp, - ChSysInit.cpp, - Msg.i; + ChSysInit.cpp; diff --git a/rainbow/Gtk/Msg.i b/rainbow/Gtk/Msg.i deleted file mode 100644 index a578ff256..000000000 --- a/rainbow/Gtk/Msg.i +++ /dev/null @@ -1,126 +0,0 @@ -#pragma BLITZ_APPROVE - -x_MSG(WM_CREATE) -x_MSG(WM_DESTROY) -x_MSG(WM_MOVE) -x_MSG(WM_SIZE) -x_MSG(WM_ACTIVATE) -x_MSG(WM_SETFOCUS) -x_MSG(WM_KILLFOCUS) -x_MSG(WM_ENABLE) -x_MSG(WM_SETREDRAW) -x_MSG(WM_SETTEXT) -x_MSG(WM_GETTEXT) -x_MSG(WM_GETTEXTLENGTH) -x_MSG(WM_PAINT) -x_MSG(WM_CLOSE) -x_MSG(WM_QUIT) -x_MSG(WM_ERASEBKGND) -x_MSG(WM_SYSCOLORCHANGE) -x_MSG(WM_SHOWWINDOW) -x_MSG(WM_WININICHANGE) -x_MSG(WM_FONTCHANGE) -x_MSG(WM_NEXTDLGCTL) -x_MSG(WM_DRAWITEM) -x_MSG(WM_MEASUREITEM) -x_MSG(WM_DELETEITEM) -x_MSG(WM_VKEYTOITEM) -x_MSG(WM_CHARTOITEM) -x_MSG(WM_SETFONT) -x_MSG(WM_GETFONT) -x_MSG(WM_QUERYDRAGICON) -x_MSG(WM_COMPAREITEM) -x_MSG(WM_GETDLGCODE) -x_MSG(WM_KEYDOWN) -x_MSG(WM_KEYUP) -x_MSG(WM_CHAR) -x_MSG(WM_DEADCHAR) -x_MSG(WM_SYSKEYDOWN) -x_MSG(WM_SYSKEYUP) -x_MSG(WM_SYSCHAR) -x_MSG(WM_SYSDEADCHAR) -x_MSG(WM_KEYLAST) -x_MSG(WM_INITDIALOG) -x_MSG(WM_COMMAND) -x_MSG(WM_SYSCOMMAND) -x_MSG(WM_TIMER) -x_MSG(WM_HSCROLL) -x_MSG(WM_VSCROLL) -x_MSG(WM_INITMENUPOPUP) -x_MSG(WM_MENUCHAR) -x_MSG(WM_LBUTTONDOWN) -x_MSG(WM_LBUTTONUP) -x_MSG(WM_LBUTTONDBLCLK) -x_MSG(WM_RBUTTONDOWN) -x_MSG(WM_RBUTTONUP) -x_MSG(WM_RBUTTONDBLCLK) -x_MSG(WM_MBUTTONDOWN) -x_MSG(WM_MBUTTONUP) -x_MSG(WM_MBUTTONDBLCLK) -x_MSG(WM_MOUSEMOVE) -x_MSG(WM_CUT) -x_MSG(WM_COPY) -x_MSG(WM_PASTE) -x_MSG(WM_CLEAR) -x_MSG(WM_UNDO) -x_MSG(WM_RENDERFORMAT) -x_MSG(WM_RENDERALLFORMATS) -x_MSG(WM_DESTROYCLIPBOARD) -x_MSG(WM_QUERYNEWPALETTE) -x_MSG(WM_PALETTECHANGED) -x_MSG(WM_WINDOWPOSCHANGED) - -#ifndef PLATFORM_WINCE -x_MSG(WM_QUERYENDSESSION) -x_MSG(WM_ENDSESSION) -x_MSG(WM_QUERYOPEN) -x_MSG(WM_DEVMODECHANGE) -x_MSG(WM_ACTIVATEAPP) -x_MSG(WM_TIMECHANGE) -x_MSG(WM_MOUSEACTIVATE) -x_MSG(WM_CHILDACTIVATE) -x_MSG(WM_QUEUESYNC) -x_MSG(WM_GETMINMAXINFO) -x_MSG(WM_ICONERASEBKGND) -x_MSG(WM_SPOOLERSTATUS) -x_MSG(WM_COMPACTING) -x_MSG(WM_NCLBUTTONDOWN) -x_MSG(WM_NCLBUTTONUP) -x_MSG(WM_NCLBUTTONDBLCLK) -x_MSG(WM_NCRBUTTONDOWN) -x_MSG(WM_NCRBUTTONUP) -x_MSG(WM_NCRBUTTONDBLCLK) -x_MSG(WM_NCMBUTTONDOWN) -x_MSG(WM_NCMBUTTONUP) -x_MSG(WM_NCMBUTTONDBLCLK) -x_MSG(WM_NCCREATE) -x_MSG(WM_NCDESTROY) -x_MSG(WM_NCCALCSIZE) -x_MSG(WM_NCPAINT) -x_MSG(WM_NCACTIVATE) -x_MSG(WM_INITMENU) -x_MSG(WM_MENUSELECT) -x_MSG(WM_PARENTNOTIFY) -x_MSG(WM_MDICREATE) -x_MSG(WM_MDIDESTROY) -x_MSG(WM_MDIACTIVATE) -x_MSG(WM_MDIRESTORE) -x_MSG(WM_MDINEXT) -x_MSG(WM_MDIMAXIMIZE) -x_MSG(WM_MDITILE) -x_MSG(WM_MDICASCADE) -x_MSG(WM_MDIICONARRANGE) -x_MSG(WM_MDIGETACTIVE) -x_MSG(WM_MDISETMENU) -x_MSG(WM_DRAWCLIPBOARD) -x_MSG(WM_PAINTCLIPBOARD) -x_MSG(WM_VSCROLLCLIPBOARD) -x_MSG(WM_SIZECLIPBOARD) -x_MSG(WM_ASKCBFORMATNAME) -x_MSG(WM_CHANGECBCHAIN) -x_MSG(WM_HSCROLLCLIPBOARD) -x_MSG(WM_PALETTEISCHANGING) -x_MSG(WM_DROPFILES) -x_MSG(WM_POWER) -x_MSG(WM_WINDOWPOSCHANGING) -#endif diff --git a/rainbow/Gtk/Proc.cpp b/rainbow/Gtk/Proc.cpp index 104d4bb89..119cd2818 100644 --- a/rainbow/Gtk/Proc.cpp +++ b/rainbow/Gtk/Proc.cpp @@ -8,18 +8,35 @@ NAMESPACE_UPP -#define LLOG(x) // LOG(x) +#define LLOG(x) LOG(x) +#define LOG_EVENTS +static Point sMousepos; +static GdkModifierType sModmask; +static bool sMouseposValid; +void syncMousePos() +{ + if(sMouseposValid) + return; + gint x, y; + gdk_window_get_pointer(gdk_get_default_root_window(), &x, &y, &sModmask); + sMousepos = Point(x, y); +} -bool GetShift() { return false; } -bool GetCtrl() { return false; } -bool GetAlt() { return false; } -bool GetCapsLock() { return false; } -bool GetMouseLeft() { return false; } -bool GetMouseRight() { return false; } -bool GetMouseMiddle() { return false; } -Point GetMousePos() { return Point(0, 0); } +void Ctrl::InvalidateMousePos() +{ + sMouseposValid = false; +} + +bool GetShift() { syncMousePos(); return sModmask & GDK_SHIFT_MASK; } +bool GetCtrl() { syncMousePos(); return sModmask & GDK_CONTROL_MASK ; } +bool GetAlt() { syncMousePos(); return sModmask & GDK_MOD1_MASK; } +bool GetCapsLock() { syncMousePos(); return sModmask & GDK_LOCK_MASK; } +bool GetMouseLeft() { syncMousePos(); return sModmask & GDK_BUTTON1_MASK; } +bool GetMouseRight() { syncMousePos(); return sModmask & GDK_BUTTON3_MASK; } +bool GetMouseMiddle() { syncMousePos(); return sModmask & GDK_BUTTON2_MASK; } +Point GetMousePos() { syncMousePos(); return sMousepos; } void Ctrl::GtkMouseEvent(int action, GdkEvent *event) { @@ -28,22 +45,92 @@ void Ctrl::GtkMouseEvent(int action, GdkEvent *event) Point((int)e->x, (int)e->y)); } +#ifdef LOG_EVENTS +Tuple2 xEvent[] = { + { GDK_NOTHING, "GDK_NOTHING" }, + { GDK_DELETE, "GDK_DELETE" }, + { GDK_DESTROY, "GDK_DESTROY" }, + { GDK_EXPOSE, "GDK_EXPOSE" }, + { GDK_MOTION_NOTIFY, "GDK_MOTION_NOTIFY" }, + { GDK_BUTTON_PRESS, "GDK_BUTTON_PRESS" }, + { GDK_2BUTTON_PRESS, "GDK_2BUTTON_PRESS" }, + { GDK_3BUTTON_PRESS, "GDK_3BUTTON_PRESS" }, + { GDK_BUTTON_RELEASE, "GDK_BUTTON_RELEASE" }, + { GDK_KEY_PRESS, "GDK_KEY_PRESS" }, + { GDK_KEY_RELEASE, "GDK_KEY_RELEASE" }, + { GDK_ENTER_NOTIFY, "GDK_ENTER_NOTIFY" }, + { GDK_LEAVE_NOTIFY, "GDK_LEAVE_NOTIFY" }, + { GDK_FOCUS_CHANGE, "GDK_FOCUS_CHANGE" }, + { GDK_CONFIGURE, "GDK_CONFIGURE" }, + { GDK_MAP, "GDK_MAP" }, + { GDK_UNMAP, "GDK_UNMAP" }, + { GDK_PROPERTY_NOTIFY, "GDK_PROPERTY_NOTIFY" }, + { GDK_SELECTION_CLEAR, "GDK_SELECTION_CLEAR" }, + { GDK_SELECTION_REQUEST, "GDK_SELECTION_REQUEST" }, + { GDK_SELECTION_NOTIFY, "GDK_SELECTION_NOTIFY" }, + { GDK_PROXIMITY_IN, "GDK_PROXIMITY_IN" }, + { GDK_PROXIMITY_OUT, "GDK_PROXIMITY_OUT" }, + { GDK_DRAG_ENTER, "GDK_DRAG_ENTER" }, + { GDK_DRAG_LEAVE, "GDK_DRAG_LEAVE" }, + { GDK_DRAG_MOTION, "GDK_DRAG_MOTION" }, + { GDK_DRAG_STATUS, "GDK_DRAG_STATUS" }, + { GDK_DROP_START, "GDK_DROP_START" }, + { GDK_DROP_FINISHED, "GDK_DROP_FINISHED" }, + { GDK_CLIENT_EVENT, "GDK_CLIENT_EVENT" }, + { GDK_VISIBILITY_NOTIFY, "GDK_VISIBILITY_NOTIFY" }, + { GDK_NO_EXPOSE, "GDK_NO_EXPOSE" }, + { GDK_SCROLL, "GDK_SCROLL" }, + { GDK_WINDOW_STATE, "GDK_WINDOW_STATE" }, + { GDK_SETTING, "GDK_SETTING" }, + { GDK_OWNER_CHANGE, "GDK_OWNER_CHANGE" }, + { GDK_GRAB_BROKEN, "GDK_GRAB_BROKEN" }, + { GDK_DAMAGE, "GDK_DAMAGE" }, + { GDK_EVENT_LAST, "GDK_EVENT_LAST" }, +}; +#endif + bool Ctrl::Proc(GdkEvent *event) { if(!top) return false; +#ifdef LOG_EVENTS + String ev = "?"; + Tuple2 *f = FindTuple(xEvent, __countof(xEvent), event->type); + if(f) + ev = f->b; + LOG(rmsecs() << " EVENT " << Upp::Name(this) << " " << ev); +#endif GdkEventKey *key; bool pressed = false; int kv; + InvalidateMousePos(); switch(event->type) { + case GDK_DELETE: { + TopWindow *w = dynamic_cast(this); + if(w) { + if(IsEnabled()) { + IgnoreMouseUp(); + w->WhenClose(); + } + return true; + } + return false; + } case GDK_FOCUS_CHANGE: - if(((GdkEventFocus *)event)->in) + LLOG("FocusChange in: " << ((GdkEventFocus *)event)->in << ", focusCtrlWnd " << focusCtrlWnd); + if(((GdkEventFocus *)event)->in) { gtk_im_context_focus_in(top->im_context); - else + if(this != focusCtrlWnd && IsEnabled()) + ActivateWnd(); + } + else { gtk_im_context_focus_out(top->im_context); + KillFocusWnd(); + } break; case GDK_EXPOSE: case GDK_DAMAGE: { + TimeStop tm; fullrefresh = false; GdkEventExpose *e = (GdkEventExpose *)event; SystemDraw w(gdk_cairo_create(top->window->window)); @@ -51,6 +138,7 @@ bool Ctrl::Proc(GdkEvent *event) UpdateArea(w, RectC(e->area.x, e->area.y, e->area.width, e->area.height)); cairo_destroy(w); painting = false; + DDUMP(tm); break; } case GDK_MOTION_NOTIFY: { @@ -60,6 +148,9 @@ bool Ctrl::Proc(GdkEvent *event) break; } case GDK_BUTTON_PRESS: + if(!HasWndFocus() && !popup) + SetWndFocus(); + ClickActivateWnd(); GtkMouseEvent(DOWN, event); break; case GDK_2BUTTON_PRESS: @@ -76,25 +167,60 @@ bool Ctrl::Proc(GdkEvent *event) kv = key->keyval; if(gtk_im_context_filter_keypress(top->im_context, key)) break; - if(kv >= 0 && kv < 65536) - DispatchKey((pressed ? K_KEYUP : kv + K_DELTA), 1); + if(kv >= 0 && kv < 65536) { + DDUMP(pressed); + LOG(FormatIntHex(kv) << ' ' << (char)kv); + DDUMP(key->state & GDK_CONTROL_MASK); + if(kv >= 'a' && kv <= 'z') + kv = kv - 'a' + 'A'; + static Tuple2 cv[] = { + { GDK_KEY_BackSpace, K_BACKSPACE }, + { GDK_KEY_Tab, K_TAB }, + { GDK_KEY_Return, K_ENTER }, + { GDK_KEY_Escape, K_ESCAPE }, + }; + Tuple2 *x = FindTuple(cv, __countof(cv), kv); + if(x) + kv = x->b; + else + kv += K_DELTA; + if(key->state & GDK_SHIFT_MASK) + kv |= K_SHIFT; + if(key->state & GDK_CONTROL_MASK) + kv |= K_CTRL; + if(key->state & GDK_MOD1_MASK) + kv |= K_ALT; + DispatchKey(!pressed * K_KEYUP + kv, 1); + } break; - case GDK_CONFIGURE: { GdkEventConfigure *e = (GdkEventConfigure *)event; Rect rect = RectC(e->x, e->y, e->width, e->height); - LLOG("CongigureNotify " << rect); - if(GetRect() != rect) + LLOG("ConfigureNotify " << rect << ", GetRect() " << GetRect()); +// if(GetRect() != rect) SetWndRect(rect); // TODO: Add DHCtrl support } - break; + return false; // 'return true' leads to size problems default: return false; } return true; } +gboolean Ctrl::TimeHandler(GtkWidget *) +{ + InvalidateMousePos(); + TimerProc(GetTickCount()); + AnimateCaret(); + return true; +} + +gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + return ((Ctrl *)(user_data))->Proc(event); +} + END_UPP_NAMESPACE #endif diff --git a/rainbow/Gtk/Top.cpp b/rainbow/Gtk/Top.cpp index d77fbfbaa..0f7e5df95 100644 --- a/rainbow/Gtk/Top.cpp +++ b/rainbow/Gtk/Top.cpp @@ -12,16 +12,24 @@ void TopWindow::SyncSizeHints() if(!top) return; GdkGeometry m; - Size sz = GetRect().GetSize(); + Size sz0 = GetRect().GetSize(); + DDUMP(sz0); + Size sz = sz0; if(sizeable) sz = GetMinSize(); +// sz = Size(50, 50); + DDUMP(sz); m.min_width = sz.cx; m.min_height = sz.cy; + sz = sz0; if(sizeable) sz = GetMaxSize(); + DDUMP(sz); m.max_width = sz.cx; m.max_height = sz.cy; - gtk_window_set_geometry_hints(gtk(), NULL, &m, (GdkWindowHints)(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE)); + // TODO!!! + gtk_window_set_resizable(gtk(), sizeable); + gtk_window_set_geometry_hints(gtk(), top->window, &m, GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE)); } void TopWindow::SyncTitle0() diff --git a/rainbow/Gtk/Util.cpp b/rainbow/Gtk/Util.cpp index a48da9edb..40c8bf0ce 100644 --- a/rainbow/Gtk/Util.cpp +++ b/rainbow/Gtk/Util.cpp @@ -47,6 +47,12 @@ GdkRect::GdkRect(const Rect& r) height = r.GetHeight(); } +int rmsecs() +{ + static int msecs0 = msecs(); + return msecs(msecs0); +} + END_UPP_NAMESPACE #endif diff --git a/rainbow/Gtk/Wnd.cpp b/rainbow/Gtk/Wnd.cpp index 1a4473d10..716b548c8 100644 --- a/rainbow/Gtk/Wnd.cpp +++ b/rainbow/Gtk/Wnd.cpp @@ -15,6 +15,8 @@ NAMESPACE_UPP #define ELOG(x) // RLOG(GetSysTime() << ": " << x) Vector Ctrl::wins; +int Ctrl::WndCaretTime; +bool Ctrl::WndCaretVisible; int Ctrl::FindCtrl(Ctrl *ctrl) { @@ -50,18 +52,11 @@ bool Ctrl::IsCompositedGui() return false; } -gboolean Ctrl::GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - bool b = ((Ctrl *)(user_data))->Proc(event); - FocusSync(); - return b; -} - void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data) { WString s = FromUtf8(str); for(int i = 0; i < s.GetCount(); i++) - ((Ctrl *)(user_data))->Key(s[i], 1); + ((Ctrl *)(user_data))->DispatchKey(s[i], 1); } void Ctrl::Create(Ctrl *owner, bool popup) @@ -74,11 +69,24 @@ void Ctrl::Create(Ctrl *owner, bool popup) top = new Top; top->window = gtk_window_new(popup ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint(gtk(), popup ? GDK_WINDOW_TYPE_HINT_COMBO + : owner ? GDK_WINDOW_TYPE_HINT_DIALOG + : GDK_WINDOW_TYPE_HINT_NORMAL); + top->cursor_id = -1; + gtk_widget_set_events(top->window, 0xffffffff); - g_signal_connect(top->window, "event", G_CALLBACK(GtkProc), this); + g_signal_connect(top->window, "event", G_CALLBACK(GtkEvent), this); + + gtk_widget_realize(top->window); + + WndSetPos0(GetRect()); +/* + TopWindow *tw = dynamic_cast(this); + gtk_window_set_resizable(gtk(), tw && tw->IsSizeable()); +*/ if(owner && owner->top) - gtk_window_set_transient_for((GtkWindow *)top->window, (GtkWindow *)owner->top->window); + gtk_window_set_transient_for(gtk(), owner->gtk()); gtk_widget_set_app_paintable(top->window, TRUE); isopen = true; @@ -88,13 +96,22 @@ void Ctrl::Create(Ctrl *owner, bool popup) g_signal_connect(top->im_context, "commit", G_CALLBACK(IMCommit), this); WndShow(IsShown()); - WndSetPos0(GetRect()); Win& w = wins.Add(); w.ctrl = this; w.gtk = top->window; w.gdk = top->window->window; FocusSync(); + if(!popup) + SetWndFocus(); +} + +void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) +{ + DLOG("POPUP " << GetRect()); + Create(owner, true); + if(activate) + SetWndFocus(); } void Ctrl::WndDestroy0() @@ -112,6 +129,8 @@ void Ctrl::WndDestroy0() Vector Ctrl::GetTopCtrls() { Vector h; + for(int i = 0; i < wins.GetCount(); i++) + h.Add(wins[i].ctrl); return h; } @@ -119,8 +138,8 @@ void Ctrl::SetMouseCursor(const Image& image) { GuiLock __; int64 id = image.GetSerialId(); - Ctrl *topctrl; - Top *top; + Ctrl *topctrl = NULL; + Top *top = NULL; if(mouseCtrl) topctrl = mouseCtrl->GetTopCtrl(); if(topctrl) @@ -201,13 +220,17 @@ bool Ctrl::IsWaitingEvent() bool Ctrl::ProcessEvent(bool *quit) { ASSERT(IsMainThread()); + bool r = false; if(IsWaitingEvent()) { gtk_main_iteration(); if(quit) *quit = IsEndSession(); - return true; - } - return false; + r = true; + } + TimerProc(GetTickCount()); + SyncCaret(); + AnimateCaret(); + return r; } void SweepMkImageCache(); @@ -239,15 +262,10 @@ void Ctrl::EventLoop0(Ctrl *ctrl) ctrl->inloop = true; } - DDUMP(IsEndSession()); - DDUMP(ctrl->InLoop()); - while(!IsEndSession() && (ctrl ? true/* ctrl->IsOpen()*/ && ctrl->InLoop() : true /*GetTopCtrls().GetCount()*/)) // Fix this + while(!IsEndSession() && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) { -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); - SyncCaret(); if(IsEndSession()) break; -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); - DLOG("Before gtk_main"); + DLOG(rmsecs() << " before gtk_main"); gtk_main(); } @@ -279,6 +297,47 @@ void Ctrl::FocusSync() } } +void Ctrl::PaintCaret(SystemDraw& w) +{ + GuiLock __; + // LLOG("PaintCaret " << this << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible); + if(this == caretCtrl && WndCaretVisible) + w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor); +} + +void Ctrl::SetCaret(int x, int y, int cx, int cy) +{ + GuiLock __; + if(this == caretCtrl) + RefreshCaret(); + caretx = x; + carety = y; + caretcx = cx; + caretcy = cy; + WndCaretTime = GetTickCount(); + if(this == caretCtrl) + RefreshCaret(); +} + +void Ctrl::SyncCaret() { + GuiLock __; + if(focusCtrl != caretCtrl) { + RefreshCaret(); + caretCtrl = focusCtrl; + RefreshCaret(); + } +} + +void Ctrl::AnimateCaret() +{ + GuiLock __; + int v = !(((GetTickCount() - WndCaretTime) / 500) & 1); + if(v != WndCaretVisible) { + RefreshCaret(); + WndCaretVisible = v; + } +} + Rect Ctrl::GetWndScreenRect() const { GuiLock __; @@ -313,22 +372,20 @@ void Ctrl::SetAlpha(byte alpha) Rect Ctrl::GetWorkArea() const { GuiLock __; - return Rect(); + return GetWorkArea(GetRect().TopLeft()); } void Ctrl::GetWorkArea(Array& rc) { GuiLock __; -} - -Rect Ctrl::GetVirtualWorkArea() -{ - Rect out = GetPrimaryWorkArea(); - Array rc; - GetWorkArea(rc); - for(int i = 0; i < rc.GetCount(); i++) - out |= rc[i]; - return out; + GdkScreen *s = gdk_screen_get_default(); + int n = gdk_screen_get_n_monitors(s); + rc.Clear(); + for(int i = 0; i < n; i++) { + GdkRectangle r; + gdk_screen_get_monitor_geometry(s, i, &r); // TODO: Use WorkArea (for GTK 3.4) + rc.Add(RectC(r.x, r.y, r.width, r.height)); + } } Rect Ctrl::GetWorkArea(Point pt) @@ -341,21 +398,35 @@ Rect Ctrl::GetWorkArea(Point pt) return GetPrimaryWorkArea(); } +Rect Ctrl::GetVirtualWorkArea() +{ + Rect out = GetPrimaryWorkArea(); + Array rc; + GetWorkArea(rc); + for(int i = 0; i < rc.GetCount(); i++) + out |= rc[i]; + return out; +} + Rect Ctrl::GetVirtualScreenArea() { GuiLock __; - return Rect(); + gint x, y, width, height; + gdk_window_get_geometry(gdk_screen_get_root_window(gdk_screen_get_default()), + &x, &y, &width, &height, NULL); + return RectC(x, y, width, height); } Rect Ctrl::GetPrimaryWorkArea() { - Rect r; - return r; + Array rc; + GetWorkArea(rc); + return rc.GetCount() ? rc[0] : RectC(0, 0, 0, 0); } Rect Ctrl::GetPrimaryScreenArea() { - return Size(); + return GetPrimaryWorkArea(); } int Ctrl::GetKbdDelay() @@ -373,35 +444,52 @@ int Ctrl::GetKbdSpeed() void Ctrl::SetWndForeground0() { GuiLock __; - gtk_window_present((GtkWindow *)top->window); + if(top) + gtk_window_present(gtk()); } bool Ctrl::IsWndForeground() const { GuiLock __; - return gtk_window_is_active((GtkWindow *)top->window); + return top && gtk_window_is_active(gtk()); } void Ctrl::WndEnable0(bool *b) { GuiLock __; + if(top) + gtk_widget_set_sensitive(top->window, *b); } void Ctrl::SetWndFocus0(bool *b) { GuiLock __; + if(top) { + gtk_widget_grab_focus(top->window); + *b = true; + } } bool Ctrl::HasWndFocus() const { GuiLock __; - return false; + return top && gtk_widget_is_focus(top->window); } +Ptr Ctrl::grabwindow; + bool Ctrl::SetWndCapture() { GuiLock __; ASSERT(IsMainThread()); + if(grabwindow) + ReleaseWndCapture(); + if(gdk_pointer_grab(gdk(), FALSE, + GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK), + NULL, NULL, gtk_get_current_event_time()) == GDK_GRAB_SUCCESS) { + grabwindow = this; + return true; + } return false; } @@ -409,18 +497,21 @@ bool Ctrl::ReleaseWndCapture() { GuiLock __; ASSERT(IsMainThread()); - return false; + gdk_pointer_ungrab(gtk_get_current_event_time()); + grabwindow = NULL; + return true; } bool Ctrl::HasWndCapture() const { GuiLock __; - return false; + return this == grabwindow && gdk_pointer_is_grabbed(); } void Ctrl::WndInvalidateRect(const Rect& r) { GuiLock __; + LLOG("WndInvalidateRect " << rect); gdk_window_invalidate_rect(gdk(), GdkRect(r), true); } @@ -439,10 +530,7 @@ void Ctrl::WndUpdate0r(const Rect& r) void Ctrl::WndScrollView0(const Rect& r, int dx, int dy) { GuiLock __; -} - -void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) -{ + gdk_window_invalidate_rect(gdk(), GdkRect(r), true); } Rect Ctrl::GetDefaultWindowRect() { diff --git a/rainbow/GtkMain/GtkMain.upp b/rainbow/GtkMain/GtkMain.upp index 3b835eb6b..b136bc7f8 100644 --- a/rainbow/GtkMain/GtkMain.upp +++ b/rainbow/GtkMain/GtkMain.upp @@ -7,5 +7,6 @@ file main.cpp; mainconfig - "" = "GUI SSE2 GTK"; + "" = "GUI SSE2 GTK", + "" = "GUI SSE2"; diff --git a/rainbow/GtkMain/main.cpp b/rainbow/GtkMain/main.cpp index 59b7488df..a3c424471 100644 --- a/rainbow/GtkMain/main.cpp +++ b/rainbow/GtkMain/main.cpp @@ -68,11 +68,13 @@ struct MyApp : TopWindow { virtual bool Key(dword key, int count) { Log(GetKeyDesc(key).Cat() << ' ' << count); + return false; } virtual void MouseMove(Point p, dword keyflags) { pos = p; + SetCaret(p.x, 0, 5, 5); Refresh(); } @@ -85,7 +87,7 @@ struct MyApp : TopWindow { return Image::Hand(); if(p.x < 3 * sz.cx / 4) return CtrlImg::ibeam0(); - return CtrlImg::HelpCursor0(); + return (msecs() / 500) & 1 ? CtrlImg::HelpCursor1() : CtrlImg::HelpCursor0(); } virtual void Paint(Draw& w) { @@ -105,8 +107,9 @@ struct MyApp : TopWindow { w.DrawText(100, y, log[i]); y += fcy; } - w.DrawRect(0, 0, 50, fcy * 3, InvertColor()); } + + EditString text; MyApp() { Sizeable().Zoomable().Title("Event test"); @@ -115,19 +118,70 @@ struct MyApp : TopWindow { } }; +struct MyApp2 : TopWindow { + DocEdit text; +/* + virtual void Activate() + { + LOG("Activate"); + } + + virtual void Deactivate() + { + LOG("Deactivate"); + } + + virtual void Layout() + { + LOG("Layout"); + } + + virtual void GotFocus() + { + LOG("GotFocus"); + } + + virtual void LostFocus() + { + LOG("LostFocus"); + } +*/ + MyApp2() { + Zoomable(). + Sizeable(). + Title("Widget test"); + Add(text.SizePos()); + text <<= "Test\nHello World!"; + + DDUMP(Ctrl::GetWorkArea()); + } +}; + GUI_APP_MAIN { - MyApp().Run(); - return; +#if 0 + String txt = "Test"; + EditText(txt, "Test", "Test"); + return; +#endif + +#if 0 + MyApp2().Run(); + return; +#endif + +#if 0 PromptOK("Hello world!"); return; +#endif -/* +#if 1 RichEditWithToolBar edit; - edit.SetQTF("[A500 Hello World!"); + edit.SetQTF("[A9 Hello World!"); TopWindow win; + win.Sizeable(); win.Add(edit.SizePos()); win.Run(); -*/ +#endif }