add dragger

This commit is contained in:
xianjimli 2018-07-01 11:56:06 +08:00
parent 6e8c9ba39c
commit a42b8f0669
9 changed files with 419 additions and 9 deletions

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

173
src/base/dragger.c Normal file
View 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
View 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*/

View File

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

View File

@ -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其它请求编号起始值

View File

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

View File

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