Annwan
3 months ago
9 changed files with 411 additions and 129 deletions
-
2.clang-format
-
4.gitignore
-
33CMakeLists.txt
-
163src/Application.cppm
-
52src/Base.cppm
-
32src/Button.cppm
-
46src/Node.cppm
-
136src/Port.cppm
-
14src/main.cpp
@ -1,5 +1,5 @@ |
|||
build/* |
|||
/ffmpegraph |
|||
/.idea |
|||
/cmake-build-debug |
|||
/cmake-build-release |
|||
/out |
|||
/release |
@ -0,0 +1,32 @@ |
|||
module; |
|||
#include <string> |
|||
#include <raylib.h> |
|||
export module Button; |
|||
import Base; |
|||
|
|||
export namespace ffmpegraph { |
|||
struct Button { |
|||
i32 pos_x, pos_y; |
|||
i32 width, height; |
|||
std::string label; |
|||
void Render() const; |
|||
bool IsHovered() const; |
|||
Button(i32 x, i32 y, i32 w, i32 h, std::string label): pos_x(x), pos_y(y), width(w), height(h), label(std::move(label)) {} |
|||
}; |
|||
} |
|||
|
|||
module: private; |
|||
namespace ffmpegraph { |
|||
void Button::Render() const { |
|||
auto color = IsHovered()? LIGHTGRAY : WHITE; |
|||
DrawRectangle(pos_x, pos_y, width, height, color); |
|||
DrawRectangleLines(pos_x, pos_y, width, height, BLACK); |
|||
DrawText(label.c_str(), pos_x + 5, pos_y + 5, 10, BLACK); |
|||
} |
|||
|
|||
bool Button::IsHovered() const { |
|||
return pos_x <= GetMouseX() and GetMouseX() <= pos_x + width |
|||
and pos_y <= GetMouseY() and GetMouseY() <= pos_y + height; |
|||
} |
|||
|
|||
} |
@ -1,87 +1,141 @@ |
|||
module; |
|||
#include <optional> |
|||
#include <string> |
|||
#include <format> |
|||
#include <limits> |
|||
#include <raylib.h> |
|||
export module Port; |
|||
#include <string> |
|||
#include <variant> |
|||
export module Node:Port; |
|||
import Base; |
|||
|
|||
using namespace std::literals; |
|||
export namespace ffmpegraph { |
|||
|
|||
struct Node; |
|||
|
|||
enum struct PortType { |
|||
INT, |
|||
STRING, |
|||
}; |
|||
|
|||
constexpr i32 min_port_width = 100; |
|||
using PortData = std::variant<i32, std::string, std::monostate>; |
|||
} |
|||
|
|||
template <> struct std::formatter<ffmpegraph::PortData> : std::formatter<std::string> { |
|||
template <class FormatContext> auto format(ffmpegraph::PortData const& data, FormatContext& ctx) const { |
|||
auto repr = std::visit( |
|||
utils::Overloaded{ |
|||
[](std::monostate) { return "()"s; }, |
|||
[](std::string const& x) { return x; }, |
|||
[](i32 x) { return std::to_string(x); }, |
|||
}, |
|||
data |
|||
); |
|||
return formatter<std::string>::format(repr, ctx); |
|||
} |
|||
}; |
|||
|
|||
export namespace ffmpegraph { |
|||
struct Port { |
|||
protected: |
|||
std::string name; |
|||
explicit Port(std::string name): name(std::move(name)) {} |
|||
explicit Port(std::string name, Node* owner) : name(std::move(name)), owner(owner) {} |
|||
virtual ~Port() = default; |
|||
public: |
|||
i32 pos_x{}, pos_y{}; |
|||
virtual void Render(i32 x, i32 y) = 0; |
|||
Node* owner; |
|||
// Returns the desired width for the port. |
|||
virtual i32 Render(i32 x, i32 y, i32 width) = 0; |
|||
}; |
|||
|
|||
struct OutputPort; |
|||
|
|||
struct InputPort : Port { |
|||
protected: |
|||
std::optional<int> value = std::nullopt; |
|||
PortType type; |
|||
PortData value = std::monostate{}; |
|||
public: |
|||
explicit InputPort(std::string name): Port(std::move(name)) {} |
|||
std::optional<int> GetValue(); |
|||
void Render(i32 x, i32 y) override; |
|||
InputPort(std::string name, Node* owner, PortType type) : Port(std::move(name), owner), type(type) {} |
|||
PortData const& GetValue() const; |
|||
i32 Render(i32 x, i32 y, i32 width) override; |
|||
|
|||
friend OutputPort; |
|||
}; |
|||
struct OutputPort : Port { |
|||
protected: |
|||
PortType type; |
|||
InputPort* connected = nullptr; |
|||
public: |
|||
explicit OutputPort(std::string name): Port(std::move(name)) {} |
|||
void SetValue(std::optional<int>); |
|||
void Connect(InputPort& ip); |
|||
OutputPort(std::string name, Node* owner, PortType type) : Port(std::move(name), owner), type(type) {} |
|||
void SetValue(PortData value); |
|||
bool TryConnect(InputPort& ip); |
|||
InputPort* GetConnected() const { return connected; } |
|||
void Disconnect(); |
|||
void Render(i32 x, i32 y) override; |
|||
i32 Render(i32 x, i32 y, i32 width) override; |
|||
}; |
|||
|
|||
struct Label : Port { |
|||
void Render(i32 x, i32 y) override; |
|||
explicit Label(std::string name): Port(std::move(name)) { |
|||
pos_x = -1; |
|||
pos_y = -1; |
|||
i32 Render(i32 x, i32 y, i32 width) override; |
|||
explicit Label(std::string name, Node* owner) : Port(std::move(name), owner) { |
|||
pos_x = pos_y = std::numeric_limits<i32>::min(); |
|||
} |
|||
}; |
|||
|
|||
std::optional<int> InputPort::GetValue(){ |
|||
return value; |
|||
} |
|||
void OutputPort::SetValue(std::optional<int> val){ |
|||
if (connected) { |
|||
connected->value = val; |
|||
struct StringUserInput : Port { |
|||
explicit StringUserInput(std::string name, Node* owner) : Port(std::move(name), owner), data("") { |
|||
pos_x = pos_y = std::numeric_limits<i32>::min(); |
|||
} |
|||
i32 Render(i32 x, i32 y, i32 width) override; |
|||
std::string data; |
|||
}; |
|||
|
|||
PortData const& InputPort::GetValue() const { return value; } |
|||
|
|||
void OutputPort::SetValue(PortData value) { |
|||
if (connected) { connected->value = std::move(value); } |
|||
} |
|||
void OutputPort::Connect(InputPort& ip){ |
|||
bool OutputPort::TryConnect(InputPort& ip) { |
|||
if (ip.type == type) { |
|||
connected = &ip; |
|||
return true; |
|||
} |
|||
|
|||
void OutputPort::Disconnect(){ |
|||
connected = nullptr; |
|||
return false; |
|||
} |
|||
|
|||
void OutputPort::Render(i32 x, i32 y) { |
|||
pos_x = x+100; pos_y = y+10; |
|||
DrawRectangleLines(x, y, 100, 20, BLACK); |
|||
void OutputPort::Disconnect() { connected = nullptr; } |
|||
|
|||
i32 OutputPort::Render(i32 x, i32 y, i32 width) { |
|||
pos_x = x + width; |
|||
pos_y = y + 10; |
|||
DrawRectangleLines(x, y, width, 20, BLACK); |
|||
DrawText(name.c_str(), x + 5, y + 5, 10, RED); |
|||
DrawCircle(x+100, y+10, 2.5f, BLACK); |
|||
if (connected) { |
|||
DrawLine(pos_x, pos_y, connected->pos_x, connected->pos_y, BLUE); |
|||
DrawCircle(x + width, y + 10, 2.5f, BLACK); |
|||
if (connected) { DrawLine(pos_x, pos_y, connected->pos_x, connected->pos_y, BLUE); } |
|||
return 10 + MeasureText(name.c_str(), 10); |
|||
} |
|||
} |
|||
void InputPort::Render(i32 x, i32 y) { |
|||
pos_x = x; pos_y = y+10; |
|||
DrawRectangleLines(x, y, 100, 20, BLACK); |
|||
DrawText(name.c_str(), x + 5, y + 5, 10, BLUE); |
|||
i32 InputPort::Render(i32 x, i32 y, i32 width) { |
|||
pos_x = x; |
|||
pos_y = y + 10; |
|||
auto formatted = std::format("{}: {}", name, value); |
|||
auto new_width = 10 + MeasureText(formatted.c_str(), 10); |
|||
DrawRectangleLines(x, y, width, 20, BLACK); |
|||
DrawText(formatted.c_str(), x + 5, y + 5, 10, BLUE); |
|||
DrawCircle(x, y + 10, 2.5f, BLACK); |
|||
return new_width; |
|||
} |
|||
void Label::Render(i32 x, i32 y){ |
|||
DrawRectangleLines(x, y, 100, 20, BLACK); |
|||
i32 Label::Render(i32 x, i32 y, i32 width) { |
|||
DrawRectangleLines(x, y, width, 20, BLACK); |
|||
DrawText(name.c_str(), x + 5, y + 5, 10, BLACK); |
|||
return 10 + MeasureText(name.c_str(), 10); |
|||
} |
|||
|
|||
i32 StringUserInput::Render(i32 x, i32 y, i32 width) { |
|||
DrawRectangleLines(x, y, width, 20, BLACK); |
|||
if (data.empty()) { |
|||
DrawText(name.c_str(), x + 5, y + 5, 10, GRAY); |
|||
return 10 + MeasureText(name.c_str(), 10); |
|||
} else { |
|||
DrawText(data.c_str(), x + 5, y + 5, 10, BLACK); |
|||
return 10 + MeasureText(data.c_str(), 10); |
|||
} |
|||
} |
|||
} // namespace ffmpegraph |
@ -1,8 +1,20 @@ |
|||
#include <clopts.hh>
|
|||
#include <print>
|
|||
import Base; |
|||
import Application; |
|||
using namespace ffmpegraph; |
|||
|
|||
int main() { |
|||
namespace detail { |
|||
using namespace command_line_options; |
|||
using options = clopts< |
|||
help<>, |
|||
option<"--ffmpeg-path", "Path to ffmpeg, default is `ffmpeg'">, |
|||
positional<"savefile", "Savefile to load", file<>, false> |
|||
>; |
|||
} |
|||
|
|||
int main(int argc, char *argv[]) { |
|||
auto opts = detail::options::parse(argc, argv); |
|||
Application app("FFMpeGraph"); |
|||
app.Run(); |
|||
return 0; |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue