yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
background_renderer.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5
6#include "app/core/timing.h"
8#include "imgui/imgui.h"
9
10#ifndef M_PI
11#define M_PI 3.14159265358979323846
12#endif
13
14namespace yaze {
15namespace gui {
16
17// BackgroundRenderer Implementation
19 static BackgroundRenderer instance;
20 return instance;
21}
22
23void BackgroundRenderer::RenderDockingBackground(ImDrawList* draw_list, const ImVec2& window_pos,
24 const ImVec2& window_size, const Color& theme_color) {
25 if (!draw_list) return;
26
28
29 // Get current theme colors
30 auto& theme_manager = ThemeManager::Get();
31 auto current_theme = theme_manager.GetCurrentTheme();
32
33 // Create a subtle tinted background
34 Color bg_tint = {
35 current_theme.background.red * 1.1f,
36 current_theme.background.green * 1.1f,
37 current_theme.background.blue * 1.1f,
38 0.3f
39 };
40
41 ImU32 bg_color = ImGui::ColorConvertFloat4ToU32(ConvertColorToImVec4(bg_tint));
42 draw_list->AddRectFilled(window_pos,
43 ImVec2(window_pos.x + window_size.x, window_pos.y + window_size.y),
44 bg_color);
45
46 // Render the grid if enabled
47 if (grid_settings_.grid_size > 0) {
48 RenderGridBackground(draw_list, window_pos, window_size, theme_color);
49 }
50
51 // Add subtle corner accents
52 if (current_theme.enable_glow_effects) {
53 float corner_size = 60.0f;
54 Color accent_faded = current_theme.accent;
55 accent_faded.alpha = 0.1f + 0.05f * sinf(animation_time_ * 2.0f);
56
57 ImU32 corner_color = ImGui::ColorConvertFloat4ToU32(ConvertColorToImVec4(accent_faded));
58
59 // Top-left corner
60 draw_list->AddRectFilledMultiColor(
61 window_pos,
62 ImVec2(window_pos.x + corner_size, window_pos.y + corner_size),
63 corner_color, IM_COL32(0,0,0,0), IM_COL32(0,0,0,0), corner_color);
64
65 // Bottom-right corner
66 draw_list->AddRectFilledMultiColor(
67 ImVec2(window_pos.x + window_size.x - corner_size, window_pos.y + window_size.y - corner_size),
68 ImVec2(window_pos.x + window_size.x, window_pos.y + window_size.y),
69 IM_COL32(0,0,0,0), corner_color, corner_color, IM_COL32(0,0,0,0));
70 }
71}
72
73void BackgroundRenderer::RenderGridBackground(ImDrawList* draw_list, const ImVec2& window_pos,
74 const ImVec2& window_size, const Color& grid_color) {
75 if (!draw_list || grid_settings_.grid_size <= 0) return;
76
77 // Grid parameters with optional animation
78 float grid_size = grid_settings_.grid_size;
79 float offset_x = 0.0f;
80 float offset_y = 0.0f;
81
82 // Apply animation if enabled
84 float animation_offset = animation_time_ * grid_settings_.animation_speed * 10.0f;
85 offset_x = fmodf(animation_offset, grid_size);
86 offset_y = fmodf(animation_offset * 0.7f, grid_size); // Different speed for interesting effect
87 }
88
89 // Window center for radial calculations
90 ImVec2 center = ImVec2(window_pos.x + window_size.x * 0.5f,
91 window_pos.y + window_size.y * 0.5f);
92 float max_distance = sqrtf(window_size.x * window_size.x + window_size.y * window_size.y) * 0.5f;
93
94 // Apply breathing effect to color if enabled
95 Color themed_grid_color = grid_color;
96 themed_grid_color.alpha = grid_settings_.opacity;
97
99 float breathing_factor = 1.0f + grid_settings_.breathing_intensity *
101 themed_grid_color.red = std::min(1.0f, themed_grid_color.red * breathing_factor);
102 themed_grid_color.green = std::min(1.0f, themed_grid_color.green * breathing_factor);
103 themed_grid_color.blue = std::min(1.0f, themed_grid_color.blue * breathing_factor);
104 }
105
107 // Render grid as dots
108 for (float x = window_pos.x - offset_x; x < window_pos.x + window_size.x + grid_size; x += grid_size) {
109 for (float y = window_pos.y - offset_y; y < window_pos.y + window_size.y + grid_size; y += grid_size) {
110 ImVec2 dot_pos(x, y);
111
112 // Calculate radial fade
113 float fade_factor = 1.0f;
115 float distance = sqrtf((dot_pos.x - center.x) * (dot_pos.x - center.x) +
116 (dot_pos.y - center.y) * (dot_pos.y - center.y));
117 fade_factor = 1.0f - std::min(distance / grid_settings_.fade_distance, 1.0f);
118 fade_factor = fade_factor * fade_factor; // Square for smoother falloff
119 }
120
121 if (fade_factor > 0.01f) {
122 ImU32 dot_color = BlendColorWithFade(themed_grid_color, fade_factor);
123 DrawGridDot(draw_list, dot_pos, dot_color, grid_settings_.dot_size);
124 }
125 }
126 }
127 } else {
128 // Render grid as lines
129 // Vertical lines
130 for (float x = window_pos.x - offset_x; x < window_pos.x + window_size.x + grid_size; x += grid_size) {
131 ImVec2 line_start(x, window_pos.y);
132 ImVec2 line_end(x, window_pos.y + window_size.y);
133
134 // Calculate average fade for this line
135 float avg_fade = 0.0f;
137 for (float y = window_pos.y; y < window_pos.y + window_size.y; y += grid_size * 0.5f) {
138 float distance = sqrtf((x - center.x) * (x - center.x) + (y - center.y) * (y - center.y));
139 float fade = 1.0f - std::min(distance / grid_settings_.fade_distance, 1.0f);
140 avg_fade += fade * fade;
141 }
142 avg_fade /= (window_size.y / (grid_size * 0.5f));
143 } else {
144 avg_fade = 1.0f;
145 }
146
147 if (avg_fade > 0.01f) {
148 ImU32 line_color = BlendColorWithFade(themed_grid_color, avg_fade);
149 DrawGridLine(draw_list, line_start, line_end, line_color, grid_settings_.line_thickness);
150 }
151 }
152
153 // Horizontal lines
154 for (float y = window_pos.y - offset_y; y < window_pos.y + window_size.y + grid_size; y += grid_size) {
155 ImVec2 line_start(window_pos.x, y);
156 ImVec2 line_end(window_pos.x + window_size.x, y);
157
158 // Calculate average fade for this line
159 float avg_fade = 0.0f;
161 for (float x = window_pos.x; x < window_pos.x + window_size.x; x += grid_size * 0.5f) {
162 float distance = sqrtf((x - center.x) * (x - center.x) + (y - center.y) * (y - center.y));
163 float fade = 1.0f - std::min(distance / grid_settings_.fade_distance, 1.0f);
164 avg_fade += fade * fade;
165 }
166 avg_fade /= (window_size.x / (grid_size * 0.5f));
167 } else {
168 avg_fade = 1.0f;
169 }
170
171 if (avg_fade > 0.01f) {
172 ImU32 line_color = BlendColorWithFade(themed_grid_color, avg_fade);
173 DrawGridLine(draw_list, line_start, line_end, line_color, grid_settings_.line_thickness);
174 }
175 }
176 }
177}
178
179void BackgroundRenderer::RenderRadialGradient(ImDrawList* draw_list, const ImVec2& center,
180 float radius, const Color& inner_color, const Color& outer_color) {
181 if (!draw_list) return;
182
183 const int segments = 32;
184 const int rings = 8;
185
186 for (int ring = 0; ring < rings; ++ring) {
187 float ring_radius = radius * (ring + 1) / rings;
188 float inner_ring_radius = radius * ring / rings;
189
190 // Interpolate colors for this ring
191 float t = static_cast<float>(ring) / rings;
192 Color ring_color = {
193 inner_color.red * (1.0f - t) + outer_color.red * t,
194 inner_color.green * (1.0f - t) + outer_color.green * t,
195 inner_color.blue * (1.0f - t) + outer_color.blue * t,
196 inner_color.alpha * (1.0f - t) + outer_color.alpha * t
197 };
198
199 ImU32 color = ImGui::ColorConvertFloat4ToU32(ConvertColorToImVec4(ring_color));
200
201 if (ring == 0) {
202 // Center circle
203 draw_list->AddCircleFilled(center, ring_radius, color, segments);
204 } else {
205 // Ring
206 for (int i = 0; i < segments; ++i) {
207 float angle1 = (2.0f * M_PI * i) / segments;
208 float angle2 = (2.0f * M_PI * (i + 1)) / segments;
209
210 ImVec2 p1_inner = ImVec2(center.x + cosf(angle1) * inner_ring_radius,
211 center.y + sinf(angle1) * inner_ring_radius);
212 ImVec2 p2_inner = ImVec2(center.x + cosf(angle2) * inner_ring_radius,
213 center.y + sinf(angle2) * inner_ring_radius);
214 ImVec2 p1_outer = ImVec2(center.x + cosf(angle1) * ring_radius,
215 center.y + sinf(angle1) * ring_radius);
216 ImVec2 p2_outer = ImVec2(center.x + cosf(angle2) * ring_radius,
217 center.y + sinf(angle2) * ring_radius);
218
219 draw_list->AddQuadFilled(p1_inner, p2_inner, p2_outer, p1_outer, color);
220 }
221 }
222 }
223}
224
227 animation_time_ += delta_time;
228 }
229}
230
231void BackgroundRenderer::UpdateForTheme(const Color& primary_color, const Color& background_color) {
232 // Create a grid color that's a subtle blend of the theme's primary and background
234 (primary_color.red * 0.3f + background_color.red * 0.7f),
235 (primary_color.green * 0.3f + background_color.green * 0.7f),
236 (primary_color.blue * 0.3f + background_color.blue * 0.7f),
238 };
239}
240
242 if (ImGui::CollapsingHeader("Background Grid Settings")) {
243 ImGui::Indent();
244
245 ImGui::SliderFloat("Grid Size", &grid_settings_.grid_size, 8.0f, 128.0f, "%.0f px");
246 ImGui::SliderFloat("Line Thickness", &grid_settings_.line_thickness, 0.5f, 3.0f, "%.1f px");
247 ImGui::SliderFloat("Opacity", &grid_settings_.opacity, 0.01f, 0.3f, "%.3f");
248 ImGui::SliderFloat("Fade Distance", &grid_settings_.fade_distance, 50.0f, 500.0f, "%.0f px");
249
250 ImGui::Separator();
251 ImGui::Text("Visual Effects:");
252 ImGui::Checkbox("Enable Animation", &grid_settings_.enable_animation);
253 ImGui::SameLine();
254 if (ImGui::IsItemHovered()) {
255 ImGui::SetTooltip("Makes the grid move slowly across the screen");
256 }
257
258 ImGui::Checkbox("Color Breathing", &grid_settings_.enable_breathing);
259 if (ImGui::IsItemHovered()) {
260 ImGui::SetTooltip("Grid color pulses with a breathing effect");
261 }
262
263 ImGui::Checkbox("Radial Fade", &grid_settings_.radial_fade);
264 ImGui::Checkbox("Use Dots Instead of Lines", &grid_settings_.enable_dots);
265
266 // Animation settings (only show if animation is enabled)
268 ImGui::Indent();
269 ImGui::SliderFloat("Animation Speed", &grid_settings_.animation_speed, 0.1f, 3.0f, "%.1fx");
270 ImGui::Unindent();
271 }
272
273 // Breathing settings (only show if breathing is enabled)
275 ImGui::Indent();
276 ImGui::SliderFloat("Breathing Speed", &grid_settings_.breathing_speed, 0.5f, 3.0f, "%.1fx");
277 ImGui::SliderFloat("Breathing Intensity", &grid_settings_.breathing_intensity, 0.1f, 0.8f, "%.1f");
278 ImGui::Unindent();
279 }
280
282 ImGui::SliderFloat("Dot Size", &grid_settings_.dot_size, 1.0f, 8.0f, "%.1f px");
283 }
284
285 // Preview
286 ImGui::Spacing();
287 ImGui::Text("Preview:");
288 ImVec2 preview_size(200, 100);
289 ImVec2 preview_pos = ImGui::GetCursorScreenPos();
290
291 ImDrawList* preview_draw_list = ImGui::GetWindowDrawList();
292 auto& theme_manager = ThemeManager::Get();
293 auto theme_color = theme_manager.GetCurrentTheme().primary;
294
295 // Draw preview background
296 preview_draw_list->AddRectFilled(preview_pos,
297 ImVec2(preview_pos.x + preview_size.x, preview_pos.y + preview_size.y),
298 IM_COL32(30, 30, 30, 255));
299
300 // Draw preview grid
301 RenderGridBackground(preview_draw_list, preview_pos, preview_size, theme_color);
302
303 // Advance cursor
304 ImGui::Dummy(preview_size);
305
306 ImGui::Unindent();
307 }
308}
309
310float BackgroundRenderer::CalculateRadialFade(const ImVec2& pos, const ImVec2& center, float max_distance) const {
311 float distance = sqrtf((pos.x - center.x) * (pos.x - center.x) +
312 (pos.y - center.y) * (pos.y - center.y));
313 float fade = 1.0f - std::min(distance / max_distance, 1.0f);
314 return fade * fade; // Square for smoother falloff
315}
316
317ImU32 BackgroundRenderer::BlendColorWithFade(const Color& base_color, float fade_factor) const {
318 Color faded_color = {
319 base_color.red,
320 base_color.green,
321 base_color.blue,
322 base_color.alpha * fade_factor
323 };
324 return ImGui::ColorConvertFloat4ToU32(ConvertColorToImVec4(faded_color));
325}
326
327void BackgroundRenderer::DrawGridLine(ImDrawList* draw_list, const ImVec2& start, const ImVec2& end,
328 ImU32 color, float thickness) const {
329 draw_list->AddLine(start, end, color, thickness);
330}
331
332void BackgroundRenderer::DrawGridDot(ImDrawList* draw_list, const ImVec2& pos, ImU32 color, float size) const {
333 draw_list->AddCircleFilled(pos, size, color);
334}
335
336// DockSpaceRenderer Implementation
342
343void DockSpaceRenderer::BeginEnhancedDockSpace(ImGuiID dockspace_id, const ImVec2& size,
344 ImGuiDockNodeFlags flags) {
345 // Store window info
346 last_dockspace_pos_ = ImGui::GetWindowPos();
347 last_dockspace_size_ = ImGui::GetWindowSize();
348
349 // Create the actual dockspace first
350 ImGui::DockSpace(dockspace_id, size, flags);
351
352 // NOW draw the background effects on the foreground draw list so they're visible
354 ImDrawList* fg_draw_list = ImGui::GetForegroundDrawList();
355 auto& theme_manager = ThemeManager::Get();
356 auto current_theme = theme_manager.GetCurrentTheme();
357
358 if (grid_enabled_) {
359 auto& bg_renderer = BackgroundRenderer::Get();
360 // Use the main viewport for full-screen grid
361 const ImGuiViewport* viewport = ImGui::GetMainViewport();
362 ImVec2 grid_pos = viewport->WorkPos;
363 ImVec2 grid_size = viewport->WorkSize;
364
365 // Use subtle grid color that doesn't distract
366 Color subtle_grid_color = current_theme.primary;
367 // Use the grid settings opacity for consistency
368 subtle_grid_color.alpha = bg_renderer.GetGridSettings().opacity;
369
370 bg_renderer.RenderGridBackground(fg_draw_list, grid_pos, grid_size, subtle_grid_color);
371 }
372 }
373}
374
376 // Additional post-processing effects could go here
377 // For now, this is just for API consistency
378}
379
380} // namespace gui
381} // namespace yaze
#define M_PI
static TimingManager & Get()
Definition timing.h:20
Renders themed background effects for docking windows.
void RenderRadialGradient(ImDrawList *draw_list, const ImVec2 &center, float radius, const Color &inner_color, const Color &outer_color)
void RenderGridBackground(ImDrawList *draw_list, const ImVec2 &window_pos, const ImVec2 &window_size, const Color &grid_color)
void DrawGridLine(ImDrawList *draw_list, const ImVec2 &start, const ImVec2 &end, ImU32 color, float thickness) const
static BackgroundRenderer & Get()
float CalculateRadialFade(const ImVec2 &pos, const ImVec2 &center, float max_distance) const
void UpdateAnimation(float delta_time)
void UpdateForTheme(const Color &primary_color, const Color &background_color)
void DrawGridDot(ImDrawList *draw_list, const ImVec2 &pos, ImU32 color, float size) const
ImU32 BlendColorWithFade(const Color &base_color, float fade_factor) const
void RenderDockingBackground(ImDrawList *draw_list, const ImVec2 &window_pos, const ImVec2 &window_size, const Color &theme_color)
static void BeginEnhancedDockSpace(ImGuiID dockspace_id, const ImVec2 &size=ImVec2(0, 0), ImGuiDockNodeFlags flags=0)
static ThemeManager & Get()
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:21
Main namespace for the application.
float alpha
Definition color.h:18
float green
Definition color.h:16