Skip to content

Commit

Permalink
gui: fix input/output grid connection
Browse files Browse the repository at this point in the history
  • Loading branch information
quesnel committed Nov 7, 2024
1 parent 88620ba commit cbe1ff5
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 109 deletions.
196 changes: 91 additions & 105 deletions app/gui/grid/modeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ static void show_grid(application& app,
ImGui::InvisibleButton("Canvas",
canvas_sz,
ImGuiButtonFlags_MouseButtonLeft |
ImGuiButtonFlags_MouseButtonMiddle |
ImGuiButtonFlags_MouseButtonRight);

const bool is_hovered = ImGui::IsItemHovered();
Expand All @@ -380,7 +381,7 @@ static void show_grid(application& app,
io.MousePos.y - origin.y);

const float mouse_threshold_for_pan = -1.f;
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right,
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Middle,
mouse_threshold_for_pan)) {
ed.scrolling.x += io.MouseDelta.x;
ed.scrolling.y += io.MouseDelta.y;
Expand All @@ -393,108 +394,6 @@ static void show_grid(application& app,
ed.zoom[1] = ImClamp(ed.zoom[1], 0.1f, 10.f);
}

ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);

if (drag_delta.x == 0.0f && drag_delta.y == 0.0f and
ed.hovered_component == nullptr) {
ed.col =
static_cast<int>(ImFloor((io.MousePos.x - origin.x) / ed.zoom[0]));
ed.row =
static_cast<int>(ImFloor((io.MousePos.y - origin.y) / ed.zoom[1]));

if (0 <= ed.row and ed.row < data.row and 0 <= ed.col and
ed.col < data.column) {
ed.hovered_component = app.mod.components.try_to_get(
data.children[data.pos(ed.row, ed.col)]);
}
}

if (ImGui::BeginPopupContextItem("Canvas-Context")) {
auto deselect = false;

if (ImGui::BeginMenu("Menu##compo")) {
if (ImGui::BeginMenu("Connect to grid input port")) {
if (ed.hovered_component) {
ed.hovered_component->x.for_each<port_str>(
[&](const auto s_id, const auto& s_name) noexcept {
ImGui::PushID(ordinal(s_id));

compo.x.for_each<port_str>(
[&](auto id, auto& name) noexcept {
ImGui::PushID(ordinal(id));
small_string<128> str;

format(str,
"grid port {} to {}",
name.sv(),
s_name.sv());

if (ImGui::MenuItem(str.c_str())) {
auto ret = data.connect_input(
s_id, ed.row, ed.col, id);
if (!ret) {
auto& n = app.notifications.alloc();
n.title = "Fail to connect input";
app.notifications.enable(n);
}
deselect = true;
}
ImGui::PopID();
});

ImGui::PopID();
});
}
ImGui::EndMenu();
}

if (ImGui::BeginMenu("Connect to grid output port")) {
if (ed.hovered_component) {
ed.hovered_component->y.for_each<port_str>(
[&](const auto s_id, const auto& s_name) noexcept {
ImGui::PushID(ordinal(s_id));

compo.y.for_each<port_str>(
[&](const auto id, const auto& name) noexcept {
ImGui::PushID(ordinal(id));
small_string<128> str;

format(str,
"{} to grid port {}",
s_name.sv(),
name.sv());

if (ImGui::MenuItem(str.c_str())) {
auto ret = data.connect_output(
s_id, ed.row, ed.col, id);
if (!ret) {
auto& n = app.notifications.alloc();
n.title = "Fail to connect output";
app.notifications.enable(n);
}
deselect = true;
}
ImGui::PopID();
});

ImGui::PopID();
});
}

ImGui::EndMenu();
}

if (deselect)
ed.hovered_component = nullptr;
ImGui::EndMenu();
}

ImGui::EndPopup();
}

ImGui::OpenPopupOnItemClick("Canvas-Context",
ImGuiPopupFlags_MouseButtonRight);

draw_list->PushClipRect(canvas_p0, canvas_p1, true);
const float GRID_STEP = 64.0f;

Expand All @@ -513,8 +412,8 @@ static void show_grid(application& app,
for (int row = 0; row < data.row; ++row) {
for (int col = 0; col < data.column; ++col) {
ImVec2 p_min(
origin.x + (col * (ed.distance.x + ed.size.x) * ed.zoom[0]),
origin.y + (row * (ed.distance.y + ed.size.y) * ed.zoom[1]));
origin.x + (row * (ed.distance.x + ed.size.x) * ed.zoom[0]),
origin.y + (col * (ed.distance.y + ed.size.y) * ed.zoom[1]));

ImVec2 p_max(p_min.x + ed.zoom[0] * ed.size.x,
p_min.y + ed.zoom[1] * ed.size.y);
Expand All @@ -534,6 +433,93 @@ static void show_grid(application& app,
}

draw_list->PopClipRect();

if (ImGui::BeginPopupContextItem("Canvas-Context")) {
const auto click_pos = ImGui::GetMousePosOnOpeningCurrentPopup();
ed.row =
(click_pos.x - origin.x) / ((ed.distance.x + ed.size.x) * ed.zoom[0]);
ed.col =
(click_pos.y - origin.y) / ((ed.distance.y + ed.size.y) * ed.zoom[1]);

if (0 <= ed.row and ed.row < data.row and 0 <= ed.col and
ed.col < data.column)
ed.hovered_component = app.mod.components.try_to_get(
data.children[data.pos(ed.row, ed.col)]);

if (ed.hovered_component and ImGui::BeginMenu("Menu##compo")) {
if (ImGui::BeginMenu("Connect to grid input port")) {
compo.x.for_each<port_str>(
[&](const auto s_id, const auto& s_name) noexcept {
ImGui::PushID(ordinal(s_id));

ed.hovered_component->x.for_each<port_str>(
[&](auto id, auto& name) noexcept {
ImGui::PushID(ordinal(id));
small_string<128> str;

format(str,
"Connect X port {} grid input port {}",
s_name.sv(),
name.sv());

if (ImGui::MenuItem(str.c_str())) {
auto ret =
data.connect_input(s_id, ed.row, ed.col, id);
if (!ret) {
auto& n = app.notifications.alloc();
n.title = "Fail to connect input ";
app.notifications.enable(n);
}
ed.hovered_component = nullptr;
}
ImGui::PopID();
});

ImGui::PopID();
});
ImGui::EndMenu();
}

if (ImGui::BeginMenu("Connect from grid output port")) {
ed.hovered_component->y.for_each<port_str>(
[&](const auto s_id, const auto& s_name) noexcept {
ImGui::PushID(ordinal(s_id));

compo.y.for_each<port_str>(
[&](const auto id, const auto& name) noexcept {
ImGui::PushID(ordinal(id));
small_string<128> str;

format(str,
"{} to grid port {}",
s_name.sv(),
name.sv());

if (ImGui::MenuItem(str.c_str())) {
auto ret =
data.connect_output(s_id, ed.row, ed.col, id);
if (!ret) {
auto& n = app.notifications.alloc();
n.title = "Fail to connect output ";
app.notifications.enable(n);
}
}
ImGui::PopID();
});

ImGui::PopID();
});

ImGui::EndMenu();
}

ImGui::EndMenu();
}

ImGui::EndPopup();
} else {
ed.hovered_component = nullptr;
}
}

grid_component_editor_data::grid_component_editor_data(
Expand Down
32 changes: 28 additions & 4 deletions lib/src/modeling-grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,20 @@ result<input_connection_id> grid_component::connect_input(
const i32 col,
const port_id id) noexcept
{
if (exists_input_connection(x, row, col, id))
return new_error(input_connection_error{}, already_exist_error{});
for (const auto& con : input_connections)
if (x == con.x and row == con.row and col == con.col and id == con.id)
return input_connections.get_id(con);

if (not input_connections.can_alloc()) {
const auto capacity = input_connections.capacity();
const auto request = capacity == 0 ? 8 : capacity * 2;

input_connections.reserve(request);

if (input_connections.capacity() == capacity)
return new_error(input_connection_error{},
e_memory{ request, capacity });
}

return input_connections.get_id(input_connections.alloc(x, row, col, id));
}
Expand All @@ -386,8 +398,20 @@ result<output_connection_id> grid_component::connect_output(
const i32 col,
const port_id id) noexcept
{
if (exists_output_connection(y, row, col, id))
return new_error(input_connection_error{}, already_exist_error{});
for (const auto& con : output_connections)
if (y == con.y and row == con.row and col == con.col and id == con.id)
return output_connections.get_id(con);

if (not output_connections.can_alloc()) {
const auto capacity = output_connections.capacity();
const auto request = capacity == 0 ? 8 : capacity * 2;

output_connections.reserve(request);

if (output_connections.capacity() == capacity)
return new_error(input_connection_error{},
e_memory{ request, capacity });
}

return output_connections.get_id(output_connections.alloc(y, row, col, id));
}
Expand Down

0 comments on commit cbe1ff5

Please sign in to comment.