overlay support always_on_top prop

This commit is contained in:
lixianjing 2020-12-14 11:03:58 +08:00
parent 351f154378
commit ba97d3470f
12 changed files with 1495 additions and 1394 deletions

View File

@ -0,0 +1,5 @@
<overlay text="overlay" x="100" y="100" w="150" h="40" always_on_top="true">
<draggable drag_window="true"/>
<image image="logo" x="c" y="m" w="100%" h="100%"/>
<button x="10" y="m" w="16" h="16" name="close" text="x"/>
</overlay>

View File

@ -1,5 +1,8 @@
# 最新动态
2020/12/14
* overlay窗口支持always\_on\_top属性。
2020/12/12
* 在支持 mmap/FileMapping 的系统,优先使用 mmap 加载大资源。

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,12 @@ BEGIN_C_DECLS
*/
#define WIDGET_PROP_INPUTING "inputing"
/**
* @const WIDGET_PROP_ALWAYS_ON_TOP
* always on top
*/
#define WIDGET_PROP_ALWAYS_ON_TOP "always_on_top"
/**
* @const WIDGET_PROP_CARET_X
* caret x

View File

@ -532,9 +532,24 @@ widget_t* window_manager_find_target_by_win(widget_t* widget, void* win) {
return NULL;
}
static bool_t window_manager_is_win_valid_target(widget_t* iter, void* win) {
if (win != NULL) {
native_window_t* nw =
(native_window_t*)widget_get_prop_pointer(iter, WIDGET_PROP_NATIVE_WINDOW);
if (nw == NULL || nw->handle != win) {
return FALSE;
}
}
if (!iter->visible || !iter->sensitive || !iter->enable) {
return FALSE;
}
return TRUE;
}
widget_t* window_manager_find_target(widget_t* widget, void* win, xy_t x, xy_t y) {
point_t p = {x, y};
native_window_t* nw = NULL;
return_value_if_fail(widget != NULL, NULL);
if (widget->grab_widget != NULL) {
@ -543,14 +558,17 @@ widget_t* window_manager_find_target(widget_t* widget, void* win, xy_t x, xy_t y
widget_to_local(widget, &p);
WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i)
if (win != NULL) {
nw = (native_window_t*)widget_get_prop_pointer(iter, WIDGET_PROP_NATIVE_WINDOW);
if (nw == NULL || nw->handle != win) {
continue;
}
if (!window_manager_is_win_valid_target(iter, win)) {
continue;
}
if (widget_get_prop_bool(iter, WIDGET_PROP_ALWAYS_ON_TOP, FALSE) &&
widget_is_point_in(iter, x, y, FALSE)) {
return iter;
}
WIDGET_FOR_EACH_CHILD_END()
if (!iter->visible || !iter->sensitive || !iter->enable) {
WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i)
if (!window_manager_is_win_valid_target(iter, win)) {
continue;
}

View File

@ -29,6 +29,8 @@ static ret_t overlay_set_prop(widget_t* widget, const char* name, const value_t*
if (tk_str_eq(name, WIDGET_PROP_CLICK_THROUGH)) {
return overlay_set_click_through(widget, value_bool(v));
} else if (tk_str_eq(name, WIDGET_PROP_ALWAYS_ON_TOP)) {
return overlay_set_always_on_top(widget, value_bool(v));
}
return window_base_set_prop(widget, name, v);
@ -41,6 +43,9 @@ static ret_t overlay_get_prop(widget_t* widget, const char* name, value_t* v) {
if (tk_str_eq(name, WIDGET_PROP_CLICK_THROUGH)) {
value_set_bool(v, overlay->click_through);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_ALWAYS_ON_TOP)) {
value_set_bool(v, overlay->always_on_top);
return RET_OK;
}
return window_base_get_prop(widget, name, v);
@ -68,7 +73,7 @@ static bool_t overlay_is_point_in(widget_t* widget, xy_t x, xy_t y) {
static const char* const s_overlay_properties[] = {
WIDGET_PROP_MOVE_FOCUS_PREV_KEY, WIDGET_PROP_MOVE_FOCUS_NEXT_KEY, WIDGET_PROP_THEME,
WIDGET_PROP_CLICK_THROUGH, NULL};
WIDGET_PROP_CLICK_THROUGH, WIDGET_PROP_ALWAYS_ON_TOP, NULL};
TK_DECL_VTABLE(overlay) = {.type = WIDGET_TYPE_OVERLAY,
.size = sizeof(overlay_t),
@ -104,3 +109,12 @@ ret_t overlay_set_click_through(widget_t* widget, bool_t click_through) {
return RET_OK;
}
ret_t overlay_set_always_on_top(widget_t* widget, bool_t always_on_top) {
overlay_t* overlay = OVERLAY(widget);
return_value_if_fail(overlay != NULL, RET_BAD_PARAMS);
overlay->always_on_top = always_on_top;
return RET_OK;
}

View File

@ -81,6 +81,16 @@ typedef struct _overlay_t {
*
*/
bool_t click_through;
/**
* @property {bool_t} always_on_top
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
*
*
*
*
*/
bool_t always_on_top;
} overlay_t;
/**
@ -108,6 +118,17 @@ widget_t* overlay_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
*/
ret_t overlay_set_click_through(widget_t* widget, bool_t click_through);
/**
* @method overlay_set_always_on_top
*
* @annotation ["scriptable"]
* @param {widget_t*} widget
* @param {bool_t} always_on_top
*
* @return {ret_t} RET_OK表示成功
*/
ret_t overlay_set_always_on_top(widget_t* widget, bool_t always_on_top);
/**
* @method overlay_cast
* overlay对象(使)

View File

@ -830,6 +830,7 @@ static ret_t window_manager_paint_animation(widget_t* widget, canvas_t* c) {
widget_dispatch(widget, paint_event_init(&e, EVT_BEFORE_PAINT, widget, c));
ret_t ret = window_animator_update(wm->animator, start_time);
window_manager_default_paint_always_on_top(widget, c);
widget_dispatch(widget, paint_event_init(&e, EVT_AFTER_PAINT, widget, c));
@ -915,6 +916,18 @@ static widget_t* window_manager_default_get_prev_window(widget_t* widget) {
return wm->prev_win;
}
static ret_t window_manager_default_paint_always_on_top(widget_t* widget, canvas_t* c) {
WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i)
if (iter->visible) {
if (widget_get_prop_bool(iter, WIDGET_PROP_ALWAYS_ON_TOP, FALSE)) {
widget_paint(iter, c);
}
}
WIDGET_FOR_EACH_CHILD_END()
return RET_OK;
}
static ret_t window_manager_default_on_paint_children(widget_t* widget, canvas_t* c) {
int32_t start = 0;
bool_t has_fullscreen_win = FALSE;
@ -964,6 +977,8 @@ static ret_t window_manager_default_on_paint_children(widget_t* widget, canvas_t
}
}
WIDGET_FOR_EACH_CHILD_END()
window_manager_default_paint_always_on_top(widget, c);
return RET_OK;
}

View File

@ -15,20 +15,12 @@ static ret_t load_image(const char* filename, bitmap_t* image) {
ret_t ret = RET_OK;
image_loader_t* loader = image_loader_stb();
uint32_t size = file_get_size(filename);
asset_info_t* info = (asset_info_t*)TKMEM_ALLOC(sizeof(asset_info_t) + size);
asset_info_t* info = asset_info_create(ASSET_TYPE_IMAGE, ASSET_TYPE_IMAGE_PNG, "name", size);
return_value_if_fail(info != NULL, RET_OOM);
memset(info, 0x00, sizeof(asset_info_t));
info->size = size;
info->type = ASSET_TYPE_IMAGE;
info->subtype = ASSET_TYPE_IMAGE_PNG;
info->refcount = 1;
info->is_in_rom = FALSE;
strncpy(info->name, "name", TK_NAME_LEN);
ENSURE(file_read_part(filename, info->data, size, 0) == size);
ret = image_loader_load(loader, info, image);
TKMEM_FREE(info);
asset_info_destroy(info);
return ret;
}

27
tests/overlay_test.cc Normal file
View File

@ -0,0 +1,27 @@
#include "widgets/overlay.h"
#include "gtest/gtest.h"
TEST(Overlay, cast) {
widget_t* w = overlay_create(NULL, 10, 20, 30, 40);
ASSERT_EQ(w, overlay_cast(w));
widget_destroy(w);
}
TEST(Overlay, props) {
widget_t* w = overlay_create(NULL, 10, 20, 30, 40);
overlay_t* overlay = OVERLAY(w);
ASSERT_EQ(overlay->click_through, FALSE);
widget_set_prop_bool(w, WIDGET_PROP_CLICK_THROUGH, TRUE);
ASSERT_EQ(overlay->click_through, TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_CLICK_THROUGH, FALSE), TRUE);
ASSERT_EQ(overlay->always_on_top, FALSE);
widget_set_prop_bool(w, WIDGET_PROP_ALWAYS_ON_TOP, TRUE);
ASSERT_EQ(overlay->always_on_top, TRUE);
ASSERT_EQ(widget_get_prop_bool(w, WIDGET_PROP_ALWAYS_ON_TOP, FALSE), TRUE);
widget_destroy(w);
}