diff --git a/Hardware/3rdparty/bugui b/Hardware/3rdparty/bugui index 08fcc66..9a0bded 160000 --- a/Hardware/3rdparty/bugui +++ b/Hardware/3rdparty/bugui @@ -1 +1 @@ -Subproject commit 08fcc660909bfb688156904cf520d150e3b426f6 +Subproject commit 9a0bded62d9632d05fac99988a8c53bb5e42b7a4 diff --git a/Hardware/Widgets/EventWidget.cpp b/Hardware/Widgets/EventWidget.cpp index 41e1eb6..4e5bee0 100644 --- a/Hardware/Widgets/EventWidget.cpp +++ b/Hardware/Widgets/EventWidget.cpp @@ -1,28 +1,56 @@ #include +#include "TimeSyncWidget.hpp" +#include "StateWidget.hpp" +#include "ScenarioWidget.hpp" #include "EventWidget.hpp" namespace Hardware { EventWidget::EventWidget(Scenario::EventModel& event, + ScenarioWidget* scenario, bugui::container_widget* parent) - : ScenarioComponentSpec{event, parent} - , bugui::container_widget{parent} -{ } - -int EventWidget::x() const + : ScenarioComponentSpec{event, scenario, parent} { - return model.date().sec(); + Scenario::ProcessModel* scen{scenario->get_model()}; + + scen->states.mutable_added.connect<&EventWidget::on_state_added>(this); + scen->states.removed.connect<&EventWidget::on_state_removed>(this); + + for(Scenario::StateModel& s : scen->states) + if (s.eventId() == model.id()) + add_widget(s, scenario); + + set_y_height(); + update(); } int EventWidget::y() const { - return 0; + return m_y; } int EventWidget::height() const { - return 1; + return m_height; +} + +void EventWidget::set_y_height() +{ + m_y = std::numeric_limits::max(); + m_height = std::numeric_limits::lowest(); + + for(const auto& s : children) + { + int sy = s->y(); + if (sy < m_y) m_y = sy; + + int sh = s->height(); + if (sh > m_height) m_height = sh; + } + + static_cast(parent)->set_y_height(); } void EventWidget::paint(bugui::painter& painter) const @@ -41,14 +69,30 @@ bool EventWidget::contains(int px, int py) const return false; } +void EventWidget::on_state_added(Scenario::StateModel& state) +{ + if (state.eventId() != model.id()) return; + + add_widget(state, scenario); + + set_y_height(); +} + +void EventWidget::on_state_removed(const Scenario::StateModel& state) +{ + if (state.eventId() != model.id()) + return; + + remove_widget([&state] + (const auto& w) + { return static_cast*>(w.get())->this_model(state); }); + + set_y_height(); +} + void EventWidget::on_press(int x, int y, bool pressed) { qDebug() << "is inside!"; } -const Scenario::EventModel& EventWidget::get_model() const -{ - return model; -} - } diff --git a/Hardware/Widgets/EventWidget.hpp b/Hardware/Widgets/EventWidget.hpp index ec6c9ff..b0c9902 100644 --- a/Hardware/Widgets/EventWidget.hpp +++ b/Hardware/Widgets/EventWidget.hpp @@ -5,24 +5,29 @@ namespace Hardware { -struct EventWidget final : virtual bugui::container_widget - , ScenarioComponentSpec - +struct EventWidget final : ScenarioComponentSpec { explicit EventWidget(Scenario::EventModel& event, + ScenarioWidget* scenario, bugui::container_widget* parent); void paint(bugui::painter& painter) const override; void on_press(int x, int y, bool pressed) override; - int x() const override; int y() const override; int height() const override; - const Scenario::EventModel& get_model() const; + void set_y_height(); protected: bool contains(int px, int py) const override; + + void on_state_added(Scenario::StateModel& state); + void on_state_removed(const Scenario::StateModel& state); + + int m_y; + int m_height; }; } //namespace Hardware diff --git a/Hardware/Widgets/IntervalWidget.cpp b/Hardware/Widgets/IntervalWidget.cpp index 94a453f..2c09950 100644 --- a/Hardware/Widgets/IntervalWidget.cpp +++ b/Hardware/Widgets/IntervalWidget.cpp @@ -1,12 +1,14 @@ #include #include "IntervalWidget.hpp" +#include "Hardware/Widgets/ScenarioWidget.hpp" namespace Hardware { IntervalWidget::IntervalWidget(Scenario::IntervalModel& interval, + ScenarioWidget* scenario, bugui::container_widget* parent) - : ScenarioComponentSpec{interval, parent} + : ScenarioComponentSpec{interval, scenario, parent} { } int IntervalWidget::x() const @@ -16,7 +18,7 @@ int IntervalWidget::x() const int IntervalWidget::y() const { - return model.heightPercentage() * parent->height(); + return model.heightPercentage() * scenario->height(); } int IntervalWidget::width() const @@ -55,13 +57,8 @@ void IntervalWidget::on_double_press(int x, int y) void IntervalWidget::on_drag(int from_x, int from_y, int to_x, int to_y) { - double increment{to_y / static_cast(parent->height())}; + double increment{to_y / static_cast(scenario->height())}; model.requestHeightChange(model.heightPercentage() + increment); } -const Scenario::IntervalModel& IntervalWidget::get_model() const -{ - return model; -} - } // namespace hardware diff --git a/Hardware/Widgets/IntervalWidget.hpp b/Hardware/Widgets/IntervalWidget.hpp index 6dcf36b..0a1ba6b 100644 --- a/Hardware/Widgets/IntervalWidget.hpp +++ b/Hardware/Widgets/IntervalWidget.hpp @@ -10,6 +10,7 @@ namespace Hardware struct IntervalWidget final : ScenarioComponentSpec { explicit IntervalWidget(Scenario::IntervalModel& interval, + ScenarioWidget* scenario, bugui::container_widget* parent); void paint(bugui::painter& painter) const override; @@ -21,8 +22,6 @@ struct IntervalWidget final : ScenarioComponentSpec int y() const override; int width() const override; - const Scenario::IntervalModel& get_model() const; - protected: bool contains(int px, int py) const override; }; diff --git a/Hardware/Widgets/ScenarioComponent.hpp b/Hardware/Widgets/ScenarioComponent.hpp index 3c27711..1fdca86 100644 --- a/Hardware/Widgets/ScenarioComponent.hpp +++ b/Hardware/Widgets/ScenarioComponent.hpp @@ -1,11 +1,19 @@ #pragma once -#include "widgets/base_widget.hpp" #include +#include #include +namespace bugui +{ +struct base_widget; +struct container_widget; +} + namespace Hardware { +class ScenarioWidget; + template requires (std::same_as || std::derived_from) @@ -17,9 +25,15 @@ struct ScenarioComponent : T virtual bool this_model(const Scenario::StateModel&) const { return false; }; protected: - explicit ScenarioComponent(bugui::container_widget* parent) + explicit ScenarioComponent(ScenarioWidget* s, + bugui::container_widget* parent) : T{parent} + , scenario{s} + , skin{Process::Style::instance()} { } + + ScenarioWidget* scenario; + const Process::Style& skin; }; template @@ -30,17 +44,17 @@ template struct ScenarioComponentSpec : ScenarioComponent { bool this_model(const T& m) const override { return m.id() == model.id(); }; + const T& get_model() const { return model; } protected: explicit ScenarioComponentSpec(T& m, + ScenarioWidget* scenario, bugui::container_widget* parent) - : ScenarioComponent{parent} + : ScenarioComponent{scenario, parent} , model{m} - , skin{Process::Style::instance()} { } T& model; - const Process::Style& skin; }; } // hardware diff --git a/Hardware/Widgets/ScenarioWidget.cpp b/Hardware/Widgets/ScenarioWidget.cpp index d49f6c9..074a74b 100644 --- a/Hardware/Widgets/ScenarioWidget.cpp +++ b/Hardware/Widgets/ScenarioWidget.cpp @@ -18,13 +18,13 @@ ScenarioWidget::ScenarioWidget(Scenario::ProcessModel* scenario, [this] { update(); }); for(Scenario::IntervalModel& i : model->intervals) - add_widget(i); + add_widget(i, this); model->timeSyncs.mutable_added.connect<&ScenarioWidget::on_time_sync_added>(this); model->timeSyncs.removed.connect<&ScenarioWidget::on_time_sync_removed>(this); for(Scenario::TimeSyncModel& t : model->timeSyncs) - add_widget(t); + add_widget(t, this); } int ScenarioWidget::x() const @@ -47,9 +47,14 @@ int ScenarioWidget::height() const return bugui::base_widget::parent->height(); } +Scenario::ProcessModel *ScenarioWidget::get_model() const +{ + return model; +} + void ScenarioWidget::on_interval_added(Scenario::IntervalModel& interval) { - add_widget(interval); + add_widget(interval, this); update(); } @@ -69,8 +74,7 @@ void ScenarioWidget::on_interval_changed(const Scenario::IntervalModel&) void ScenarioWidget::on_time_sync_added(Scenario::TimeSyncModel& timeSync) { - add_widget(timeSync); - update(); + add_widget(timeSync, this); } void ScenarioWidget::on_time_sync_removed(const Scenario::TimeSyncModel& timeSync) @@ -78,8 +82,6 @@ void ScenarioWidget::on_time_sync_removed(const Scenario::TimeSyncModel& timeSyn remove_widget([&timeSync] (const auto& w) { return static_cast*>(w.get())->this_model(timeSync); }); - - update(); } } // namespace Hardware diff --git a/Hardware/Widgets/ScenarioWidget.hpp b/Hardware/Widgets/ScenarioWidget.hpp index a012bca..bf7eab7 100644 --- a/Hardware/Widgets/ScenarioWidget.hpp +++ b/Hardware/Widgets/ScenarioWidget.hpp @@ -23,6 +23,8 @@ public: int width() const override; int height() const override; + Scenario::ProcessModel* get_model() const; + private: void on_interval_added(Scenario::IntervalModel& interval); void on_interval_removed(const Scenario::IntervalModel& interval); diff --git a/Hardware/Widgets/StateWidget.cpp b/Hardware/Widgets/StateWidget.cpp index fcd793b..a0272df 100644 --- a/Hardware/Widgets/StateWidget.cpp +++ b/Hardware/Widgets/StateWidget.cpp @@ -1,22 +1,19 @@ #include #include "StateWidget.hpp" +#include "Hardware/Widgets/ScenarioWidget.hpp" namespace Hardware { StateWidget::StateWidget(Scenario::StateModel& state, + ScenarioWidget* scenario, bugui::container_widget* parent) - : ScenarioComponentSpec{state, parent} + : ScenarioComponentSpec{state, scenario, parent} { } -int StateWidget::x() const -{ - return parent->x(); -} - int StateWidget::y() const { - return model.heightPercentage() * parent->height(); + return model.heightPercentage() * scenario->height(); } void StateWidget::paint(bugui::painter& painter) const @@ -51,9 +48,4 @@ void StateWidget::on_drag(int from_x, int from_y, int to_x, int to_y) model.setHeightPercentage(to_y / static_cast(parent->height())); } -const Scenario::StateModel& StateWidget::get_model() const -{ - return model; -} - } diff --git a/Hardware/Widgets/StateWidget.hpp b/Hardware/Widgets/StateWidget.hpp index ba9c45c..3985fca 100644 --- a/Hardware/Widgets/StateWidget.hpp +++ b/Hardware/Widgets/StateWidget.hpp @@ -8,6 +8,7 @@ namespace Hardware struct StateWidget final : ScenarioComponentSpec { explicit StateWidget(Scenario::StateModel& state, + ScenarioWidget* scenario, bugui::container_widget* parent); void paint(bugui::painter& painter) const override; @@ -15,11 +16,8 @@ struct StateWidget final : ScenarioComponentSpec void on_double_press(int x, int y) override; void on_drag(int from_x, int from_y, int to_x, int to_y) override; - int x() const override; int y() const override; - const Scenario::StateModel& get_model() const; - protected: bool contains(int px, int py) const override; }; diff --git a/Hardware/Widgets/TimeSyncWidget.cpp b/Hardware/Widgets/TimeSyncWidget.cpp index 13d6ea1..c82fded 100644 --- a/Hardware/Widgets/TimeSyncWidget.cpp +++ b/Hardware/Widgets/TimeSyncWidget.cpp @@ -1,14 +1,26 @@ #include +#include "Hardware/Widgets/EventWidget.hpp" +#include "ScenarioWidget.hpp" #include "TimeSyncWidget.hpp" namespace Hardware { TimeSyncWidget::TimeSyncWidget(Scenario::TimeSyncModel& timeSync, + ScenarioWidget* scenario, bugui::container_widget* parent) : ScenarioComponentSpec{timeSync, parent} -{ } + bugui::container_widget>{timeSync, scenario, parent} +{ + Scenario::ProcessModel* scen{scenario->get_model()}; + + scen->events.mutable_added.connect<&TimeSyncWidget::on_event_added>(this); + scen->events.removed.connect<&TimeSyncWidget::on_event_removed>(this); + + for(Scenario::EventModel& e : scen->events) + if (e.timeSync() == model.id()) + add_widget(e, scenario); +} int TimeSyncWidget::x() const { @@ -17,12 +29,29 @@ int TimeSyncWidget::x() const int TimeSyncWidget::y() const { - return 0; + return m_y; } int TimeSyncWidget::height() const { - return 1; + return m_height; +} + +void TimeSyncWidget::set_y_height() +{ + m_y = std::numeric_limits::max(); + m_height = std::numeric_limits::lowest(); + + for(const auto& e : children) + { + int ey = e->y(); + if (ey <= m_y) m_y = ey; + + int eh = e->height(); + if (eh >= m_height) m_height = eh; + } + + update(); } void TimeSyncWidget::paint(bugui::painter& painter) const @@ -41,14 +70,26 @@ bool TimeSyncWidget::contains(int px, int py) const return false; } +void TimeSyncWidget::on_event_added(Scenario::EventModel& event) +{ + if (event.timeSync() != model.id()) return; + + add_widget(event, scenario); +} + +void TimeSyncWidget::on_event_removed(const Scenario::EventModel& event) +{ + if (event.timeSync() != model.id()) + return; + + remove_widget([&event] + (const auto& w) + { return static_cast*>(w.get())->this_model(event); }); +} + void TimeSyncWidget::on_press(int x, int y, bool pressed) { qDebug() << "is inside!"; } -const Scenario::TimeSyncModel& TimeSyncWidget::get_model() const -{ - return model; -} - -} +} // namespace Hardware diff --git a/Hardware/Widgets/TimeSyncWidget.hpp b/Hardware/Widgets/TimeSyncWidget.hpp index 4d676f8..6d92bba 100644 --- a/Hardware/Widgets/TimeSyncWidget.hpp +++ b/Hardware/Widgets/TimeSyncWidget.hpp @@ -10,6 +10,7 @@ struct TimeSyncWidget final : ScenarioComponentSpec { explicit TimeSyncWidget(Scenario::TimeSyncModel& timeSync, + ScenarioWidget* scenario, bugui::container_widget* parent); void paint(bugui::painter& painter) const override; @@ -19,10 +20,16 @@ struct TimeSyncWidget final : ScenarioComponentSpec