Unravel Engine C++ Reference
Loading...
Searching...
No Matches
create_scene_modal.cpp
Go to the documentation of this file.
4#include <imgui/imgui.h>
5#include <imgui/imgui_internal.h>
6
7namespace unravel
8{
9
10namespace
11{
12
13struct preset_card_info
14{
15 const char* id;
16 const char* icon;
17 const char* title;
18 const char* description;
20};
21
22const preset_card_info presets[] = {
23 {"preset_low",
25 "Low End",
26 "Basic lighting and minimal post-processing.\n"
27 "Best for low-end hardware or mobile targets.",
29 {"preset_medium",
31 "Standard",
32 "Balanced lighting, soft shadows and post-processing.\n"
33 "Recommended for most projects.",
35 {"preset_high",
37 "High End",
38 "Full Lighting, SSR, Bloom, Volumetric Clouds, Soft Shadows and Post-Processing.\n"
39 "Best for high-end desktop builds.",
41 {"preset_showcase",
43 "Showcase",
44 "Full Lighting, SSIL, SSR, Bloom, TAA, Volumetric Clouds, Soft Shadows and Post-Processing.\n"
45 "Best for showcase builds. Requires a powerful GPU.",
47};
48
49enum class card_action
50{
51 none,
52 selected,
53 confirmed
54};
55
56auto draw_preset_card(const preset_card_info& info, float card_width, bool is_selected) -> card_action
57{
58 auto result = card_action::none;
59 bool is_hovered = false;
60
61 ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 8.0f);
62 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 16));
63 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 8.0f);
64
65 if(is_selected)
66 {
67 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.25f));
68 }
69 else
70 {
71 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg, 0.6f));
72 }
73
74 ImVec2 card_size(card_width, 0);
75 if(ImGui::BeginChild(info.id, card_size,
76 ImGuiChildFlags_FrameStyle | ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeY))
77 {
78 is_hovered = ImGui::IsWindowHovered();
79
80 ImDrawList* draw_list = ImGui::GetWindowDrawList();
81 ImVec2 p_min = ImGui::GetWindowPos();
82 ImVec2 p_max = ImVec2(p_min.x + ImGui::GetWindowSize().x, p_min.y + ImGui::GetWindowSize().y);
83
84 if(is_hovered)
85 {
86 draw_list->AddRectFilled(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonHovered, 0.4f), 8.0f);
87 draw_list->AddRect(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.6f), 8.0f, 0, 2.0f);
88 }
89 else if(is_selected)
90 {
91 draw_list->AddRect(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.6f), 8.0f, 0, 1.5f);
92 }
93
94 ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX() + 4, ImGui::GetCursorPosY() + 2));
95 ImGui::BeginGroup();
96 {
98 if(is_hovered || is_selected)
99 {
100 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_ButtonActive));
101 }
102 // Icon in regular font (Black font has no icons)
103 ImGui::Text("%s", info.icon);
104 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
105 // Title in Black font
107 ImGui::Text("%s", info.title);
108 ImGui::PopFont();
109 if(is_hovered || is_selected)
110 {
111 ImGui::PopStyleColor();
112 }
114
115 ImGui::Spacing();
116
117 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.9f));
118 ImGui::TextWrapped("%s", info.description);
119 ImGui::PopStyleColor();
120 }
121 ImGui::EndGroup();
122 }
123 ImGui::EndChild();
124
125 ImGui::PopStyleColor();
126 ImGui::PopStyleVar(3);
127
128 if(is_hovered && ImGui::IsMouseDoubleClicked(0))
129 {
130 result = card_action::confirmed;
131 }
132 else if(is_hovered && ImGui::IsMouseClicked(0))
133 {
134 result = card_action::selected;
135 }
136
137 return result;
138}
139
140} // namespace
141
142void create_scene_modal::show(std::function<void(defaults::scene_preset)> on_preset_selected)
143{
144 auto& inst = get_instance();
145 inst.callback_ = std::move(on_preset_selected);
146 inst.show_requested_ = true;
147 inst.open_requested_ = true;
148 inst.selected_preset_ = defaults::scene_preset::medium;
149}
150
152{
153 return get_instance().show_requested_;
154}
155
157{
158 auto& inst = get_instance();
159 if(!inst.show_requested_)
160 {
161 return false;
162 }
163
164 auto callback = std::move(inst.callback_);
165 inst.callback_ = {};
166 inst.show_requested_ = false;
167 inst.open_requested_ = false;
168 inst.selected_preset_ = preset;
169
170 if(callback)
171 {
172 callback(preset);
173 }
174 return true;
175}
176
178{
179 auto& inst = get_instance();
180 inst.callback_ = {};
181 inst.show_requested_ = false;
182 inst.open_requested_ = false;
183}
184
186{
187 auto& inst = get_instance();
188 if(!inst.show_requested_)
189 {
190 return;
191 }
192
193 // if(inst.open_requested_)
194 {
195 ImGui::OpenPopup("Create Scene");
196 // inst.open_requested_ = false;
197 }
198
199 auto* viewport = ImGui::GetMainViewport();
200 ImGui::SetNextWindowPos(viewport->GetCenter(),
201 ImGuiCond_Always,
202 ImVec2(0.5f, 0.5f));
203
204 const float modal_width = viewport->Size.x * 0.3f;
205 ImGui::SetNextWindowSize(ImVec2(modal_width, 0), ImGuiCond_Always);
206
207 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(24, 20));
208 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 10.0f);
209 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(12, 10));
210
211 if(!ImGui::BeginPopupModal("Create Scene", nullptr,
212 ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings))
213 {
214 ImGui::PopStyleVar(3);
215 return;
216 }
217
218 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.8f));
219 ImGui::TextWrapped("Choose a preset for your new scene.");
220 ImGui::PopStyleColor();
221
222 ImGui::Spacing();
223 ImGui::PushStyleColor(ImGuiCol_Separator, ImVec4(0.25f, 0.25f, 0.25f, 1.0f));
224 ImGui::Separator();
225 ImGui::PopStyleColor();
226 ImGui::Spacing();
227
228 // Cards list
229 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 10.0f));
230 float card_width = ImGui::GetContentRegionAvail().x;
231 bool should_confirm = false;
232
233 for(const auto& p : presets)
234 {
235 bool is_selected = (p.preset == inst.selected_preset_);
236 auto action = draw_preset_card(p, card_width, is_selected);
237 if(action == card_action::confirmed)
238 {
239 inst.selected_preset_ = p.preset;
240 should_confirm = true;
241 }
242 else if(action == card_action::selected)
243 {
244 inst.selected_preset_ = p.preset;
245 }
246 }
247 ImGui::PopStyleVar();
248
249 ImGui::Spacing();
250 ImGui::PushStyleColor(ImGuiCol_Separator, ImVec4(0.25f, 0.25f, 0.25f, 1.0f));
251 ImGui::Separator();
252 ImGui::PopStyleColor();
253 ImGui::Spacing();
254
255 // Bottom button row, right-aligned
256 float button_width = 100.0f;
257 float total_buttons_w = button_width * 2 + ImGui::GetStyle().ItemSpacing.x;
258
259 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 6.0f);
260
261 ImGui::AlignedItem(1.0f, ImGui::GetContentRegionAvail().x, total_buttons_w, [&]() -> void
262 {
263 if(ImGui::Button("Create", ImVec2(button_width, 30)) || should_confirm)
264 {
265 if(inst.callback_)
266 {
267 inst.callback_(inst.selected_preset_);
268 }
269 ImGui::CloseCurrentPopup();
270 inst.show_requested_ = false;
271 }
272
273 ImGui::SameLine();
274
275 if(ImGui::Button("Cancel", ImVec2(button_width, 30)))
276 {
277 ImGui::CloseCurrentPopup();
278 inst.show_requested_ = false;
279 }
280 });
281
282 ImGui::PopStyleVar(); // FrameRounding
283
284 ImGui::EndPopup();
285 ImGui::PopStyleVar(3); // WindowPadding, WindowRounding, ItemSpacing
286}
287
288auto create_scene_modal::get_instance() -> create_scene_modal&
289{
290 static create_scene_modal instance;
291 return instance;
292}
293
294} // namespace unravel
Modal for selecting a scene preset when creating a new scene. Call ShowCreateSceneModal() to open; Re...
static void show(std::function< void(defaults::scene_preset)> on_preset_selected)
Request the create scene modal to open.
static void render()
Draw the modal. Call every frame from the main UI render loop.
static auto complete_if_pending(defaults::scene_preset preset) -> bool
static auto is_pending() -> bool
True when Show was requested and the user has not yet confirmed/cancelled.
static void cancel_if_pending()
Dismiss a pending create-scene modal without invoking the callback.
float x
defaults::scene_preset preset
const char * description
const char * icon
const char * title
const char * id
#define ICON_MDI_DIAMOND_STONE
#define ICON_MDI_GIFT
#define ICON_MDI_LAYERS
#define ICON_MDI_LIGHTNING_BOLT_OUTLINE
void PushFont(Font::Enum _font)
Definition imgui.cpp:646
void PopWindowFontScale()
Definition imgui.cpp:734
void PushWindowFontScale(float scale)
Definition imgui.cpp:721
scene_preset
Quality presets for new scene creation (low = less expensive, high = more expensive).
Definition defaults.h:215