From 768a928dd3888efb8a433ac90a9a8cda66b8a976 Mon Sep 17 00:00:00 2001 From: gambas Date: Mon, 8 Mar 2021 00:02:32 +0100 Subject: [PATCH] UserControl: Support for the 'Change' pseudo event. Use the new GB_FUNCTION structure to optimize support of UserControl_* pseudo event handlers. [GB.GTK] * NEW: UserControl: Support for the 'Change' pseudo event. * OPT: UserControl: Use the new GB_FUNCTION structure to optimize support of UserControl_* pseudo event handlers. [GB.GTK3] * NEW: UserControl: Support for the 'Change' pseudo event. * OPT: UserControl: Use the new GB_FUNCTION structure to optimize support of UserControl_* pseudo event handlers. [GB.QT4] * NEW: UserControl: Support for the 'Change' pseudo event. * OPT: UserControl: Use the new GB_FUNCTION structure to optimize support of UserControl_* pseudo event handlers. [GB.QT5] * NEW: UserControl: Support for the 'Change' pseudo event. * OPT: UserControl: Use the new GB_FUNCTION structure to optimize support of UserControl_* pseudo event handlers. --- gb.gtk/src/CContainer.cpp | 60 +++++++++++++++++++++++++++++---------- gb.gtk/src/CContainer.h | 6 +++- gb.gtk/src/CScreen.cpp | 14 +++++++-- gb.qt4/src/CContainer.cpp | 52 ++++++++++++++++++++++++--------- gb.qt4/src/CContainer.h | 6 +++- gb.qt4/src/CScreen.cpp | 11 +++++-- 6 files changed, 115 insertions(+), 34 deletions(-) diff --git a/gb.gtk/src/CContainer.cpp b/gb.gtk/src/CContainer.cpp index d209986c4..8be8675e5 100644 --- a/gb.gtk/src/CContainer.cpp +++ b/gb.gtk/src/CContainer.cpp @@ -27,8 +27,21 @@ #include "CContainer.h" #include "gpanel.h" #include "gmainwindow.h" +#include "gapplication.h" #include "cpaint_impl.h" +#define CALL_FUNCTION(_this, _func) \ +{ \ + if ((_this) && (_this)->_func) \ + { \ + GB_FUNCTION func; \ + func.object = (_this); \ + func.index = (_this)->_func; \ + GB.Call(&func, 0, TRUE); \ + } \ +} + + /*************************************************************************** Container @@ -75,7 +88,7 @@ void CUSERCONTROL_cb_draw(gContainer *sender, cairo_t *cr) handler.handler = (GB_CALLBACK)cleanup_drawing; GB.OnErrorBegin(&handler); - GB.Call(&THIS_USERCONTROL->paint_func, 0, TRUE); + CALL_FUNCTION(THIS_USERCONTROL, paint_func); GB.OnErrorEnd(&handler); PAINT_end(); @@ -106,7 +119,7 @@ void CUSERCONTROL_cb_draw(gContainer *sender, GdkRegion *region, int dx, int dy) handler.handler = (GB_CALLBACK)cleanup_drawing; handler.arg1 = (intptr_t)cr; GB.OnErrorBegin(&handler); - GB.Call(&THIS_USERCONTROL->paint_func, 0, TRUE); + CALL_FUNCTION(THIS_USERCONTROL, paint_func); GB.OnErrorEnd(&handler); cairo_restore(cr); @@ -118,15 +131,23 @@ void CUSERCONTROL_cb_draw(gContainer *sender, GdkRegion *region, int dx, int dy) void CUSERCONTROL_cb_font(gContainer *sender) { CWIDGET *_object = GetObject(sender); - GB_FUNCTION func; - - if (!THIS) - return; - - if (!GB.GetFunction(&func, THIS, "UserControl_Font", NULL, NULL)) - GB.Call(&func, 0, TRUE); - else - GB.Error(NULL); + CALL_FUNCTION(THIS_USERCONTROL, font_func); +} + +static bool cb_change_filter(gControl *control) +{ + return control->isContainer() && ((gContainer *)control)->isPaint(); +} + +static void cb_change(gControl *control) +{ + CWIDGET *_object = GetObject(control); + CALL_FUNCTION(THIS_USERCONTROL, change_func); +} + +void CUSERCONTROL_send_change_event(void) +{ + gApplication::forEachControl(cb_change, cb_change_filter); } static void get_client_area(gContainer *cont, int *x, int *y, int *w, int *h) @@ -456,6 +477,8 @@ GB_DESC ContainerDesc[] = BEGIN_METHOD(UserControl_new, GB_OBJECT parent) + GB_FUNCTION func; + InitControl(new gPanel(CONTAINER(VARG(parent))), (CWIDGET*)THIS); PANEL->setArrange(ARRANGE_FILL); @@ -464,12 +487,19 @@ BEGIN_METHOD(UserControl_new, GB_OBJECT parent) if (GB.Is(THIS, CLASS_UserContainer)) PANEL->setUserContainer(); - THIS_USERCONTAINER->container = THIS; + THIS_USERCONTROL->container = THIS; - if (!GB.GetFunction(&THIS_USERCONTROL->paint_func, THIS, "UserControl_Draw", NULL, NULL)) + if (!GB.GetFunction(&func, THIS, "UserControl_Draw", NULL, NULL)) + { PANEL->setPaint(); - else - GB.Error(NULL); + THIS_USERCONTROL->paint_func = func.index; + if (!GB.GetFunction(&func, THIS, "UserControl_Font", NULL, NULL)) + THIS_USERCONTROL->font_func = func.index; + if (!GB.GetFunction(&func, THIS, "UserControl_Change", NULL, NULL)) + THIS_USERCONTROL->change_func = func.index; + } + + GB.Error(NULL); END_METHOD diff --git a/gb.gtk/src/CContainer.h b/gb.gtk/src/CContainer.h index 5e642c20a..dd0da4e7c 100644 --- a/gb.gtk/src/CContainer.h +++ b/gb.gtk/src/CContainer.h @@ -94,10 +94,12 @@ typedef { CWIDGET widget; CCONTAINER *container; - GB_FUNCTION paint_func; #ifdef GTK3 cairo_t *context; #endif + ushort paint_func; + ushort font_func; + ushort change_func; } CUSERCONTROL; @@ -117,5 +119,7 @@ DECLARE_PROPERTY(Container_Centered); void CCONTAINER_cb_arrange(gContainer *sender); void CCONTAINER_cb_before_arrange(gContainer *sender); void CCONTAINER_raise_insert(CCONTAINER *_object, CWIDGET *child); +void CUSERCONTROL_send_change_event(); + #endif diff --git a/gb.gtk/src/CScreen.cpp b/gb.gtk/src/CScreen.cpp index a85260b70..94e39989c 100644 --- a/gb.gtk/src/CScreen.cpp +++ b/gb.gtk/src/CScreen.cpp @@ -26,6 +26,7 @@ #include "CWindow.h" #include "CPicture.h" #include "CFont.h" +#include "CContainer.h" #include "CDrawingArea.h" #include "CScreen.h" @@ -51,6 +52,15 @@ static CSCREEN *_screens[MAX_SCREEN] = { NULL }; static bool _animations = FALSE; static bool _shadows = FALSE; +//------------------------------------------------------------------------- + +static void send_change_event() +{ + CDRAWINGAREA_send_change_event(); + CUSERCONTROL_send_change_event(); +} + + static CSCREEN *get_screen(int num) { if (num < 0 || num >= MAX_SCREEN || num >= gDesktop::count()) @@ -252,7 +262,7 @@ BEGIN_PROPERTY(Application_Animations) else if (_animations != VPROP(GB_BOOLEAN)) { _animations = VPROP(GB_BOOLEAN); - CDRAWINGAREA_send_change_event(); + send_change_event(); } END_PROPERTY @@ -265,7 +275,7 @@ BEGIN_PROPERTY(Application_Shadows) else if (_shadows != VPROP(GB_BOOLEAN)) { _shadows = VPROP(GB_BOOLEAN); - CDRAWINGAREA_send_change_event(); + send_change_event(); } END_PROPERTY diff --git a/gb.qt4/src/CContainer.cpp b/gb.qt4/src/CContainer.cpp index 3a11af462..5f84ee475 100755 --- a/gb.qt4/src/CContainer.cpp +++ b/gb.qt4/src/CContainer.cpp @@ -55,6 +55,31 @@ //#define DEBUG_ME //#define USE_CACHE 1 +#define CALL_FUNCTION(_this, _func) \ +{ \ + if ((_this)->_func) \ + { \ + GB_FUNCTION func; \ + func.object = (_this); \ + func.index = (_this)->_func; \ + GB.Call(&func, 0, TRUE); \ + } \ +} + +static void send_change_event(CWIDGET *_object) +{ + if (GB.Is(THIS, CLASS_UserControl)) + CALL_FUNCTION(THIS_USERCONTROL, change_func); +} + +void CUSERCONTROL_send_change_event() +{ + CWidget::each(send_change_event); +} + + +//------------------------------------------------------------------------- + DECLARE_EVENT(EVENT_Insert); //DECLARE_EVENT(EVENT_Remove); DECLARE_EVENT(EVENT_BeforeArrange); @@ -816,7 +841,7 @@ void MyContainer::paintEvent(QPaintEvent *event) handler.handler = (GB_CALLBACK)cleanup_drawing; GB.OnErrorBegin(&handler); - GB.Call(&THIS_USERCONTROL->paint_func, 0, TRUE); + CALL_FUNCTION(THIS_USERCONTROL, paint_func); GB.OnErrorEnd(&handler); PAINT_end(); @@ -833,13 +858,7 @@ void MyContainer::changeEvent(QEvent *e) } if (e->type() == QEvent::FontChange) - { - GB_FUNCTION func; - if (!GB.GetFunction(&func, THIS, "UserControl_Font", NULL, NULL)) - GB.Call(&func, 0, TRUE); - else - GB.Error(NULL); - } + CALL_FUNCTION(THIS_USERCONTROL, font_func); } @@ -1205,6 +1224,7 @@ END_PROPERTY BEGIN_METHOD(UserControl_new, GB_OBJECT parent) + GB_FUNCTION func; MyContainer *wid = new MyContainer(QCONTAINER(VARG(parent))); THIS->container = wid; @@ -1213,14 +1233,20 @@ BEGIN_METHOD(UserControl_new, GB_OBJECT parent) CWIDGET_new(wid, (void *)_object); - if (!GB.GetFunction(&THIS_USERCONTROL->paint_func, THIS, "UserControl_Draw", NULL, NULL)) + if (!GB.GetFunction(&func, THIS, "UserControl_Draw", NULL, NULL)) + { THIS_ARRANGEMENT->paint = true; - else - GB.Error(NULL); - + THIS_USERCONTROL->paint_func = func.index; + if (!GB.GetFunction(&func, THIS, "UserControl_Font", NULL, NULL)) + THIS_USERCONTROL->font_func = func.index; + if (!GB.GetFunction(&func, THIS, "UserControl_Change", NULL, NULL)) + THIS_USERCONTROL->change_func = func.index; + } + + GB.Error(NULL); + END_METHOD - BEGIN_PROPERTY(UserControl_Container) void *current = (CCONTAINER *)CWidget::get(CONTAINER); diff --git a/gb.qt4/src/CContainer.h b/gb.qt4/src/CContainer.h index 83af33aa2..8bb3691d4 100644 --- a/gb.qt4/src/CContainer.h +++ b/gb.qt4/src/CContainer.h @@ -80,7 +80,9 @@ extern GB_DESC UserContainerDesc[]; typedef struct { CCONTAINER parent; - GB_FUNCTION paint_func; + ushort paint_func; + ushort font_func; + ushort change_func; } CUSERCONTROL; @@ -138,6 +140,8 @@ int CCONTAINER_get_border_width(char border); void CCONTAINER_update_design(void *_object); +void CUSERCONTROL_send_change_event(); + class MyFrame : public QWidget { Q_OBJECT diff --git a/gb.qt4/src/CScreen.cpp b/gb.qt4/src/CScreen.cpp index 0d9aa55d5..7b2696da8 100644 --- a/gb.qt4/src/CScreen.cpp +++ b/gb.qt4/src/CScreen.cpp @@ -40,6 +40,7 @@ #include "CWindow.h" #include "CFont.h" #include "CDrawingArea.h" +#include "CContainer.h" #include "CScreen.h" #ifndef QT5 @@ -105,6 +106,12 @@ static void free_screens(void) } } +static void send_change_event() +{ + CDRAWINGAREA_send_change_event(); + CUSERCONTROL_send_change_event(); +} + //------------------------------------------------------------------------- BEGIN_PROPERTY(Desktop_X) @@ -271,7 +278,7 @@ BEGIN_PROPERTY(Application_Animations) else if (_animations != VPROP(GB_BOOLEAN)) { _animations = VPROP(GB_BOOLEAN); - CDRAWINGAREA_send_change_event(); + send_change_event(); } END_PROPERTY @@ -284,7 +291,7 @@ BEGIN_PROPERTY(Application_Shadows) else if (_shadows != VPROP(GB_BOOLEAN)) { _shadows = VPROP(GB_BOOLEAN); - CDRAWINGAREA_send_change_event(); + send_change_event(); } END_PROPERTY