main
Brett 2024-07-29 14:01:07 -04:00
parent e927954d6a
commit 9516c479f2
6 changed files with 143 additions and 99 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(graphs VERSION 0.1.5) project(graphs VERSION 0.1.6)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)

View File

@ -41,6 +41,7 @@ namespace conf
} }
class graph_t; class graph_t;
class selector_t;
struct loader_t; struct loader_t;
#endif //GRAPHS_CONFIG_H #endif //GRAPHS_CONFIG_H

View File

@ -21,6 +21,7 @@
#include <config.h> #include <config.h>
#include <graph_base.h> #include <graph_base.h>
#include <selection.h>
#include <force_algorithms.h> #include <force_algorithms.h>
#include <blt/gfx/window.h> #include <blt/gfx/window.h>
#include <blt/math/interpolation.h> #include <blt/math/interpolation.h>
@ -28,14 +29,6 @@
namespace im = ImGui; namespace im = ImGui;
enum class anim_state_t
{
NONE,
HIGHLIGHT_NODE,
SELECT_NODE,
HIGHLIGHT_TO_SELECT
};
struct bounding_box struct bounding_box
{ {
int min_x = 0; int min_x = 0;
@ -53,6 +46,7 @@ struct bounding_box
class graph_t class graph_t
{ {
friend struct loader_t; friend struct loader_t;
friend class selector_t;
private: private:
std::vector<node_t> nodes; std::vector<node_t> nodes;
blt::hashmap_t<std::string, blt::u64> names_to_node; blt::hashmap_t<std::string, blt::u64> names_to_node;
@ -66,14 +60,7 @@ class graph_t
int current_iterations = 0; int current_iterations = 0;
int max_iterations = 5000; int max_iterations = 5000;
std::unique_ptr<force_equation> equation; std::unique_ptr<force_equation> equation;
blt::i64 last_selected_node = -1;
blt::i64 last_selected_node2 = -1;
bool is_edge = false;
blt::quad_easing easing;
blt::quint_easing highlight_easing;
void create_random_graph(bounding_box bb, blt::size_t min_nodes, blt::size_t max_nodes, blt::f64 connectivity, void create_random_graph(bounding_box bb, blt::size_t min_nodes, blt::size_t max_nodes, blt::f64 connectivity,
blt::f64 scaling_connectivity, blt::f64 distance_factor); blt::f64 scaling_connectivity, blt::f64 distance_factor);
@ -130,17 +117,6 @@ class graph_t
void render(); void render();
void reset_mouse_drag();
void reset_mouse_highlight()
{
highlight_easing.reset();
}
void process_mouse_drag(blt::i32 width, blt::i32 height);
void handle_mouse();
void use_Eades() void use_Eades()
{ {
equation = std::make_unique<Eades_equation>(); equation = std::make_unique<Eades_equation>();
@ -212,6 +188,7 @@ class engine_t
friend struct loader_t; friend struct loader_t;
private: private:
graph_t graph; graph_t graph;
selector_t selector;
void draw_gui(const blt::gfx::window_data& data); void draw_gui(const blt::gfx::window_data& data);
@ -228,11 +205,10 @@ class engine_t
auto& io = ImGui::GetIO(); auto& io = ImGui::GetIO();
if (!io.WantCaptureMouse) if (!io.WantCaptureMouse)
{ selector.process_mouse(graph, data.width, data.height);
graph.process_mouse_drag(data.width, data.height);
}
graph.render(); graph.render();
selector.render(graph, data.width, data.height);
} }
}; };

46
include/selection.h Normal file
View File

@ -0,0 +1,46 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GRAPHS_SELECTION_H
#define GRAPHS_SELECTION_H
#include <config.h>
class selector_t
{
public:
// called inside the info panel block, used for adding more information
void draw_gui(graph_t& graph, blt::i32 width, blt::i32 height);
// called once per frame, for rendering animations
void render(graph_t& graph, blt::i32 width, blt::i32 height);
// called once per frame assuming imgui doesn't want the mouse
void process_mouse(graph_t& graph, blt::i32 width, blt::i32 height);
private:
void set_primary_selection(blt::i64 n);
void set_drag_selection(blt::i64 n);
void set_secondary_selection(blt::i64 n);
private:
blt::i64 drag_selection = -1;
blt::i64 primary_selection = -1;
blt::i64 secondary_selection = -1;
bool edge = false;
};
#endif //GRAPHS_SELECTION_H

View File

@ -83,59 +83,6 @@ void graph_t::render()
} }
} }
// called every frame as long as imgui doesn't require the mouse.
void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
{
const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(),
global_matrices.getOrtho()));
bool mouse_pressed = blt::gfx::isMousePressed(0);
blt::i64 new_selection = -1;
for (const auto& [index, node] : blt::enumerate(nodes))
{
const auto pos = node.getPosition();
const auto dist = pos - mouse_pos;
const auto mag = dist.magnitude();
if (mag < node.getRenderObj().scale && mouse_pressed)
{
new_selection = static_cast<blt::i64>(index);
break;
}
}
if (new_selection != last_selected_node)
{
if (last_selected_node != -1)
nodes[last_selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
}
if (mouse_pressed && new_selection == -1 && last_selected_node != -1)
{
last_selected_node = -1;
}
last_selected_node = new_selection;
if (!mouse_pressed && blt::gfx::mouseReleaseLastFrame())
{
reset_mouse_drag();
}
if (last_selected_node != -1 && mouse_pressed)
{
auto& node = nodes[last_selected_node];
easing.progress(8 * static_cast<float>(blt::gfx::getFrameDeltaSeconds()));
node.outline_color = conf::POINT_SELECT_COLOR;
node.getPositionRef() = mouse_pos;
}
}
void graph_t::handle_mouse()
{}
void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes, const blt::size_t max_nodes, const blt::f64 connectivity, void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes, const blt::size_t max_nodes, const blt::f64 connectivity,
const blt::f64 scaling_connectivity, const blt::f64 distance_factor) const blt::f64 scaling_connectivity, const blt::f64 distance_factor)
{ {
@ -221,16 +168,6 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
} }
} }
void graph_t::reset_mouse_drag()
{
if (last_selected_node != -1)
{
nodes[last_selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
easing.reset();
}
last_selected_node = -1;
}
void engine_t::draw_gui(const blt::gfx::window_data& data) void engine_t::draw_gui(const blt::gfx::window_data& data)
{ {
double ft = blt::gfx::getFrameDeltaSeconds(); double ft = blt::gfx::getFrameDeltaSeconds();
@ -332,11 +269,7 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
} }
} }
} }
im::SetNextItemOpen(true, ImGuiCond_Once); selector.draw_gui(graph, data.width, data.height);
if (im::CollapsingHeader("Node Information"))
{
}
im::End(); im::End();
} }
} }

88
src/selector.cpp Normal file
View File

@ -0,0 +1,88 @@
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <selection.h>
#include <graph.h>
#include <blt/gfx/raycast.h>
extern blt::gfx::batch_renderer_2d renderer_2d;
extern blt::gfx::matrix_state_manager global_matrices;
void selector_t::render(graph_t& graph, blt::i32 width, blt::i32 height)
{
}
void selector_t::process_mouse(graph_t& graph, blt::i32 width, blt::i32 height)
{
const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(),
global_matrices.getOrtho()));
bool mouse_pressed = blt::gfx::isMousePressed(0) && blt::gfx::mousePressedLastFrame();
for (const auto& [index, node] : blt::enumerate(graph.nodes))
{
const auto pos = node.getPosition();
const auto dist = pos - mouse_pos;
const auto mag = dist.magnitude();
if (mag < node.getRenderObj().scale && mouse_pressed)
{
set_drag_selection(static_cast<blt::i64>(index));
if (primary_selection == drag_selection || secondary_selection == drag_selection)
{
edge = false;
break;
}
if (blt::gfx::isKeyPressed(GLFW_KEY_LEFT_SHIFT))
set_secondary_selection(drag_selection);
else
set_primary_selection(drag_selection);
break;
}
}
if (blt::gfx::mouseReleaseLastFrame())
set_drag_selection(-1);
if (drag_selection >= 0 && drag_selection < static_cast<blt::i64>(graph.nodes.size()) && blt::gfx::isMousePressed(0))
{
graph.nodes[drag_selection].getPositionRef() = mouse_pos;
}
}
void selector_t::draw_gui(graph_t& graph, blt::i32 width, blt::i32 height)
{
im::SetNextItemOpen(true, ImGuiCond_Once);
if (im::CollapsingHeader("Selection Information"))
{
im::Text("Silly (%ld) | (%ld || %ld)", drag_selection, primary_selection, secondary_selection);
}
}
void selector_t::set_secondary_selection(blt::i64 n)
{
secondary_selection = n;
}
void selector_t::set_primary_selection(blt::i64 n)
{
primary_selection = n;
}
void selector_t::set_drag_selection(blt::i64 n)
{
drag_selection = n;
}