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