diff --git a/source/blender/editors/include/UI_interface_layout.hh b/source/blender/editors/include/UI_interface_layout.hh index 905eff7b3a3..15e6282c3d6 100644 --- a/source/blender/editors/include/UI_interface_layout.hh +++ b/source/blender/editors/include/UI_interface_layout.hh @@ -96,12 +96,6 @@ enum class LayoutSeparatorType : int8_t { */ struct uiLayout : public uiItem, blender::NonCopyable, blender::NonMovable { // protected: - uiLayoutRoot *root_ = nullptr; - bContextStore *context_ = nullptr; - uiLayout *parent_ = nullptr; - blender::Vector items_; - - std::string heading_; /** Sub layout to add child items, if not the layout itself. */ uiLayout *child_items_layout_ = nullptr; @@ -124,8 +118,16 @@ struct uiLayout : public uiItem, blender::NonCopyable, blender::NonMovable { /** Is copied to uiButs created in this layout. */ float search_weight_ = 0.0f; + protected: + uiLayoutRoot *root_ = nullptr; + bContextStore *context_ = nullptr; + uiLayout *parent_ = nullptr; + std::string heading_; + + blender::Vector items_; + public: - uiLayout(blender::ui::ItemType type); + uiLayout(blender::ui::ItemType type, uiLayoutRoot *root); [[nodiscard]] bool active() const; /** @@ -677,6 +679,13 @@ struct uiLayout : public uiItem, blender::NonCopyable, blender::NonMovable { void separator_spacer(); friend struct blender::ui::LayoutInternal; + + [[nodiscard]] uiLayoutRoot *root() const; + [[nodiscard]] const bContextStore *context() const; + [[nodiscard]] uiLayout *parent() const; + [[nodiscard]] blender::StringRef heading() const; + void heading_reset(); + [[nodiscard]] blender::Span items() const; }; inline bool uiLayout::active() const diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 68f82e3a73c..d38a4b7b1d4 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -169,6 +169,9 @@ struct ItemInternal { /** Helper internal struct to provide #uiLayout private/protected access. */ struct LayoutInternal { static void init_from_parent(uiLayout *item, uiLayout *layout, int align); + + static void layout_add_but(uiLayout *layout, uiBut *but); + static void layout_remove_but(uiLayout *layout, const uiBut *but); }; } // namespace blender::ui @@ -183,7 +186,7 @@ blender::ui::ItemType uiItem::type() const return type_; }; -uiLayout::uiLayout(blender::ui::ItemType type) : uiItem(type){}; +uiLayout::uiLayout(blender::ui::ItemType type, uiLayoutRoot *root) : uiItem(type), root_{root} {}; using uiItemType = blender::ui::ItemType; using uiItemInternalFlag = blender::ui::ItemInternalFlag; @@ -196,7 +199,7 @@ struct uiButtonItem : public uiItem { struct uiLayoutItemFlow : public uiLayout { int number = 0; int totcol = 0; - uiLayoutItemFlow() : uiLayout(uiItemType::LayoutColumnFlow) {} + uiLayoutItemFlow() : uiLayout(uiItemType::LayoutColumnFlow, nullptr) {} }; struct uiLayoutItemGridFlow : public uiLayout { @@ -215,27 +218,27 @@ struct uiLayoutItemGridFlow : public uiLayout { /* Pure internal runtime storage. */ int tot_items = 0, tot_columns = 0, tot_rows = 0; - uiLayoutItemGridFlow() : uiLayout(uiItemType::LayoutGridFlow) {} + uiLayoutItemGridFlow() : uiLayout(uiItemType::LayoutGridFlow, nullptr) {} }; struct uiLayoutItemBx : public uiLayout { uiBut *roundbox = nullptr; - uiLayoutItemBx() : uiLayout(uiItemType::LayoutBox) {} + uiLayoutItemBx() : uiLayout(uiItemType::LayoutBox, nullptr) {} }; struct uiLayoutItemPanelHeader : public uiLayout { PointerRNA open_prop_owner; std::string open_prop_name; - uiLayoutItemPanelHeader() : uiLayout(uiItemType::LayoutPanelHeader) {} + uiLayoutItemPanelHeader() : uiLayout(uiItemType::LayoutPanelHeader, nullptr) {} }; struct uiLayoutItemPanelBody : public uiLayout { - uiLayoutItemPanelBody() : uiLayout(uiItemType::LayoutPanelBody) {} + uiLayoutItemPanelBody() : uiLayout(uiItemType::LayoutPanelBody, nullptr) {} }; struct uiLayoutItemSplit : public uiLayout { float percentage = 0.0f; - uiLayoutItemSplit() : uiLayout(uiItemType::LayoutSplit) {} + uiLayoutItemSplit() : uiLayout(uiItemType::LayoutSplit, nullptr) {} }; /** \} */ @@ -315,7 +318,7 @@ static int ui_item_fit(const int item, static int ui_layout_vary_direction(uiLayout *layout) { - return ((ELEM(layout->root_->type, + return ((ELEM(layout->root()->type, blender::ui::LayoutType::Header, blender::ui::LayoutType::PieMenu) || (layout->alignment_ != blender::ui::LayoutAlign::Expand)) ? @@ -579,7 +582,7 @@ static void ui_item_array(uiLayout *layout, const bool compact, const bool show_text) { - const uiStyle *style = layout->root_->style; + const uiStyle *style = layout->root()->style; /* retrieve type and subtype */ const PropertyType type = RNA_property_type(prop); @@ -879,7 +882,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout, BLI_assert(RNA_property_type(prop) == PROP_ENUM); - const bool radial = (layout->root_->type == blender::ui::LayoutType::PieMenu); + const bool radial = (layout->root()->type == blender::ui::LayoutType::PieMenu); bool free; const EnumPropertyItem *item_array; @@ -895,7 +898,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout, /* We don't want nested rows, cols in menus. */ uiLayout *layout_radial = nullptr; if (radial) { - if (layout->root_->layout == layout) { + if (layout->root()->layout == layout) { layout_radial = &layout->menu_pie(); blender::ui::block_layout_set_current(block, layout_radial); } @@ -907,7 +910,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout, } } else if (ELEM(layout->type(), uiItemType::LayoutGridFlow, uiItemType::LayoutColumnFlow) || - layout->root_->type == blender::ui::LayoutType::Menu) + layout->root()->type == blender::ui::LayoutType::Menu) { blender::ui::block_layout_set_current(block, layout); } @@ -1308,7 +1311,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout, } } - if (layout->root_->type == blender::ui::LayoutType::Menu && !icon) { + if (layout->root()->type == blender::ui::LayoutType::Menu && !icon) { icon = ICON_BLANK1; } @@ -1450,7 +1453,7 @@ BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout) { return (layout->type() == uiItemType::LayoutRadial) || ((layout->type() == uiItemType::LayoutRoot) && - (layout->root_->type == blender::ui::LayoutType::PieMenu)); + (layout->root()->type == blender::ui::LayoutType::PieMenu)); } void uiLayout::op_enum_items(wmOperatorType *ot, @@ -1802,8 +1805,8 @@ static bool ui_item_rna_is_expand(PropertyRNA *prop, int index, const eUI_Item_F */ static uiLayout *ui_layout_heading_find(uiLayout *cur_layout) { - for (uiLayout *parent = cur_layout; parent; parent = parent->parent_) { - if (!parent->heading_.empty()) { + for (uiLayout *parent = cur_layout; parent; parent = parent->parent()) { + if (!parent->heading().is_empty()) { return parent; } } @@ -1823,14 +1826,14 @@ static void ui_layout_heading_label_add(uiLayout *layout, } if (respect_prop_split) { - uiItemL_respect_property_split(layout, heading_layout->heading_, ICON_NONE); + uiItemL_respect_property_split(layout, heading_layout->heading(), ICON_NONE); } else { - layout->label(heading_layout->heading_, ICON_NONE); + layout->label(heading_layout->heading(), ICON_NONE); } /* After adding the heading label, we have to mark it somehow as added, so it's not added again * for other items in this layout. For now just clear it. */ - heading_layout->heading_ = {}; + heading_layout->heading_reset(); layout->alignment_ = prev_alignment; } @@ -2759,12 +2762,12 @@ static uiBut *ui_item_menu(uiLayout *layout, blender::ui::block_layout_set_current(block, layout); ui_block_new_button_group(block, uiButtonGroupFlag(0)); - if (layout->root_->type == blender::ui::LayoutType::Menu && !icon) { + if (layout->root()->type == blender::ui::LayoutType::Menu && !icon) { icon = ICON_BLANK1; } uiTextIconPadFactor pad_factor = ui_text_pad_compact; - if (layout->root_->type == blender::ui::LayoutType::Header) { /* Ugly! */ + if (layout->root()->type == blender::ui::LayoutType::Header) { /* Ugly! */ if (icon == ICON_NONE && force_menu) { /* pass */ } @@ -2808,10 +2811,11 @@ static uiBut *ui_item_menu(uiLayout *layout, but->func_argN_copy_fn = func_argN_copy_fn; } - if (ELEM( - layout->root_->type, blender::ui::LayoutType::Panel, blender::ui::LayoutType::Toolbar) || + if (ELEM(layout->root()->type, + blender::ui::LayoutType::Panel, + blender::ui::LayoutType::Toolbar) || /* We never want a drop-down in menu! */ - (force_menu && layout->root_->type != blender::ui::LayoutType::Menu)) + (force_menu && layout->root()->type != blender::ui::LayoutType::Menu)) { UI_but_type_set_menu_from_pulldown(but); } @@ -3038,7 +3042,7 @@ static uiBut *uiItem_simple(uiLayout *layout, blender::ui::block_layout_set_current(block, layout); ui_block_new_button_group(block, uiButtonGroupFlag(0)); - if (layout->root_->type == blender::ui::LayoutType::Menu && !icon) { + if (layout->root()->type == blender::ui::LayoutType::Menu && !icon) { icon = ICON_BLANK1; } @@ -3485,12 +3489,12 @@ static void ui_litem_estimate_row(uiLayout *litem) litem->w_ = 0; litem->h_ = 0; - if (litem->items_.is_empty()) { + if (litem->items().is_empty()) { return; } - const uiItem *item_last = litem->items_.last(); - for (uiItem *item : litem->items_) { + const uiItem *item_last = litem->items().last(); + for (uiItem *item : litem->items()) { const bool is_item_last = (item == item_last); ui_item_size(item, &itemw, &itemh); @@ -3516,7 +3520,7 @@ static int ui_litem_min_width(int itemw) static void ui_litem_layout_row(uiLayout *litem) { - if (litem->items_.is_empty()) { + if (litem->items().is_empty()) { return; } @@ -3531,7 +3535,7 @@ static void ui_litem_layout_row(uiLayout *litem) int totw = 0; int tot = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_size(item, &itemw, &itemh); totw += itemw; tot++; @@ -3546,7 +3550,7 @@ static void ui_litem_layout_row(uiLayout *litem) } int fixedw = 0; - const uiItem *item_last = litem->items_.last(); + const uiItem *item_last = litem->items().last(); /* keep clamping items to fixed minimum size until all are done */ do { @@ -3556,7 +3560,7 @@ static void ui_litem_layout_row(uiLayout *litem) newtotw = totw; extra_pixel = 0.0f; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { if (ItemInternal::auto_fixed_size(item)) { continue; } @@ -3613,7 +3617,7 @@ static void ui_litem_layout_row(uiLayout *litem) x = litem->x_; int item_idx = -1; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { item_idx++; const bool is_item_last = (item == item_last); ui_item_size(item, &itemw, &itemh); @@ -3663,9 +3667,9 @@ static void ui_litem_layout_row(uiLayout *litem) if (extra_pixel_move > 0 && litem->alignment_ == blender::ui::LayoutAlign::Expand && last_free_item_idx >= 0 && item_last && ItemInternal::auto_fixed_size(item_last)) { - ui_item_move(litem->items_[last_free_item_idx], 0, extra_pixel_move); - blender::MutableSpan items_after_last_free = - litem->items_.as_mutable_span().drop_front(last_free_item_idx + 1); + ui_item_move(litem->items()[last_free_item_idx], 0, extra_pixel_move); + blender::Span items_after_last_free = litem->items().drop_front(last_free_item_idx + + 1); for (uiItem *item : items_after_last_free) { ui_item_move(item, extra_pixel_move, extra_pixel_move); } @@ -3700,7 +3704,7 @@ static int spaces_after_column_item(const uiLayout *litem, if (!is_box) { return 1; } - if (item != litem->items_.first()) { + if (item != litem->items().first()) { return 1; } return 0; @@ -3715,7 +3719,7 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) litem->w_ = 0; litem->h_ = 0; - for (auto *iter = litem->items_.begin(); iter != litem->items_.end(); iter++) { + for (auto *iter = litem->items().begin(); iter != litem->items().end(); iter++) { uiItem *item = *iter; ui_item_size(item, &itemw, &itemh); @@ -3724,7 +3728,7 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) litem->w_ = std::max(litem->w_, itemw); litem->h_ += itemh; - const uiItem *next_item = (item == litem->items_.last()) ? nullptr : *(iter + 1); + const uiItem *next_item = (item == litem->items().last()) ? nullptr : *(iter + 1); const int spaces_num = spaces_after_column_item(litem, item, next_item, is_box); litem->h_ += spaces_num * litem->space_; } @@ -3739,7 +3743,7 @@ static void ui_litem_layout_column(uiLayout *litem, bool is_box, bool is_menu) const int x = litem->x_; int y = litem->y_; - for (auto *iter = litem->items_.begin(); iter != litem->items_.end(); iter++) { + for (auto *iter = litem->items().begin(); iter != litem->items().end(); iter++) { uiItem *item = *iter; int itemw, itemh; ui_item_size(item, &itemw, &itemh); @@ -3747,7 +3751,7 @@ static void ui_litem_layout_column(uiLayout *litem, bool is_box, bool is_menu) y -= itemh; ui_item_position(item, x, y, is_menu ? itemw : litem->w_, itemh); - const uiItem *next_item = (item == litem->items_.last()) ? nullptr : *(iter + 1); + const uiItem *next_item = (item == litem->items().last()) ? nullptr : *(iter + 1); const int spaces_num = spaces_after_column_item(litem, item, next_item, is_box); y -= spaces_num * litem->space_; @@ -3817,7 +3821,7 @@ static void ui_litem_layout_radial(uiLayout *litem) litem->block()->pie_data.pie_dir_mask = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { /* Not all button types are drawn in a radial menu, do filtering here. */ if (!ui_item_is_radial_displayable(item)) { continue; @@ -3886,7 +3890,7 @@ static void ui_litem_estimate_root(uiLayout * /*litem*/) static void ui_litem_layout_root_radial(uiLayout *litem) { /* first item is pie menu title, align on center of menu */ - uiItem *item = litem->items_.first(); + uiItem *item = litem->items().first(); if (item->type() == uiItemType::Button) { int itemh, itemw, x, y; @@ -3902,13 +3906,13 @@ static void ui_litem_layout_root_radial(uiLayout *litem) static void ui_litem_layout_root(uiLayout *litem) { - if (litem->root_->type == blender::ui::LayoutType::Header) { + if (litem->root()->type == blender::ui::LayoutType::Header) { ui_litem_layout_row(litem); } - else if (litem->root_->type == blender::ui::LayoutType::PieMenu) { + else if (litem->root()->type == blender::ui::LayoutType::PieMenu) { ui_litem_layout_root_radial(litem); } - else if (litem->root_->type == blender::ui::LayoutType::Menu) { + else if (litem->root()->type == blender::ui::LayoutType::Menu) { ui_litem_layout_column(litem, false, true); } else { @@ -3919,8 +3923,8 @@ static void ui_litem_layout_root(uiLayout *litem) /* panel header layout */ static void ui_litem_estimate_panel_header(uiLayout *litem) { - BLI_assert(litem->items_.size() == 1); - uiItem *item = litem->items_.first(); + BLI_assert(litem->items().size() == 1); + uiItem *item = litem->items().first(); int w, h; ui_item_size(item, &w, &h); @@ -3933,8 +3937,8 @@ static void ui_litem_layout_panel_header(uiLayout *litem) uiLayoutItemPanelHeader *header_litem = static_cast(litem); Panel *panel = litem->root_panel(); - BLI_assert(litem->items_.size() == 1); - uiItem *item = litem->items_.first(); + BLI_assert(litem->items().size() == 1); + uiItem *item = litem->items().first(); int w, h; ui_item_size(item, &w, &h); @@ -3967,12 +3971,12 @@ static void ui_litem_layout_panel_body(uiLayout *litem) /* box layout */ static void ui_litem_estimate_box(uiLayout *litem) { - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; ui_litem_estimate_column(litem, true); int boxspace = style->boxspace; - if (litem->root_->type == blender::ui::LayoutType::Header) { + if (litem->root()->type == blender::ui::LayoutType::Header) { boxspace = 0; } litem->w_ += 2 * boxspace; @@ -3982,10 +3986,10 @@ static void ui_litem_estimate_box(uiLayout *litem) static void ui_litem_layout_box(uiLayout *litem) { uiLayoutItemBx *box = static_cast(litem); - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; int boxspace = style->boxspace; - if (litem->root_->type == blender::ui::LayoutType::Header) { + if (litem->root()->type == blender::ui::LayoutType::Header) { boxspace = 0; } @@ -4025,14 +4029,14 @@ static void ui_litem_layout_box(uiLayout *litem) /* multi-column layout, automatically flowing to the next */ static void ui_litem_estimate_column_flow(uiLayout *litem) { - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; uiLayoutItemFlow *flow = static_cast(litem); int itemw, itemh, maxw = 0; /* compute max needed width and total height */ int toth = 0; int totitem = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_size(item, &itemw, &itemh); maxw = std::max(maxw, itemw); toth += itemh; @@ -4046,7 +4050,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) return; } - flow->totcol = max_ii(litem->root_->emw / maxw, 1); + flow->totcol = max_ii(litem->root()->emw / maxw, 1); flow->totcol = min_ii(flow->totcol, totitem); } else { @@ -4064,7 +4068,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) /* create column per column */ int col = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_size(item, &itemw, &itemh); y -= itemh + style->buttonspacey; @@ -4088,13 +4092,13 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) static void ui_litem_layout_column_flow(uiLayout *litem) { - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; uiLayoutItemFlow *flow = static_cast(litem); int col, emh, itemw, itemh; /* compute max needed width and total height */ int toth = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_size(item, &itemw, &itemh); toth += itemh; } @@ -4110,7 +4114,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) /* create column per column */ col = 0; int w = (litem->w_ - (flow->totcol - 1) * style->columnspace) / flow->totcol; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_size(item, &itemw, &itemh); itemw = (litem->alignment_ == blender::ui::LayoutAlign::Expand) ? w : min_ii(w, itemw); @@ -4311,7 +4315,7 @@ static void ui_litem_grid_flow_compute(blender::Span items, static void ui_litem_estimate_grid_flow(uiLayout *litem) { - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; uiLayoutItemGridFlow *gflow = static_cast(litem); const int space_x = style->columnspace; @@ -4335,7 +4339,7 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) output.tot_items = &gflow->tot_items; output.global_avg_w = &avg_w; output.global_max_h = &max_h; - ui_litem_grid_flow_compute(litem->items_, &input, &output); + ui_litem_grid_flow_compute(litem->items(), &input, &output); if (gflow->tot_items == 0) { litem->w_ = litem->h_ = 0; @@ -4426,7 +4430,7 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) UILayoutGridFlowOutput output{}; output.tot_w = &tot_w; output.tot_h = &tot_h; - ui_litem_grid_flow_compute(litem->items_, &input, &output); + ui_litem_grid_flow_compute(litem->items(), &input, &output); litem->w_ = tot_w; litem->h_ = tot_h; @@ -4435,7 +4439,7 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) static void ui_litem_layout_grid_flow(uiLayout *litem) { - const uiStyle *style = litem->root_->style; + const uiStyle *style = litem->root()->style; uiLayoutItemGridFlow *gflow = static_cast(litem); if (gflow->tot_items == 0) { @@ -4471,10 +4475,10 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) output.cos_y_array = cos_y.data(); output.widths_array = widths.data(); output.heights_array = heights.data(); - ui_litem_grid_flow_compute(litem->items_, &input, &output); + ui_litem_grid_flow_compute(litem->items(), &input, &output); int i = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows; const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows; int item_w, item_h; @@ -4503,7 +4507,7 @@ static void ui_litem_estimate_absolute(uiLayout *litem) litem->w_ = 0; litem->h_ = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { int itemx, itemy, itemw, itemh; ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4529,7 +4533,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) int totw = 0; int toth = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4553,7 +4557,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) x = litem->x_; y = litem->y_ - scaley * toth; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4589,7 +4593,7 @@ static void ui_litem_layout_split(uiLayout *litem) { uiLayoutItemSplit *split = static_cast(litem); float extra_pixel = 0.0f; - const int tot = int(litem->items_.size()); + const int tot = int(litem->items().size()); if (tot == 0) { return; @@ -4604,8 +4608,8 @@ static void ui_litem_layout_split(uiLayout *litem) int colw = w * percentage; colw = std::max(colw, 0); - const uiItem *item_last = litem->items_.last(); - for (uiItem *item : litem->items_) { + const uiItem *item_last = litem->items().last(); + for (uiItem *item : litem->items()) { const bool is_item_last = (item == item_last); int itemh; ui_item_size(item, nullptr, &itemh); @@ -4635,7 +4639,7 @@ static void ui_litem_estimate_overlap(uiLayout *litem) litem->w_ = 0; litem->h_ = 0; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { int itemw, itemh; ui_item_size(item, &itemw, &itemh); @@ -4650,7 +4654,7 @@ static void ui_litem_layout_overlap(uiLayout *litem) const int x = litem->x_; const int y = litem->y_; - for (uiItem *item : litem->items_) { + for (uiItem *item : litem->items()) { int itemw, itemh; ui_item_size(item, &itemw, &itemh); ui_item_position(item, x, y - itemh, litem->w_, itemh); @@ -4689,7 +4693,7 @@ void LayoutInternal::init_from_parent(uiLayout *litem, uiLayout *layout, int ali uiLayout &uiLayout::row(bool align) { - uiLayout *litem = MEM_new(__func__, uiItemType::LayoutRow); + uiLayout *litem = MEM_new(__func__, uiItemType::LayoutRow, nullptr); LayoutInternal::init_from_parent(litem, this, align); litem->space_ = (align) ? 0 : root_->style->buttonspacex; @@ -4794,10 +4798,10 @@ uiLayout *uiLayout::panel(const bContext *C, bool uiLayoutEndsWithPanelHeader(const uiLayout &layout) { - if (layout.items_.is_empty()) { + if (layout.items().is_empty()) { return false; } - const uiItem *item = layout.items_.last(); + const uiItem *item = layout.items().last(); return item->type() == uiItemType::LayoutPanelHeader; } @@ -4810,7 +4814,7 @@ uiLayout &uiLayout::row(bool align, const StringRef heading) uiLayout &uiLayout::column(bool align) { - uiLayout *litem = MEM_new(__func__, uiItemType::LayoutColumn); + uiLayout *litem = MEM_new(__func__, uiItemType::LayoutColumn, nullptr); LayoutInternal::init_from_parent(litem, this, align); litem->space_ = (align) ? 0 : root_->style->buttonspacey; @@ -4862,7 +4866,7 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, ButType type) uiLayoutItemBx *box = MEM_new(__func__); LayoutInternal::init_from_parent(box, layout, false); - box->space_ = layout->root_->style->columnspace; + box->space_ = layout->root()->style->columnspace; blender::ui::block_layout_set_current(layout->block(), box); @@ -4879,7 +4883,7 @@ uiLayout &uiLayout::menu_pie() } /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ - for (uiItem *item : root_->layout->items_) { + for (uiItem *item : root_->layout->items()) { if (item->type() == uiItemType::LayoutRadial) { uiLayout *litem = static_cast(item); blender::ui::block_layout_set_current(this->block(), litem); @@ -4887,7 +4891,7 @@ uiLayout &uiLayout::menu_pie() } } - uiLayout *litem = MEM_new(__func__, uiItemType::LayoutRadial); + uiLayout *litem = MEM_new(__func__, uiItemType::LayoutRadial, nullptr); LayoutInternal::init_from_parent(litem, this, false); blender::ui::block_layout_set_current(this->block(), litem); @@ -4902,7 +4906,7 @@ uiLayout &uiLayout::box() void ui_layout_list_set_labels_active(uiLayout *layout) { - for (uiItem *item : layout->items_) { + for (uiItem *item : layout->items()) { if (item->type() != uiItemType::Button) { ui_layout_list_set_labels_active(static_cast(item)); } @@ -4935,7 +4939,7 @@ uiLayout &uiLayout::list_box(uiList *ui_list, PointerRNA *actptr, PropertyRNA *a uiLayout &uiLayout::absolute(bool align) { - uiLayout *litem = MEM_new(__func__, uiItemType::LayoutAbsolute); + uiLayout *litem = MEM_new(__func__, uiItemType::LayoutAbsolute, nullptr); LayoutInternal::init_from_parent(litem, this, align); blender::ui::block_layout_set_current(this->block(), litem); @@ -4953,7 +4957,7 @@ uiBlock *uiLayout::absolute_block() uiLayout &uiLayout::overlap() { - uiLayout *litem = MEM_new(__func__, uiItemType::LayoutOverlap); + uiLayout *litem = MEM_new(__func__, uiItemType::LayoutOverlap, nullptr); LayoutInternal::init_from_parent(litem, this, false); blender::ui::block_layout_set_current(this->block(), litem); @@ -5192,7 +5196,7 @@ static void ui_item_scale(uiLayout *litem, const float scale[2]) { int x, y, w, h; - for (auto riter = litem->items_.rbegin(); riter != litem->items_.rend(); riter++) { + for (auto riter = litem->items().rbegin(); riter != litem->items().rend(); riter++) { uiItem *item = *riter; if (item->type() != uiItemType::Button) { uiLayout *subitem = static_cast(item); @@ -5221,13 +5225,13 @@ static void ui_item_estimate(uiItem *item) if (item->type() != uiItemType::Button) { uiLayout *litem = static_cast(item); - if (litem->items_.is_empty()) { + if (litem->items().is_empty()) { litem->w_ = 0; litem->h_ = 0; return; } - for (uiItem *subitem : litem->items_) { + for (uiItem *subitem : litem->items()) { ui_item_estimate(subitem); } @@ -5285,7 +5289,7 @@ static void ui_item_estimate(uiItem *item) static void ui_item_align(uiLayout *litem, short nr) { - for (auto riter = litem->items_.rbegin(); riter != litem->items_.rend(); riter++) { + for (auto riter = litem->items().rbegin(); riter != litem->items().rend(); riter++) { uiItem *item = *riter; if (item->type() == uiItemType::Button) { uiButtonItem *bitem = static_cast(item); @@ -5321,7 +5325,7 @@ static void ui_item_align(uiLayout *litem, short nr) static void ui_item_flag(uiLayout *litem, int flag) { - for (auto riter = litem->items_.rbegin(); riter != litem->items_.rend(); riter++) { + for (auto riter = litem->items().rbegin(); riter != litem->items().rend(); riter++) { uiItem *item = *riter; if (item->type() == uiItemType::Button) { uiButtonItem *bitem = static_cast(item); @@ -5338,7 +5342,7 @@ static void ui_item_layout(uiItem *item) if (item->type() != uiItemType::Button) { uiLayout *litem = static_cast(item); - if (litem->items_.is_empty()) { + if (litem->items().is_empty()) { return; } @@ -5393,7 +5397,7 @@ static void ui_item_layout(uiItem *item) break; } - for (uiItem *subitem : litem->items_) { + for (uiItem *subitem : litem->items()) { if (ItemInternal::box_item(item)) { ItemInternal::box_item_set(subitem, true); } @@ -5410,8 +5414,8 @@ static void ui_item_layout(uiItem *item) static blender::int2 ui_layout_end(uiBlock *block, uiLayout *layout) { - if (layout->root_->handlefunc) { - UI_block_func_handle_set(block, layout->root_->handlefunc, layout->root_->argv); + if (layout->root()->handlefunc) { + UI_block_func_handle_set(block, layout->root()->handlefunc, layout->root()->argv); } ui_item_estimate(layout); @@ -5421,7 +5425,7 @@ static blender::int2 ui_layout_end(uiBlock *block, uiLayout *layout) static void ui_layout_free(uiLayout *layout) { - for (uiItem *item : layout->items_) { + for (uiItem *item : layout->items()) { if (item->type() == uiItemType::Button) { uiButtonItem *bitem = static_cast(item); @@ -5470,18 +5474,16 @@ uiLayout &block_layout(uiBlock *block, root->opcontext = wm::OpCallContext::InvokeRegionWin; const ItemType item_type = type == LayoutType::VerticalBar ? uiItemType::LayoutColumn : uiItemType::LayoutRoot; - uiLayout *layout = MEM_new(__func__, item_type); + uiLayout *layout = MEM_new(__func__, item_type, root); /* Only used when 'uiItemInternalFlag::PropSep' is set. */ layout->use_property_decorate_set(true); layout->x_ = x; layout->y_ = y; - layout->root_ = root; layout->space_ = style->templatespace; layout->active_ = true; layout->enabled_ = true; - layout->context_ = nullptr; layout->emboss_ = EmbossType::Undefined; if (ELEM(type, LayoutType::Menu, LayoutType::PieMenu)) { @@ -5490,11 +5492,11 @@ uiLayout &block_layout(uiBlock *block, if (dir == LayoutDirection::Horizontal) { layout->h_ = size; - layout->root_->emh = em * UI_UNIT_Y; + layout->root()->emh = em * UI_UNIT_Y; } else { layout->w_ = size; - layout->root_->emw = em * UI_UNIT_X; + layout->root()->emw = em * UI_UNIT_X; } block->curlayout = layout; @@ -5518,7 +5520,7 @@ blender::wm::OpCallContext uiLayout::operator_context() const return root_->opcontext; } -void ui_layout_add_but(uiLayout *layout, uiBut *but) +void LayoutInternal::layout_add_but(uiLayout *layout, uiBut *but) { uiButtonItem *bitem = MEM_new(__func__); bitem->but = but; @@ -5552,11 +5554,16 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but) ui_button_group_add_but(layout->block(), but); } +void ui_layout_add_but(uiLayout *layout, uiBut *but) +{ + LayoutInternal::layout_add_but(layout, but); +}; + static uiButtonItem *ui_layout_find_button_item(const uiLayout *layout, const uiBut *but) { const blender::Vector &child_list = layout->child_items_layout_ ? - layout->child_items_layout_->items_ : - layout->items_; + layout->child_items_layout_->items() : + layout->items(); for (uiItem *item : child_list) { if (item->type() == uiItemType::Button) { @@ -5577,7 +5584,7 @@ static uiButtonItem *ui_layout_find_button_item(const uiLayout *layout, const ui return nullptr; } -void ui_layout_remove_but(uiLayout *layout, const uiBut *but) +void LayoutInternal::layout_remove_but(uiLayout *layout, const uiBut *but) { blender::Vector &child_list = layout->child_items_layout_ ? layout->child_items_layout_->items_ : @@ -5594,6 +5601,11 @@ void ui_layout_remove_but(uiLayout *layout, const uiBut *but) UNUSED_VARS_NDEBUG(removed_num); } +void ui_layout_remove_but(uiLayout *layout, const uiBut *but) +{ + LayoutInternal::layout_remove_but(layout, but); +} + bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but) { uiButtonItem *bitem = ui_layout_find_button_item(layout, @@ -5623,8 +5635,8 @@ void uiLayout::operator_context_set(blender::wm::OpCallContext opcontext) void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) { - layout->root_->handlefunc = handlefunc; - layout->root_->argv = argv; + layout->root()->handlefunc = handlefunc; + layout->root()->argv = argv; } namespace blender::ui { @@ -5725,7 +5737,7 @@ void uiLayoutSetTooltipFunc(uiLayout *layout, { bool arg_used = false; - for (uiItem *item : layout->items_) { + for (uiItem *item : layout->items()) { /* Each button will call free_arg for "its" argument, so we need to * duplicate the allocation for each button after the first. */ if (copy_arg != nullptr && arg_used) { @@ -5760,7 +5772,7 @@ void uiLayoutSetTooltipCustomFunc(uiLayout *layout, { bool arg_used = false; - for (uiItem *item : layout->items_) { + for (uiItem *item : layout->items()) { /* Each button will call free_arg for "its" argument, so we need to * duplicate the allocation for each button after the first. */ if (copy_arg != nullptr && arg_used) { @@ -5858,8 +5870,8 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout) } bContextStore context_store; - if (layout->context_) { - context_store = *layout->context_; + if (layout->context()) { + context_store = *layout->context(); } const bContextStore *previous_context_store = CTX_store_get(C); if (previous_context_store) { @@ -5874,7 +5886,7 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout) static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *pt) { - for (uiItem *subitem : layout->items_) { + for (uiItem *subitem : layout->items()) { if (subitem->type() == uiItemType::Button) { uiButtonItem *bitem = static_cast(subitem); if (!(bitem->but->flag & UI_HIDDEN) && @@ -5911,7 +5923,7 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, UI_popup_dummy_panel_set(block->handle->region, block); } - uiItem *item_last = layout->items_.is_empty() ? nullptr : layout->items_.last(); + uiItem *item_last = layout->items().is_empty() ? nullptr : layout->items().last(); /* Draw main panel. */ if (show_header) { @@ -5943,9 +5955,9 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, if (child_pt->poll == nullptr || child_pt->poll(C, child_pt)) { /* Add space if something was added to the layout. */ - if (!layout->items_.is_empty() && item_last != layout->items_.last()) { + if (!layout->items().is_empty() && item_last != layout->items().last()) { layout->separator(); - item_last = layout->items_.last(); + item_last = layout->items().last(); } uiLayout *col = &layout->column(false); @@ -5956,13 +5968,13 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout) { - if (layout->context_) { - CTX_store_set(C, layout->context_); + if (layout->context()) { + CTX_store_set(C, layout->context()); } ui_paneltype_draw_impl(C, pt, layout, false); - if (layout->context_) { + if (layout->context()) { CTX_store_set(C, nullptr); } } @@ -6060,7 +6072,7 @@ static void ui_layout_introspect_items(DynStr *ds, blender::Span break; default: BLI_dynstr_append(ds, "'items':"); - ui_layout_introspect_items(ds, (static_cast(item))->items_); + ui_layout_introspect_items(ds, (static_cast(item))->items()); break; } @@ -6155,3 +6167,28 @@ uiLayout *uiItemsAlertBox(uiBlock *block, const int size, const eAlertIcon icon) } /** \} */ + +uiLayoutRoot *uiLayout::root() const +{ + return root_; +}; +const bContextStore *uiLayout::context() const +{ + return context_; +}; +uiLayout *uiLayout::parent() const +{ + return parent_; +}; +blender::StringRef uiLayout::heading() const +{ + return heading_; +}; +void uiLayout::heading_reset() +{ + heading_ = {}; +} +blender::Span uiLayout::items() const +{ + return items_; +};