#ifndef XTC_GRAPH_WIDGET_HPP #define XTC_GRAPH_WIDGET_HPP #include #include #include "xtc/xtc_engine.h" class Fl_Box; /* GUI positions/selection only. Domain snapshots and edits stay in the C API. */ class GraphWidget : public Fl_Widget { public: using EditHandler = xtc_result (*)(void *, const xtc_graph_edit &, size_t *); GraphWidget(int x, int y, int width, int height, const xtc_graph *graph, EditHandler handler, void *context, Fl_Box *feedback); void reset_layout() { count_ = 0; selected_node_ = SIZE_MAX; edge_selected_ = dragging_ = wiring_ = false; } void set_graph(const xtc_graph *graph); const xtc_graph *graph() const { return graph_; } // Borrowed, GUI thread only. xtc_result add_node(xtc_node_type type); xtc_result connect_ports(const xtc_connection_info &connection); xtc_result delete_selected(); bool select_node(size_t id); bool select_connection(size_t source, size_t destination); bool move_node(size_t id, int left, int top); bool node_position(size_t id, int &left, int &top) const; int handle(int event) override; protected: void draw() override; private: struct Position { size_t id = SIZE_MAX; int left = 0, top = 0; }; std::array positions_{}; size_t count_ = 0U; const xtc_graph *graph_; EditHandler handler_; void *context_; Fl_Box *feedback_; size_t selected_node_ = SIZE_MAX; xtc_connection_info selected_edge_{}; bool edge_selected_ = false; bool dragging_ = false, wiring_ = false; size_t wire_node_ = SIZE_MAX, wire_port_ = 0U; int drag_x_ = 0, drag_y_ = 0, mouse_x_ = 0, mouse_y_ = 0; void feedback(xtc_result result, const char *success); bool hit_port(int left, int top, size_t &node, size_t &port) const; bool port_position(size_t id, size_t port, int &left, int &top) const; }; #endif