From 0907b4e120f111028500f02378f7ac28348f4eae Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 8 Dec 2012 14:14:33 +0000 Subject: [PATCH] .gtk git-svn-id: svn://ultimatepp.org/upp/trunk@5630 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/DevDraw/DevDraw.upp | 6 ++ rainbow/DevDraw/init | 4 + rainbow/DevDraw/main.cpp | 103 ++++++++++++++++++ rainbow/Gtk/After.h | 31 +----- rainbow/Gtk/App.cpp | 16 +++ rainbow/Gtk/Ctrl.h | 21 +++- rainbow/Gtk/Gtk.h | 4 +- rainbow/Gtk/Gtk.upp | 1 + rainbow/Gtk/Keys.h | 202 ++++++++++++++++++------------------ rainbow/Gtk/Proc.cpp | 27 ++++- rainbow/Gtk/Top.cpp | 3 +- rainbow/Gtk/Wnd.cpp | 95 +++++++++++++---- rainbow/GtkMain/main.cpp | 183 ++++++++++---------------------- 13 files changed, 416 insertions(+), 280 deletions(-) create mode 100644 rainbow/DevDraw/DevDraw.upp create mode 100644 rainbow/DevDraw/init create mode 100644 rainbow/DevDraw/main.cpp create mode 100644 rainbow/Gtk/App.cpp diff --git a/rainbow/DevDraw/DevDraw.upp b/rainbow/DevDraw/DevDraw.upp new file mode 100644 index 000000000..b5be94b68 --- /dev/null +++ b/rainbow/DevDraw/DevDraw.upp @@ -0,0 +1,6 @@ +uses + Draw; + +file + main.cpp; + diff --git a/rainbow/DevDraw/init b/rainbow/DevDraw/init new file mode 100644 index 000000000..ef6b91d46 --- /dev/null +++ b/rainbow/DevDraw/init @@ -0,0 +1,4 @@ +#ifndef _DevDraw_icpp_init_stub +#define _DevDraw_icpp_init_stub +#include "Draw/init" +#endif diff --git a/rainbow/DevDraw/main.cpp b/rainbow/DevDraw/main.cpp new file mode 100644 index 000000000..a10e8dfa0 --- /dev/null +++ b/rainbow/DevDraw/main.cpp @@ -0,0 +1,103 @@ +#include +#include + +using namespace Upp; + +void TestDraw(Draw& w) +{ + w.DrawRect(0, 0, 10000, 10000, WhiteGray()); + w.DrawRect(0, 0, 100, 100, Yellow()); + + w.DrawLine(10, 40, 400, 20, 3, Blue()); + + w.DrawImage(0, 0, CtrlImg::exclamation()); + + w.Clipoff(50, 50, 30, 30); + w.DrawImage(0, 0, CtrlImg::exclamation()); + w.End(); + + w.DrawImage(50, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10)); + + w.DrawImage(150, 50, CtrlImg::exclamation(), Red()); + w.DrawImage(150, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10), Red()); + +// w.DrawText(20, 20, "Hello GTK!", Roman(50)); + + + w.Offset(150, 50); + const char *text = "Programming is fun"; + Font fnt(Roman(60)); + FontInfo fi = fnt.Info(); + int x = 0; + Vector dx; + for(const char *s = text; *s; s++) { + int width = fi[*s]; + w.DrawRect(x, 0, width - 1, fi.GetAscent(), Color(255, 255, 200)); + w.DrawRect(x, fi.GetAscent(), width - 1, fi.GetDescent(), Color(255, 200, 255)); + w.DrawRect(x + width - 1, 0, 1, fi.GetHeight(), Black()); + dx.Add(width + 4); + x += width; + } + w.DrawRect(0, 0, 4, 4, Black()); + w.DrawText(0, 0, text, fnt); + w.DrawText(0, 70, text, fnt, Blue(), dx.GetCount(), dx.Begin()); + + w.DrawRect(50, 400, 2, 2, Black()); + w.DrawText(50, 400, 200, "Angled text", Arial(50).Underline(), Red()); + + w.DrawRect(600, 400, 2, 2, Black()); + w.DrawText(600, 400, 1000, "Angled text", Arial(50).Underline(), Black()); + w.End(); +} + +static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) +{ + SystemDraw w(gdk_cairo_create(widget->window)); + + TestDraw(w); + + cairo_destroy(w); + + return FALSE; +} + +GUI_APP_MAIN +{ + Ctrl myapp; + + { + ImageDraw w(1000, 1000); + TestDraw(w); + PNGEncoder().SaveFile("/home/cxl/test.png", w); + } + + { + ImageDraw w(1000, 1000); + TestDraw(w); + for(int i = 0; i < 100; i++) + w.Alpha().DrawRect(i * 10, 0, 10, 1000, GrayColor(255 - i)); + PNGEncoder().SaveFile("/home/cxl/test_alpha.png", w); + } + + GtkWidget *window; + +// window = gtk_window_new(GTK_WINDOW_POPUP); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_default_size((GtkWindow *)window, 1000, 600); + + GtkWidget *darea = gtk_drawing_area_new(); + gtk_container_add(GTK_CONTAINER (window), darea); + + + gtk_widget_set_events(darea, 0xffffffff); + g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), &myapp); + g_signal_connect(darea, "event", G_CALLBACK(CtrlEvent), &myapp); +// g_signal_connect(window, "expose-event", G_CALLBACK(on_expose_event), NULL); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + gtk_widget_show_all(window); + + Ctrl::EventLoop(&myapp); +// gtk_main(); +} diff --git a/rainbow/Gtk/After.h b/rainbow/Gtk/After.h index 4f36409d6..1e3593b4a 100644 --- a/rainbow/Gtk/After.h +++ b/rainbow/Gtk/After.h @@ -4,33 +4,16 @@ public: ~ViewDraw(); }; -Vector& coreCmdLine__(); -Vector SplitCmdLine__(const char *cmd); +class DHCtrl : Ctrl {}; -#ifdef PLATFORM_WIN32 +void InitGtkApp(int argc, char **argv, const char **envptr); -#define GUI_APP_MAIN \ -void GuiMainFn_();\ -\ -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow) \ -{ \ - UPP::coreCmdLine__() = UPP::SplitCmdLine__(UPP::FromSystemCharset(lpCmdLine)); \ - UPP::AppInitEnvironment__(); \ - GuiMainFn_(); \ - UPP::Ctrl::CloseTopCtrls(); \ - return UPP::GetExitCode(); \ -} \ -\ -void GuiMainFn_() - -#endif - -#ifdef PLATFORM_POSIX #define GUI_APP_MAIN \ void GuiMainFn_(); \ \ -int main(int argc, const char **argv, const char **envptr) { \ - UPP::AppInit__(argc, argv, envptr); \ +int main(int argc, char **argv, const char **envptr) { \ + UPP::AppInit__(argc, (const char **)argv, envptr); \ + UPP::InitGtkApp(argc, argv, envptr); \ GuiMainFn_(); \ UPP::Ctrl::CloseTopCtrls(); \ UPP::AppExit__(); \ @@ -38,7 +21,3 @@ int main(int argc, const char **argv, const char **envptr) { \ } \ \ void GuiMainFn_() - -#endif - -class DHCtrl : Ctrl {}; diff --git a/rainbow/Gtk/App.cpp b/rainbow/Gtk/App.cpp new file mode 100644 index 000000000..985d5a65e --- /dev/null +++ b/rainbow/Gtk/App.cpp @@ -0,0 +1,16 @@ +#include + +#ifdef GUI_GTK + +NAMESPACE_UPP + +void InitGtkApp(int argc, char **argv, const char **envptr) +{ + gtk_init(0, NULL); + Ctrl::GlobalBackBuffer(); + SetStdFont(Arial(12)); +} + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/Gtk/Ctrl.h b/rainbow/Gtk/Ctrl.h index 02759f9c5..c4c302149 100644 --- a/rainbow/Gtk/Ctrl.h +++ b/rainbow/Gtk/Ctrl.h @@ -1,11 +1,28 @@ //$ class Ctrl { - void Create(bool popup); + void Create(Ctrl *owner, bool popup); + static gboolean GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data); + static void IMCommit(GtkIMContext *context, gchar *str, gpointer user_data); + bool Proc(GdkEvent *event); void GtkMouseEvent(int action, GdkEvent *event); + + GdkWindow *gdk() { return top->window->window; } - GdkWindow *win() { return top->window->window; } + struct Win : Moveable { + GtkWidget *gtk; + GdkWindow *gdk; + Ctrl *ctrl; + }; + + static Vector wins; + int FindCtrl(Ctrl *ctrl); + int FindGtkWindow(GtkWidget *gtk); + int FindGdkWindow(GdkWindow *gdk); + + static void FocusSync(); + public: static void EndSession() {} static bool IsEndSession() { return false; } diff --git a/rainbow/Gtk/Gtk.h b/rainbow/Gtk/Gtk.h index 3444dd697..08e34b294 100644 --- a/rainbow/Gtk/Gtk.h +++ b/rainbow/Gtk/Gtk.h @@ -1,6 +1,7 @@ #define GUI_GTK #include +#include NAMESPACE_UPP @@ -120,7 +121,8 @@ void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rec //$ struct Ctrl::Top { #define GUIPLATFORM_CTRL_TOP_DECLS \ - GtkWidget *window; \ + GtkWidget *window; \ + GtkIMContext *im_context; \ //$ } #define GUIPLATFORM_CTRL_DECLS_INCLUDE diff --git a/rainbow/Gtk/Gtk.upp b/rainbow/Gtk/Gtk.upp index b0e2aed8a..6fcfbf953 100644 --- a/rainbow/Gtk/Gtk.upp +++ b/rainbow/Gtk/Gtk.upp @@ -12,6 +12,7 @@ file Ctrl.cpp, Wnd.cpp, Proc.cpp, + App.cpp, Top.h, Top.cpp, Clip.cpp, diff --git a/rainbow/Gtk/Keys.h b/rainbow/Gtk/Keys.h index 65bf2f058..f9c0a40ae 100644 --- a/rainbow/Gtk/Keys.h +++ b/rainbow/Gtk/Keys.h @@ -1,109 +1,111 @@ -K_BACK = 53000, -K_BACKSPACE, +K_BACK = 8, +K_BACKSPACE = 8, -K_TAB, +K_TAB = 9, -K_SPACE, +K_RETURN = 13, +K_ENTER = 13, +K_ESCAPE = 27, -K_RETURN, -K_ENTER, +K_SPACE = 32, -K_SHIFT_KEY, -K_CTRL_KEY, -K_ALT_KEY, -K_CAPSLOCK, -K_ESCAPE, -K_PRIOR, -K_PAGEUP, -K_NEXT, -K_PAGEDOWN, -K_END, -K_HOME, -K_LEFT, -K_UP, -K_RIGHT, -K_DOWN, -K_INSERT, -K_DELETE, +K_DELETE = GDK_KEY_Delete|K_DELTA, -K_NUMPAD0, -K_NUMPAD1, -K_NUMPAD2, -K_NUMPAD3, -K_NUMPAD4, -K_NUMPAD5, -K_NUMPAD6, -K_NUMPAD7, -K_NUMPAD8, -K_NUMPAD9, -K_MULTIPLY, -K_ADD, -K_SEPARATOR, -K_SUBTRACT, -K_DECIMAL, -K_DIVIDE, -K_SCROLL, +K_SHIFT_KEY = GDK_KEY_Shift_L|K_DELTA, +K_CTRL_KEY = GDK_KEY_Control_L|K_DELTA, +K_ALT_KEY = GDK_KEY_Meta_L|K_DELTA, +K_CAPSLOCK = GDK_KEY_Caps_Lock|K_DELTA, +K_PRIOR = GDK_KEY_Page_Up|K_DELTA, +K_PAGEUP = GDK_KEY_Page_Up|K_DELTA, +K_NEXT = GDK_KEY_Page_Down|K_DELTA, +K_PAGEDOWN = GDK_KEY_Page_Down|K_DELTA, +K_END = GDK_KEY_End|K_DELTA, +K_HOME = GDK_KEY_Home|K_DELTA, +K_LEFT = GDK_KEY_Left|K_DELTA, +K_UP = GDK_KEY_Up|K_DELTA, +K_RIGHT = GDK_KEY_Right|K_DELTA, +K_DOWN = GDK_KEY_Down|K_DELTA, +K_INSERT = GDK_KEY_Insert|K_DELTA, -K_F1, -K_F2, -K_F3, -K_F4, -K_F5, -K_F6, -K_F7, -K_F8, -K_F9, -K_F10, -K_F11, -K_F12, +K_NUMPAD0 = GDK_KEY_KP_0|K_DELTA, +K_NUMPAD1 = GDK_KEY_KP_1|K_DELTA, +K_NUMPAD2 = GDK_KEY_KP_2|K_DELTA, +K_NUMPAD3 = GDK_KEY_KP_3|K_DELTA, +K_NUMPAD4 = GDK_KEY_KP_4|K_DELTA, +K_NUMPAD5 = GDK_KEY_KP_5|K_DELTA, +K_NUMPAD6 = GDK_KEY_KP_6|K_DELTA, +K_NUMPAD7 = GDK_KEY_KP_7|K_DELTA, +K_NUMPAD8 = GDK_KEY_KP_8|K_DELTA, +K_NUMPAD9 = GDK_KEY_KP_9|K_DELTA, +K_MULTIPLY = GDK_KEY_KP_Multiply|K_DELTA, +K_ADD = GDK_KEY_KP_Add|K_DELTA, +K_SEPARATOR = GDK_KEY_KP_Separator|K_DELTA, +K_SUBTRACT = GDK_KEY_KP_Subtract|K_DELTA, +K_DECIMAL = GDK_KEY_KP_Decimal|K_DELTA, +K_DIVIDE = GDK_KEY_KP_Divide|K_DELTA, -K_A, -K_B, -K_C, -K_D, -K_E, -K_F, -K_G, -K_H, -K_I, -K_J, -K_K, -K_L, -K_M, -K_N, -K_O, -K_P, -K_Q, -K_R, -K_S, -K_T, -K_U, -K_V, -K_W, -K_X, -K_Y, -K_Z, -K_0, -K_1, -K_2, -K_3, -K_4, -K_5, -K_6, -K_7, -K_8, -K_9, +K_SCROLL = GDK_KEY_Scroll_Lock|K_DELTA, -K_CTRL_LBRACKET, -K_CTRL_RBRACKET, -K_CTRL_MINUS, -K_CTRL_GRAVE, -K_CTRL_SLASH, -K_CTRL_BACKSLASH, -K_CTRL_COMMA, -K_CTRL_PERIOD, -K_CTRL_SEMICOLON, -K_CTRL_EQUAL, -K_CTRL_APOSTROPHE, +K_F1 = GDK_KEY_F1|K_DELTA, +K_F2 = GDK_KEY_F2|K_DELTA, +K_F3 = GDK_KEY_F3|K_DELTA, +K_F4 = GDK_KEY_F4|K_DELTA, +K_F5 = GDK_KEY_F5|K_DELTA, +K_F6 = GDK_KEY_F6|K_DELTA, +K_F7 = GDK_KEY_F7|K_DELTA, +K_F8 = GDK_KEY_F8|K_DELTA, +K_F9 = GDK_KEY_F9|K_DELTA, +K_F10 = GDK_KEY_F10|K_DELTA, +K_F11 = GDK_KEY_F11|K_DELTA, +K_F12 = GDK_KEY_F12|K_DELTA, -K_BREAK, +K_A = GDK_KEY_A|K_DELTA, +K_B = GDK_KEY_B|K_DELTA, +K_C = GDK_KEY_C|K_DELTA, +K_D = GDK_KEY_D|K_DELTA, +K_E = GDK_KEY_E|K_DELTA, +K_F = GDK_KEY_F|K_DELTA, +K_G = GDK_KEY_G|K_DELTA, +K_H = GDK_KEY_H|K_DELTA, +K_I = GDK_KEY_I|K_DELTA, +K_J = GDK_KEY_J|K_DELTA, +K_K = GDK_KEY_K|K_DELTA, +K_L = GDK_KEY_L|K_DELTA, +K_M = GDK_KEY_M|K_DELTA, +K_N = GDK_KEY_N|K_DELTA, +K_O = GDK_KEY_O|K_DELTA, +K_P = GDK_KEY_P|K_DELTA, +K_Q = GDK_KEY_Q|K_DELTA, +K_R = GDK_KEY_R|K_DELTA, +K_S = GDK_KEY_S|K_DELTA, +K_T = GDK_KEY_T|K_DELTA, +K_U = GDK_KEY_U|K_DELTA, +K_V = GDK_KEY_V|K_DELTA, +K_W = GDK_KEY_W|K_DELTA, +K_X = GDK_KEY_X|K_DELTA, +K_Y = GDK_KEY_Y|K_DELTA, +K_Z = GDK_KEY_Z|K_DELTA, +K_0 = GDK_KEY_0|K_DELTA, +K_1 = GDK_KEY_1|K_DELTA, +K_2 = GDK_KEY_2|K_DELTA, +K_3 = GDK_KEY_3|K_DELTA, +K_4 = GDK_KEY_4|K_DELTA, +K_5 = GDK_KEY_5|K_DELTA, +K_6 = GDK_KEY_6|K_DELTA, +K_7 = GDK_KEY_7|K_DELTA, +K_8 = GDK_KEY_8|K_DELTA, +K_9 = GDK_KEY_9|K_DELTA, + +K_CTRL_LBRACKET = K_CTRL|GDK_KEY_bracketleft|K_DELTA, +K_CTRL_RBRACKET = K_CTRL|GDK_KEY_bracketright|K_DELTA, +K_CTRL_MINUS = K_CTRL|GDK_KEY_minus|K_DELTA, +K_CTRL_GRAVE = K_CTRL|GDK_KEY_grave|K_DELTA, +K_CTRL_SLASH = K_CTRL|GDK_KEY_slash|K_DELTA, +K_CTRL_BACKSLASH = K_CTRL|GDK_KEY_backslash|K_DELTA, +K_CTRL_COMMA = K_CTRL|GDK_KEY_comma|K_DELTA, +K_CTRL_PERIOD = K_CTRL|GDK_KEY_period|K_DELTA, +K_CTRL_SEMICOLON = K_CTRL|GDK_KEY_semicolon|K_DELTA, +K_CTRL_EQUAL = K_CTRL|GDK_KEY_equal|K_DELTA, +K_CTRL_APOSTROPHE= K_CTRL|GDK_KEY_apostrophe|K_DELTA, + +K_BREAK = GDK_KEY_Break|K_DELTA, diff --git a/rainbow/Gtk/Proc.cpp b/rainbow/Gtk/Proc.cpp index 20a31d501..1fc1a22b2 100644 --- a/rainbow/Gtk/Proc.cpp +++ b/rainbow/Gtk/Proc.cpp @@ -10,6 +10,8 @@ NAMESPACE_UPP #define LLOG(x) // LOG(x) + + bool GetShift() { return false; } bool GetCtrl() { return false; } bool GetAlt() { return false; } @@ -28,8 +30,18 @@ void Ctrl::GtkMouseEvent(int action, GdkEvent *event) bool Ctrl::Proc(GdkEvent *event) { - DDUMP((int)event->type); + if(!top) + return false; + GdkEventKey *key; + bool pressed = false; + int kv; switch(event->type) { + case GDK_FOCUS_CHANGE: + if(((GdkEventFocus *)event)->in) + gtk_im_context_focus_in(top->im_context); + else + gtk_im_context_focus_out(top->im_context); + break; case GDK_EXPOSE: case GDK_DAMAGE: { fullrefresh = false; @@ -56,7 +68,18 @@ bool Ctrl::Proc(GdkEvent *event) case GDK_BUTTON_RELEASE: GtkMouseEvent(UP, event); break; - default:; + case GDK_KEY_PRESS: + pressed = true; + key = (GdkEventKey *)event; + case GDK_KEY_RELEASE: + key = (GdkEventKey *)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); + break; + default: return false; } return false; diff --git a/rainbow/Gtk/Top.cpp b/rainbow/Gtk/Top.cpp index ef4a0a107..f922d17fc 100644 --- a/rainbow/Gtk/Top.cpp +++ b/rainbow/Gtk/Top.cpp @@ -21,10 +21,9 @@ void TopWindow::SyncCaption0() void TopWindow::Open(Ctrl *owner) { GuiLock __; - DDUMP(GetRect()); if(GetSize().cx == 0) SetRect(10, 10, 400, 400); - Create(false); + Create(owner, false); } void TopWindow::Open() diff --git a/rainbow/Gtk/Wnd.cpp b/rainbow/Gtk/Wnd.cpp index 52522cf7c..d7be26bad 100644 --- a/rainbow/Gtk/Wnd.cpp +++ b/rainbow/Gtk/Wnd.cpp @@ -14,6 +14,32 @@ NAMESPACE_UPP #define ELOGW(x) // RLOG(GetSysTime() << ": " << x) // Only activate in MT! #define ELOG(x) // RLOG(GetSysTime() << ": " << x) +Vector Ctrl::wins; + +int Ctrl::FindCtrl(Ctrl *ctrl) +{ + for(int i = 0; i < wins.GetCount(); i++) + if(wins[i].ctrl == ctrl) + return i; + return -1; +} + +int Ctrl::FindGtkWindow(GtkWidget *gtk) +{ + for(int i = 0; i < wins.GetCount(); i++) + if(wins[i].gtk == gtk) + return i; + return -1; +} + +int Ctrl::FindGdkWindow(GdkWindow *gdk) +{ + for(int i = 0; i < wins.GetCount(); i++) + if(wins[i].gdk == gdk) + return i; + return -1; +} + bool Ctrl::IsAlphaSupported() { return false; @@ -26,11 +52,19 @@ bool Ctrl::IsCompositedGui() gboolean Ctrl::GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data) { - Ctrl *q = (Ctrl *)user_data; - return q->Proc(event); + bool b = ((Ctrl *)(user_data))->Proc(event); + FocusSync(); + return b; } -void Ctrl::Create(bool popup) +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); +} + +void Ctrl::Create(Ctrl *owner, bool popup) { GuiLock __; ASSERT(IsMainThread()); @@ -42,15 +76,34 @@ void Ctrl::Create(bool popup) top->window = gtk_window_new(popup ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); gtk_widget_set_events(top->window, 0xffffffff); g_signal_connect(top->window, "event", G_CALLBACK(GtkProc), this); + if(owner && owner->top) + gtk_window_set_transient_for((GtkWindow *)top->window, (GtkWindow *)owner->top->window); gtk_widget_set_app_paintable(top->window, TRUE); gtk_widget_show_all(top->window); isopen = true; + + top->im_context = gtk_im_multicontext_new(); + gtk_im_context_set_client_window(top->im_context, gdk()); + gtk_im_context_set_use_preedit(top->im_context, false); + g_signal_connect(top->im_context, "commit", G_CALLBACK(IMCommit), this); + + Win& w = wins.Add(); + w.ctrl = this; + w.gtk = top->window; + w.gdk = top->window->window; + FocusSync(); } void Ctrl::WndDestroy0() { gtk_widget_destroy(top->window); + g_object_unref(top->im_context); isopen = false; + delete top; + top = NULL; + int q = FindCtrl(this); + if(q >= 0) + wins.Remove(q); } Vector Ctrl::GetTopCtrls() @@ -163,14 +216,7 @@ void Ctrl::EventLoop0(Ctrl *ctrl) if(IsEndSession()) break; // LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); DLOG("Before gtk_main"); - gtk_main(); - - DLOG("After gtk_main"); - if(ctrl) { - DDUMP(ctrl->IsOpen()); - DDUMP(ctrl->InLoop()); - } } if(ctrl) @@ -184,6 +230,23 @@ void Ctrl::GuiSleep0(int ms) GuiLock __; } +void Ctrl::FocusSync() +{ + GuiLock __; + Ctrl *focus = NULL; + static Ctrl *ctrl; + for(int i = 0; i < wins.GetCount(); i++) + if(gtk_window_is_active((GtkWindow *)wins[i].gtk)) + focus = wins[i].ctrl; + if(focus != ctrl) { + if(ctrl) + ctrl->KillFocusWnd(); + ctrl = focus; + if(ctrl) + ctrl->SetFocusWnd(); + } +} + Rect Ctrl::GetWndScreenRect() const { GuiLock __; @@ -274,12 +337,13 @@ int Ctrl::GetKbdSpeed() void Ctrl::SetWndForeground0() { GuiLock __; + gtk_window_present((GtkWindow *)top->window); } bool Ctrl::IsWndForeground() const { GuiLock __; - return true; + return gtk_window_is_active((GtkWindow *)top->window); } void Ctrl::WndEnable0(bool *b) @@ -321,18 +385,13 @@ bool Ctrl::HasWndCapture() const void Ctrl::WndInvalidateRect(const Rect& r) { GuiLock __; - DLOG("WndInvalidateRect " << r); - GdkRect gr(r); - DDUMP(gr.x); - DDUMP(gr.y); - DDUMP(gr.width); - DDUMP(gr.height); - gdk_window_invalidate_rect(win(), &gr, true); + gdk_window_invalidate_rect(gdk(), GdkRect(r), true); } void Ctrl::WndSetPos0(const Rect& rect) { GuiLock __; + gdk_window_move_resize(gdk(), rect.left, rect.top, rect.GetWidth(), rect.GetHeight()); } void Ctrl::WndUpdate0r(const Rect& r) diff --git a/rainbow/GtkMain/main.cpp b/rainbow/GtkMain/main.cpp index 8f89ebdcd..8f3db2b4b 100644 --- a/rainbow/GtkMain/main.cpp +++ b/rainbow/GtkMain/main.cpp @@ -3,88 +3,45 @@ using namespace Upp; -void TestDraw(Draw& w) -{ - w.DrawRect(0, 0, 10000, 10000, WhiteGray()); - w.DrawRect(0, 0, 100, 100, Yellow()); - - w.DrawLine(10, 40, 400, 20, 3, Blue()); - - w.DrawImage(0, 0, CtrlImg::exclamation()); - - w.Clipoff(50, 50, 30, 30); - w.DrawImage(0, 0, CtrlImg::exclamation()); - w.End(); - - w.DrawImage(50, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10)); - - w.DrawImage(150, 50, CtrlImg::exclamation(), Red()); - w.DrawImage(150, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10), Red()); - -// w.DrawText(20, 20, "Hello GTK!", Roman(50)); - - - w.Offset(150, 50); - const char *text = "Programming is fun"; - Font fnt(Roman(60)); - FontInfo fi = fnt.Info(); - int x = 0; - Vector dx; - for(const char *s = text; *s; s++) { - int width = fi[*s]; - w.DrawRect(x, 0, width - 1, fi.GetAscent(), Color(255, 255, 200)); - w.DrawRect(x, fi.GetAscent(), width - 1, fi.GetDescent(), Color(255, 200, 255)); - w.DrawRect(x + width - 1, 0, 1, fi.GetHeight(), Black()); - dx.Add(width + 4); - x += width; - } - w.DrawRect(0, 0, 4, 4, Black()); - w.DrawText(0, 0, text, fnt); - w.DrawText(0, 70, text, fnt, Blue(), dx.GetCount(), dx.Begin()); - - w.DrawRect(50, 400, 2, 2, Black()); - w.DrawText(50, 400, 200, "Angled text", Arial(50).Underline(), Red()); - - w.DrawRect(600, 400, 2, 2, Black()); - w.DrawText(600, 400, 1000, "Angled text", Arial(50).Underline(), Black()); - w.End(); -} - -static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - SystemDraw w(gdk_cairo_create(widget->window)); - - TestDraw(w); - - cairo_destroy(w); - - return FALSE; -} - -gboolean CtrlEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - Ctrl *ctrl = (Ctrl *)user_data; - DDUMP((int)event->type); - switch(event->type) { - case GDK_MOTION_NOTIFY: { - GdkEventMotion *e = (GdkEventMotion *)event; - DLOG("Motion"); - DDUMP(e->x); - DDUMP(e->y); - DDUMP(e->state); - return true; - } - case GDK_BUTTON_PRESS: - DLOG("EndLoop!"); - ctrl->EndLoop(); - return true; - default:; - } - return false; -} - struct MyApp : TopWindow { - Point pos; + Point pos; + Vector log; + + void Log(const String& s) + { + log.Add(s); + log.Remove(0, max(log.GetCount() - 16, 0)); + } + + virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags) + { + static Tuple2 map[] = { + { 0x10, "MOUSEENTER" }, + { 0x20, "MOUSEMOVE" }, + { 0x30, "MOUSELEAVE" }, + { 0x40, "CURSORIMAGE" }, + { 0x50, "MOUSEWHEEL" }, + { 0x80, "DOWN" }, + { 0x90, "UP" }, + { 0xa0, "DOUBLE" }, + { 0xb0, "REPEAT" }, + { 0xc0, "DRAG" }, + { 0xd0, "HOLD" }, + { 0xe0, "TRIPLE" }, + }; + Tuple2 *a = FindTuple(map, __countof(map), event & BUTTON); + Tuple2 *b = FindTuple(map, __countof(map), event & ACTION); + Log(String().Cat() << "MOUSE " << (a ? a->b : "") << '|' << (b ? b->b : "") << ' ' << p); + + Refresh(); + return TopWindow::MouseEvent(event, p, zdelta, keyflags); + } + + virtual bool Key(dword key, int count) + { + Log(GetKeyDesc(key).Cat() << ' ' << count); + Refresh(); + } virtual void MouseMove(Point p, dword keyflags) { @@ -96,34 +53,27 @@ struct MyApp : TopWindow { } virtual void Paint(Draw& w) { + int fcy = GetStdFontCy(); w.DrawRect(GetSize(), White()); - w.DrawText(10, 10, AsString(pos)); + int y = 0; + w.DrawText(0, y += fcy, AsString(pos)); + w.DrawText(0, y += fcy, String().Cat() << "Shift: " << (int)GetShift()); + w.DrawText(0, y += fcy, String().Cat() << "Ctrl: " << (int)GetCtrl()); + w.DrawText(0, y += fcy, String().Cat() << "Alt: " << (int)GetAlt()); + w.DrawText(0, y += fcy, String().Cat() << "CapsLock: " << (int)GetCapsLock()); + w.DrawText(0, y += fcy, String().Cat() << "MouseLeft: " << (int)GetMouseLeft()); + w.DrawText(0, y += fcy, String().Cat() << "MouseRight: " << (int)GetMouseRight()); + w.DrawText(0, y += fcy, String().Cat() << "MouseMiddle: " << (int)GetMouseMiddle()); + y = 0; + for(int i = 0; i < log.GetCount(); i++) { + w.DrawText(100, y, log[i]); + y += fcy; + } } }; -CONSOLE_APP_MAIN +GUI_APP_MAIN { - Ctrl myapp; - - { - ImageDraw w(1000, 1000); - TestDraw(w); - PNGEncoder().SaveFile("/home/cxl/test.png", w); - } - - { - ImageDraw w(1000, 1000); - TestDraw(w); - for(int i = 0; i < 100; i++) - w.Alpha().DrawRect(i * 10, 0, 10, 1000, GrayColor(255 - i)); - PNGEncoder().SaveFile("/home/cxl/test_alpha.png", w); - } - -// gtk_init(&argc, &argv); - gtk_init(0, NULL); - Ctrl::GlobalBackBuffer(); - -#if 1 // MyApp().Run(); // return; @@ -135,29 +85,4 @@ CONSOLE_APP_MAIN TopWindow win; win.Add(edit.SizePos()); win.Run(); - -// MyApp().Run(); -#else - GtkWidget *window; - -// window = gtk_window_new(GTK_WINDOW_POPUP); - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_default_size((GtkWindow *)window, 1000, 600); - - GtkWidget *darea = gtk_drawing_area_new(); - gtk_container_add(GTK_CONTAINER (window), darea); - - - gtk_widget_set_events(darea, 0xffffffff); - g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), &myapp); - g_signal_connect(darea, "event", G_CALLBACK(CtrlEvent), &myapp); -// g_signal_connect(window, "expose-event", G_CALLBACK(on_expose_event), NULL); - g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - - gtk_widget_show_all(window); - - Ctrl::EventLoop(&myapp); -// gtk_main(); -#endif }