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 '"': result += "\\\""; break;
23 case '\\': result += "\\\\"; break;
24 case '\n': result += "\\n"; break;
25 case '\r': result += "\\r"; break;
26 case '\t': result += "\\t"; break;
27 default: result += chr; break;
28 }
29 }
30 return result;
31}
32
33std::string DirToString(ImGuiDir dir) {
34 switch (dir) {
35 case ImGuiDir_None: return "none";
36 case ImGuiDir_Left: return "left";
37 case ImGuiDir_Right: return "right";
38 case ImGuiDir_Up: return "up";
39 case ImGuiDir_Down: return "down";
40 case ImGuiDir_COUNT: return "none"; // Unused, but handle for completeness
41 default: return "none";
42 }
43}
44
45ImGuiDir StringToDir(const std::string& str) {
46 if (str == "left") return ImGuiDir_Left;
47 if (str == "right") return ImGuiDir_Right;
48 if (str == "up") return ImGuiDir_Up;
49 if (str == "down") return ImGuiDir_Down;
50 return ImGuiDir_None;
51}
52
53std::string NodeTypeToString(DockNodeType type) {
54 switch (type) {
55 case DockNodeType::Root: return "root";
56 case DockNodeType::Split: return "split";
57 case DockNodeType::Leaf: return "leaf";
58 default: return "leaf";
59 }
60}
61
62DockNodeType StringToNodeType(const std::string& str) {
63 if (str == "root") return DockNodeType::Root;
64 if (str == "split") return DockNodeType::Split;
65 if (str == "leaf") return DockNodeType::Leaf;
66 return DockNodeType::Leaf;
67}
68
69} // namespace
70
71std::string LayoutSerializer::ToJson(const LayoutDefinition& layout) {
72 std::ostringstream json;
73
74 json << "{\n";
75 json << " \"layout\": {\n";
76 json << " \"name\": \"" << EscapeJson(layout.name) << "\",\n";
77 json << " \"description\": \"" << EscapeJson(layout.description) << "\",\n";
78 json << " \"version\": \"" << EscapeJson(layout.version) << "\",\n";
79 json << " \"author\": \"" << EscapeJson(layout.author) << "\",\n";
80 json << " \"created_timestamp\": " << layout.created_timestamp << ",\n";
81 json << " \"modified_timestamp\": " << layout.modified_timestamp << ",\n";
82 json << " \"canvas_size\": [" << layout.canvas_size.x << ", "
83 << layout.canvas_size.y << "],\n";
84
85 if (layout.root) {
86 json << " \"root_node\": " << SerializeDockNode(*layout.root) << "\n";
87 } else {
88 json << " \"root_node\": null\n";
89 }
90
91 json << " }\n";
92 json << "}\n";
93
94 return json.str();
95}
96
98 std::ostringstream json;
99
100 json << "{\n";
101 json << " \"type\": \"" << NodeTypeToString(node.type) << "\",\n";
102
103 if (node.IsSplit()) {
104 json << " \"split_dir\": \"" << DirToString(node.split_dir) << "\",\n";
105 json << " \"split_ratio\": " << node.split_ratio << ",\n";
106
107 json << " \"left_child\": ";
108 if (node.child_left) {
109 json << SerializeDockNode(*node.child_left);
110 } else {
111 json << "null";
112 }
113 json << ",\n";
114
115 json << " \"right_child\": ";
116 if (node.child_right) {
117 json << SerializeDockNode(*node.child_right);
118 } else {
119 json << "null";
120 }
121 json << "\n";
122
123 } else if (node.IsLeaf()) {
124 json << " \"panels\": [\n";
125 for (size_t idx = 0; idx < node.panels.size(); ++idx) {
126 json << " " << SerializePanel(node.panels[idx]);
127 if (idx < node.panels.size() - 1) {
128 json << ",";
129 }
130 json << "\n";
131 }
132 json << " ]\n";
133 }
134
135 json << " }";
136
137 return json.str();
138}
139
141 return absl::StrFormat(
142 "{\"id\":\"%s\",\"name\":\"%s\",\"icon\":\"%s\","
143 "\"priority\":%d,\"visible\":%s,\"closable\":%s,\"pinnable\":%s}",
144 EscapeJson(panel.panel_id),
145 EscapeJson(panel.display_name),
146 EscapeJson(panel.icon),
147 panel.priority,
148 panel.visible_by_default ? "true" : "false",
149 panel.closable ? "true" : "false",
150 panel.pinnable ? "true" : "false");
151}
152
153absl::StatusOr<LayoutDefinition> LayoutSerializer::FromJson(
154 const std::string& json_str) {
155 // TODO(scawful): Implement full JSON parsing
156 // For now, this is a placeholder that returns an error
157 return absl::UnimplementedError(
158 "JSON deserialization not yet implemented. "
159 "This requires integrating nlohmann/json library.");
160}
161
163 const std::string& filepath) {
164 std::ofstream file(filepath);
165 if (!file.is_open()) {
166 return absl::InternalError(
167 absl::StrFormat("Failed to open file for writing: %s", filepath));
168 }
169
170 std::string json = ToJson(layout);
171 file << json;
172 file.close();
173
174 if (file.fail()) {
175 return absl::InternalError(
176 absl::StrFormat("Failed to write to file: %s", filepath));
177 }
178
179 LOG_INFO("LayoutSerializer", "Saved layout to: %s", filepath.c_str());
180 return absl::OkStatus();
181}
182
183absl::StatusOr<LayoutDefinition> LayoutSerializer::LoadFromFile(
184 const std::string& filepath) {
185 std::ifstream file(filepath);
186 if (!file.is_open()) {
187 return absl::InternalError(
188 absl::StrFormat("Failed to open file for reading: %s", filepath));
189 }
190
191 std::stringstream buffer;
192 buffer << file.rdbuf();
193 file.close();
194
195 return FromJson(buffer.str());
196}
197
198} // namespace layout_designer
199} // namespace editor
200} // namespace yaze
201
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.