mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
improve spin box for easy touch
This commit is contained in:
parent
1a5a000521
commit
d3785ba561
@ -52,6 +52,18 @@
|
||||
<over bg_color="#e0e0e0" icon="arrow_down_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_bottom" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_down_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_down_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_down_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_top" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_up_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_up_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_up_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_down" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_down_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_down_p"/>
|
||||
@ -163,6 +175,14 @@
|
||||
<empty bg_color="#f0f0f0" text_color="#a0a0a0" />
|
||||
<empty_focus bg_color="#f0f0f0" text_color="#a0a0a0" border_color="black"/>
|
||||
</style>
|
||||
<style name="center" border_color="#a0a0a0" text_color="black" text_align_h="center">
|
||||
<normal bg_color="#f0f0f0" />
|
||||
<focused bg_color="#f0f0f0" border_color="black"/>
|
||||
<disable bg_color="gray" text_color="#d0d0d0" />
|
||||
<error bg_color="#f0f0f0" text_color="red" />
|
||||
<empty bg_color="#f0f0f0" text_color="#a0a0a0" />
|
||||
<empty_focus bg_color="#f0f0f0" text_color="#a0a0a0" border_color="black"/>
|
||||
</style>
|
||||
</spin_box>
|
||||
|
||||
<digit_clock>
|
||||
|
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2022/06/11
|
||||
* 完善spin box,支持不同的形态。具体请参考[spin box的三种形态](spin_box.md)
|
||||
|
||||
2022/06/10
|
||||
* edit/mledit 支持属性获取行高。
|
||||
* 完善软键盘弹出,平移窗口的距离由编辑器决定。
|
||||
|
BIN
docs/images/spin_box.png
Normal file
BIN
docs/images/spin_box.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
docs/images/spin_box_1.png
Normal file
BIN
docs/images/spin_box_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
BIN
docs/images/spin_box_2.png
Normal file
BIN
docs/images/spin_box_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
docs/images/spin_box_3.png
Normal file
BIN
docs/images/spin_box_3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
129
docs/spin_box.md
Normal file
129
docs/spin_box.md
Normal file
@ -0,0 +1,129 @@
|
||||
# spin_box 的几种形态
|
||||
|
||||
spin_box 是一个特殊的 edit,主要用于数值编辑。它自带两个按钮,点击它们可以增加/减少数值,增量可以用 step 来设置。
|
||||
|
||||
在 AWTK 中,spin\_box 有三种形态。
|
||||
|
||||
## 1. 传统形态
|
||||
|
||||
![](images/spin_box_1.png)
|
||||
|
||||
### 1.1 特点
|
||||
|
||||
两个按钮均在右侧,按钮比较小,相距很近,只要移动很小距离,即可在两个按钮之间切换,适合鼠标这种比较精确的输入设备。
|
||||
|
||||
### 1.2 按钮的 style:
|
||||
|
||||
* 增加 (inc) 按钮的 style 由 spinbox_up 决定。
|
||||
* 减小 (dec) 按钮的 style 由 spinbox_down 决定。
|
||||
|
||||
### 1.3 示例:
|
||||
|
||||
* UI
|
||||
|
||||
```xml
|
||||
<spin_box x="5%" y="10" w="50%" h="30" text="100"/>
|
||||
```
|
||||
|
||||
* style
|
||||
|
||||
```xml
|
||||
<style name="spinbox_down" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_down_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_down_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_down_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_up" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_up_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_up_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_up_o"/>
|
||||
</style>
|
||||
```
|
||||
|
||||
## 2. 按钮在左右两侧
|
||||
|
||||
![](images/spin_box_2.png)
|
||||
|
||||
### 2.1 特点
|
||||
|
||||
按钮在编辑器左右两侧,按钮比较大,不容易发生误操作。适合电容屏这种不太精确的输入设备。
|
||||
|
||||
### 2.2 按钮的 style:
|
||||
|
||||
* 增加 (inc) 按钮的 style 由 spinbox_right 决定。
|
||||
* 减小 (dec) 按钮的 style 由 spinbox_left 决定。
|
||||
|
||||
### 2.3 使用方法
|
||||
|
||||
* 需要设置 easy\_touch\_mode="true"
|
||||
* 控件的 style 中设置文本居中。
|
||||
|
||||
### 2.4 示例:
|
||||
|
||||
* UI
|
||||
|
||||
```xml
|
||||
<spin_box x="5%" y="100" w="50%" h="30" text="100" easy_touch_mode="true" style="center"/>
|
||||
```
|
||||
|
||||
* style
|
||||
|
||||
```xml
|
||||
<style name="spinbox_left" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_left_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_left_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_left_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_right" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_right_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_right_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_right_o"/>
|
||||
</style>
|
||||
```
|
||||
|
||||
## 3. 按钮在上下两端
|
||||
|
||||
![](images/spin_box_3.png)
|
||||
|
||||
### 3.1 特点
|
||||
|
||||
按钮在编辑器上下两端,按钮比较大,不容易发生误操作。适合电容屏这种不太精确的输入设备。
|
||||
|
||||
### 3.2 按钮的 style:
|
||||
|
||||
* 增加 (inc) 按钮的 style 由 spinbox_top 决定。
|
||||
* 减小 (dec) 按钮的 style 由 spinbox_bottom 决定。
|
||||
|
||||
### 3.3 使用方法:
|
||||
|
||||
* 需要设置 easy\_touch\_mode="true"
|
||||
* 控件的 style 中设置文本居中。
|
||||
* 并保证控件的高度大于字体大小的 3 倍
|
||||
|
||||
### 3.4 示例:
|
||||
|
||||
* UI
|
||||
|
||||
```xml
|
||||
<spin_box x="5%" y="200" w="40%" h="90" text="100" easy_touch_mode="true" style="center"/>
|
||||
```
|
||||
|
||||
* style
|
||||
|
||||
```xml
|
||||
<style name="spinbox_bottom" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_down_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_down_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_down_o"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_top" border_color="#a0a0a0">
|
||||
<normal bg_color="#f0f0f0" icon="arrow_up_n"/>
|
||||
<pressed bg_color="#c0c0c0" icon="arrow_up_p"/>
|
||||
<over bg_color="#e0e0e0" icon="arrow_up_o"/>
|
||||
</style>
|
||||
```
|
||||
|
||||
> 在 AWTK 中,spin\_box 完全可以用 edit + button 来实现,只是直接使用 spin\_box 要简单一些。使用时可以根据自己的实际情况进行选择。
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -293,6 +293,12 @@ BEGIN_C_DECLS
|
||||
*/
|
||||
#define WIDGET_PROP_VALUE "value"
|
||||
|
||||
/**
|
||||
* @const WIDGET_PROP_EASY_TOUCH_MODE
|
||||
* 容易点击模式(目前用于spinbox)。
|
||||
*/
|
||||
#define WIDGET_PROP_EASY_TOUCH_MODE "easy_touch_mode"
|
||||
|
||||
/**
|
||||
* @const WIDGET_PROP_RADIO
|
||||
* CheckButton是否单选。
|
||||
|
@ -23,24 +23,92 @@
|
||||
#include "base/layout.h"
|
||||
#include "widgets/spin_box.h"
|
||||
|
||||
extern const char* s_edit_properties[];
|
||||
const char* const s_spin_box_properties[] = {TK_EDIT_PROPS, WIDGET_PROP_EASY_TOUCH_MODE, NULL};
|
||||
|
||||
widget_t* spin_box_create_self(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
static ret_t spin_box_on_copy(widget_t* widget, widget_t* other) {
|
||||
spin_box_t* spin_box = SPIN_BOX(widget);
|
||||
spin_box_t* spin_box_other = SPIN_BOX(other);
|
||||
return_value_if_fail(spin_box != NULL && spin_box_other != NULL, RET_BAD_PARAMS);
|
||||
spin_box->easy_touch_mode = spin_box_other->easy_touch_mode;
|
||||
|
||||
return edit_on_copy(widget, other);
|
||||
}
|
||||
|
||||
static ret_t spin_box_set_prop(widget_t* widget, const char* name, const value_t* v) {
|
||||
if (tk_str_eq(name, WIDGET_PROP_EASY_TOUCH_MODE)) {
|
||||
spin_box_set_easy_touch_mode(widget, value_bool(v));
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return edit_set_prop(widget, name, v);
|
||||
}
|
||||
|
||||
static ret_t spin_box_get_prop(widget_t* widget, const char* name, value_t* v) {
|
||||
if (tk_str_eq(name, WIDGET_PROP_EASY_TOUCH_MODE)) {
|
||||
value_set_bool(v, SPIN_BOX(widget)->easy_touch_mode);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return edit_get_prop(widget, name, v);
|
||||
}
|
||||
|
||||
static ret_t spin_box_on_layout_children(widget_t* widget) {
|
||||
edit_t* edit = EDIT(widget);
|
||||
spin_box_t* spin_box = SPIN_BOX(widget);
|
||||
widget_t* inc = widget_child(widget, STR_EDIT_INC_NAME);
|
||||
widget_t* dec = widget_child(widget, STR_EDIT_DEC_NAME);
|
||||
return_value_if_fail(inc != NULL && dec != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (spin_box->easy_touch_mode) {
|
||||
int32_t font_size = style_get_int(widget->astyle, STYLE_ID_FONT_SIZE, 18);
|
||||
if (widget->h > font_size * 3) {
|
||||
int32_t h = widget->h / 3;
|
||||
edit->top_margin = h;
|
||||
edit->bottom_margin = h;
|
||||
widget_move_resize(inc, 0, 0, widget->w, h);
|
||||
widget_move_resize(dec, 0, widget->h - h, widget->w, h);
|
||||
widget_use_style(inc, "spinbox_top");
|
||||
widget_use_style(dec, "spinbox_bottom");
|
||||
} else {
|
||||
int32_t size = widget->h;
|
||||
edit->left_margin = size;
|
||||
edit->right_margin = size;
|
||||
widget_move_resize(dec, 0, 0, size, size);
|
||||
widget_move_resize(inc, widget->w - size, 0, size, size);
|
||||
widget_use_style(dec, "spinbox_left");
|
||||
widget_use_style(inc, "spinbox_right");
|
||||
}
|
||||
} else {
|
||||
int32_t size = widget->h / 2;
|
||||
int32_t x = widget->w - size;
|
||||
|
||||
edit->right_margin = size + 1;
|
||||
widget_move_resize(inc, x, 0, size, size);
|
||||
widget_move_resize(dec, x, size, size, size);
|
||||
widget_use_style(inc, "spinbox_up");
|
||||
widget_use_style(dec, "spinbox_down");
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
TK_DECL_VTABLE(spin_box) = {.size = sizeof(spin_box_t),
|
||||
.type = WIDGET_TYPE_SPIN_BOX,
|
||||
.inputable = TRUE,
|
||||
.focusable = TRUE,
|
||||
.pointer_cursor = WIDGET_CURSOR_EDIT,
|
||||
.clone_properties = s_edit_properties,
|
||||
.persistent_properties = s_edit_properties,
|
||||
.clone_properties = s_spin_box_properties,
|
||||
.persistent_properties = s_spin_box_properties,
|
||||
.parent = TK_PARENT_VTABLE(edit),
|
||||
.create = spin_box_create_self,
|
||||
.on_paint_self = edit_on_paint_self,
|
||||
.set_prop = edit_set_prop,
|
||||
.get_prop = edit_get_prop,
|
||||
.set_prop = spin_box_set_prop,
|
||||
.get_prop = spin_box_get_prop,
|
||||
.on_layout_children = spin_box_on_layout_children,
|
||||
.on_destroy = edit_on_destroy,
|
||||
.on_copy = edit_on_copy,
|
||||
.on_copy = spin_box_on_copy,
|
||||
.on_event = edit_on_event};
|
||||
|
||||
widget_t* spin_box_create_self(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
@ -49,7 +117,6 @@ widget_t* spin_box_create_self(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h)
|
||||
return_value_if_fail(spin_box != NULL, NULL);
|
||||
|
||||
edit->step = 1;
|
||||
edit->right_margin = 21;
|
||||
edit->input_type = INPUT_INT;
|
||||
|
||||
return spin_box;
|
||||
@ -64,20 +131,25 @@ widget_t* spin_box_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
inc = button_create(spin_box, 0, 0, 0, 0);
|
||||
inc->auto_created = TRUE;
|
||||
button_set_repeat(inc, 300);
|
||||
widget_set_name(inc, "inc");
|
||||
widget_use_style(inc, "spinbox_up");
|
||||
widget_set_self_layout_params(inc, "right", "0", "20", "50%");
|
||||
widget_set_name(inc, STR_EDIT_INC_NAME);
|
||||
|
||||
dec = button_create(spin_box, 0, 0, 0, 0);
|
||||
dec->auto_created = TRUE;
|
||||
button_set_repeat(dec, 300);
|
||||
widget_set_name(dec, "dec");
|
||||
widget_use_style(dec, "spinbox_down");
|
||||
widget_set_self_layout_params(dec, "right", "bottom", "20", "50%");
|
||||
widget_set_name(dec, STR_EDIT_DEC_NAME);
|
||||
|
||||
return spin_box;
|
||||
}
|
||||
|
||||
ret_t spin_box_set_easy_touch_mode(widget_t* widget, bool_t easy_touch_mode) {
|
||||
spin_box_t* spin_box = SPIN_BOX(widget);
|
||||
return_value_if_fail(spin_box != NULL, RET_BAD_PARAMS);
|
||||
|
||||
spin_box->easy_touch_mode = easy_touch_mode;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
widget_t* spin_box_cast(widget_t* widget) {
|
||||
return_value_if_fail(WIDGET_IS_INSTANCE_OF(widget, spin_box), NULL);
|
||||
|
||||
|
@ -80,7 +80,22 @@ BEGIN_C_DECLS
|
||||
* default](https://github.com/zlgopen/awtk/blob/master/design/default/styles/default.xml#L128)
|
||||
*
|
||||
*/
|
||||
typedef edit_t spin_box_t;
|
||||
typedef struct _spin_box_t {
|
||||
edit_t edit;
|
||||
|
||||
/**
|
||||
* @property {bool_t} easy_touch_mode
|
||||
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
|
||||
* 是否启用易点击模式(在电容屏设备上建议启用)。
|
||||
* > 在该模式下:
|
||||
* > * 1.当高度大于font size的3倍时,inc按钮在顶部(style名为spinbox_top),dec按钮在底部(style名为spinbox_bottom)。
|
||||
* > * 2.当高度正常时,dec按钮在左边(style名为spinbox_left),inc按钮在右边(style名为spinbox_right)。
|
||||
* > 不在该模式下:
|
||||
* > inc按钮在右上角(style名为spinbox_up),dec按钮在右下角(style名为spinbox_down)。
|
||||
*/
|
||||
bool_t easy_touch_mode;
|
||||
|
||||
} spin_box_t;
|
||||
|
||||
/**
|
||||
* @method spin_box_create
|
||||
@ -106,6 +121,17 @@ widget_t* spin_box_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
*/
|
||||
widget_t* spin_box_cast(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method spin_box_set_easy_touch_mode
|
||||
* 设置是否启用易点击模式。
|
||||
* @annotation ["scriptable"]
|
||||
* @param {widget_t*} widget widget对象。
|
||||
* @param {bool_t} easy_touch_mode 易点击模式。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t spin_box_set_easy_touch_mode(widget_t* widget, bool_t easy_touch_mode);
|
||||
|
||||
#define SPIN_BOX(widget) ((spin_box_t*)(spin_box_cast(WIDGET(widget))))
|
||||
|
||||
/*public for subclass and runtime type check*/
|
||||
|
@ -39,8 +39,8 @@ TEST(SpinBox, to_xml) {
|
||||
"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\r\n<spin_box x=\"10\" y=\"20\" "
|
||||
"w=\"30\" h=\"40\" focusable=\"true\" min=\"0\" max=\"1024\" step=\"1.000000\" "
|
||||
"input_type=\"1\" readonly=\"false\" cancelable=\"false\" auto_fix=\"false\" "
|
||||
"left_margin=\"2\" right_margin=\"21\" top_margin=\"2\" bottom_margin=\"2\" "
|
||||
"action_text=\"done\" password_visible=\"false\">\n</spin_box>\n"));
|
||||
"left_margin=\"2\" right_margin=\"2\" top_margin=\"2\" bottom_margin=\"2\" "
|
||||
"action_text=\"done\" password_visible=\"false\" easy_touch_mode=\"false\">\n</spin_box>\n"));
|
||||
|
||||
str_reset(&str);
|
||||
widget_destroy(w1);
|
||||
@ -65,3 +65,51 @@ TEST(SpinBox, set_value) {
|
||||
|
||||
widget_destroy(w);
|
||||
}
|
||||
|
||||
TEST(SpinBox, easy_touch_mode) {
|
||||
widget_t* w = spin_box_create(NULL, 0, 0, 100, 40);
|
||||
widget_t* inc = widget_lookup(w, STR_EDIT_INC_NAME, TRUE);
|
||||
widget_t* dec = widget_lookup(w, STR_EDIT_DEC_NAME, TRUE);
|
||||
widget_layout(w);
|
||||
|
||||
ASSERT_EQ(inc->w, inc->h);
|
||||
ASSERT_EQ(dec->w, dec->h);
|
||||
ASSERT_EQ(inc->w, 20);
|
||||
ASSERT_EQ(dec->h, 20);
|
||||
ASSERT_EQ(inc->x, w->w - inc->w);
|
||||
ASSERT_EQ(inc->y, 0);
|
||||
ASSERT_EQ(dec->x, w->w - inc->w);
|
||||
ASSERT_EQ(dec->y, inc->h);
|
||||
ASSERT_EQ(dec->w, dec->h);
|
||||
|
||||
spin_box_set_easy_touch_mode(w, TRUE);
|
||||
widget_layout(w);
|
||||
|
||||
ASSERT_EQ(inc->w, w->h);
|
||||
ASSERT_EQ(inc->h, w->h);
|
||||
ASSERT_EQ(inc->y, 0);
|
||||
ASSERT_EQ(inc->x, w->w - inc->w);
|
||||
ASSERT_EQ(dec->w, w->h);
|
||||
ASSERT_EQ(dec->h, w->h);
|
||||
ASSERT_EQ(dec->y, 0);
|
||||
ASSERT_EQ(dec->x, 0);
|
||||
|
||||
widget_resize(w, 80, 90);
|
||||
widget_layout(w);
|
||||
|
||||
ASSERT_EQ(inc->w, w->w);
|
||||
ASSERT_EQ(inc->h, w->h/3);
|
||||
ASSERT_EQ(inc->x, 0);
|
||||
ASSERT_EQ(inc->y, 0);
|
||||
|
||||
ASSERT_EQ(dec->w, w->w);
|
||||
ASSERT_EQ(dec->h, w->h/3);
|
||||
ASSERT_EQ(dec->x, 0);
|
||||
ASSERT_EQ(dec->y, 2 * w->h/3);
|
||||
|
||||
widget_t* w1 = widget_clone(w, NULL);
|
||||
ASSERT_EQ(SPIN_BOX(w1)->easy_touch_mode, TRUE);
|
||||
|
||||
widget_destroy(w);
|
||||
widget_destroy(w1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user