Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove old & complete refactor of Node system
  • Loading branch information
The3dVehicleguy committed Dec 2, 2025
commit 4cd3ac2a8177d03c7f26a239d7a0075b597ae099
159 changes: 134 additions & 25 deletions source/editor/ImGui/ImGui_ViewGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,54 +23,163 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "pch.h"
#include "ImGui_ViewGrid.h"
#include "../Widgets/NodeWidget.h"
#include "Nodes/imgui_node_editor.h"
//================================

//= NAMESPACES =========
using namespace std;
using namespace spartan;
//======================

ImVec2 Grid::GetGridPos() const
void Grid::Draw()
{
// Return the canvas origin position
if (m_widget_context)
return {0, 0}; // Could return a calculated grid position based on node editor state
if (!m_settings.enabled)
return;

return {0, 0};
ImDrawList* draw_list = ImGui::GetWindowDrawList();
const ImVec2 canvas_pos = GetCanvasPos();
const ImVec2 canvas_size = GetCanvasSize();

// Draw background
draw_list->AddRectFilled(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y),
m_settings.colors.grid_background);

DrawGridLines();
}

void Grid::DrawGridLines()
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
const ImVec2 canvas_pos = GetCanvasPos();
const ImVec2 canvas_size = GetCanvasSize();

const float grid_step = m_settings.grid_scale * m_zoom;

// Calculate grid offset based on scroll
const float offset_x = fmodf(m_scroll.x * m_zoom, grid_step);
const float offset_y = fmodf(m_scroll.y * m_zoom, grid_step);

// Draw vertical lines
for (float x = offset_x; x < canvas_size.x; x += grid_step)
{
const bool is_thick_line = fmodf(x - offset_x, grid_step * 10.0f) < 0.1f;
const ImU32 color = is_thick_line ? m_settings.colors.grid_lines_thick : m_settings.colors.grid_lines_thin;
draw_list->AddLine(
ImVec2(canvas_pos.x + x, canvas_pos.y),
ImVec2(canvas_pos.x + x, canvas_pos.y + canvas_size.y),
color);
}

// Draw horizontal lines
for (float y = offset_y; y < canvas_size.y; y += grid_step)
{
const bool is_thick_line = fmodf(y - offset_y, grid_step * 10.0f) < 0.1f;
const ImU32 color = is_thick_line ? m_settings.colors.grid_lines_thick : m_settings.colors.grid_lines_thin;
draw_list->AddLine(
ImVec2(canvas_pos.x, canvas_pos.y + y),
ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + y),
color);
}
}

ImVec2 Grid::GetScroll() const
ImVec2 Grid::ScreenToGrid(const ImVec2& screen_pos) const
{
if (m_widget_context)
return NodeEditor::GetViewOffset();
const ImVec2 canvas_pos = GetCanvasPos();
return ImVec2(
(screen_pos.x - canvas_pos.x) / m_zoom - m_scroll.x,
(screen_pos.y - canvas_pos.y) / m_zoom - m_scroll.y
);
}

return {0, 0};
ImVec2 Grid::GridToScreen(const ImVec2& grid_pos) const
{
const ImVec2 canvas_pos = GetCanvasPos();
return ImVec2(
(grid_pos.x + m_scroll.x) * m_zoom + canvas_pos.x,
(grid_pos.y + m_scroll.y) * m_zoom + canvas_pos.y
);
}

ImVec2 Grid::GetZoom() const
void Grid::HandleInput()
{
if (m_widget_context)
const ImGuiIO& io = ImGui::GetIO();
const ImVec2 canvas_pos = GetCanvasPos();
const ImVec2 canvas_size = GetCanvasSize();
const ImVec2 mouse_pos = ImGui::GetMousePos();

const bool is_mouse_in_canvas =
mouse_pos.x >= canvas_pos.x && mouse_pos.x <= canvas_pos.x + canvas_size.x &&
mouse_pos.y >= canvas_pos.y && mouse_pos.y <= canvas_pos.y + canvas_size.y;

if (!is_mouse_in_canvas)
return;

// Handle zoom
if (io.MouseWheel != 0.0f)
{
float zoom = NodeEditor::GetCurrentZoom();
return {zoom, zoom};
const float zoom_delta = io.MouseWheel * 0.1f;
float new_zoom = m_target_zoom + zoom_delta;

// Clamp zoom
if (new_zoom < m_settings.min_zoom)
new_zoom = m_settings.min_zoom;
if (new_zoom > m_settings.max_zoom)
new_zoom = m_settings.max_zoom;

m_target_zoom = new_zoom;
}

// Smooth zoom interpolation
if (fabsf(m_zoom - m_target_zoom) > 0.01f)
{
// Linear interpolation
m_zoom = m_zoom + (m_target_zoom - m_zoom) * io.DeltaTime * m_settings.zoom_smoothness;
}
else
{
m_zoom = m_target_zoom;
}

// Handle panning (middle mouse button or Alt+Left mouse button)
const bool pan_button = ImGui::IsMouseDown(ImGuiMouseButton_Middle) ||
(ImGui::IsMouseDown(ImGuiMouseButton_Left) && io.KeyAlt);

if (pan_button && !m_is_panning)
{
m_is_panning = true;
m_pan_start_pos = mouse_pos;
}
else if (!pan_button && m_is_panning)
{
m_is_panning = false;
}

if (m_is_panning)
{
const ImVec2 delta = ImVec2(mouse_pos.x - m_pan_start_pos.x, mouse_pos.y - m_pan_start_pos.y);
m_scroll.x += delta.x / m_zoom;
m_scroll.y += delta.y / m_zoom;
m_pan_start_pos = mouse_pos;
}

return {1, 1};
}

ImVec2 Grid::ScreenToGrid(const ImVec2& screen_pos) const
void Grid::SetZoom(float zoom)
{
if (m_widget_context)
return NodeEditor::ScreenToCanvas(screen_pos);

return screen_pos;
// Clamp zoom
if (zoom < m_settings.min_zoom)
zoom = m_settings.min_zoom;
if (zoom > m_settings.max_zoom)
zoom = m_settings.max_zoom;

m_zoom = zoom;
m_target_zoom = m_zoom;
}

ImVec2 Grid::GridToScreen(const ImVec2& grid_pos) const
ImVec2 Grid::GetCanvasSize() const
{
if (m_widget_context)
return NodeEditor::CanvasToScreen(grid_pos);
return ImGui::GetContentRegionAvail();
}

return grid_pos;
ImVec2 Grid::GetCanvasPos() const
{
return ImGui::GetCursorScreenPos();
}
55 changes: 33 additions & 22 deletions source/editor/ImGui/ImGui_ViewGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,15 @@ struct GridColors
ImU32 grid_background = IM_COL32(33, 41, 45, 255);
};

struct GridZoomLevels
{
bool grid_zoom_enabled = true;
float grid_min_zoom = 0.3f;
float grid_max_zoom = 2.f;
float grid_divisions = 10.f;
float grid_zoom_smoothness = 5.f;
float grid_default_zoom = 1.f;
};

struct GridSettings
{
bool enabled = false;
bool opacity_enabled = false;
bool snap_to_grid = false;
float opacity = 0.0f;
float grid_scale = 50.0f;
GridColors grid_colors;
GridZoomLevels grid_zoom;
bool enabled = true;
bool snap_to_grid = false;
float grid_scale = 50.0f;
float min_zoom = 0.3f;
float max_zoom = 2.0f;
float zoom_smoothness = 5.0f;
GridColors colors;
};

class Grid
Expand All @@ -65,15 +55,36 @@ class Grid

void SetWidgetContext(NodeWidget* widget) { m_widget_context = widget; }

ImVec2 GetGridPos() const;
ImVec2 GetScroll() const;
ImVec2 GetZoom() const;

// Rendering
void Draw();

// Coordinate transforms
ImVec2 ScreenToGrid(const ImVec2& screen_pos) const;
ImVec2 GridToScreen(const ImVec2& grid_pos) const;

// Input handling
void HandleInput();

// Accessors
ImVec2 GetScroll() const { return m_scroll; }
float GetZoom() const { return m_zoom; }
ImVec2 GetCanvasSize() const;
ImVec2 GetCanvasPos() const;

void SetScroll(const ImVec2& scroll) { m_scroll = scroll; }
void SetZoom(float zoom);

GridSettings& GetSettings() { return m_settings; }
const GridSettings& GetSettings() const { return m_settings; }

private:
void DrawGridLines();

NodeWidget* m_widget_context = nullptr;
GridSettings m_settings;
GridSettings& GetSettings() { return m_settings; }
ImVec2 m_scroll = ImVec2(0, 0);
float m_zoom = 1.0f;
float m_target_zoom = 1.0f;
bool m_is_panning = false;
ImVec2 m_pan_start_pos = ImVec2(0, 0);
};
Loading