mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-21 06:52:22 -04:00
Editor inventory tab
This commit is contained in:
+268
-9
@@ -14,12 +14,13 @@
|
||||
#include "string_button.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace dusk::ui {
|
||||
namespace {
|
||||
@@ -56,6 +57,27 @@ dSv_horse_place_c* get_horse_place() {
|
||||
return &dComIfGs_getSaveData()->getPlayer().getHorsePlace();
|
||||
}
|
||||
|
||||
dSv_player_item_c* get_player_item() {
|
||||
if (!has_save_data()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &dComIfGs_getSaveData()->getPlayer().getItem();
|
||||
}
|
||||
|
||||
dSv_player_item_record_c* get_player_item_record() {
|
||||
if (!has_save_data()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &dComIfGs_getSaveData()->getPlayer().getItemRecord();
|
||||
}
|
||||
|
||||
dSv_player_item_max_c* get_player_item_max() {
|
||||
if (!has_save_data()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &dComIfGs_getSaveData()->getPlayer().getItemMax();
|
||||
}
|
||||
|
||||
template <size_t Size>
|
||||
Rml::String fixed_string(const char (&value)[Size]) {
|
||||
size_t length = 0;
|
||||
@@ -436,7 +458,11 @@ std::map<int, itemInfo> itemMap = {
|
||||
};
|
||||
|
||||
Rml::String get_item_name(u8 id) {
|
||||
return itemMap.find(id)->second.m_name;
|
||||
const auto it = itemMap.find(id);
|
||||
if (it == itemMap.end()) {
|
||||
return fmt::format("Item {}", id);
|
||||
}
|
||||
return it->second.m_name;
|
||||
}
|
||||
|
||||
Rml::String item_label_for_slot(u8 slot) {
|
||||
@@ -447,6 +473,116 @@ Rml::String item_label_for_slot(u8 slot) {
|
||||
return fmt::format("Slot {0} ({1})", slot, get_item_name(id));
|
||||
}
|
||||
|
||||
struct DefaultInventoryEntry {
|
||||
u8 slot;
|
||||
u8 item;
|
||||
};
|
||||
|
||||
constexpr std::array<DefaultInventoryEntry, 22> defaultInventory = {
|
||||
DefaultInventoryEntry{SLOT_0, dItemNo_BOOMERANG_e},
|
||||
DefaultInventoryEntry{SLOT_1, dItemNo_KANTERA_e},
|
||||
DefaultInventoryEntry{SLOT_2, dItemNo_SPINNER_e},
|
||||
DefaultInventoryEntry{SLOT_3, dItemNo_HVY_BOOTS_e},
|
||||
DefaultInventoryEntry{SLOT_4, dItemNo_BOW_e},
|
||||
DefaultInventoryEntry{SLOT_5, dItemNo_HAWK_EYE_e},
|
||||
DefaultInventoryEntry{SLOT_6, dItemNo_IRONBALL_e},
|
||||
DefaultInventoryEntry{SLOT_8, dItemNo_COPY_ROD_e},
|
||||
DefaultInventoryEntry{SLOT_9, dItemNo_HOOKSHOT_e},
|
||||
DefaultInventoryEntry{SLOT_10, dItemNo_W_HOOKSHOT_e},
|
||||
DefaultInventoryEntry{SLOT_11, dItemNo_EMPTY_BOTTLE_e},
|
||||
DefaultInventoryEntry{SLOT_12, dItemNo_EMPTY_BOTTLE_e},
|
||||
DefaultInventoryEntry{SLOT_13, dItemNo_EMPTY_BOTTLE_e},
|
||||
DefaultInventoryEntry{SLOT_14, dItemNo_EMPTY_BOTTLE_e},
|
||||
DefaultInventoryEntry{SLOT_15, dItemNo_NORMAL_BOMB_e},
|
||||
DefaultInventoryEntry{SLOT_16, dItemNo_WATER_BOMB_e},
|
||||
DefaultInventoryEntry{SLOT_17, dItemNo_POKE_BOMB_e},
|
||||
DefaultInventoryEntry{SLOT_18, dItemNo_DUNGEON_EXIT_e},
|
||||
DefaultInventoryEntry{SLOT_20, dItemNo_FISHING_ROD_1_e},
|
||||
DefaultInventoryEntry{SLOT_21, dItemNo_HORSE_FLUTE_e},
|
||||
DefaultInventoryEntry{SLOT_22, dItemNo_ANCIENT_DOCUMENT_e},
|
||||
DefaultInventoryEntry{SLOT_23, dItemNo_PACHINKO_e},
|
||||
};
|
||||
|
||||
u8 get_slot_default(int slot) {
|
||||
for (const auto& entry : defaultInventory) {
|
||||
if (entry.slot == slot) {
|
||||
return entry.item;
|
||||
}
|
||||
}
|
||||
return dItemNo_NONE_e;
|
||||
}
|
||||
|
||||
void set_item_first_bit(u8 itemNo, bool owned) {
|
||||
if (owned) {
|
||||
dComIfGs_onItemFirstBit(itemNo);
|
||||
} else {
|
||||
dComIfGs_offItemFirstBit(itemNo);
|
||||
}
|
||||
}
|
||||
|
||||
void toggle_item_first_bit(u8 itemNo) {
|
||||
set_item_first_bit(itemNo, !dComIfGs_isItemFirstBit(itemNo));
|
||||
}
|
||||
|
||||
bool can_edit_item_first_bit(int itemId, const itemInfo& item) {
|
||||
return itemId < 254 && item.m_name != "Reserved";
|
||||
}
|
||||
|
||||
void set_all_item_first_bits(bool owned) {
|
||||
for (const auto& [itemId, item] : itemMap) {
|
||||
if (!can_edit_item_first_bit(itemId, item)) {
|
||||
continue;
|
||||
}
|
||||
set_item_first_bit(static_cast<u8>(itemId), owned);
|
||||
}
|
||||
}
|
||||
|
||||
void populate_item_slot_picker(Pane& pane, int slot) {
|
||||
pane.clear();
|
||||
pane.add_section("Actions");
|
||||
pane.add_button(fmt::format("Default ({})", get_item_name(get_slot_default(slot))),
|
||||
[slot] { dComIfGs_setItem(slot, get_slot_default(slot)); });
|
||||
|
||||
pane.add_section("Items");
|
||||
pane.add_button(
|
||||
{
|
||||
.text = "None",
|
||||
.isSelected = [slot] { return get_player_item()->mItems[slot] == dItemNo_NONE_e; },
|
||||
},
|
||||
[slot] { dComIfGs_setItem(slot, dItemNo_NONE_e); });
|
||||
for (const auto& [itemId, item] : itemMap) {
|
||||
if (item.m_type != ITEMTYPE_EQUIP_e) {
|
||||
continue;
|
||||
}
|
||||
pane.add_button(
|
||||
{
|
||||
.text = item.m_name,
|
||||
.isSelected = [slot, itemId] { return get_player_item()->mItems[slot] == itemId; },
|
||||
},
|
||||
[slot, itemId] { dComIfGs_setItem(slot, static_cast<u8>(itemId)); });
|
||||
}
|
||||
}
|
||||
|
||||
void populate_item_flag_picker(Pane& pane) {
|
||||
pane.clear();
|
||||
pane.add_section("Actions");
|
||||
pane.add_button("Select All", [] { set_all_item_first_bits(true); });
|
||||
pane.add_button("Clear None", [] { set_all_item_first_bits(false); });
|
||||
|
||||
pane.add_section("Items");
|
||||
for (const auto& [itemId, item] : itemMap) {
|
||||
if (!can_edit_item_first_bit(itemId, item)) {
|
||||
continue;
|
||||
}
|
||||
pane.add_button(
|
||||
{
|
||||
.text = item.m_name,
|
||||
.isSelected = [itemId] { return dComIfGs_isItemFirstBit(static_cast<u8>(itemId)); },
|
||||
},
|
||||
[itemId] { toggle_item_first_bit(static_cast<u8>(itemId)); });
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array<Rml::String, 3> walletSizeNames = {
|
||||
"Normal",
|
||||
"Big",
|
||||
@@ -476,8 +612,8 @@ void set_clock_time(int hour, int minute) {
|
||||
|
||||
EditorWindow::EditorWindow() {
|
||||
add_tab("Player Status", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
leftPane.add_section("Player");
|
||||
leftPane
|
||||
@@ -754,8 +890,8 @@ EditorWindow::EditorWindow() {
|
||||
});
|
||||
|
||||
add_tab("Location", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
leftPane.add_section("Save Location");
|
||||
leftPane
|
||||
@@ -864,9 +1000,132 @@ EditorWindow::EditorWindow() {
|
||||
});
|
||||
|
||||
add_tab("Inventory", [this](Rml::Element* content) {
|
||||
// TODO
|
||||
});
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
leftPane.add_section("Item Wheel");
|
||||
leftPane
|
||||
.add_button("Default All",
|
||||
[&rightPane] {
|
||||
for (int slot = 0; slot < 24; ++slot) {
|
||||
dComIfGs_setItem(slot, get_slot_default(slot));
|
||||
}
|
||||
rightPane.clear();
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
leftPane
|
||||
.add_button("Clear All",
|
||||
[&rightPane] {
|
||||
for (int slot = 0; slot < 24; ++slot) {
|
||||
dComIfGs_setItem(slot, dItemNo_NONE_e);
|
||||
}
|
||||
rightPane.clear();
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
for (int slot = 0; slot < 24; ++slot) {
|
||||
leftPane
|
||||
.add_select_button({
|
||||
.key = fmt::format("Slot {0:02d}", slot),
|
||||
.getValue = [slot] { return get_item_name(get_player_item()->mItems[slot]); },
|
||||
})
|
||||
.on_focus([&rightPane, slot](
|
||||
Rml::Event&) { populate_item_slot_picker(rightPane, slot); });
|
||||
}
|
||||
|
||||
leftPane.add_section("Amounts");
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Arrows Amount",
|
||||
.getValue = [] { return get_player_item_record()->mArrowNum; },
|
||||
.setValue =
|
||||
[](int value) { get_player_item_record()->mArrowNum = static_cast<u8>(value); },
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Slingshot Amount",
|
||||
.getValue = [] { return get_player_item_record()->mPachinkoNum; },
|
||||
.setValue =
|
||||
[](int value) {
|
||||
get_player_item_record()->mPachinkoNum = static_cast<u8>(value);
|
||||
},
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
for (int bag = 0; bag < 3; ++bag) {
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = fmt::format("Bomb Bag {} Amount", bag + 1),
|
||||
.getValue = [bag] { return get_player_item_record()->mBombNum[bag]; },
|
||||
.setValue =
|
||||
[bag](int value) {
|
||||
get_player_item_record()->mBombNum[bag] = static_cast<u8>(value);
|
||||
},
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
}
|
||||
for (int bottle = 0; bottle < 4; ++bottle) {
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = fmt::format("Bottle {} Amount", bottle + 1),
|
||||
.getValue = [bottle] { return get_player_item_record()->mBottleNum[bottle]; },
|
||||
.setValue =
|
||||
[bottle](int value) {
|
||||
get_player_item_record()->mBottleNum[bottle] = static_cast<u8>(value);
|
||||
},
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
}
|
||||
|
||||
leftPane.add_section("Capacities");
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Arrows Max",
|
||||
.getValue = [] { return get_player_item_max()->mItemMax[0]; },
|
||||
.setValue =
|
||||
[](int value) { get_player_item_max()->mItemMax[0] = static_cast<u8>(value); },
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Normal Bombs Max",
|
||||
.getValue = [] { return get_player_item_max()->mItemMax[1]; },
|
||||
.setValue =
|
||||
[](int value) { get_player_item_max()->mItemMax[1] = static_cast<u8>(value); },
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Water Bombs Max",
|
||||
.getValue = [] { return get_player_item_max()->mItemMax[2]; },
|
||||
.setValue =
|
||||
[](int value) { get_player_item_max()->mItemMax[2] = static_cast<u8>(value); },
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
leftPane
|
||||
.add_child<NumberButton>(NumberButton::Props{
|
||||
.key = "Bomblings Max",
|
||||
.getValue = [] { return get_player_item_max()->mItemMax[3]; },
|
||||
.setValue =
|
||||
[](int value) { get_player_item_max()->mItemMax[3] = static_cast<u8>(value); },
|
||||
.max = std::numeric_limits<u8>::max(),
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { rightPane.clear(); });
|
||||
|
||||
leftPane.add_section("Flags");
|
||||
leftPane
|
||||
.add_select_button({
|
||||
.key = "Obtained Items",
|
||||
.getValue = [] { return "Edit"; },
|
||||
})
|
||||
.on_focus([&rightPane](Rml::Event&) { populate_item_flag_picker(rightPane); });
|
||||
});
|
||||
add_tab("Collection", [this](Rml::Element* content) {
|
||||
// TODO
|
||||
});
|
||||
|
||||
+29
-39
@@ -13,15 +13,12 @@ Rml::Element* createRoot(Rml::Element* parent) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Pane::Pane(Rml::Element* parent, Direction direction)
|
||||
: FluentComponent(createRoot(parent)), mDirection(direction) {
|
||||
Pane::Pane(Rml::Element* parent, Type type) : FluentComponent(createRoot(parent)), mType(type) {
|
||||
listen(Rml::EventId::Keydown, [this](Rml::Event& event) {
|
||||
const auto cmd = map_nav_event(event);
|
||||
|
||||
// If navigating to the next pane, select the focused item
|
||||
if ((mDirection == Direction::Vertical && cmd == NavCommand::Right) ||
|
||||
(mDirection == Direction::Horizontal && cmd == NavCommand::Down))
|
||||
{
|
||||
if (mType == Type::Controlled && cmd == NavCommand::Right) {
|
||||
auto* target = event.GetTargetElement();
|
||||
int focusedChild = -1;
|
||||
for (size_t i = 0; i < mChildren.size(); ++i) {
|
||||
@@ -38,13 +35,9 @@ Pane::Pane(Rml::Element* parent, Direction direction)
|
||||
}
|
||||
|
||||
int direction = 0;
|
||||
if ((mDirection == Direction::Vertical && cmd == NavCommand::Down) ||
|
||||
(mDirection == Direction::Horizontal && cmd == NavCommand::Right))
|
||||
{
|
||||
if (cmd == NavCommand::Down) {
|
||||
direction = 1;
|
||||
} else if ((mDirection == Direction::Vertical && cmd == NavCommand::Up) ||
|
||||
(mDirection == Direction::Horizontal && cmd == NavCommand::Left))
|
||||
{
|
||||
} else if (cmd == NavCommand::Up) {
|
||||
direction = -1;
|
||||
} else {
|
||||
return;
|
||||
@@ -70,29 +63,31 @@ Pane::Pane(Rml::Element* parent, Direction direction)
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for selection change events
|
||||
listen(Rml::EventId::Change, [this](Rml::Event& event) {
|
||||
const auto it = std::find_if(event.GetParameters().begin(), event.GetParameters().end(),
|
||||
[](const auto& param) { return param.first == "selected"; });
|
||||
if (it != event.GetParameters().end()) {
|
||||
const auto selected = it->second.Get<bool>();
|
||||
int childIndex = -1;
|
||||
for (int i = 0; i < mChildren.size(); ++i) {
|
||||
if (event.GetTargetElement() == mChildren[i]->root()) {
|
||||
childIndex = i;
|
||||
if (type == Type::Controlled) {
|
||||
// Listen for selection change events
|
||||
listen(Rml::EventId::Change, [this](Rml::Event& event) {
|
||||
const auto it = std::find_if(event.GetParameters().begin(), event.GetParameters().end(),
|
||||
[](const auto& param) { return param.first == "selected"; });
|
||||
if (it != event.GetParameters().end()) {
|
||||
const auto selected = it->second.Get<bool>();
|
||||
int childIndex = -1;
|
||||
for (int i = 0; i < mChildren.size(); ++i) {
|
||||
if (event.GetTargetElement() == mChildren[i]->root()) {
|
||||
childIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (childIndex != -1) {
|
||||
if (selected) {
|
||||
set_selected_item(childIndex);
|
||||
} else if (childIndex == mSelectedItem) {
|
||||
if (childIndex != -1) {
|
||||
if (selected) {
|
||||
set_selected_item(childIndex);
|
||||
} else if (childIndex == mSelectedItem) {
|
||||
set_selected_item(-1);
|
||||
}
|
||||
} else {
|
||||
set_selected_item(-1);
|
||||
}
|
||||
} else {
|
||||
set_selected_item(-1);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Pane::update() {
|
||||
@@ -116,17 +111,12 @@ void Pane::set_selected_item(int index) {
|
||||
}
|
||||
|
||||
bool Pane::focus() {
|
||||
// Update selected child
|
||||
for (int i = 0; i < mChildren.size(); ++i) {
|
||||
if (mChildren[i]->selected()) {
|
||||
mSelectedItem = i;
|
||||
// Focus the first selected child
|
||||
for (const auto& child : mChildren) {
|
||||
if (child->selected() && child->focus()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If there's a selected child, focus that
|
||||
if (mSelectedItem >= 0 && mSelectedItem < mChildren.size() && mChildren[mSelectedItem]->focus())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
for (const auto& child : mChildren) {
|
||||
if (child->focus()) {
|
||||
return true;
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace dusk::ui {
|
||||
|
||||
class Pane : public FluentComponent<Pane> {
|
||||
public:
|
||||
enum class Direction {
|
||||
Vertical,
|
||||
Horizontal,
|
||||
enum class Type {
|
||||
Controlled,
|
||||
Uncontrolled,
|
||||
};
|
||||
|
||||
explicit Pane(Rml::Element* parent, Direction direction);
|
||||
explicit Pane(Rml::Element* parent, Type type);
|
||||
|
||||
bool focus() override;
|
||||
void update() override;
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Direction mDirection;
|
||||
Type mType;
|
||||
bool finalized = false;
|
||||
int mSelectedItem = -1;
|
||||
};
|
||||
|
||||
@@ -231,8 +231,8 @@ private:
|
||||
|
||||
SettingsWindow::SettingsWindow() {
|
||||
add_tab("Audio", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
leftPane.add_section("Volume");
|
||||
leftPane.add_child<ConfigIntSelect>(ConfigIntSelect::Props{
|
||||
@@ -270,8 +270,8 @@ SettingsWindow::SettingsWindow() {
|
||||
});
|
||||
|
||||
add_tab("Cheats", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
auto addCheat = [&](const Rml::String& key, ConfigVar<bool>& value,
|
||||
const Rml::String& helpText) {
|
||||
@@ -315,8 +315,8 @@ SettingsWindow::SettingsWindow() {
|
||||
});
|
||||
|
||||
add_tab("Gameplay", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
auto addOption = [&](const Rml::String& key, ConfigVar<bool>& value,
|
||||
const Rml::String& helpText) {
|
||||
@@ -422,8 +422,8 @@ SettingsWindow::SettingsWindow() {
|
||||
});
|
||||
|
||||
add_tab("Graphics", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Direction::Vertical);
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
|
||||
leftPane.add_section("Display");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user