removing nodes causes problems!

main
Brett 2024-07-29 22:05:18 -04:00
parent 9516c479f2
commit b328c17a13
14 changed files with 174 additions and 31 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(graphs VERSION 0.1.6) project(graphs VERSION 0.1.7)
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

@ -30,7 +30,7 @@ namespace conf
inline constexpr float DEFAULT_INITIAL_TEMPERATURE = 100; inline constexpr float DEFAULT_INITIAL_TEMPERATURE = 100;
inline constexpr float POINT_SIZE = 35; inline constexpr float POINT_SIZE = 35;
inline constexpr auto DEFAULT_IMAGE = "parker_point"; inline constexpr auto DEFAULT_IMAGE = "unknown";
inline constexpr auto POINT_OUTLINE_COLOR = blt::make_color(0, 0.6, 0.6); inline constexpr auto POINT_OUTLINE_COLOR = blt::make_color(0, 0.6, 0.6);
inline constexpr auto POINT_HIGHLIGHT_COLOR = blt::make_color(0, 1.0, 1.0); inline constexpr auto POINT_HIGHLIGHT_COLOR = blt::make_color(0, 1.0, 1.0);
inline constexpr auto POINT_SELECT_COLOR = blt::make_color(0, 0.9, 0.7); inline constexpr auto POINT_SELECT_COLOR = blt::make_color(0, 0.9, 0.7);

View File

@ -188,7 +188,7 @@ class engine_t
friend struct loader_t; friend struct loader_t;
private: private:
graph_t graph; graph_t graph;
selector_t selector; selector_t selector {graph};
void draw_gui(const blt::gfx::window_data& data); void draw_gui(const blt::gfx::window_data& data);
@ -205,10 +205,12 @@ 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); selector.process_mouse(data.width, data.height);
if (!io.WantCaptureKeyboard)
selector.process_keyboard(data.width, data.height);
graph.render(); graph.render();
selector.render(graph, data.width, data.height); selector.render(data.width, data.height);
} }
}; };

View File

@ -24,23 +24,36 @@
class selector_t class selector_t
{ {
public: public:
explicit selector_t(graph_t& graph): graph(graph)
{}
// called inside the info panel block, used for adding more information // called inside the info panel block, used for adding more information
void draw_gui(graph_t& graph, blt::i32 width, blt::i32 height); void draw_gui(blt::i32 width, blt::i32 height);
// called once per frame, for rendering animations // called once per frame, for rendering animations
void render(graph_t& graph, blt::i32 width, blt::i32 height); void render(blt::i32 width, blt::i32 height);
// called once per frame assuming imgui doesn't want the mouse // called once per frame assuming imgui doesn't want the mouse
void process_mouse(graph_t& graph, blt::i32 width, blt::i32 height); void process_mouse(blt::i32 width, blt::i32 height);
void process_keyboard(blt::i32 width, blt::i32 height);
private: private:
void set_primary_selection(blt::i64 n); void set_primary_selection(blt::i64 n);
void set_drag_selection(blt::i64 n); void set_drag_selection(blt::i64 n);
void set_secondary_selection(blt::i64 n); void set_secondary_selection(blt::i64 n);
void create_placement_node(const blt::vec2& pos);
void destroy_node(blt::i64 node);
private: private:
blt::i64 drag_selection = -1; blt::i64 drag_selection = -1;
blt::i64 primary_selection = -1; blt::i64 primary_selection = -1;
blt::i64 secondary_selection = -1; blt::i64 secondary_selection = -1;
bool edge = false; bool placement = false;
graph_t& graph;
}; };
#endif //GRAPHS_SELECTION_H #endif //GRAPHS_SELECTION_H

BIN
res/ben.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
res/braxton.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

BIN
res/ivy.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

BIN
res/jacob.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
res/me.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 KiB

BIN
res/no_image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
res/sayori.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -269,7 +269,7 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
} }
} }
} }
selector.draw_gui(graph, data.width, data.height); selector.draw_gui(data.width, data.height);
im::End(); im::End();
} }
} }

View File

@ -54,6 +54,13 @@ void init(const blt::gfx::window_data& data)
resources.enqueue("res/parker.png", "parker"); resources.enqueue("res/parker.png", "parker");
resources.enqueue("res/parkerpoint.png", "parker_point"); resources.enqueue("res/parkerpoint.png", "parker_point");
resources.enqueue("res/parker cat ears.jpg", "parkercat"); resources.enqueue("res/parker cat ears.jpg", "parkercat");
resources.enqueue("res/ivy.jpg", "ivy");
resources.enqueue("res/sayori.jpg", "sayori");
resources.enqueue("res/jacob.jpg", "jacob");
resources.enqueue("res/braxton.jpg", "braxton");
resources.enqueue("res/ben.jpg", "ben");
resources.enqueue("res/no_image.jpg", "unknown");
resources.enqueue("res/me.png", "me");
if (auto loader = loader_t::load_for(engine, data, "default.json", "save.json")) if (auto loader = loader_t::load_for(engine, data, "default.json", "save.json"))
{ {
@ -76,7 +83,8 @@ void update(const blt::gfx::window_data& data)
engine.render(data); engine.render(data);
camera.update(); if (!im::GetIO().WantCaptureKeyboard)
camera.update();
camera.update_view(global_matrices); camera.update_view(global_matrices);
global_matrices.update(); global_matrices.update();

View File

@ -18,71 +18,191 @@
#include <selection.h> #include <selection.h>
#include <graph.h> #include <graph.h>
#include <blt/gfx/raycast.h> #include <blt/gfx/raycast.h>
#include <blt/std/memory.h>
extern blt::gfx::batch_renderer_2d renderer_2d; extern blt::gfx::batch_renderer_2d renderer_2d;
extern blt::gfx::matrix_state_manager global_matrices; extern blt::gfx::matrix_state_manager global_matrices;
void selector_t::render(graph_t& graph, blt::i32 width, blt::i32 height) blt::expanding_buffer<char> name_input;
blt::expanding_buffer<char> texture_input;
blt::expanding_buffer<char> description_input;
struct callback_data_t
{
std::string& str;
blt::expanding_buffer<char>& buffer;
};
void from_string(std::string& str, blt::expanding_buffer<char>& buf)
{
if (buf.size() <= str.size())
buf.resize(str.size() + 1);
std::memcpy(buf.data(), str.data(), str.size());
buf.data()[str.size()] = '\0';
}
int text_input_callback(ImGuiInputTextCallbackData* data)
{
auto [str, buffer] = *static_cast<callback_data_t*>(data->UserData);
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
{
buffer.resize(data->BufSize);
data->Buf = buffer.data();
} else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit || data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
str = std::string_view{data->Buf, static_cast<blt::size_t>(data->BufTextLen)};
return 0;
}
void selector_t::render(blt::i32 width, blt::i32 height)
{ {
} }
void selector_t::process_mouse(graph_t& graph, blt::i32 width, blt::i32 height) void selector_t::process_mouse(blt::i32 width, blt::i32 height)
{ {
const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(), const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(),
global_matrices.getOrtho())); global_matrices.getOrtho()));
bool mouse_pressed = blt::gfx::isMousePressed(0) && blt::gfx::mousePressedLastFrame(); bool mouse_pressed = blt::gfx::isMousePressed(0) && blt::gfx::mousePressedLastFrame();
for (const auto& [index, node] : blt::enumerate(graph.nodes)) if (placement)
{ {
const auto pos = node.getPosition(); if (mouse_pressed)
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)); placement = false;
if (primary_selection == drag_selection || secondary_selection == drag_selection) set_drag_selection(-1);
} else if (blt::gfx::isKeyPressed(GLFW_KEY_ESCAPE))
{
destroy_node(primary_selection);
}
} else
{
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)
{ {
edge = false; set_drag_selection(static_cast<blt::i64>(index));
if (blt::gfx::isKeyPressed(GLFW_KEY_LEFT_SHIFT))
set_secondary_selection(drag_selection);
else
{
set_primary_selection(drag_selection);
set_secondary_selection(-1);
}
break; 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 (blt::gfx::mouseReleaseLastFrame()) if (drag_selection >= 0 && drag_selection < static_cast<blt::i64>(graph.nodes.size()) && (blt::gfx::isMousePressed(0) || placement))
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; graph.nodes[drag_selection].getPositionRef() = mouse_pos;
} }
} }
void selector_t::draw_gui(graph_t& graph, blt::i32 width, blt::i32 height) void selector_t::process_keyboard(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()));
if (blt::gfx::keyPressedLastFrame())
{
if (blt::gfx::isKeyPressed(GLFW_KEY_C))
{
if (placement)
destroy_node(primary_selection);
else
create_placement_node(mouse_pos);
} else if (blt::gfx::isKeyPressed(GLFW_KEY_X))
{
if (primary_selection != -1)
destroy_node(primary_selection);
}
}
}
void selector_t::draw_gui(blt::i32 width, blt::i32 height)
{ {
im::SetNextItemOpen(true, ImGuiCond_Once); im::SetNextItemOpen(true, ImGuiCond_Once);
if (im::CollapsingHeader("Selection Information")) if (im::CollapsingHeader("Selection Information"))
{ {
im::Text("Silly (%ld) | (%ld || %ld)", drag_selection, primary_selection, secondary_selection); im::Text("Silly (%ld) | (%ld || %ld)", drag_selection, primary_selection, secondary_selection);
if (primary_selection >= 0)
{
if (secondary_selection >= 0)
{
} else
{
im::InputFloat("Size", &graph.nodes[primary_selection].point.scale);
callback_data_t name_data{graph.nodes[primary_selection].name, name_input};
callback_data_t texture_data{graph.nodes[primary_selection].texture, texture_input};
callback_data_t description_data{graph.nodes[primary_selection].description, description_input};
im::InputText("Name", name_input.data(), name_input.size(),
ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackCompletion,
text_input_callback, &name_data);
im::InputText("Texture", texture_input.data(), texture_input.size(),
ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackCompletion,
text_input_callback, &texture_data);
im::InputTextMultiline("Description", description_input.data(), description_input.size(), {},
ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackCompletion,
text_input_callback, &description_data);
}
}
} }
} }
void selector_t::set_secondary_selection(blt::i64 n) void selector_t::set_secondary_selection(blt::i64 n)
{ {
secondary_selection = n; secondary_selection = n;
} }
void selector_t::set_primary_selection(blt::i64 n) void selector_t::set_primary_selection(blt::i64 n)
{ {
primary_selection = n; primary_selection = n;
if (primary_selection >= 0)
{
from_string(graph.nodes[primary_selection].name, name_input);
from_string(graph.nodes[primary_selection].texture, texture_input);
from_string(graph.nodes[primary_selection].description, description_input);
}
} }
void selector_t::set_drag_selection(blt::i64 n) void selector_t::set_drag_selection(blt::i64 n)
{ {
drag_selection = n; drag_selection = n;
} }
void selector_t::create_placement_node(const blt::vec2& pos)
{
auto node = static_cast<blt::i64>(graph.nodes.size());
graph.nodes.push_back(node_t{{pos, conf::POINT_SIZE}});
set_drag_selection(node);
set_primary_selection(node);
placement = true;
}
void selector_t::destroy_node(blt::i64 node)
{
auto& node_v = graph.nodes[node];
graph.names_to_node.erase(node_v.name);
erase_if(graph.edges, [node](const edge_t& v) {
return static_cast<blt::i64>(v.getFirst()) == node || static_cast<blt::i64>(v.getSecond()) == node;
});
graph.connected_nodes.erase(node);
for (auto& v : graph.connected_nodes)
{
v.second.erase(node);
}
graph.nodes.erase(graph.nodes.begin() + node);
set_drag_selection(-1);
set_primary_selection(-1);
placement = false;
}