yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
layout_serialization.cc
Go to the documentation of this file.
2
3#include <fstream>
4#include <sstream>
5
6#include "absl/status/status.h"
7#include "absl/strings/str_format.h"
8#include "util/log.h"
9
10// Simple JSON-like serialization (can be replaced with nlohmann/json later)
11namespace yaze {
12namespace editor {
13namespace layout_designer {
14
15namespace {
16
17// Helper to escape JSON strings
18std::string EscapeJson(const std::string& str) {
19 std::string result;
20 for (char chr : str) {
21 switch (chr) {
22 case '"':
23 result += "\\\"";
24 break;
25 case '\\':
26 result += "\\\\";
27 break;
28 case '\n':
29 result += "\\n";
30 break;
31 case '\r':
32 result += "\\r";
33 break;
34 case '\t':
35 result += "\\t";
36 break;
37 default:
38 result += chr;
39 break;
40 }
41 }
42 return result;
43}
44
45std::string DirToString(ImGuiDir dir) {
46 switch (dir) {
47 case ImGuiDir_None:
48 return "none";
49 case ImGuiDir_Left:
50 return "left";
51 case ImGuiDir_Right:
52 return "right";
53 case ImGuiDir_Up:
54 return "up";
55 case ImGuiDir_Down:
56 return "down";
57 case ImGuiDir_COUNT:
58 return "none"; // Unused, but handle for completeness
59 default:
60 return "none";
61 }
62}
63
64ImGuiDir StringToDir(const std::string& str) {
65 if (str == "left")
66 return ImGuiDir_Left;
67 if (str == "right")
68 return ImGuiDir_Right;
69 if (str == "up")
70 return ImGuiDir_Up;
71 if (str == "down")
72 return ImGuiDir_Down;
73 return ImGuiDir_None;
74}
75
76std::string NodeTypeToString(DockNodeType type) {
77 switch (type) {
79 return "root";
81 return "split";
83 return "leaf";
84 default:
85 return "leaf";
86 }
87}
88
89DockNodeType StringToNodeType(const std::string& str) {
90 if (str == "root")
91 return DockNodeType::Root;
92 if (str == "split")
94 if (str == "leaf")
95 return DockNodeType::Leaf;
96 return DockNodeType::Leaf;
97}
98
99} // namespace
100
101std::string LayoutSerializer::ToJson(const LayoutDefinition& layout) {
102 std::ostringstream json;
103
104 json << "{\n";
105 json << " \"layout\": {\n";
106 json << " \"name\": \"" << EscapeJson(layout.name) << "\",\n";
107 json << " \"description\": \"" << EscapeJson(layout.description)
108 << "\",\n";
109 json << " \"version\": \"" << EscapeJson(layout.version) << "\",\n";
110 json << " \"author\": \"" << EscapeJson(layout.author) << "\",\n";
111 json << " \"created_timestamp\": " << layout.created_timestamp << ",\n";
112 json << " \"modified_timestamp\": " << layout.modified_timestamp << ",\n";
113 json << " \"canvas_size\": [" << layout.canvas_size.x << ", "
114 << layout.canvas_size.y << "],\n";
115
116 if (layout.root) {
117 json << " \"root_node\": " << SerializeDockNode(*layout.root) << "\n";
118 } else {
119 json << " \"root_node\": null\n";
120 }
121
122 json << " }\n";
123 json << "}\n";
124
125 return json.str();
126}
127
129 std::ostringstream json;
130
131 json << "{\n";
132 json << " \"type\": \"" << NodeTypeToString(node.type) << "\",\n";
133
134 if (node.IsSplit()) {
135 json << " \"split_dir\": \"" << DirToString(node.split_dir) << "\",\n";
136 json << " \"split_ratio\": " << node.split_ratio << ",\n";
137
138 json << " \"left_child\": ";
139 if (node.child_left) {
140 json << SerializeDockNode(*node.child_left);
141 } else {
142 json << "null";
143 }
144 json << ",\n";
145
146 json << " \"right_child\": ";
147 if (node.child_right) {
148 json << SerializeDockNode(*node.child_right);
149 } else {
150 json << "null";
151 }
152 json << "\n";
153
154 } else if (node.IsLeaf()) {
155 json << " \"panels\": [\n";
156 for (size_t idx = 0; idx < node.panels.size(); ++idx) {
157 json << " " << SerializePanel(node.panels[idx]);
158 if (idx < node.panels.size() - 1) {
159 json << ",";
160 }
161 json << "\n";
162 }
163 json << " ]\n";
164 }
165
166 json << " }";
167
168 return json.str();
169}
170
172 return absl::StrFormat(
173 "{\"id\":\"%s\",\"name\":\"%s\",\"icon\":\"%s\","
174 "\"priority\":%d,\"visible\":%s,\"closable\":%s,\"pinnable\":%s}",
175 EscapeJson(panel.panel_id), EscapeJson(panel.display_name),
176 EscapeJson(panel.icon), panel.priority,
177 panel.visible_by_default ? "true" : "false",
178 panel.closable ? "true" : "false", panel.pinnable ? "true" : "false");
179}
180
181absl::StatusOr<LayoutDefinition> LayoutSerializer::FromJson(
182 const std::string& json_str) {
183 // TODO(scawful): Implement full JSON parsing
184 // For now, this is a placeholder that returns an error
185 return absl::UnimplementedError(
186 "JSON deserialization not yet implemented. "
187 "This requires integrating nlohmann/json library.");
188}
189
191 const std::string& filepath) {
192 std::ofstream file(filepath);
193 if (!file.is_open()) {
194 return absl::InternalError(
195 absl::StrFormat("Failed to open file for writing: %s", filepath));
196 }
197
198 std::string json = ToJson(layout);
199 file << json;
200 file.close();
201
202 if (file.fail()) {
203 return absl::InternalError(
204 absl::StrFormat("Failed to write to file: %s", filepath));
205 }
206
207 LOG_INFO("LayoutSerializer", "Saved layout to: %s", filepath.c_str());
208 return absl::OkStatus();
209}
210
211absl::StatusOr<LayoutDefinition> LayoutSerializer::LoadFromFile(
212 const std::string& filepath) {
213 std::ifstream file(filepath);
214 if (!file.is_open()) {
215 return absl::InternalError(
216 absl::StrFormat("Failed to open file for reading: %s", filepath));
217 }
218
219 std::stringstream buffer;
220 buffer << file.rdbuf();
221 file.close();
222
223 return FromJson(buffer.str());
224}
225
226} // namespace layout_designer
227} // namespace editor
228} // namespace yaze
static absl::StatusOr< LayoutDefinition > LoadFromFile(const std::string &filepath)
Load layout from JSON file.
static absl::Status SaveToFile(const LayoutDefinition &layout, const std::string &filepath)
Save layout to JSON file.
static absl::StatusOr< LayoutDefinition > FromJson(const std::string &json_str)
Deserialize a layout from JSON string.
static std::string ToJson(const LayoutDefinition &layout)
Serialize a layout to JSON string.
static std::string SerializeDockNode(const DockNode &node)
static std::string SerializePanel(const LayoutPanel &panel)
#define LOG_INFO(category, format,...)
Definition log.h:105
DockNodeType
Type of dock node in the layout tree.
Represents a dock node in the layout tree.
std::unique_ptr< DockNode > child_left
std::unique_ptr< DockNode > child_right
Complete layout definition with metadata.
Represents a single panel in a layout.