Unravel Engine C++ Reference
Loading...
Searching...
No Matches
layout_panel.cpp
Go to the documentation of this file.
1#include "layout_panel.h"
2#include "../panel.h"
3
5
7#include <imgui/imgui.h>
8
9namespace unravel
10{
11namespace
12{
13auto filename_char_filter(ImGuiInputTextCallbackData* data) -> int
14{
15 auto c = data->EventChar;
16 if(c == '<' || c == '>' || c == ':' || c == '"' || c == '/' || c == '\\' || c == '|' || c == '?' || c == '*')
17 {
18 return 1;
19 }
20 return 0;
21}
22} // namespace
23
25{
26}
27
28auto layout_panel::get_window_flags() const -> ImGuiWindowFlags
29{
30 return 0;
31}
32
34{
35 (void)ctx;
36
37 auto& lm = parent_->get_layout_manager();
38
39 if(ImGui::Button(ICON_MDI_PLUS " Create Layout", ImVec2(-1, 0)))
40 {
41 open_create_popup_ = true;
42 create_name_buf_.fill('\0');
43 }
44
45 if(ImGui::Button(ICON_MDI_RESTORE " Reset to Default", ImVec2(-1, 0)))
46 {
47 lm.reset_to_default();
48 }
49
50 ImGui::Separator();
51
52 draw_presets_list();
53
54 ImGui::Separator();
55
56 if(ImGui::Button(ICON_MDI_FOLDER_OPEN " Open in Explorer", ImVec2(-1, 0)))
57 {
58 fs::show_in_graphical_env(lm.get_layouts_directory());
59 }
60
61 draw_create_popup();
62}
63
64void layout_panel::draw_create_popup()
65{
66 if(open_create_popup_)
67 {
68 ImGui::OpenPopup("Create Layout");
69 open_create_popup_ = false;
70 }
71
72 auto* viewport = ImGui::GetMainViewport();
73 ImGui::SetNextWindowPos(ImVec2(viewport->GetCenter().x, viewport->GetCenter().y),
74 ImGuiCond_Appearing,
75 ImVec2(0.5f, 0.5f));
76 ImGui::SetNextWindowSize(ImVec2(400, 0), ImGuiCond_Appearing);
77
78 if(!ImGui::BeginPopupModal("Create Layout", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
79 {
80 return;
81 }
82
83 auto& lm = parent_->get_layout_manager();
84
85 ImGui::TextWrapped("Enter the name of the layout you want to create");
86 ImGui::Spacing();
87
88 ImGui::AlignTextToFramePadding();
89 ImGui::Text("Layout Name");
90 ImGui::SameLine();
91 ImGui::SetNextItemWidth(-1);
92
93 bool enter_pressed = ImGui::InputText("##create_name",
94 create_name_buf_.data(),
95 create_name_buf_.size(),
96 ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCharFilter,
97 filename_char_filter);
98
99 bool name_empty = (create_name_buf_[0] == '\0');
100 bool already_exists = !name_empty && lm.has_preset(create_name_buf_.data());
101
102 if(already_exists)
103 {
104 ImGui::TextColored(ImVec4(1.0f, 0.7f, 0.0f, 1.0f), ICON_MDI_ALERT " A preset with this name already exists and will be overwritten.");
105 }
106
107 ImGui::Spacing();
108
109 float button_width = 120.0f;
110 float total_width = button_width * 2 + ImGui::GetStyle().ItemSpacing.x;
111 ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - total_width + ImGui::GetCursorPosX());
112
113 if(ImGui::Button("Create", ImVec2(button_width, 0)) || (enter_pressed && !name_empty))
114 {
115 if(!name_empty)
116 {
117 lm.save_preset(create_name_buf_.data());
118 ImGui::CloseCurrentPopup();
119 }
120 }
121
122 ImGui::SameLine();
123
124 if(ImGui::Button("Cancel", ImVec2(button_width, 0)))
125 {
126 ImGui::CloseCurrentPopup();
127 }
128
129 ImGui::EndPopup();
130}
131
132void layout_panel::draw_presets_list()
133{
134 auto& lm = parent_->get_layout_manager();
135 auto presets = lm.get_preset_names();
136
137 ImGui::Text("Saved Layouts:");
138
139 if(presets.empty())
140 {
141 ImGui::TextDisabled("No saved layouts yet.");
142 return;
143 }
144
145 for(const auto& name : presets)
146 {
147 ImGui::PushID(name.c_str());
148
149 float icon_btn_width = ImGui::CalcTextSize(ICON_MDI_DELETE).x + ImGui::GetStyle().FramePadding.x * 2;
150 float apply_width = ImGui::GetContentRegionAvail().x - icon_btn_width * 2 - ImGui::GetStyle().ItemSpacing.x * 2;
151
152 if(ImGui::Button(name.c_str(), ImVec2(apply_width, 0)))
153 {
154 lm.load_preset(name);
155 }
156 ImGui::SetItemTooltipEx("Click to apply \"%s\"", name.c_str());
157
158 ImGui::SameLine();
159
160 if(ImGui::Button(ICON_MDI_UPDATE, ImVec2(icon_btn_width, 0)))
161 {
162 lm.save_preset(name);
163 }
164 ImGui::SetItemTooltipEx("Update \"%s\" with current layout", name.c_str());
165
166 ImGui::SameLine();
167
168 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.15f, 0.15f, 0.65f));
169 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.8f, 0.2f, 0.2f, 0.8f));
170 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.9f, 0.1f, 0.1f, 1.0f));
171 if(ImGui::Button(ICON_MDI_DELETE, ImVec2(icon_btn_width, 0)))
172 {
173 auto preset_name = name;
174 auto* panels = parent_;
176 "Delete Layout?",
177 fmt::format("Delete layout preset \"{}\"?\n\nThis cannot be undone.", preset_name),
178 [panels, preset_name](ImBox::ModalResult result) -> void
179 {
180 if(result == ImBox::ModalResult::Delete)
181 {
182 panels->get_layout_manager().delete_preset(preset_name);
183 }
184 });
185 }
186 ImGui::PopStyleColor(3);
187 ImGui::SetItemTooltipEx("Delete \"%s\"", name.c_str());
188
189 ImGui::PopID();
190 }
191}
192
193} // namespace unravel
auto get_layout_manager() -> layout_manager &
Definition panel.cpp:281
layout_panel(imgui_panels *parent, const char *name)
void draw_ui(rtti::context &ctx) override
float x
std::string name
Definition hub.cpp:33
#define ICON_MDI_ALERT
#define ICON_MDI_UPDATE
#define ICON_MDI_RESTORE
#define ICON_MDI_PLUS
#define ICON_MDI_DELETE
#define ICON_MDI_FOLDER_OPEN
std::vector< size_t > parent_
ModalResult
Modal result flags for message box buttons.
auto ShowDeleteConfirmation(const std::string &title, const std::string &message, std::function< void(ModalResult)> callback) -> std::shared_ptr< MsgBox >
Show a delete confirmation dialog with Delete/Cancel buttons.