mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
add dragger
This commit is contained in:
parent
6e8c9ba39c
commit
a42b8f0669
11
demos/res/raw/ui/dragger.xml
Normal file
11
demos/res/raw/ui/dragger.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<window name="main" anim_hint="htranslate">
|
||||
<dragger x="0" y="5" w="20" h="20" x_min="0" x_max="200" y_min="5" y_max="5">
|
||||
<image image="earth" x="center" y="middle" w="100%" h="100%"/>
|
||||
</dragger>
|
||||
<dragger x="0" y="50" w="20" h="20" x_min="0" x_max="0" y_min="50" y_max="200">
|
||||
<image image="earth" x="center" y="middle" w="100%" h="100%"/>
|
||||
</dragger>
|
||||
<dragger x="50" y="50" w="20" h="20" x_min="0" x_max="200" y_min="0" y_max="200">
|
||||
<image image="earth" x="center" y="middle" w="100%" h="100%"/>
|
||||
</dragger>
|
||||
</window>
|
@ -161,17 +161,17 @@
|
||||
#include "res/inc/images/unchecked.data"
|
||||
#include "res/inc/images/unmuted.data"
|
||||
#include "res/inc/images/warn.data"
|
||||
#endif/*WITH_STB_IMAGE*/
|
||||
#endif /*WITH_STB_IMAGE*/
|
||||
#ifdef WITH_STB_FONT
|
||||
#ifdef WITH_MINI_FONT
|
||||
#include "res/inc/fonts/default.mini.res"
|
||||
#else/*WITH_MINI_FONT*/
|
||||
#else /*WITH_MINI_FONT*/
|
||||
#include "res/inc/fonts/default.res"
|
||||
#endif/*WITH_MINI_FONT*/
|
||||
#else/*WITH_STB_FONT*/
|
||||
#endif /*WITH_MINI_FONT*/
|
||||
#else /*WITH_STB_FONT*/
|
||||
#include "res/inc/fonts/default.data"
|
||||
#endif/*WITH_STB_FONT*/
|
||||
#endif/*WITH_FS_RES*/
|
||||
#endif /*WITH_STB_FONT*/
|
||||
#endif /*WITH_FS_RES*/
|
||||
|
||||
ret_t resource_init(void) {
|
||||
resource_manager_t* rm = resource_manager();
|
||||
|
173
src/base/dragger.c
Normal file
173
src/base/dragger.c
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* File: dragger.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: dragger
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* 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
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-01-28 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/mem.h"
|
||||
#include "base/utils.h"
|
||||
#include "base/dragger.h"
|
||||
|
||||
static ret_t dragger_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
return widget_paint_helper(widget, c, NULL, NULL);
|
||||
}
|
||||
|
||||
static ret_t dragger_move(widget_t* widget, xy_t dx, xy_t dy) {
|
||||
dragger_t* dragger = DRAGGER(widget);
|
||||
xy_t x = dragger->save_x + dx;
|
||||
xy_t y = dragger->save_y + dy;
|
||||
|
||||
x = tk_max(x, dragger->x_min);
|
||||
y = tk_max(y, dragger->y_min);
|
||||
x = tk_min(x, dragger->x_max);
|
||||
y = tk_min(y, dragger->y_max);
|
||||
|
||||
if (x != widget->x || y != widget->y) {
|
||||
event_t evt = event_init(EVT_DRAG, widget);
|
||||
widget_move(widget, x, y);
|
||||
widget_dispatch(widget, (event_t*)&evt);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t dragger_on_event(widget_t* widget, event_t* e) {
|
||||
uint16_t type = e->type;
|
||||
dragger_t* dragger = DRAGGER(widget);
|
||||
|
||||
switch (type) {
|
||||
case EVT_POINTER_DOWN: {
|
||||
pointer_event_t* pointer_event = (pointer_event_t*)e;
|
||||
event_t evt = event_init(EVT_DRAG_START, widget);
|
||||
widget_set_state(widget, WIDGET_STATE_PRESSED);
|
||||
widget_dispatch(widget, (event_t*)&evt);
|
||||
widget_grab(widget->parent, widget);
|
||||
|
||||
dragger->down_x = pointer_event->x;
|
||||
dragger->down_y = pointer_event->y;
|
||||
dragger->save_x = widget->x;
|
||||
dragger->save_y = widget->y;
|
||||
dragger_move(widget, 0, 0);
|
||||
dragger->dragging = TRUE;
|
||||
break;
|
||||
}
|
||||
case EVT_POINTER_UP: {
|
||||
pointer_event_t* pointer_event = (pointer_event_t*)e;
|
||||
event_t evt = event_init(EVT_DRAG_END, widget);
|
||||
dragger_move(widget, pointer_event->x - dragger->down_x, pointer_event->y - dragger->down_y);
|
||||
widget_set_state(widget, WIDGET_STATE_NORMAL);
|
||||
widget_dispatch(widget, (event_t*)&evt);
|
||||
widget_ungrab(widget->parent, widget);
|
||||
dragger->dragging = FALSE;
|
||||
break;
|
||||
}
|
||||
case EVT_POINTER_MOVE: {
|
||||
if (dragger->dragging) {
|
||||
pointer_event_t* pointer_event = (pointer_event_t*)e;
|
||||
dragger_move(widget, pointer_event->x - dragger->down_x,
|
||||
pointer_event->y - dragger->down_y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVT_POINTER_LEAVE:
|
||||
widget_set_state(widget, WIDGET_STATE_NORMAL);
|
||||
break;
|
||||
case EVT_POINTER_ENTER:
|
||||
widget_set_state(widget, WIDGET_STATE_OVER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t dragger_set_range(widget_t* widget, xy_t x_min, xy_t y_min, xy_t x_max, xy_t y_max) {
|
||||
dragger_t* dragger = DRAGGER(widget);
|
||||
return_value_if_fail(widget != NULL && x_min <= x_max && y_min <= y_max, RET_BAD_PARAMS);
|
||||
|
||||
dragger->x_min = x_min;
|
||||
dragger->x_max = x_max;
|
||||
dragger->y_min = y_min;
|
||||
dragger->y_max = y_max;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t dragger_get_prop(widget_t* widget, const char* name, value_t* v) {
|
||||
dragger_t* dragger = DRAGGER(widget);
|
||||
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_eq(name, WIDGET_PROP_X_MIN)) {
|
||||
value_set_int(v, dragger->x_min);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_X_MAX)) {
|
||||
value_set_int(v, dragger->x_max);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_Y_MIN)) {
|
||||
value_set_int(v, dragger->y_min);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_Y_MAX)) {
|
||||
value_set_int(v, dragger->y_max);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
static ret_t dragger_set_prop(widget_t* widget, const char* name, const value_t* v) {
|
||||
dragger_t* dragger = DRAGGER(widget);
|
||||
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_eq(name, WIDGET_PROP_X_MIN)) {
|
||||
dragger->x_min = value_int(v);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_X_MAX)) {
|
||||
dragger->x_max = value_int(v);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_Y_MIN)) {
|
||||
dragger->y_min = value_int(v);
|
||||
return RET_OK;
|
||||
} else if (tk_str_eq(name, WIDGET_PROP_Y_MAX)) {
|
||||
dragger->y_max = value_int(v);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
static const widget_vtable_t s_dragger_vtable = {.type_name = WIDGET_TYPE_DRAGGER,
|
||||
.set_prop = dragger_set_prop,
|
||||
.get_prop = dragger_get_prop,
|
||||
.on_event = dragger_on_event,
|
||||
.on_paint_self = dragger_on_paint_self};
|
||||
|
||||
widget_t* dragger_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
widget_t* widget = NULL;
|
||||
dragger_t* dragger = TKMEM_ZALLOC(dragger_t);
|
||||
return_value_if_fail(dragger != NULL, NULL);
|
||||
|
||||
widget = WIDGET(dragger);
|
||||
widget->vt = &s_dragger_vtable;
|
||||
widget_init(widget, parent, WIDGET_DRAGGER);
|
||||
widget_move_resize(widget, x, y, w, h);
|
||||
|
||||
widget_set_state(widget, WIDGET_STATE_NORMAL);
|
||||
|
||||
return widget;
|
||||
}
|
80
src/base/dragger.h
Normal file
80
src/base/dragger.h
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* File: dragger.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: dragger
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* 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
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-07-01 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_DRAGGER_H
|
||||
#define TK_DRAGGER_H
|
||||
|
||||
#include "base/widget.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class dragger_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* dragger控件。
|
||||
*/
|
||||
typedef struct _dragger_t {
|
||||
widget_t widget;
|
||||
xy_t x_min;
|
||||
xy_t y_min;
|
||||
xy_t x_max;
|
||||
xy_t y_max;
|
||||
|
||||
xy_t save_x;
|
||||
xy_t save_y;
|
||||
xy_t down_x;
|
||||
xy_t down_y;
|
||||
bool_t dragging;
|
||||
} dragger_t;
|
||||
|
||||
/**
|
||||
* @method dragger_create
|
||||
* @constructor
|
||||
* 创建dragger对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* dragger_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method dragger_set_range
|
||||
* 创建dragger对象
|
||||
* @param {widget_t*} widget dragger控件。
|
||||
* @param {xy_t} x_min x坐标最小值。
|
||||
* @param {xy_t} y_min y坐标最小值。
|
||||
* @param {xy_t} x_max x坐标最大值。
|
||||
* @param {xy_t} y_max y坐标最大值。
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
ret_t dragger_set_range(widget_t* widget, xy_t x_min, xy_t y_min, xy_t x_max, xy_t y_max);
|
||||
|
||||
#define DRAGGER(widget) ((dragger_t*)(widget))
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_DRAGGER_H*/
|
@ -34,6 +34,7 @@ static const key_type_value_t widget_type_value[] = {
|
||||
{WIDGET_TYPE_POPUP, 0, WIDGET_POPUP},
|
||||
{WIDGET_TYPE_SPRITE, 0, WIDGET_SPRITE},
|
||||
{WIDGET_TYPE_KEYBOARD, 0, WIDGET_KEYBOARD},
|
||||
{WIDGET_TYPE_DND, 0, WIDGET_DND},
|
||||
{WIDGET_TYPE_DRAGGER, 0, WIDGET_DRAGGER},
|
||||
{WIDGET_TYPE_LABEL, 0, WIDGET_LABEL},
|
||||
{WIDGET_TYPE_BUTTON, 0, WIDGET_BUTTON},
|
||||
|
@ -201,6 +201,22 @@ typedef enum _event_type_t {
|
||||
* 请求更新软键盘上的Action按钮的信息。
|
||||
*/
|
||||
EVT_IM_ACTION_INFO,
|
||||
/**
|
||||
* @const EVT_DRAG_START
|
||||
* 开始拖动。
|
||||
*/
|
||||
EVT_DRAG_START,
|
||||
/**
|
||||
* @const EVT_DRAG
|
||||
* 拖动。
|
||||
*/
|
||||
EVT_DRAG,
|
||||
/**
|
||||
* @const EVT_DRAG_END
|
||||
* 结束拖动。
|
||||
*/
|
||||
EVT_DRAG_END,
|
||||
|
||||
/**
|
||||
* @const EVT_REQ_START
|
||||
* event queue其它请求编号起始值。
|
||||
|
@ -59,6 +59,10 @@ BEGIN_C_DECLS
|
||||
#define WIDGET_PROP_YOFFSET "yoffset"
|
||||
#define WIDGET_PROP_AUTO_PLAY "auto_play"
|
||||
#define WIDGET_PROP_AUTO_FIX "auto_fix"
|
||||
#define WIDGET_PROP_X_MIN "x_min"
|
||||
#define WIDGET_PROP_X_MAX "x_max"
|
||||
#define WIDGET_PROP_Y_MIN "y_min"
|
||||
#define WIDGET_PROP_Y_MAX "y_max"
|
||||
|
||||
/*widget type name*/
|
||||
#define WIDGET_TYPE_NONE "widget"
|
||||
@ -69,7 +73,7 @@ BEGIN_C_DECLS
|
||||
#define WIDGET_TYPE_POPUP "popup"
|
||||
#define WIDGET_TYPE_SPRITE "sprite"
|
||||
#define WIDGET_TYPE_KEYBOARD "keyboard"
|
||||
#define WIDGET_TYPE_DRAGGER "dragger"
|
||||
#define WIDGET_TYPE_DND "dnd"
|
||||
#define WIDGET_TYPE_LABEL "label"
|
||||
#define WIDGET_TYPE_BUTTON "button"
|
||||
#define WIDGET_TYPE_IMAGE "image"
|
||||
@ -86,6 +90,7 @@ BEGIN_C_DECLS
|
||||
#define WIDGET_TYPE_PAGES "pages"
|
||||
#define WIDGET_TYPE_CANDIDATES "candidates"
|
||||
#define WIDGET_TYPE_SPIN_BOX "spin_box"
|
||||
#define WIDGET_TYPE_DRAGGER "dragger"
|
||||
|
||||
/**
|
||||
* @enum widget_type_t
|
||||
@ -134,10 +139,10 @@ typedef enum _widget_type_t {
|
||||
*/
|
||||
WIDGET_KEYBOARD,
|
||||
/**
|
||||
* @const WIDGET_DRAGGER
|
||||
* @const WIDGET_DND
|
||||
* drag & drop icon。
|
||||
*/
|
||||
WIDGET_DRAGGER,
|
||||
WIDGET_DND,
|
||||
/**
|
||||
* @const WIDGET_LABEL
|
||||
* 简单文本。
|
||||
@ -218,6 +223,11 @@ typedef enum _widget_type_t {
|
||||
* Spin Box。
|
||||
*/
|
||||
WIDGET_SPIN_BOX,
|
||||
/**
|
||||
* @const WIDGET_DRAGGER
|
||||
* DRAGGER。
|
||||
*/
|
||||
WIDGET_DRAGGER,
|
||||
|
||||
WIDGET_NR,
|
||||
WIDGET_USER_START = 100
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "base/edit.h"
|
||||
#include "base/pages.h"
|
||||
#include "base/view.h"
|
||||
#include "base/dragger.h"
|
||||
#include "base/keyboard.h"
|
||||
#include "base/candidates.h"
|
||||
#include "base/spin_box.h"
|
||||
@ -62,6 +63,7 @@ static const creator_item_t s_builtin_creators[] = {
|
||||
{WIDGET_TYPE_RADIO_BUTTON, check_button_create_radio},
|
||||
{WIDGET_TYPE_PAGES, pages_create},
|
||||
{WIDGET_TYPE_SPIN_BOX, spin_box_create},
|
||||
{WIDGET_TYPE_DRAGGER, dragger_create},
|
||||
|
||||
#ifndef WITH_LOW_RES
|
||||
{WIDGET_TYPE_SLIDE_VIEW, slide_view_create},
|
||||
|
117
tests/dragger_test.cc
Normal file
117
tests/dragger_test.cc
Normal file
@ -0,0 +1,117 @@
|
||||
#include "base/dragger.h"
|
||||
#include "base/canvas.h"
|
||||
#include "base/widget.h"
|
||||
#include "font_dummy.h"
|
||||
#include "lcd_log.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
TEST(Dragger, basic) {
|
||||
value_t v1;
|
||||
value_t v2;
|
||||
widget_t* b = dragger_create(NULL, 0, 0, 30, 30);
|
||||
dragger_t* dragger = DRAGGER(b);
|
||||
|
||||
ASSERT_EQ(dragger_set_range(b, 0, 100, 100, 200), RET_OK);
|
||||
ASSERT_EQ(widget_get_prop(b, WIDGET_PROP_X_MIN, &v2), RET_OK);
|
||||
ASSERT_EQ(0, value_int(&v2));
|
||||
ASSERT_EQ(widget_get_prop(b, WIDGET_PROP_Y_MIN, &v2), RET_OK);
|
||||
ASSERT_EQ(100, value_int(&v2));
|
||||
|
||||
ASSERT_EQ(widget_get_prop(b, WIDGET_PROP_X_MAX, &v2), RET_OK);
|
||||
ASSERT_EQ(100, value_int(&v2));
|
||||
ASSERT_EQ(widget_get_prop(b, WIDGET_PROP_Y_MAX, &v2), RET_OK);
|
||||
ASSERT_EQ(200, value_int(&v2));
|
||||
|
||||
value_set_int(&v1, 1);
|
||||
ASSERT_EQ(widget_set_prop(b, WIDGET_PROP_X_MIN, &v1), RET_OK);
|
||||
ASSERT_EQ(dragger->x_min, 1);
|
||||
|
||||
value_set_int(&v1, 2);
|
||||
ASSERT_EQ(widget_set_prop(b, WIDGET_PROP_X_MAX, &v1), RET_OK);
|
||||
ASSERT_EQ(dragger->x_max, 2);
|
||||
|
||||
value_set_int(&v1, 3);
|
||||
ASSERT_EQ(widget_set_prop(b, WIDGET_PROP_Y_MIN, &v1), RET_OK);
|
||||
ASSERT_EQ(dragger->y_min, 3);
|
||||
|
||||
value_set_int(&v1, 4);
|
||||
ASSERT_EQ(widget_set_prop(b, WIDGET_PROP_Y_MAX, &v1), RET_OK);
|
||||
ASSERT_EQ(dragger->y_max, 4);
|
||||
|
||||
widget_destroy(b);
|
||||
}
|
||||
|
||||
TEST(Dragger, dragger_h) {
|
||||
pointer_event_t e;
|
||||
widget_t* b = dragger_create(NULL, 0, 0, 30, 30);
|
||||
|
||||
ASSERT_EQ(dragger_set_range(b, 0, 0, 100, 0), RET_OK);
|
||||
|
||||
e.x = 0;
|
||||
e.y = 0;
|
||||
e.e = event_init(EVT_POINTER_DOWN, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 0);
|
||||
ASSERT_EQ(b->y, 0);
|
||||
|
||||
e.x = 90;
|
||||
e.y = 90;
|
||||
e.e = event_init(EVT_POINTER_MOVE, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 90);
|
||||
ASSERT_EQ(b->y, 0);
|
||||
|
||||
e.x = 140;
|
||||
e.y = 90;
|
||||
e.e = event_init(EVT_POINTER_MOVE, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 100);
|
||||
ASSERT_EQ(b->y, 0);
|
||||
|
||||
e.x = 90;
|
||||
e.y = 90;
|
||||
e.e = event_init(EVT_POINTER_UP, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 90);
|
||||
ASSERT_EQ(b->y, 0);
|
||||
|
||||
widget_destroy(b);
|
||||
}
|
||||
|
||||
TEST(Dragger, dragger_v) {
|
||||
pointer_event_t e;
|
||||
widget_t* b = dragger_create(NULL, 0, 0, 30, 30);
|
||||
|
||||
ASSERT_EQ(dragger_set_range(b, 0, 0, 0, 100), RET_OK);
|
||||
|
||||
e.x = 0;
|
||||
e.y = 0;
|
||||
e.e = event_init(EVT_POINTER_DOWN, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 0);
|
||||
ASSERT_EQ(b->y, 0);
|
||||
|
||||
e.x = 90;
|
||||
e.y = 90;
|
||||
e.e = event_init(EVT_POINTER_MOVE, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 0);
|
||||
ASSERT_EQ(b->y, 90);
|
||||
|
||||
e.x = 90;
|
||||
e.y = 160;
|
||||
e.e = event_init(EVT_POINTER_MOVE, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 0);
|
||||
ASSERT_EQ(b->y, 100);
|
||||
|
||||
e.x = 90;
|
||||
e.y = 90;
|
||||
e.e = event_init(EVT_POINTER_UP, b);
|
||||
widget_dispatch(b, &(e.e));
|
||||
ASSERT_EQ(b->x, 0);
|
||||
ASSERT_EQ(b->y, 90);
|
||||
|
||||
widget_destroy(b);
|
||||
}
|
Loading…
Reference in New Issue
Block a user