Mouse hover highlight for grid items
Like the tree-view rows, grid items use an overlapping layout to draw the background and a custom layout on top. There is a new dedicated button type for the grid view items. Adds some related bits needed for persistent view-item state storage. Also a bunch of code for the grid item button type can be shared with the tree-row one, but I prefer doing that separately.
This commit is contained in:
parent
29fdd43605
commit
400d7235c3
|
@ -27,8 +27,10 @@
|
|||
#include "BLI_vector.hh"
|
||||
#include "UI_resources.h"
|
||||
|
||||
struct bContext;
|
||||
struct PreviewImage;
|
||||
struct uiBlock;
|
||||
struct uiButGridTile;
|
||||
struct uiLayout;
|
||||
struct wmNotifier;
|
||||
|
||||
|
@ -41,10 +43,17 @@ class AbstractGridView;
|
|||
* \{ */
|
||||
|
||||
class AbstractGridViewItem {
|
||||
friend AbstractGridView;
|
||||
friend class AbstractGridView;
|
||||
friend class GridViewLayoutBuilder;
|
||||
|
||||
const AbstractGridView *view_;
|
||||
|
||||
protected:
|
||||
/** This label is used as the default way to identifying an item in the view. */
|
||||
std::string label_{};
|
||||
/** Every visible item gets a button of type #UI_BTYPE_GRID_TILE during the layout building. */
|
||||
uiButGridTile *grid_tile_but_ = nullptr;
|
||||
|
||||
public:
|
||||
virtual ~AbstractGridViewItem() = default;
|
||||
|
||||
|
@ -52,8 +61,20 @@ class AbstractGridViewItem {
|
|||
|
||||
const AbstractGridView &get_view() const;
|
||||
|
||||
/**
|
||||
* Compare this item to \a other to check if they represent the same data.
|
||||
* Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active,
|
||||
* renaming, etc.). By default this just matches the item's label. If that isn't good enough for
|
||||
* a sub-class, that can override it.
|
||||
*/
|
||||
virtual bool matches(const AbstractGridViewItem &other) const;
|
||||
|
||||
protected:
|
||||
AbstractGridViewItem() = default;
|
||||
|
||||
private:
|
||||
static void grid_tile_click_fn(bContext *, void *but_arg1, void *);
|
||||
void add_grid_tile_button(uiBlock &block);
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -94,6 +94,8 @@ typedef struct uiTreeViewHandle uiTreeViewHandle;
|
|||
typedef struct uiTreeViewItemHandle uiTreeViewItemHandle;
|
||||
/* C handle for C++ #ui::AbstractGridView type. */
|
||||
typedef struct uiGridViewHandle uiGridViewHandle;
|
||||
/* C handle for C++ #ui::AbstractGridViewItem type. */
|
||||
typedef struct uiGridViewItemHandle uiGridViewItemHandle;
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
@ -407,6 +409,8 @@ typedef enum {
|
|||
UI_BTYPE_DECORATOR = 58 << 9,
|
||||
/* An item in a tree view. Parent items may be collapsible. */
|
||||
UI_BTYPE_TREEROW = 59 << 9,
|
||||
/* An item in a grid view. */
|
||||
UI_BTYPE_GRID_TILE = 60 << 9,
|
||||
} eButType;
|
||||
|
||||
#define BUTTYPE (63 << 9)
|
||||
|
@ -3178,6 +3182,7 @@ void UI_block_views_listen(const uiBlock *block,
|
|||
const struct wmRegionListenerParams *listener_params);
|
||||
|
||||
bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item);
|
||||
bool UI_grid_view_item_matches(const uiGridViewItemHandle *a, const uiGridViewItemHandle *b);
|
||||
bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b);
|
||||
/**
|
||||
* Attempt to start dragging the tree-item \a item_. This will not work if the tree item doesn't
|
||||
|
|
|
@ -203,7 +203,7 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
|
|||
bool is_renaming_ = false;
|
||||
|
||||
protected:
|
||||
/** This label is used for identifying an item within its parent. */
|
||||
/** This label is used as the default way to identifying an item within its parent. */
|
||||
std::string label_{};
|
||||
/** Every visible item gets a button of type #UI_BTYPE_TREEROW during the layout building. */
|
||||
uiButTreeRow *tree_row_but_ = nullptr;
|
||||
|
|
|
@ -68,6 +68,44 @@ GridViewStyle::GridViewStyle(int width, int height) : tile_width(width), tile_he
|
|||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
bool AbstractGridViewItem::matches(const AbstractGridViewItem &other) const
|
||||
{
|
||||
return label_ == other.label_;
|
||||
}
|
||||
|
||||
void AbstractGridViewItem::grid_tile_click_fn(struct bContext * /*C*/,
|
||||
void *but_arg1,
|
||||
void * /*arg2*/)
|
||||
{
|
||||
uiButGridTile *grid_tile_but = (uiButGridTile *)but_arg1;
|
||||
AbstractGridViewItem &grid_item = reinterpret_cast<AbstractGridViewItem &>(
|
||||
*grid_tile_but->view_item);
|
||||
|
||||
// tree_item.activate();
|
||||
}
|
||||
|
||||
void AbstractGridViewItem::add_grid_tile_button(uiBlock &block)
|
||||
{
|
||||
const GridViewStyle &style = get_view().get_style();
|
||||
grid_tile_but_ = (uiButGridTile *)uiDefBut(&block,
|
||||
UI_BTYPE_GRID_TILE,
|
||||
0,
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
style.tile_width,
|
||||
style.tile_height,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
|
||||
grid_tile_but_->view_item = reinterpret_cast<uiGridViewItemHandle *>(this);
|
||||
UI_but_func_set(&grid_tile_but_->but, grid_tile_click_fn, grid_tile_but_, nullptr);
|
||||
}
|
||||
|
||||
const AbstractGridView &AbstractGridViewItem::get_view() const
|
||||
{
|
||||
if (UNLIKELY(!view_)) {
|
||||
|
@ -87,7 +125,9 @@ class GridViewLayoutBuilder {
|
|||
public:
|
||||
GridViewLayoutBuilder(uiBlock &block);
|
||||
|
||||
void build_from_view(const AbstractGridView &grid_view);
|
||||
void build_from_view(const AbstractGridView &grid_view) const;
|
||||
void build_grid_tile(uiLayout &grid_layout, AbstractGridViewItem &item) const;
|
||||
|
||||
uiLayout *current_layout() const;
|
||||
};
|
||||
|
||||
|
@ -95,8 +135,19 @@ GridViewLayoutBuilder::GridViewLayoutBuilder(uiBlock &block) : block_(block)
|
|||
{
|
||||
}
|
||||
|
||||
void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
|
||||
void GridViewLayoutBuilder::build_grid_tile(uiLayout &grid_layout,
|
||||
AbstractGridViewItem &item) const
|
||||
{
|
||||
uiLayout *overlap = uiLayoutOverlap(&grid_layout);
|
||||
|
||||
item.add_grid_tile_button(block_);
|
||||
item.build_grid_tile(*uiLayoutRow(overlap, false));
|
||||
}
|
||||
|
||||
void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view) const
|
||||
{
|
||||
uiLayout *prev_layout = current_layout();
|
||||
|
||||
uiLayout &layout = *uiLayoutColumn(current_layout(), false);
|
||||
const GridViewStyle &style = grid_view.get_style();
|
||||
|
||||
|
@ -108,7 +159,7 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
|
|||
|
||||
int item_count = 0;
|
||||
grid_view.foreach_item([&](AbstractGridViewItem &item) {
|
||||
item.build_grid_tile(*grid_layout);
|
||||
build_grid_tile(*grid_layout, item);
|
||||
item_count++;
|
||||
});
|
||||
|
||||
|
@ -120,6 +171,8 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
|
|||
uiItemS(grid_layout);
|
||||
}
|
||||
}
|
||||
|
||||
UI_block_layout_set_current(&block_, prev_layout);
|
||||
}
|
||||
|
||||
uiLayout *GridViewLayoutBuilder::current_layout() const
|
||||
|
@ -183,6 +236,9 @@ void PreviewGridItem::build_grid_tile(uiLayout &layout) const
|
|||
using namespace blender::ui;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* C-API */
|
||||
|
||||
using namespace blender::ui;
|
||||
|
||||
bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view_handle,
|
||||
const wmNotifier *notifier)
|
||||
|
@ -190,3 +246,11 @@ bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view_handle,
|
|||
const AbstractGridView &view = *reinterpret_cast<const AbstractGridView *>(view_handle);
|
||||
return view.listen(*notifier);
|
||||
}
|
||||
|
||||
bool UI_grid_view_item_matches(const uiGridViewItemHandle *a_handle,
|
||||
const uiGridViewItemHandle *b_handle)
|
||||
{
|
||||
const AbstractGridViewItem &a = reinterpret_cast<const AbstractGridViewItem &>(*a_handle);
|
||||
const AbstractGridViewItem &b = reinterpret_cast<const AbstractGridViewItem &>(*b_handle);
|
||||
return a.matches(b);
|
||||
}
|
||||
|
|
|
@ -781,6 +781,15 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
|
|||
}
|
||||
}
|
||||
|
||||
if ((but->type == UI_BTYPE_GRID_TILE) && (oldbut->type == UI_BTYPE_GRID_TILE)) {
|
||||
uiButGridTile *but_gridtile = (uiButGridTile *)but;
|
||||
uiButGridTile *oldbut_gridtile = (uiButGridTile *)oldbut;
|
||||
if (!but_gridtile->view_item || !oldbut_gridtile->view_item ||
|
||||
!UI_grid_view_item_matches(but_gridtile->view_item, oldbut_gridtile->view_item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -907,6 +916,12 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
|
|||
SWAP(uiTreeViewItemHandle *, treerow_newbut->tree_item, treerow_oldbut->tree_item);
|
||||
break;
|
||||
}
|
||||
case UI_BTYPE_GRID_TILE: {
|
||||
uiButGridTile *gridtile_oldbut = (uiButGridTile *)oldbut;
|
||||
uiButGridTile *gridtile_newbut = (uiButGridTile *)but;
|
||||
SWAP(uiGridViewItemHandle *, gridtile_newbut->view_item, gridtile_oldbut->view_item);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -996,9 +1011,9 @@ static bool ui_but_update_from_old_block(const bContext *C,
|
|||
else {
|
||||
int flag_copy = UI_BUT_DRAG_MULTI;
|
||||
|
||||
/* Stupid special case: The active button may be inside (as in, overlapped on top) a tree-row
|
||||
/* Stupid special case: The active button may be inside (as in, overlapped on top) a view-item
|
||||
* button which we also want to keep highlighted then. */
|
||||
if (but->type == UI_BTYPE_TREEROW) {
|
||||
if (ui_but_is_view_item(but)) {
|
||||
flag_copy |= UI_ACTIVE;
|
||||
}
|
||||
|
||||
|
@ -3967,6 +3982,10 @@ static void ui_but_alloc_info(const eButType type,
|
|||
alloc_size = sizeof(uiButTreeRow);
|
||||
alloc_str = "uiButTreeRow";
|
||||
break;
|
||||
case UI_BTYPE_GRID_TILE:
|
||||
alloc_size = sizeof(uiButGridTile);
|
||||
alloc_str = "uiButGridTile";
|
||||
break;
|
||||
default:
|
||||
alloc_size = sizeof(uiBut);
|
||||
alloc_str = "uiBut";
|
||||
|
|
|
@ -2312,6 +2312,9 @@ static void ui_apply_but(
|
|||
case UI_BTYPE_ROW:
|
||||
ui_apply_but_ROW(C, block, but, data);
|
||||
break;
|
||||
case UI_BTYPE_GRID_TILE:
|
||||
ui_apply_but_ROW(C, block, but, data);
|
||||
break;
|
||||
case UI_BTYPE_TREEROW:
|
||||
ui_apply_but_TREEROW(C, block, but, data);
|
||||
break;
|
||||
|
@ -4840,6 +4843,48 @@ static int ui_do_but_TREEROW(bContext *C,
|
|||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static int ui_do_but_GRIDTILE(bContext *C,
|
||||
uiBut *but,
|
||||
uiHandleButtonData *data,
|
||||
const wmEvent *event)
|
||||
{
|
||||
uiButGridTile *grid_tile_but = (uiButGridTile *)but;
|
||||
BLI_assert(grid_tile_but->but.type == UI_BTYPE_GRID_TILE);
|
||||
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
if (event->type == LEFTMOUSE) {
|
||||
switch (event->val) {
|
||||
case KM_PRESS:
|
||||
/* Extra icons have priority, don't mess with them. */
|
||||
if (ui_but_extra_operator_icon_mouse_over_get(but, data, event)) {
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
|
||||
data->dragstartx = event->xy[0];
|
||||
data->dragstarty = event->xy[1];
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
|
||||
case KM_CLICK:
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
|
||||
case KM_DBL_CLICK:
|
||||
data->cancel = true;
|
||||
// UI_tree_view_item_begin_rename(grid_tile_but->tree_item);
|
||||
printf("rename\n");
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
|
||||
/* Let "default" button handling take care of the drag logic. */
|
||||
return ui_do_but_EXIT(C, but, data, event);
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
|
@ -8017,6 +8062,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
|
|||
case UI_BTYPE_ROW:
|
||||
retval = ui_do_but_TOG(C, but, data, event);
|
||||
break;
|
||||
case UI_BTYPE_GRID_TILE:
|
||||
retval = ui_do_but_GRIDTILE(C, but, data, event);
|
||||
break;
|
||||
case UI_BTYPE_TREEROW:
|
||||
retval = ui_do_but_TREEROW(C, but, data, event);
|
||||
break;
|
||||
|
@ -9656,31 +9704,31 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int ui_handle_tree_hover(const wmEvent *event, const ARegion *region)
|
||||
static int ui_handle_view_items_hover(const wmEvent *event, const ARegion *region)
|
||||
{
|
||||
bool has_treerows = false;
|
||||
bool has_view_item = false;
|
||||
LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) {
|
||||
/* Avoid unnecessary work: Tree-rows are assumed to be inside tree-views. */
|
||||
/* Avoid unnecessary work: view item buttons are assumed to be inside views. */
|
||||
if (BLI_listbase_is_empty(&block->views)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
|
||||
if (but->type == UI_BTYPE_TREEROW) {
|
||||
if (ui_but_is_view_item(but)) {
|
||||
but->flag &= ~UI_ACTIVE;
|
||||
has_treerows = true;
|
||||
has_view_item = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_treerows) {
|
||||
if (!has_view_item) {
|
||||
/* Avoid unnecessary lookup. */
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
/* Always highlight the hovered tree-row, even if the mouse hovers another button inside of it.
|
||||
/* Always highlight the hovered view item, even if the mouse hovers another button inside of it.
|
||||
*/
|
||||
uiBut *hovered_row_but = ui_tree_row_find_mouse_over(region, event->xy);
|
||||
uiBut *hovered_row_but = ui_view_item_find_mouse_over(region, event->xy);
|
||||
if (hovered_row_but) {
|
||||
hovered_row_but->flag |= UI_ACTIVE;
|
||||
}
|
||||
|
@ -11288,9 +11336,9 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(use
|
|||
ui_blocks_set_tooltips(region, true);
|
||||
}
|
||||
|
||||
/* Always do this, to reliably update tree-row highlighting, even if the mouse hovers a button
|
||||
* inside the row (it's an overlapping layout). */
|
||||
ui_handle_tree_hover(event, region);
|
||||
/* Always do this, to reliably update view item highlighting, even if the mouse hovers a button
|
||||
* nested in the item (it's an overlapping layout). */
|
||||
ui_handle_view_items_hover(event, region);
|
||||
|
||||
/* delayed apply callbacks */
|
||||
ui_apply_but_funcs_after(C);
|
||||
|
|
|
@ -359,6 +359,13 @@ typedef struct uiButTreeRow {
|
|||
int indentation;
|
||||
} uiButTreeRow;
|
||||
|
||||
/** Derived struct for #UI_BTYPE_GRID_TILE. */
|
||||
typedef struct uiButGridTile {
|
||||
uiBut but;
|
||||
|
||||
uiGridViewItemHandle *view_item;
|
||||
} uiButGridTile;
|
||||
|
||||
/** Derived struct for #UI_BTYPE_HSVCUBE. */
|
||||
typedef struct uiButHSVCube {
|
||||
uiBut but;
|
||||
|
@ -1357,6 +1364,7 @@ void ui_but_anim_decorate_update_from_flag(uiButDecorator *but);
|
|||
bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
|
||||
bool ui_but_is_editable_as_text(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
|
||||
bool ui_but_is_toggle(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
|
||||
bool ui_but_is_view_item(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* Can we mouse over the button or is it hidden/disabled/layout.
|
||||
* \note ctrl is kind of a hack currently,
|
||||
|
@ -1387,6 +1395,8 @@ uiBut *ui_list_row_find_mouse_over(const struct ARegion *region, const int xy[2]
|
|||
uiBut *ui_list_row_find_from_index(const struct ARegion *region,
|
||||
int index,
|
||||
uiBut *listbox) ATTR_WARN_UNUSED_RESULT;
|
||||
uiBut *ui_view_item_find_mouse_over(const struct ARegion *region, const int xy[2])
|
||||
ATTR_NONNULL(1, 2);
|
||||
uiBut *ui_tree_row_find_mouse_over(const struct ARegion *region, const int xy[2])
|
||||
ATTR_NONNULL(1, 2);
|
||||
uiBut *ui_tree_row_find_active(const struct ARegion *region);
|
||||
|
|
|
@ -72,6 +72,11 @@ bool ui_but_is_toggle(const uiBut *but)
|
|||
UI_BTYPE_TREEROW);
|
||||
}
|
||||
|
||||
bool ui_but_is_view_item(const uiBut *but)
|
||||
{
|
||||
return ELEM(but->type, UI_BTYPE_TREEROW, UI_BTYPE_GRID_TILE);
|
||||
}
|
||||
|
||||
bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
|
||||
{
|
||||
/* NOTE: #UI_BTYPE_LABEL is included for highlights, this allows drags. */
|
||||
|
@ -459,6 +464,16 @@ static bool ui_but_is_treerow(const uiBut *but, const void *UNUSED(customdata))
|
|||
return but->type == UI_BTYPE_TREEROW;
|
||||
}
|
||||
|
||||
static bool ui_but_is_view_item_fn(const uiBut *but, const void *UNUSED(customdata))
|
||||
{
|
||||
return ui_but_is_view_item(but);
|
||||
}
|
||||
|
||||
uiBut *ui_view_item_find_mouse_over(const ARegion *region, const int xy[2])
|
||||
{
|
||||
return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_view_item_fn, NULL);
|
||||
}
|
||||
|
||||
uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int xy[2])
|
||||
{
|
||||
return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_treerow, NULL);
|
||||
|
|
|
@ -121,6 +121,7 @@ typedef enum {
|
|||
UI_WTYPE_PROGRESSBAR,
|
||||
UI_WTYPE_NODESOCKET,
|
||||
UI_WTYPE_TREEROW,
|
||||
UI_WTYPE_GRID_TILE,
|
||||
} uiWidgetTypeEnum;
|
||||
|
||||
/* Button state argument shares bits with 'uiBut.flag'.
|
||||
|
@ -3713,6 +3714,13 @@ static void widget_treerow(
|
|||
widget_treerow_exec(wcol, rect, state, roundboxalign, tree_row->indentation, zoom);
|
||||
}
|
||||
|
||||
static void widget_gridtile(
|
||||
uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, const float zoom)
|
||||
{
|
||||
/* TODO Reuse tree-row drawing. */
|
||||
widget_treerow_exec(wcol, rect, state, roundboxalign, 0, zoom);
|
||||
}
|
||||
|
||||
static void widget_nodesocket(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
|
@ -4567,6 +4575,10 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
|
|||
wt.custom = widget_treerow;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_GRID_TILE:
|
||||
wt.draw = widget_gridtile;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_NODESOCKET:
|
||||
wt.custom = widget_nodesocket;
|
||||
break;
|
||||
|
@ -4903,6 +4915,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
|
|||
fstyle = &style->widgetlabel;
|
||||
break;
|
||||
|
||||
case UI_BTYPE_GRID_TILE:
|
||||
wt = widget_type(UI_WTYPE_GRID_TILE);
|
||||
fstyle = &style->widgetlabel;
|
||||
break;
|
||||
|
||||
case UI_BTYPE_SCROLL:
|
||||
wt = widget_type(UI_WTYPE_SCROLL);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue