mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-12-04 13:07:40 +08:00
improve dialog_highlighter
This commit is contained in:
parent
0258c4a275
commit
aa88310a2f
@ -80,6 +80,26 @@ ret_t dialog_highlighter_set_bg_clip_rect(dialog_highlighter_t* h, rect_t* clip_
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t dialog_highlighter_set_system_bar_alpha(dialog_highlighter_t* h, uint8_t alpha) {
|
||||
return_value_if_fail(h != NULL && h->vt != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (h->vt->set_system_bar_alpha != NULL) {
|
||||
return h->vt->set_system_bar_alpha(h, alpha);
|
||||
}
|
||||
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
uint8_t dialog_highlighter_get_alpha(dialog_highlighter_t* h, float_t percent) {
|
||||
return_value_if_fail(h != NULL && h->vt != NULL, 0x0);
|
||||
|
||||
if (h->vt->get_alpha != NULL) {
|
||||
return h->vt->get_alpha(h, percent);
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
ret_t dialog_highlighter_draw(dialog_highlighter_t* h, float_t percent) {
|
||||
return_value_if_fail(h != NULL && h->vt != NULL, RET_BAD_PARAMS);
|
||||
|
||||
@ -90,6 +110,16 @@ ret_t dialog_highlighter_draw(dialog_highlighter_t* h, float_t percent) {
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
ret_t dialog_highlighter_draw_mask(dialog_highlighter_t* h, canvas_t* c, float_t percent) {
|
||||
return_value_if_fail(h != NULL && h->vt != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (h->vt->draw_mask != NULL) {
|
||||
return h->vt->draw_mask(h, c, percent);
|
||||
}
|
||||
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
bool_t dialog_highlighter_is_dynamic(dialog_highlighter_t* h) {
|
||||
if (h != NULL && h->vt != NULL && h->vt->is_dynamic != NULL) {
|
||||
return h->vt->is_dynamic(h);
|
||||
|
@ -29,6 +29,9 @@ BEGIN_C_DECLS
|
||||
struct _dialog_highlighter_t;
|
||||
typedef struct _dialog_highlighter_t dialog_highlighter_t;
|
||||
|
||||
typedef ret_t (*dialog_highlighter_set_system_bar_alpha_t)(dialog_highlighter_t* h, uint8_t alpha);
|
||||
typedef uint8_t (*dialog_highlighter_get_alpha_t)(dialog_highlighter_t* h, float_t percent);
|
||||
typedef ret_t (*dialog_highlighter_draw_mask_t)(dialog_highlighter_t* h, canvas_t* c, float_t percent);
|
||||
typedef ret_t (*dialog_highlighter_prepare_t)(dialog_highlighter_t* h, canvas_t* c);
|
||||
typedef ret_t (*dialog_highlighter_draw_t)(dialog_highlighter_t* h, float_t percent);
|
||||
typedef bool_t (*dialog_highlighter_is_dynamic_t)(dialog_highlighter_t* h);
|
||||
@ -42,8 +45,11 @@ typedef struct _dialog_highlighter_vtable_t {
|
||||
uint32_t size;
|
||||
dialog_highlighter_draw_t draw;
|
||||
dialog_highlighter_prepare_t prepare;
|
||||
dialog_highlighter_draw_mask_t draw_mask;
|
||||
dialog_highlighter_get_alpha_t get_alpha;
|
||||
dialog_highlighter_is_dynamic_t is_dynamic;
|
||||
dialog_highlighter_on_destroy_t on_destroy;
|
||||
dialog_highlighter_set_system_bar_alpha_t set_system_bar_alpha;
|
||||
} dialog_highlighter_vtable_t;
|
||||
|
||||
/**
|
||||
@ -148,6 +154,26 @@ ret_t dialog_highlighter_prepare(dialog_highlighter_t* h, canvas_t* c);
|
||||
*/
|
||||
ret_t dialog_highlighter_prepare_ex(dialog_highlighter_t* h, canvas_t* c, canvas_t* canvas_offline);
|
||||
|
||||
/**
|
||||
* @method dialog_highlighter_set_system_bar_alpha
|
||||
* 设置 sytem_bar 的高亮透明值。
|
||||
* @param {dialog_highlighter_t*} h 对话框高亮策略对象。
|
||||
* @param {uint8_t} alpha 设置 sytem_bar 的高亮透明值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t dialog_highlighter_set_system_bar_alpha(dialog_highlighter_t* h, uint8_t alpha);
|
||||
|
||||
/**
|
||||
* @method dialog_highlighter_get_alpha
|
||||
* 获取高亮的透明度。
|
||||
* @param {dialog_highlighter_t*} h 对话框高亮策略对象。
|
||||
* @param {float_t} percent 高亮的百分比。
|
||||
*
|
||||
* @return {uint8_t} 返回透明度。
|
||||
*/
|
||||
uint8_t dialog_highlighter_get_alpha(dialog_highlighter_t* h, float_t percent);
|
||||
|
||||
/**
|
||||
* @method dialog_highlighter_draw
|
||||
* 绘制背景。
|
||||
@ -158,6 +184,17 @@ ret_t dialog_highlighter_prepare_ex(dialog_highlighter_t* h, canvas_t* c, canvas
|
||||
*/
|
||||
ret_t dialog_highlighter_draw(dialog_highlighter_t* h, float_t percent);
|
||||
|
||||
/**
|
||||
* @method dialog_highlighter_draw_mask
|
||||
* 绘制背景高亮部分。
|
||||
* @param {dialog_highlighter_t*} h 对话框高亮策略对象。
|
||||
* @param {canvas_t*} c 画布。
|
||||
* @param {float_t} percent 高亮的百分比。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t dialog_highlighter_draw_mask(dialog_highlighter_t* h, canvas_t* c, float_t percent);
|
||||
|
||||
/**
|
||||
* @method dialog_highlighter_is_dynamic
|
||||
* 是否是动态绘制(方便外层优化)。
|
||||
|
@ -36,6 +36,55 @@ static ret_t dialog_highlighter_default_draw_mask(canvas_t* c, uint8_t alpha) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t dialog_highlighter_default_draw_mask_system_bar(canvas_t* c, uint8_t alpha) {
|
||||
if (alpha > 1) {
|
||||
widget_t* widget = window_manager();
|
||||
color_t mask = color_init(0, 0, 0, alpha);
|
||||
|
||||
WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i)
|
||||
if (widget_is_system_bar(iter)) {
|
||||
canvas_set_fill_color(c, mask);
|
||||
canvas_fill_rect(c, iter->x, iter->y, iter->w, iter->h);
|
||||
}
|
||||
WIDGET_FOR_EACH_CHILD_END()
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t dialog_highlighter_default_draw_mask_from_percent(dialog_highlighter_t* h, canvas_t* c, float_t percent) {
|
||||
dialog_highlighter_default_t* dh = (dialog_highlighter_default_t*)h;
|
||||
|
||||
return_value_if_fail(dh != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (dh->start_alpha != dh->end_alpha) {
|
||||
uint8_t a = ((dh->end_alpha - dh->start_alpha) * percent) + dh->start_alpha;
|
||||
return dialog_highlighter_default_draw_mask(c, a);
|
||||
} else {
|
||||
return dialog_highlighter_default_draw_mask(c, dh->end_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
ret_t dialog_highlighter_default_set_system_bar_alpha(dialog_highlighter_t* h, uint8_t alpha) {
|
||||
dialog_highlighter_default_t* dh = (dialog_highlighter_default_t*)h;
|
||||
return_value_if_fail(dh != NULL, RET_BAD_PARAMS);
|
||||
/* 计算叠加的 system_bar 的高亮透明度 */
|
||||
dh->system_bar_alpha = (dh->system_bar_alpha * (0xff - alpha)) >> 8;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
uint8_t dialog_highlighter_default_get_alpha(dialog_highlighter_t* h, float_t percent) {
|
||||
dialog_highlighter_default_t* dh = (dialog_highlighter_default_t*)h;
|
||||
return_value_if_fail(dh != NULL, 0x0);
|
||||
|
||||
if (dh->start_alpha == dh->end_alpha) {
|
||||
return dh->start_alpha;
|
||||
} else {
|
||||
return (0xff * (dh->end_alpha - dh->start_alpha) * percent) / 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t dialog_highlighter_default_prepare(dialog_highlighter_t* h, canvas_t* c) {
|
||||
dialog_highlighter_default_t* dh = (dialog_highlighter_default_t*)h;
|
||||
return_value_if_fail(h != NULL && h->vt != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
@ -79,6 +128,10 @@ static ret_t dialog_highlighter_default_draw(dialog_highlighter_t* h, float_t pe
|
||||
if (dh->start_alpha != dh->end_alpha) {
|
||||
uint8_t a = ((dh->end_alpha - dh->start_alpha) * percent) + dh->start_alpha;
|
||||
dialog_highlighter_default_draw_mask(c, a);
|
||||
} else {
|
||||
/* 解决黑色色块绘制到贴图导致 system_bar 的颜色不同步的问题 */
|
||||
uint8_t a = 0xff - ((dh->system_bar_alpha * (0xff - dh->end_alpha)) >> 8);
|
||||
dialog_highlighter_default_draw_mask_system_bar(c, a);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
@ -95,6 +148,9 @@ static const dialog_highlighter_vtable_t s_dialog_highlighter_default_vt = {
|
||||
.desc = "dialog_highlighter_default_t",
|
||||
.size = sizeof(dialog_highlighter_default_t),
|
||||
.prepare = dialog_highlighter_default_prepare,
|
||||
.draw_mask = dialog_highlighter_default_draw_mask_from_percent,
|
||||
.set_system_bar_alpha = dialog_highlighter_default_set_system_bar_alpha,
|
||||
.get_alpha = dialog_highlighter_default_get_alpha,
|
||||
.is_dynamic = dialog_highlighter_default_is_dynamic,
|
||||
.draw = dialog_highlighter_default_draw};
|
||||
|
||||
@ -106,6 +162,7 @@ dialog_highlighter_t* dialog_highlighter_default_create(object_t* args) {
|
||||
|
||||
dh->end_alpha = 0;
|
||||
dh->start_alpha = 0;
|
||||
dh->system_bar_alpha = 0xff;
|
||||
|
||||
if (object_get_prop(args, DIALOG_HIGHLIGHTER_DEFAULT_ARG_ALPHA, &v) == RET_OK) {
|
||||
dh->start_alpha = value_int(&v);
|
||||
|
@ -51,6 +51,12 @@ struct _dialog_highlighter_default_t {
|
||||
* 结束alpha,打开对话框的动画结束(直到对话框被关闭)时的alpha值。
|
||||
*/
|
||||
uint8_t end_alpha;
|
||||
|
||||
/**
|
||||
* @property {uint8_t} system_bar_alpha
|
||||
* 由于在没有过度动画的情况下,截图中已经包括黑色色块,为了让 system_bar 也同步高亮部分的色块透明。
|
||||
*/
|
||||
uint8_t system_bar_alpha;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -143,6 +143,59 @@ ret_t window_manager_default_snap_curr_window(widget_t* widget, widget_t* curr_w
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t window_manager_default_snap_prev_window_draw_dialog_highlighter_and_get_alpha(widget_t* widget, canvas_t* c, uint8_t* alpha){
|
||||
value_t v;
|
||||
return_value_if_fail(widget != NULL && c != NULL, FALSE);
|
||||
if (widget_get_prop(widget, WIDGET_PROP_HIGHLIGHT, &v) == RET_OK) {
|
||||
const char* args = value_str(&v);
|
||||
dialog_highlighter_factory_t* f = dialog_highlighter_factory();
|
||||
dialog_highlighter_t* dialog_highlighter = dialog_highlighter_factory_create_highlighter(f, args, widget);
|
||||
|
||||
if (dialog_highlighter != NULL) {
|
||||
dialog_highlighter_draw_mask(dialog_highlighter, c, 1.0f);
|
||||
*alpha = dialog_highlighter_get_alpha(dialog_highlighter, 1.0f);
|
||||
widget_off_by_func(widget, EVT_DESTROY, dialog_highlighter_on_dialog_destroy, dialog_highlighter);
|
||||
dialog_highlighter_destroy(dialog_highlighter);
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
static bool_t window_manager_default_is_dialog_highlighter(widget_t* widget) {
|
||||
value_t v;
|
||||
return_value_if_fail(widget != NULL, FALSE);
|
||||
|
||||
if (widget_is_dialog(widget) && widget_get_prop(widget, WIDGET_PROP_HIGHLIGHT, &v) == RET_OK) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static widget_t* window_manager_default_find_top_dialog_highlighter(widget_t* widget, widget_t* prev_win, widget_t* curr_win) {
|
||||
int32_t i = 0;
|
||||
widget_t* dialog = NULL;
|
||||
widget_t** children = (widget_t**)(widget->children->elms);
|
||||
i = widget->children->size - 1;
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
value_t v;
|
||||
widget_t* iter = children[i];
|
||||
if (iter == prev_win) {
|
||||
break;
|
||||
}
|
||||
if (iter == curr_win) {
|
||||
continue;
|
||||
}
|
||||
if (window_manager_default_is_dialog_highlighter(iter)) {
|
||||
dialog = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ret_t window_manager_default_snap_prev_window(widget_t* widget, widget_t* prev_win, bitmap_t* img) {
|
||||
rect_t r = {0};
|
||||
canvas_t* c = NULL;
|
||||
@ -181,6 +234,15 @@ ret_t window_manager_default_snap_prev_window(widget_t* widget, widget_t* prev_w
|
||||
if (widget_is_system_bar(iter) || !iter->visible) continue;
|
||||
/* 过滤 curr_win 的对象 */
|
||||
if (iter != wm->curr_win) {
|
||||
/* 给前面的高亮对话框叠加黑色色块 */
|
||||
if (widget_is_dialog(iter)) {
|
||||
uint8_t a = 0x0;
|
||||
window_manager_default_snap_prev_window_draw_dialog_highlighter_and_get_alpha(iter, canvas, &a);
|
||||
if (dialog_highlighter != NULL) {
|
||||
dialog_highlighter_set_system_bar_alpha(dialog_highlighter, a);
|
||||
}
|
||||
}
|
||||
|
||||
ENSURE(widget_paint(iter, canvas) == RET_OK);
|
||||
}
|
||||
}
|
||||
@ -473,7 +535,7 @@ static ret_t window_manager_default_close_window(widget_t* widget, widget_t* win
|
||||
|
||||
widget_remove_child(widget, window);
|
||||
idle_add(window_manager_idle_destroy_window, window);
|
||||
|
||||
/* 这里是解决没有结束动画,但是 prev_win 是高亮的对话框的情况 */
|
||||
prev_win = window_manager_get_top_window(widget);
|
||||
if (prev_win != NULL) {
|
||||
if (!widget_is_keyboard(window)) {
|
||||
@ -649,9 +711,11 @@ static ret_t window_manager_animate_done_set_window_foreground(widget_t* widget,
|
||||
static ret_t window_manager_animate_done(widget_t* widget) {
|
||||
window_manager_default_t* wm = WINDOW_MANAGER_DEFAULT(widget);
|
||||
bool_t curr_win_is_keyboard = widget_is_keyboard(wm->animator->curr_win);
|
||||
bool_t curr_win_is_normal_window = widget_is_normal_window(wm->animator->curr_win);
|
||||
|
||||
if (wm->animator != NULL) {
|
||||
bool_t is_open = wm->animator->open;
|
||||
widget_t* top_dialog_highligth = NULL;
|
||||
widget_t* prev_win = wm->animator->prev_win;
|
||||
widget_t* curr_win = wm->animator->curr_win;
|
||||
window_animator_destroy(wm->animator);
|
||||
@ -661,15 +725,28 @@ static ret_t window_manager_animate_done(widget_t* widget) {
|
||||
wm->ignore_user_input = FALSE;
|
||||
|
||||
if (is_open) {
|
||||
/* 结束打开窗口动画后 */
|
||||
if (!curr_win_is_keyboard) {
|
||||
window_manager_dispatch_window_event(prev_win, EVT_WINDOW_TO_BACKGROUND);
|
||||
}
|
||||
if (!curr_win_is_normal_window) {
|
||||
top_dialog_highligth = window_manager_default_find_top_dialog_highlighter(widget, prev_win, curr_win_is_keyboard ? curr_win : NULL);
|
||||
}
|
||||
window_manager_dispatch_window_event(curr_win, EVT_WINDOW_OPEN);
|
||||
} else {
|
||||
/* 结束关闭窗口动画后 */
|
||||
if (!curr_win_is_keyboard) {
|
||||
window_manager_animate_done_set_window_foreground(widget, prev_win, curr_win);
|
||||
window_manager_create_highlighter(widget, prev_win);
|
||||
}
|
||||
top_dialog_highligth = window_manager_default_find_top_dialog_highlighter(widget, prev_win, curr_win);
|
||||
|
||||
}
|
||||
/* 制作一张没有最后一个对话框的高亮背景贴图 */
|
||||
if (top_dialog_highligth != NULL) {
|
||||
widget_t* tmp_curr_win = wm->curr_win;
|
||||
wm->curr_win = top_dialog_highligth;
|
||||
window_manager_create_highlighter(widget, top_dialog_highligth);
|
||||
wm->curr_win = tmp_curr_win;
|
||||
}
|
||||
|
||||
if (wm->pending_close_window != NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user