yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
settings_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_SETTINGS_EDITOR_H
2#define YAZE_APP_EDITOR_SETTINGS_EDITOR_H
3
4#include "absl/status/status.h"
5#include "app/editor/editor.h"
6#include "imgui/imgui.h"
7
8namespace yaze {
9namespace editor {
10
11// Simple representation for a tree
12// (this is designed to be simple to understand for our demos, not to be
13// efficient etc.)
15 char Name[28];
16 ImGuiID UID = 0;
18 ImVector<ExampleTreeNode*> Childs;
19
20 // Data
21 bool HasData = false; // All leaves have data
22 bool DataIsEnabled = false;
23 int DataInt = 128;
24 ImVec2 DataVec2 = ImVec2(0.0f, 3.141592f);
25};
26
27// Simple representation of struct metadata/serialization data.
28// (this is a minimal version of what a typical advanced application may
29// provide)
31 const char* Name;
32 ImGuiDataType DataType;
34 int Offset;
35};
36
37// Metadata description of ExampleTreeNode struct.
38static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]{
39 {"Enabled", ImGuiDataType_Bool, 1,
40 offsetof(ExampleTreeNode, DataIsEnabled)},
41 {"MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataInt)},
42 {"MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataVec2)},
43};
44
45static ExampleTreeNode* ExampleTree_CreateNode(const char* name,
46 const ImGuiID uid,
47 ExampleTreeNode* parent) {
48 ExampleTreeNode* node = IM_NEW(ExampleTreeNode);
49 snprintf(node->Name, IM_ARRAYSIZE(node->Name), "%s", name);
50 node->UID = uid;
51 node->Parent = parent;
52 if (parent) parent->Childs.push_back(node);
53 return node;
54}
55
56// Create example tree data
57static ExampleTreeNode* ExampleTree_CreateDemoTree() {
58 static const char* root_names[] = {"Apple", "Banana", "Cherry",
59 "Kiwi", "Mango", "Orange",
60 "Pineapple", "Strawberry", "Watermelon"};
61 char name_buf[32];
62 ImGuiID uid = 0;
63 ExampleTreeNode* node_L0 = ExampleTree_CreateNode("<ROOT>", ++uid, NULL);
64 for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * 2; idx_L0++) {
65 snprintf(name_buf, 32, "%s %d", root_names[idx_L0 / 2], idx_L0 % 2);
66 ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0);
67 const int number_of_childs = (int)strlen(node_L1->Name);
68 for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++) {
69 snprintf(name_buf, 32, "Child %d", idx_L1);
70 ExampleTreeNode* node_L2 =
71 ExampleTree_CreateNode(name_buf, ++uid, node_L1);
72 node_L2->HasData = true;
73 if (idx_L1 == 0) {
74 snprintf(name_buf, 32, "Sub-child %d", 0);
75 ExampleTreeNode* node_L3 =
76 ExampleTree_CreateNode(name_buf, ++uid, node_L2);
77 node_L3->HasData = true;
78 }
79 }
80 }
81 return node_L0;
82}
83
85 ImGuiTextFilter Filter;
86
87 void Draw(ExampleTreeNode* root_node) {
88 ImGui::SetNextItemWidth(-FLT_MIN);
89 ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F,
90 ImGuiInputFlags_Tooltip);
91 ImGui::PushItemFlag(ImGuiItemFlags_NoNavDefaultFocus, true);
92 if (ImGui::InputTextWithHint("##Filter", "incl,-excl", Filter.InputBuf,
93 IM_ARRAYSIZE(Filter.InputBuf),
94 ImGuiInputTextFlags_EscapeClearsAll))
95 Filter.Build();
96 ImGui::PopItemFlag();
97
98 ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable |
99 ImGuiTableFlags_ScrollY |
100 ImGuiTableFlags_RowBg;
101 if (ImGui::BeginTable("##split", 2, table_flags)) {
102 ImGui::TableSetupColumn("Object", ImGuiTableColumnFlags_WidthStretch,
103 1.0f);
104 ImGui::TableSetupColumn("Contents", ImGuiTableColumnFlags_WidthStretch,
105 2.0f); // Default twice larger
106 // ImGui::TableSetupScrollFreeze(0, 1);
107 // ImGui::TableHeadersRow();
108
109 for (ExampleTreeNode* node : root_node->Childs)
110 if (Filter.PassFilter(node->Name)) // Filter root node
111 DrawTreeNode(node);
112 ImGui::EndTable();
113 }
114 }
115
117 // Object tree node
118 ImGui::PushID((int)node->UID);
119 ImGui::TableNextRow();
120 ImGui::TableSetColumnIndex(0);
121 ImGui::AlignTextToFramePadding();
122 ImGuiTreeNodeFlags tree_flags = ImGuiTreeNodeFlags_None;
123 tree_flags |=
124 ImGuiTreeNodeFlags_SpanAllColumns |
125 ImGuiTreeNodeFlags_AllowOverlap; // Highlight whole row for visibility
126 tree_flags |=
127 ImGuiTreeNodeFlags_OpenOnArrow |
128 ImGuiTreeNodeFlags_OpenOnDoubleClick; // Standard opening mode as we
129 // are likely to want to add
130 // selection afterwards
131 tree_flags |=
132 ImGuiTreeNodeFlags_NavLeftJumpsBackHere; // Left arrow support
133 bool node_open =
134 ImGui::TreeNodeEx("##Object", tree_flags, "%s", node->Name);
135 ImGui::TableSetColumnIndex(1);
136 ImGui::TextDisabled("UID: 0x%08X", node->UID);
137
138 // Display child and data
139 if (node_open)
140 for (ExampleTreeNode* child : node->Childs) DrawTreeNode(child);
141 if (node_open && node->HasData) {
142 // In a typical application, the structure description would be derived
143 // from a data-driven system.
144 // - We try to mimic this with our ExampleMemberInfo structure and the
145 // ExampleTreeNodeMemberInfos[] array.
146 // - Limits and some details are hard-coded to simplify the demo.
147 // - Text and Selectable are less high than framed widgets, using
148 // AlignTextToFramePadding() we add vertical spacing to make the
149 // selectable lines equal high.
150 for (const ExampleMemberInfo& field_desc : ExampleTreeNodeMemberInfos) {
151 ImGui::TableNextRow();
152 ImGui::TableSetColumnIndex(0);
153 ImGui::AlignTextToFramePadding();
154 ImGui::PushItemFlag(ImGuiItemFlags_NoTabStop | ImGuiItemFlags_NoNav,
155 true);
156 ImGui::Selectable(field_desc.Name, false,
157 ImGuiSelectableFlags_SpanAllColumns |
158 ImGuiSelectableFlags_AllowOverlap);
159 ImGui::PopItemFlag();
160 ImGui::TableSetColumnIndex(1);
161 ImGui::PushID(field_desc.Name);
162 void* field_ptr = (void*)(((unsigned char*)node) + field_desc.Offset);
163 switch (field_desc.DataType) {
164 case ImGuiDataType_Bool: {
165 IM_ASSERT(field_desc.DataCount == 1);
166 ImGui::Checkbox("##Editor", (bool*)field_ptr);
167 break;
168 }
169 case ImGuiDataType_S32: {
170 int v_min = INT_MIN, v_max = INT_MAX;
171 ImGui::SetNextItemWidth(-FLT_MIN);
172 ImGui::DragScalarN("##Editor", field_desc.DataType, field_ptr,
173 field_desc.DataCount, 1.0f, &v_min, &v_max);
174 break;
175 }
176 case ImGuiDataType_Float: {
177 float v_min = 0.0f, v_max = 1.0f;
178 ImGui::SetNextItemWidth(-FLT_MIN);
179 ImGui::SliderScalarN("##Editor", field_desc.DataType, field_ptr,
180 field_desc.DataCount, &v_min, &v_max);
181 break;
182 }
183 }
184 ImGui::PopID();
185 }
186 }
187 if (node_open) ImGui::TreePop();
188 ImGui::PopID();
189 }
190};
191
192// Demonstrate creating a simple property editor.
193static void ShowExampleAppPropertyEditor(bool* p_open) {
194 ImGui::SetNextWindowSize(ImVec2(430, 450), ImGuiCond_FirstUseEver);
195 if (!ImGui::Begin("Example: Property editor", p_open)) {
196 ImGui::End();
197 return;
198 }
199
200 static ExampleAppPropertyEditor property_editor;
201 static ExampleTreeNode* tree_data = ExampleTree_CreateDemoTree();
202 property_editor.Draw(tree_data);
203
204 ImGui::End();
205}
206
207class SettingsEditor : public Editor {
208 public:
210 void Initialize() override;
211 absl::Status Load() override;
212 absl::Status Update() override;
213 absl::Status Undo() override { return absl::UnimplementedError("Undo"); }
214 absl::Status Redo() override { return absl::UnimplementedError("Redo"); }
215 absl::Status Cut() override { return absl::UnimplementedError("Cut"); }
216 absl::Status Copy() override { return absl::UnimplementedError("Copy"); }
217 absl::Status Paste() override { return absl::UnimplementedError("Paste"); }
218 absl::Status Find() override { return absl::UnimplementedError("Find"); }
219 absl::Status Save() override { return absl::UnimplementedError("Save"); }
220
221 private:
222 void DrawGeneralSettings();
224};
225
226} // namespace editor
227} // namespace yaze
228
229#endif // YAZE_APP_EDITOR_SETTINGS_EDITOR_H_
EditorType type_
Definition editor.h:88
absl::Status Undo() override
absl::Status Update() override
absl::Status Find() override
absl::Status Redo() override
absl::Status Load() override
absl::Status Copy() override
absl::Status Paste() override
absl::Status Save() override
absl::Status Cut() override
Editors are the view controllers for the application.
Main namespace for the application.
Definition controller.cc:18
void DrawTreeNode(ExampleTreeNode *node)
void Draw(ExampleTreeNode *root_node)
ImVector< ExampleTreeNode * > Childs