add design_w/design_h/.. props for window

This commit is contained in:
lixianjing 2021-02-03 18:17:57 +08:00
parent 208d9865da
commit 8aaf01a3ea
5 changed files with 259 additions and 1 deletions

View File

@ -1,9 +1,10 @@
# 最新动态
2021/02/02
2021/02/03
* 修复缺少 SDL 线程函数的声明的问题(感谢智明提供补丁)
* 修复改变 lcd 的大小后 vg 的裁剪区没有修改的问题(感谢智明提供补丁)
* 修复 page 控件套 pages 控件的时候释放子 pages 控件导致父 pages 控件的 target 为野指针的问题(感谢智明提供补丁)
* 窗口增加design\_w/design\_h/auto\_scale\_x/auto\_scale\_y/auto\_scale\_w/auto\_scale\_h等参数。
2021/02/02
* 修改注释错误感谢网友QQ631757707提供补丁

View File

@ -65,6 +65,42 @@ BEGIN_C_DECLS
*/
#define WIDGET_PROP_H "h"
/**
* @const WIDGET_PROP_DESIGN_W
*
*/
#define WIDGET_PROP_DESIGN_W "design_w"
/**
* @const WIDGET_PROP_DESIGN_H
*
*/
#define WIDGET_PROP_DESIGN_H "design_h"
/**
* @const WIDGET_PROP_AUTO_SCALE_X
* x坐标
*/
#define WIDGET_PROP_AUTO_SCALE_X "auto_scale_x"
/**
* @const WIDGET_PROP_AUTO_SCALE_Y
* y坐标
*/
#define WIDGET_PROP_AUTO_SCALE_Y "auto_scale_y"
/**
* @const WIDGET_PROP_AUTO_SCALE_W
*
*/
#define WIDGET_PROP_AUTO_SCALE_W "auto_scale_w"
/**
* @const WIDGET_PROP_AUTO_SCALE_H
*
*/
#define WIDGET_PROP_AUTO_SCALE_H "auto_scale_h"
/**
* @const WIDGET_PROP_INPUTING
* inputing

View File

@ -178,6 +178,24 @@ ret_t window_base_get_prop(widget_t* widget, const char* name, value_t* v) {
} else if (tk_str_eq(name, WIDGET_PROP_SINGLE_INSTANCE)) {
value_set_bool(v, window_base->single_instance);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_DESIGN_W)) {
value_set_uint32(v, window_base->design_w);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_DESIGN_H)) {
value_set_uint32(v, window_base->design_h);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_X)) {
value_set_bool(v, window_base->auto_scale_x);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_Y)) {
value_set_bool(v, window_base->auto_scale_y);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_W)) {
value_set_bool(v, window_base->auto_scale_w);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_H)) {
value_set_bool(v, window_base->auto_scale_h);
return RET_OK;
}
return RET_NOT_FOUND;
@ -228,6 +246,24 @@ ret_t window_base_set_prop(widget_t* widget, const char* name, const value_t* v)
} else if (tk_str_eq(name, WIDGET_PROP_SINGLE_INSTANCE)) {
window_base->single_instance = value_bool(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_DESIGN_W)) {
window_base->design_w = value_uint32(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_DESIGN_H)) {
window_base->design_h = value_uint32(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_X)) {
window_base->auto_scale_x = value_bool(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_Y)) {
window_base->auto_scale_y = value_bool(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_W)) {
window_base->auto_scale_w = value_bool(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_AUTO_SCALE_H)) {
window_base->auto_scale_h = value_bool(v);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_CLOSABLE)) {
if (v->type == VALUE_TYPE_STRING) {
const key_type_value_t* kv = window_closable_type_find(value_str(v));
@ -295,6 +331,57 @@ static widget_t* window_base_get_key_target_leaf(widget_t* widget) {
return iter;
}
typedef struct _auto_resize_info_t {
widget_t* window;
float hscale;
float vscale;
bool_t auto_scale_x;
bool_t auto_scale_y;
bool_t auto_scale_w;
bool_t auto_scale_h;
} auto_resize_info_t;
static ret_t window_base_auto_scale_child(void* ctx, const void* data) {
auto_resize_info_t* info = (auto_resize_info_t*)ctx;
widget_t* widget = WIDGET(data);
if (widget != info->window) {
if (widget->parent->children_layout == NULL && widget->self_layout == NULL) {
if (info->auto_scale_x) {
widget->x *= info->hscale;
}
if (info->auto_scale_w) {
widget->w *= info->hscale;
}
if (info->auto_scale_y) {
widget->y *= info->vscale;
}
if (info->auto_scale_h) {
widget->h *= info->vscale;
}
}
}
return RET_OK;
}
static ret_t window_base_auto_scale_children(widget_t* widget) {
auto_resize_info_t info;
window_base_t* win = WINDOW_BASE(widget);
info.window = widget;
info.hscale = (float)(win->widget.w) / (float)(win->design_w);
info.vscale = (float)(win->widget.h) / (float)(win->design_h);
info.auto_scale_x = win->auto_scale_x;
info.auto_scale_y = win->auto_scale_y;
info.auto_scale_w = win->auto_scale_w;
info.auto_scale_h = win->auto_scale_h;
widget_foreach(widget, window_base_auto_scale_child, &info);
return RET_OK;
}
ret_t window_base_on_event(widget_t* widget, event_t* e) {
window_base_t* win = WINDOW_BASE(widget);
return_value_if_fail(widget != NULL && win != NULL, RET_BAD_PARAMS);
@ -310,6 +397,11 @@ ret_t window_base_on_event(widget_t* widget, event_t* e) {
widget_set_focused_internal(widget, TRUE);
}
} else if (e->type == EVT_WINDOW_LOAD) {
if (win->design_w && win->design_h) {
if (win->auto_scale_x || win->auto_scale_y || win->auto_scale_w || win->auto_scale_h) {
window_base_auto_scale_children(widget);
}
}
} else if (e->type == EVT_WINDOW_CLOSE) {
win->stage = WINDOW_STAGE_CLOSED;
} else if (e->type == EVT_THEME_CHANGED) {

View File

@ -60,6 +60,43 @@ typedef struct _window_base_t {
*/
char* theme;
/**
* @property {uint16_t} design_w
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
*
*/
uint16_t design_w;
/**
* @property {uint16_t} design_h
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
*
*/
uint16_t design_h;
/**
* @property {bool_t} auto_scale_x
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* x坐标
*/
uint16_t auto_scale_x : 1;
/**
* @property {bool_t} auto_scale_y
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* y坐标
*/
uint16_t auto_scale_y : 1;
/**
* @property {bool_t} auto_scale_w
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
*
*/
uint16_t auto_scale_w : 1;
/**
* @property {bool_t} auto_scale_h
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
*
*/
uint16_t auto_scale_h : 1;
/**
* @property {bool_t} disable_anim
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]

View File

@ -1,4 +1,5 @@
#include "widgets/popup.h"
#include "widgets/button.h"
#include "gtest/gtest.h"
TEST(Popup, cast) {
@ -27,3 +28,94 @@ TEST(Popup, basic) {
widget_destroy(w);
}
TEST(Popup, auto_scale_x) {
widget_t* w = popup_create(NULL, 0, 0, 400, 600);
widget_t* b = button_create(w, 10, 20, 30, 40);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_W, 200), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 200);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_H, 300), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 300);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, FALSE), TRUE);
widget_dispatch_simple_event(w, EVT_WINDOW_LOAD);
ASSERT_EQ(b->x, 20);
ASSERT_EQ(b->y, 20);
ASSERT_EQ(b->w, 30);
ASSERT_EQ(b->h, 40);
widget_destroy(w);
}
TEST(Popup, auto_scale_xy) {
widget_t* w = popup_create(NULL, 0, 0, 400, 600);
widget_t* b = button_create(w, 10, 20, 30, 40);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_W, 200), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 200);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_H, 300), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 300);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, FALSE), TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, FALSE), TRUE);
widget_dispatch_simple_event(w, EVT_WINDOW_LOAD);
ASSERT_EQ(b->x, 20);
ASSERT_EQ(b->y, 40);
ASSERT_EQ(b->w, 30);
ASSERT_EQ(b->h, 40);
widget_destroy(w);
}
TEST(Popup, auto_scale_xywh) {
widget_t* w = popup_create(NULL, 0, 0, 400, 600);
widget_t* b = button_create(w, 10, 20, 30, 40);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_W, 200), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_W, 0), 200);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 0);
ASSERT_EQ(widget_set_prop_int(w, WIDGET_PROP_DESIGN_H, 300), RET_OK);
ASSERT_EQ(widget_get_prop_int(w, WIDGET_PROP_DESIGN_H, 0), 300);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_X, FALSE), TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_Y, FALSE), TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_W, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_W, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_W, FALSE), TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_H, TRUE), FALSE);
ASSERT_EQ(widget_set_prop_bool(w, WIDGET_PROP_AUTO_SCALE_H, TRUE), RET_OK);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_AUTO_SCALE_H, FALSE), TRUE);
widget_dispatch_simple_event(w, EVT_WINDOW_LOAD);
ASSERT_EQ(b->x, 20);
ASSERT_EQ(b->y, 40);
ASSERT_EQ(b->w, 60);
ASSERT_EQ(b->h, 80);
widget_destroy(w);
}