Files
luban-lite/packages/third-party/awtk-ui/awtk/src/widgets/combo_box.h
刘可亮 3b4064f334 v1.0.2
2023-11-30 19:48:02 +08:00

506 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* File: combo_box.h
* Author: AWTK Develop Team
* Brief: combo_box
*
* Copyright (c) 2018 - 2023 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-25 Li XianJing <xianjimli@hotmail.com> created
*
*/
#ifndef TK_COMBO_BOX_H
#define TK_COMBO_BOX_H
#include "widgets/edit.h"
BEGIN_C_DECLS
typedef struct _combo_box_option_t {
char* text;
int32_t value;
struct _combo_box_option_t* next;
} combo_box_option_t;
typedef widget_t* (*combo_box_custom_open_popup_t)(widget_t* combobox);
typedef ret_t (*combo_box_custom_on_layout_combobox_popup_t)(widget_t* combobox);
/**
* @class combo_box_t
* @parent edit_t
* @annotation ["scriptable","design","widget"]
* 下拉列表控件。
*
* 点击右边的按钮,可弹出一个下拉列表,从中选择一项作为当前的值。
*
* combo\_box\_t是[edit\_t](edit_t.md)的子类控件edit\_t的函数均适用于combo\_box\_t控件。
*
* 在xml中使用"combo_box"标签创建下拉列表控件。
*
* 列表选项可以直接写在"options"属性中。如:
*
* ```xml
* <combo_box readonly="true" x="10" y="bottom:5" w="200" h="30" tr_text="ok"
*options="1:ok;2:cancel;"/>
* ```
*
* 列表选项也可以放在独立的窗口中,用属性"open_window"指定窗口的名称。如:
*
* ```xml
* <combo_box open_window="language" readonly="true" x="10" y="bottom:50" w="200" h="30"
*tr_text="english"/>
* ```
*
* language.xml:
*
* ```xml
* <popup close_when_click_outside="true" h="80" >
* <list_view x="0" y="0" w="100%" h="100%" item_height="30">
* <scroll_view name="view" x="0" y="0" w="-12" h="100%">
* <combo_box_item tr_text="english"/>
* <combo_box_item tr_text="chinese" />
* </scroll_view>
* <scroll_bar_d name="bar" x="right" y="0" w="12" h="100%" value="0"/>
* </list_view>
* </popup>
* ```
*
* > 更多用法请参考:[combo_box.xml](https://github.com/zlgopen/awtk/blob/master/design/default/ui/combo_box.xml)
*
*
*
* 如果在文本比较长时希望在获得焦点时文本自动滚动可以放入一个hscroll_label为子控件并命名为"value"。如:
*
* ```xml
* <combo_box left_margin="6" readonly="true" x="10" y="50" w="80" h="30" options="leftttttttttt;centerrrrrrrrrrrrrrrr;rightttttttttt;"
* selected_index="1">
* <hscroll_label x="0" y="0" w="-30" h="100%"
* name="value"
* lull="1000"
* loop="true"
* yoyo="true"
* ellipses="true"
* only_parent_focus="true"/>
* <button style="combobox_down" x="right:5" y="middle" w="20" h="20"/>
* </combo_box>
* ```
*
* 在c代码中使用函数combo\_box\_create创建下拉列表控件。如
*
* ```c
* widget_t* combo_box = combo_box_create(win, 10, 10, 128, 30);
*
* combo_box_set_options(combo_box, "left;center;right;");
* combo_box_set_selected_index(combo_box, 1);
*
* ```
*
* 创建之后:
*
* * 用combo\_box\_set\_options设置可选项目。
* * 用combo\_box\_set\_selected\_index设置缺省项。
*
*> 完整示例请参考:[combo_box
*demo](https://github.com/zlgopen/awtk-c-demos/blob/master/demos/combo_box.c)
*
* 可用通过style来设置控件的显示风格如字体的大小和颜色等等。如
*
* ```xml
* <combo_box>
* <style name="default" border_color="#a0a0a0" text_color="black" text_align_h="left">
* <normal bg_color="#f0f0f0" />
* <focused bg_color="#f0f0f0" border_color="black"/>
* <empty bg_color="#f0f0f0" text_color="#a0a0a0" />
* </style>
* </combo_box>
* ```
*
* * 1.combobox的下拉按钮的style名称为combobox_down可以在窗体样式文件中设置。
*
* ```xml
* <button>
* <style name="combobox_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>
* </button>
* ```
*
* * 2.combobox的弹出popup窗口的style名称为combobox_popup可以在窗体样式文件中设置。
*
* ```xml
* <popup>
* <style name="combobox_popup" border_color="red">
* <normal bg_color="#808080"/>
* </style>
* </popup>
* ```
* * 3.combobox的下拉框中的列表项的样式可以设置combo_box_item的style来改变。
*
* ```xml
* <combo_box_item>
* <style name="default" icon_at="left" text_color="black" bg_color="#f0f0f0">
* <normal icon="empty"/>
* <focused icon="empty" bg_color="#1296db" text_color="gold" />
* <pressed icon="empty" bg_color="#1296db" text_color="white" />
* <over icon="empty" bg_color="#1296db" text_color="white" />
* <normal_of_checked icon="check"/>
* <focused_of_checked icon="check" bg_color="#1296db" text_color="gold"/>
* <pressed_of_checked icon="check" bg_color="#1296db" text_color="white" />
* <over_of_checked icon="check" bg_color="#1296db" text_color="white" />
* </style>
* </combo_box_item>
* ```
*
* > 更多用法请参考:[theme
*default](https://github.com/zlgopen/awtk/blob/master/design/default/styles/default.xml#L422)
*
*/
typedef struct _combo_box_t {
edit_t edit;
/**
* @property {char*} open_window
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 为点击按钮时,要打开窗口的名称。
*/
char* open_window;
/**
* @property {char*} theme_of_popup
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 弹出窗口的主题(对应的style文件必须存在)方便为不同combo box的弹出窗口指定不同的样式。
*/
char* theme_of_popup;
/**
* @property {int32_t} selected_index
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 当前选中的选项。
*/
int32_t selected_index;
/**
* @property {int32_t} value
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 值。
*/
int32_t value;
/**
* @property {bool_t} localize_options
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 是否本地化(翻译)选项(缺省为TRUE)。
*/
bool_t localize_options;
/**
* @property {char*} options
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 设置可选项(冒号分隔值和文本,分号分隔选项,如:1:red;2:green;3:blue)。
* > 如果数据本身中有英文冒号(:)和英文分号(;)请用16进制转义。
* > * 英文冒号(:)写为\\x3a
* > * 英文冒号(;)写为\\x3b
*/
char* options;
/**
* @property {int32_t} item_height
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* 下拉选项的高度。如果open_window为空则使用缺省高度。
*/
int32_t item_height;
/*private*/
str_t text;
bool_t pressed;
widget_t* combobox_popup;
combo_box_option_t* option_items;
combo_box_custom_open_popup_t open_popup;
combo_box_custom_on_layout_combobox_popup_t on_layout_combobox_popup;
event_func_t on_item_click;
void* on_item_click_ctx;
uint32_t init_popup_button_idle_id;
} combo_box_t;
/**
* @event {value_change_event_t} EVT_VALUE_WILL_CHANGE
* 值即将改变事件。
*/
/**
* @event {value_change_event_t} EVT_VALUE_CHANGED
* 值改变事件。
*/
/**
* @method combo_box_create
* 创建combo_box对象
* @annotation ["constructor", "scriptable"]
* @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* combo_box_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
/**
* @method combo_box_cast
* 转换combo_box对象(供脚本语言使用)。
* @annotation ["cast", "scriptable"]
* @param {widget_t*} widget combo_box对象。
*
* @return {widget_t*} combo_box对象。
*/
widget_t* combo_box_cast(widget_t* widget);
/**
* @method combo_box_set_open_window
* 点击按钮时可以打开popup窗口本函数可设置窗口的名称。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {const char*} open_window 弹出窗口的名称。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_open_window(widget_t* widget, const char* open_window);
/**
* @method combo_box_set_theme_of_popup
* 设置弹出窗口的主题。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {const char*} theme_of_popup 弹出的窗口主题。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_theme_of_popup(widget_t* widget, const char* theme_of_popup);
/**
* @method combo_box_reset_options
* 重置所有选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_reset_options(widget_t* widget);
/**
* @method combo_box_count_options
* 获取选项个数。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
*
* @return {int32_t} 返回选项个数。
*/
int32_t combo_box_count_options(widget_t* widget);
/**
* @method combo_box_set_selected_index
* 设置第index个选项为当前选中的选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {uint32_t} index 选项的索引。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_selected_index(widget_t* widget, uint32_t index);
/**
* @method combo_box_set_selected_index_by_text
* 根据文本设置当前选中的选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {const char*} text 原生(非翻译的文本)。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_selected_index_by_text(widget_t* widget, const char* text);
/**
* @method combo_box_set_localize_options
* 设置是否本地化(翻译)选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {bool_t} localize_options 是否本地化(翻译)选项。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_localize_options(widget_t* widget, bool_t localize_options);
/**
* @method combo_box_set_value
* 设置值。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {int32_t} value 值。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_value(widget_t* widget, int32_t value);
/**
* @method combo_box_set_item_height
* 设置item高度。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {uint32_t} item_height item的高度。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_item_height(widget_t* widget, uint32_t item_height);
/**
* @method combo_box_append_option
* 追加一个选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {int32_t} value 值。
* @param {const char*} text 文本。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_append_option(widget_t* widget, int32_t value, const char* text);
/**
* @method combo_box_remove_option
* 删除第一个值为value的选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {int32_t} value 选项的值。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_remove_option(widget_t* widget, int32_t value);
/**
* @method combo_box_remove_option_by_index
* 删除指定序数的选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {uint32_t} index 选项的序数(0表示第一个)。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_remove_option_by_index(widget_t* widget, uint32_t index);
/**
* @method combo_box_set_options
* 设置选项。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {const char*} options 选项。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_options(widget_t* widget, const char* options);
/**
* @method combo_box_set_custom_open_popup
* 设置自定义的打开弹出窗口的函数。
* @param {widget_t*} widget combo_box对象。
* @param {combo_box_custom_open_popup_t} open_popup 回调函数。
* @param {combo_box_custom_on_layout_combobox_popup_t} on_layout_combobox_popup layout 的回调函数。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_custom_open_popup(
widget_t* widget, combo_box_custom_open_popup_t open_popup,
combo_box_custom_on_layout_combobox_popup_t on_layout_combobox_popup);
/**
* @method combo_box_set_on_item_click
* 设置弹出窗口的item被点击的回调函数回调函数返回非RET_OK继续默认处理。
* @param {widget_t*} widget combo_box对象。
* @param {event_func_t} on_item_click 回调函数。
* @param {void*} ctx 回调函数上下文。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t combo_box_set_on_item_click(widget_t* widget, event_func_t on_item_click, void* ctx);
/**
* @method combo_box_get_option
* 获取第index个选项。
* @param {widget_t*} widget combo_box对象。
* @param {uint32_t} index 选项的索引。
*
* @return {combo_box_option_t*} 返回index个选项。
*/
combo_box_option_t* combo_box_get_option(widget_t* widget, uint32_t index);
/**
* @method combo_box_get_value
* 获取combo_box的值。
* @alias combo_box_get_value_int
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
*
* @return {int32_t} 返回值。
*/
int32_t combo_box_get_value(widget_t* widget);
/**
* @method combo_box_has_option_text
* 检查选项中是否存在指定的文本。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
* @param {const char*} text option text
*
* @return {bool_t} 返回TRUE表示存在否则表示不存在。
*/
bool_t combo_box_has_option_text(widget_t* widget, const char* text);
/**
* @method combo_box_get_text
* 获取combo_box的文本(可能是翻译后的文本)。
* @annotation ["scriptable"]
* @alias combo_box_get_text_value
* @param {widget_t*} widget combo_box对象。
*
* @return {const char*} 返回文本。
*/
const char* combo_box_get_text(widget_t* widget);
/**
* @method combo_box_get_text_of_selected
* 获取combo_box当前选中项目的文本(原生非翻译的文本)。
* @annotation ["scriptable"]
* @param {widget_t*} widget combo_box对象。
*
* @return {const char*} 返回文本。
*/
const char* combo_box_get_text_of_selected(widget_t* widget);
#define COMBO_BOX(widget) ((combo_box_t*)(combo_box_cast(WIDGET(widget))))
/*public for subclass and runtime type check*/
TK_EXTERN_VTABLE(combo_box);
/*public for test*/
ret_t combo_box_parse_options(widget_t* widget, const char* str);
/*private*/
ret_t combo_box_combobox_popup_on_close_func(void* ctx, event_t* e);
ret_t combo_box_combobox_popup_calc_position(widget_t* widget, wh_t popup_w, wh_t popup_h,
point_t* p);
END_C_DECLS
#endif /*TK_COMBO_BOX_H*/