115 lines
3.4 KiB
C++
115 lines
3.4 KiB
C++
#ifndef NODE_EDITOR_HPP
|
||
#define NODE_EDITOR_HPP
|
||
|
||
#include <vector>
|
||
#include <string>
|
||
#include <functional>
|
||
#include "imgui.h"
|
||
|
||
namespace NodeEditor {
|
||
|
||
// Типы портов
|
||
enum class PortType { Input, Output };
|
||
enum class NodeType { Input, Hidden, Output };
|
||
|
||
// Порт узла
|
||
struct Port {
|
||
std::string name;
|
||
PortType type;
|
||
int index; // Индекс для множественных портов
|
||
bool isBranchPort; // true если это порт для выбора ветки (0/1)
|
||
|
||
Port(const std::string& n, PortType t, int idx = 0, bool branch = false)
|
||
: name(n), type(t), index(idx), isBranchPort(branch) {}
|
||
};
|
||
|
||
// Узел графа
|
||
struct Node {
|
||
int id;
|
||
std::string title;
|
||
NodeType type;
|
||
ImVec2 pos;
|
||
ImVec2 size;
|
||
bool selected;
|
||
bool dragging;
|
||
ImVec2 dragOffset;
|
||
|
||
// Данные слоя
|
||
int layerSize;
|
||
int layerIndex; // Индекс в ui.layerConfigs
|
||
std::vector<int> connectedInputs; // IDs узлов, подключенных к входам
|
||
std::vector<int> connectedOutputs; // IDs узлов, подключенных к выходам
|
||
|
||
// Порты
|
||
std::vector<Port> inputs;
|
||
std::vector<Port> outputs;
|
||
|
||
// Для ветвления
|
||
int branch; // -1, 0, 1
|
||
bool isSplit; // Разделяет ли выход на две ветки
|
||
|
||
Node(int id_, const std::string& title_, NodeType type_)
|
||
: id(id_), title(title_), type(type_), pos(0,0), size(200,100),
|
||
selected(false), dragging(false), layerSize(128), layerIndex(-1),
|
||
branch(-1), isSplit(false) {}
|
||
|
||
ImVec2 GetInputPos(int portIdx) const;
|
||
ImVec2 GetOutputPos(int portIdx) const;
|
||
};
|
||
|
||
// Соединение между портами
|
||
struct Connection {
|
||
int fromNode;
|
||
int fromPort;
|
||
int toNode;
|
||
int toPort;
|
||
|
||
Connection(int fn, int fp, int tn, int tp)
|
||
: fromNode(fn), fromPort(fp), toNode(tn), toPort(tp) {}
|
||
};
|
||
|
||
// Состояние редактора
|
||
struct GraphState {
|
||
std::vector<Node> nodes;
|
||
std::vector<Connection> connections;
|
||
|
||
int nextNodeId = 0;
|
||
int selectedNode = -1;
|
||
int hoveredPortNode = -1;
|
||
int hoveredPortIdx = -1;
|
||
PortType hoveredPortType = PortType::Input;
|
||
|
||
// Для создания соединения
|
||
bool creatingConnection = false;
|
||
int connectionStartNode = -1;
|
||
int connectionStartPort = -1;
|
||
PortType connectionStartType = PortType::Output;
|
||
ImVec2 connectionMousePos;
|
||
|
||
// Масштаб и панорамирование
|
||
float zoom = 1.0f;
|
||
ImVec2 panOffset;
|
||
bool panning;
|
||
ImVec2 panStart;
|
||
|
||
GraphState() : panning(false) {}
|
||
};
|
||
|
||
// === API ===
|
||
|
||
void Init(GraphState& graph);
|
||
void DrawGraph(GraphState& graph, const ImVec2& canvasSize);
|
||
void HandleInput(GraphState& graph, const ImVec2& canvasPos);
|
||
|
||
// Синхронизация с LayerStructure_t
|
||
void SyncToLayerConfigs(GraphState& graph, std::vector<LayerStructure_t>& configs);
|
||
void SyncFromLayerConfigs(GraphState& graph, const std::vector<LayerStructure_t>& configs);
|
||
|
||
// Вспомогательные функции
|
||
ImVec2 GetPortPos(const Node& node, const Port& port, const ImVec2& canvasOffset);
|
||
void DrawBezier(ImDrawList* dl, ImVec2 start, ImVec2 end, ImU32 color, float thickness = 2.0f);
|
||
ImU32 GetNodeColor(NodeType type, bool selected);
|
||
|
||
} // namespace NodeEditor
|
||
|
||
#endif // NODE_EDITOR_HPP
|