1 Commits

Author SHA1 Message Date
Sebastian 9e284be109 wip rework of interaction event system - broken right now 2026-07-19 02:39:19 +02:00
8 changed files with 101 additions and 36 deletions
+5 -3
View File
@@ -2,6 +2,7 @@
#include "datatypes.h" #include "datatypes.h"
//#include "interaction-event.h" //#include "interaction-event.h"
#include "interaction-event.h"
#include "state.h" #include "state.h"
#include "draggable.h" #include "draggable.h"
#include "raylib.h" #include "raylib.h"
@@ -21,14 +22,14 @@ namespace VISEQ::APP::CANVAS {
} }
void Canvas::pickUp() { void Canvas::pickUp() {
//std::cout << "canvas pickUp" << std::endl; std::cout << "canvas pickUp" << std::endl;
BASE::Draggable::pickUp(); BASE::Draggable::pickUp();
select_start = SCREEN_MOUSE; select_start = SCREEN_MOUSE;
state->pushEvent({getPtr(), Interaction::DESELECT}); state->pushEvent({getPtr(), Interaction::DESELECT});
} }
void Canvas::putDown() { void Canvas::putDown() {
//std::cout << "canvas putDown" << std::endl; std::cout << "canvas putDown" << std::endl;
BASE::Draggable::putDown(); BASE::Draggable::putDown();
state->pushEvent({getPtr(), Interaction::SELECT}); state->pushEvent({getPtr(), Interaction::SELECT});
} }
@@ -59,8 +60,9 @@ namespace VISEQ::APP::CANVAS {
if(state->mouse_right.down) { if(state->mouse_right.down) {
camera.target = Vector2Add(camera.target, camera_delta); camera.target = Vector2Add(camera.target, camera_delta);
} }
if(clicked()) state->pushEvent({getPtr(), APP::Interaction::DESELECT});
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP}); if(hovering() && held() && !pickedUp()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG}); if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN}); if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
+1 -1
View File
@@ -38,7 +38,7 @@ namespace VISEQ::GRAPH {
void Connector::update() { void Connector::update() {
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER}); if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP}); if(hovering() && held() && !pickedUp()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG}); if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN}); if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
if(connected) { if(connected) {
+16
View File
@@ -9,12 +9,28 @@ namespace VISEQ::BASE {
return is_hovering && !hovering(); return is_hovering && !hovering();
} }
bool Draggable::clicked() {
if(hovering() && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)){
last_tp = std::chrono::high_resolution_clock::now();
}
std::chrono::duration<double, std::micro> diff = std::chrono::high_resolution_clock::now() - last_tp;
if(released() && diff.count() < 100000){
std::cout << "draggable clicked" << std::endl;
return true;
}
return false;
}
bool Draggable::pickedUp() { bool Draggable::pickedUp() {
return held() && picked_up; return held() && picked_up;
} }
void Draggable::pickUp() { void Draggable::pickUp() {
std::chrono::duration<double, std::micro> diff = std::chrono::high_resolution_clock::now() - last_tp;
if(held() && diff.count() > 100000){
std::cout << "draggable pickedUp" << std::endl;
picked_up = true; picked_up = true;
}
drag_offset = position - SCREEN_MOUSE; drag_offset = position - SCREEN_MOUSE;
} }
+4
View File
@@ -4,6 +4,7 @@
#include "selectable.h" #include "selectable.h"
#include "state.h" #include "state.h"
#include "vmath.h" #include "vmath.h"
#include <chrono>
namespace VISEQ::BASE { namespace VISEQ::BASE {
class Draggable : public Movable, public Selectable{ class Draggable : public Movable, public Selectable{
@@ -19,8 +20,11 @@ namespace VISEQ::BASE {
bool picked_up = false; bool picked_up = false;
std::chrono::time_point<std::chrono::high_resolution_clock> last_tp;
virtual bool entered() override; virtual bool entered() override;
virtual bool exited() override; virtual bool exited() override;
virtual bool clicked() override;
virtual bool pickedUp(); virtual bool pickedUp();
virtual void pickUp() override; virtual void pickUp() override;
virtual void pickUp(Vec2Df selection_origin) override; virtual void pickUp(Vec2Df selection_origin) override;
+3 -2
View File
@@ -90,6 +90,7 @@ namespace VISEQ::GRAPH{
if(!KEYS_DOWN.shift) selected_nodes.clear(); if(!KEYS_DOWN.shift) selected_nodes.clear();
selected_nodes.insert(selected_nodes.end(), temp_nodes.begin(), temp_nodes.end()); selected_nodes.insert(selected_nodes.end(), temp_nodes.begin(), temp_nodes.end());
std::for_each(selected_nodes.begin(), selected_nodes.end(), [](WPTR_Node n){n.lock()->selected = true;}); std::for_each(selected_nodes.begin(), selected_nodes.end(), [](WPTR_Node n){n.lock()->selected = true;});
std::cout << "selected " << selected_nodes.size() << " nodes" << std::endl;
} }
void GraphManager::deselect(){ void GraphManager::deselect(){
@@ -382,8 +383,8 @@ namespace VISEQ::GRAPH{
// Dynamic opacity by distance to mouse // Dynamic opacity by distance to mouse
unsigned char opacity = 150.0f - Clamp(center_handle.dist(mouse_pos), 0.0f, 130.0f); unsigned char opacity = 150.0f - Clamp(center_handle.dist(mouse_pos), 0.0f, 130.0f);
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f); //unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f); //unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
float opacity_normalized = Clamp((float)opacity / 255.0f, .0f, 1.0f); float opacity_normalized = Clamp((float)opacity / 255.0f, .0f, 1.0f);
//float opacity_from_normalized = Clamp((float)opacity_from / 255.0f, .0f, 1.0f); //float opacity_from_normalized = Clamp((float)opacity_from / 255.0f, .0f, 1.0f);
+54 -20
View File
@@ -2,11 +2,14 @@
#include "connector.h" #include "connector.h"
#include "datatypes.h" #include "datatypes.h"
#include "interaction-event.h"
#include "node.h" #include "node.h"
#include "raylib.h" #include "raylib.h"
#include "state.h" #include "state.h"
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#include <ostream>
#include <ranges>
namespace VISEQ::INTERACTION{ namespace VISEQ::INTERACTION{
@@ -33,7 +36,7 @@ namespace VISEQ::INTERACTION{
gm->cycleModeOfSelectedNodes(false); gm->cycleModeOfSelectedNodes(false);
} }
if(IsKeyPressed(KEY_V)){ if(!KEYS_DOWN.ctrl && IsKeyPressed(KEY_V)){
state->draw_edge_lengths = !state->draw_edge_lengths; state->draw_edge_lengths = !state->draw_edge_lengths;
} }
} }
@@ -41,7 +44,7 @@ namespace VISEQ::INTERACTION{
void InteractionManager::draw(){ void InteractionManager::draw(){
doInteraction(); doInteraction();
scaleSelection(); scaleSelection();
if(!gm->getSelection().empty()){ if(gm->getSelection().size() > 1){
DrawRectangleRoundedLines(state->bounding_box, 0.1f, 3, VS_COLOR_LIGHTGREY); DrawRectangleRoundedLines(state->bounding_box, 0.1f, 3, VS_COLOR_LIGHTGREY);
scale_handle->draw(); scale_handle->draw();
} }
@@ -133,16 +136,37 @@ namespace VISEQ::INTERACTION{
bool exit = false; bool exit = false;
bool once = false; bool once = false;
bool connect_once = false; bool connect_once = false;
bool blocking = false;
//std::cout << state->mouse_z << std::endl;
state->mouse_z = canvas->z_index; state->mouse_z = canvas->z_index;
for(auto e : state->event_queue){ //auto sorted_queue = state->event_queue
auto nodes_queue = state->event_queue | RANGE_FILTER([](APP::InteractionEvent e) { return e.item->getType() == GraphItemType::NODE; }) | std::ranges::to<std::deque<APP::InteractionEvent>>();
auto connector_queue = state->event_queue | RANGE_FILTER([](APP::InteractionEvent e) { return e.item->getType() == GraphItemType::CONNECTOR; }) | std::ranges::to<std::deque<APP::InteractionEvent>>();
auto canvas_queue = state->event_queue | RANGE_FILTER([](APP::InteractionEvent e) { return e.item->getType() == GraphItemType::CANVAS; }) | std::ranges::to<std::deque<APP::InteractionEvent>>();
std::sort(nodes_queue.begin(), nodes_queue.end(), [](APP::InteractionEvent a, APP::InteractionEvent b){return a.item->z_index > b.item->z_index;});
std::deque<APP::InteractionEvent> state_queue;
state_queue.append_range(nodes_queue);
state_queue.append_range(connector_queue);
state_queue.append_range(canvas_queue);
state->event_queue.clear();
std::cout << state_queue.size() << std::endl;
for(auto e : state_queue){
if(!connect_once && e.action == APP::Interaction::CONNECT){ if(!connect_once && e.action == APP::Interaction::CONNECT){
blocking = true;
APP::InteractionEvent partner; APP::InteractionEvent partner;
bool found = false; bool found = false;
for(auto ei : state->event_queue){ for(auto ei : state->event_queue){
if(ei.action == APP::Interaction::HOVER && ei.item->getType() == GraphItemType::CONNECTOR) { if(ei.action == APP::Interaction::HOVER && ei.item->getType() == GraphItemType::CONNECTOR) {
std::cout << "YEAH" << std::endl; //std::cout << "YEAH" << std::endl;
partner = ei; partner = ei;
found = true; found = true;
break; break;
@@ -166,12 +190,16 @@ namespace VISEQ::INTERACTION{
connect_once = true; connect_once = true;
break; break;
} }
if(e.item->getType() == GraphItemType::NODE){
if(e.action == APP::Interaction::DRAG) blocking = true;
}
} }
while(state->event_queue.size() > 0 && !exit){ while(state_queue.size() > 0 && !exit){
auto e = state->event_queue.front(); auto e = state_queue.front();
if(e.action == APP::Interaction::CLICK){ if(e.action == APP::Interaction::CLICK){
gm->addToSelection(); gm->addToSelection();
std::cout << "click" << std::endl;
} }
if(e.action == APP::Interaction::RIGHTCLICK){ if(e.action == APP::Interaction::RIGHTCLICK){
gm->addToSelection(); gm->addToSelection();
@@ -183,19 +211,10 @@ namespace VISEQ::INTERACTION{
state->mouse_z = e.item->z_index; state->mouse_z = e.item->z_index;
} }
if(e.item->getType() == GraphItemType::CANVAS) {
if(e.action == APP::Interaction::SELECT) {
gm->select();
canvas->clearSelectionRect();
}
if(e.action == APP::Interaction::DESELECT) {
gm->deselect();
}
}
if(!once && e.item->getType() == GraphItemType::NODE){ if(!once && e.item->getType() == GraphItemType::NODE){
auto node = std::dynamic_pointer_cast<Node>(e.item); auto node = std::dynamic_pointer_cast<Node>(e.item);
if(e.action == APP::Interaction::PICKUP) { if(!blocking && e.action == APP::Interaction::PICKUP) {
std::cout << "node pickup" << std::endl;
node->pickUp(); node->pickUp();
if(node->selected){ if(node->selected){
for(auto s : gm->getSelection()){ for(auto s : gm->getSelection()){
@@ -205,6 +224,8 @@ namespace VISEQ::INTERACTION{
once = true; once = true;
} }
if(e.action == APP::Interaction::DRAG) { if(e.action == APP::Interaction::DRAG) {
blocking = true;
std::cout << "node drag" << std::endl;
if(KEYS_DOWN.ctrl) node->drag(MOD_MOUSE); if(KEYS_DOWN.ctrl) node->drag(MOD_MOUSE);
else if(KEYS_DOWN.shift) { else if(KEYS_DOWN.shift) {
snapPolar(node); snapPolar(node);
@@ -216,9 +237,9 @@ namespace VISEQ::INTERACTION{
s->drag(MOD_MOUSE + s->drag_offset); s->drag(MOD_MOUSE + s->drag_offset);
} }
} }
once = true;
} }
if(e.action == APP::Interaction::PUTDOWN) { if(e.action == APP::Interaction::PUTDOWN) {
std::cout << "node putdown" << std::endl;
node->putDown(); node->putDown();
if(node->selected){ if(node->selected){
for(auto s : gm->getSelection()){ for(auto s : gm->getSelection()){
@@ -227,6 +248,19 @@ namespace VISEQ::INTERACTION{
} }
} }
} }
if(!blocking && !once && e.item->getType() == GraphItemType::CANVAS) {
if(e.action == APP::Interaction::SELECT) {
std::cout << "canvas select" << std::endl;
gm->select();
canvas->clearSelectionRect();
}
if(e.action == APP::Interaction::DESELECT) {
std::cout << "canvas deselect" << std::endl;
gm->deselect();
}
}
if(exit) break; if(exit) break;
if(!once && (e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS || e.item->getType() == GraphItemType::HANDLE)) { if(!once && (e.item->getType() == GraphItemType::CONNECTOR || e.item->getType() == GraphItemType::CANVAS || e.item->getType() == GraphItemType::HANDLE)) {
@@ -253,8 +287,8 @@ namespace VISEQ::INTERACTION{
} }
} }
state->event_queue.pop_front(); state_queue.pop_front();
} }
state->event_queue.clear(); state_queue.clear();
} }
} }
+1 -1
View File
@@ -34,7 +34,7 @@ namespace VISEQ::INTERACTION{
virtual void update() override { virtual void update() override {
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER}); if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP}); if(hovering() && held() && !pickedUp()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG}); if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN}); if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
} }
+9 -1
View File
@@ -5,6 +5,7 @@
#include "connector.h" #include "connector.h"
#include "datatypes.h" #include "datatypes.h"
#include "interaction-event.h"
#include "state.h" #include "state.h"
#include "vmath.h" #include "vmath.h"
@@ -47,9 +48,16 @@ namespace VISEQ::GRAPH::NODES {
void Node::update() { void Node::update() {
if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER}); if(hovering()) state->pushEvent({getPtr(), APP::Interaction::HOVER});
if(hovering() && clicked()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(clicked()) {
selected = true;
state->pushEvent({getPtr(), APP::Interaction::CLICK});
}
if(hovering() && held() && !pickedUp()) state->pushEvent({getPtr(), APP::Interaction::PICKUP});
if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG}); if(pickedUp()) state->pushEvent({getPtr(), APP::Interaction::DRAG});
if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN}); if(picked_up && released()) state->pushEvent({getPtr(), APP::Interaction::PUTDOWN});
if(hovering() && MOUSE_RIGHT.clicked) { if(hovering() && MOUSE_RIGHT.clicked) {
selected = true; selected = true;
config = true; config = true;