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.
This commit is contained in:
gambas 2021-03-08 00:02:32 +01:00
parent d5c59c123c
commit 768a928dd3
6 changed files with 115 additions and 34 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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