From 9a2ce69deeb45375f5c76c27e74ab276f254e673 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Wed, 22 Jan 2025 23:14:58 +0000 Subject: [PATCH] [widget] propagate new TimeVal on horizontal drag --- Hardware/Widgets/EventWidget.cpp | 14 +++ Hardware/Widgets/EventWidget.hpp | 1 + Hardware/Widgets/IntervalWidget.cpp | 17 +++- Hardware/Widgets/IntervalWidget.hpp | 2 + Hardware/Widgets/ScenarioWidget.cpp | 127 ++++++++++++++++++++-------- Hardware/Widgets/ScenarioWidget.hpp | 5 +- Hardware/Widgets/StateWidget.cpp | 80 ++++++++++++------ Hardware/Widgets/StateWidget.hpp | 2 + Hardware/Widgets/TimeSyncWidget.cpp | 20 +++-- Hardware/Widgets/TimeSyncWidget.hpp | 2 +- 10 files changed, 198 insertions(+), 72 deletions(-) diff --git a/Hardware/Widgets/EventWidget.cpp b/Hardware/Widgets/EventWidget.cpp index 464688e..b94f94b 100644 --- a/Hardware/Widgets/EventWidget.cpp +++ b/Hardware/Widgets/EventWidget.cpp @@ -54,6 +54,20 @@ void EventWidget::set_span_recursive() static_cast(s.get())->set_y(); } +void EventWidget::time_propagate(const TimeVal& t) +{ + model.setDate(t); + + // FIXME : call scneario->time_propagate with StateModel + // is tehre a beter way to find connected intervals ? + for (auto& s : bugui::container_widget::children) + { + scenario->time_propagate( + static_cast(s.get())->get_model(), + t); + } +} + void EventWidget::paint(bugui::painter& painter) const { if (!press && m_height == 0) return; diff --git a/Hardware/Widgets/EventWidget.hpp b/Hardware/Widgets/EventWidget.hpp index 7403146..d69dfe6 100644 --- a/Hardware/Widgets/EventWidget.hpp +++ b/Hardware/Widgets/EventWidget.hpp @@ -20,6 +20,7 @@ struct EventWidget final : ScenarioComponentSpec< void set_y(); void set_span_recursive(); + void time_propagate(const TimeVal& t); private: void on_state_added(Scenario::StateModel& state); diff --git a/Hardware/Widgets/IntervalWidget.cpp b/Hardware/Widgets/IntervalWidget.cpp index 04bb231..20a832e 100644 --- a/Hardware/Widgets/IntervalWidget.cpp +++ b/Hardware/Widgets/IntervalWidget.cpp @@ -1,7 +1,9 @@ #include +#include + #include "IntervalWidget.hpp" -#include "Hardware/Widgets/ScenarioWidget.hpp" +#include "ScenarioWidget.hpp" namespace Hardware { @@ -38,6 +40,19 @@ void IntervalWidget::change_next(const Scenario::StateModel& state) scenario->change_next(model); } +void IntervalWidget::time_propagate(const TimeVal& t) +{ + model.translate(t - model.date()); + scenario->time_propagate(model, + model.date() + model.duration.defaultDuration()); +} + +void IntervalWidget::set_duration(const TimeVal& t) +{ + Scenario::IntervalDurations::Algorithms::changeAllDurations( + model, t - model.date()); +} + bool IntervalWidget::contains(int px, int py) const { // ignore first and last cell diff --git a/Hardware/Widgets/IntervalWidget.hpp b/Hardware/Widgets/IntervalWidget.hpp index b594341..f696884 100644 --- a/Hardware/Widgets/IntervalWidget.hpp +++ b/Hardware/Widgets/IntervalWidget.hpp @@ -19,6 +19,8 @@ struct IntervalWidget final : ScenarioComponentSpec void change_previous(const Scenario::StateModel& state); void change_next(const Scenario::StateModel& state); + void time_propagate(const TimeVal& t); + void set_duration(const TimeVal& t); private: bool contains(int px, int py) const override; diff --git a/Hardware/Widgets/ScenarioWidget.cpp b/Hardware/Widgets/ScenarioWidget.cpp index e416954..09acc4f 100644 --- a/Hardware/Widgets/ScenarioWidget.cpp +++ b/Hardware/Widgets/ScenarioWidget.cpp @@ -65,14 +65,81 @@ void ScenarioWidget::on_time_sync_removed(const Scenario::TimeSyncModel& timeSyn void ScenarioWidget::recursive_change(const Scenario::StateModel& state) { - change_next(state); change_previous(state); + change_next(state); } void ScenarioWidget::recursive_change(const Scenario::IntervalModel& interval) { - change_next(interval); change_previous(interval); + change_next(interval); +} + +void ScenarioWidget::time_propagate(const Scenario::StateModel& state, const TimeVal& t) +{ + auto interval{state.previousInterval()}; + + if (interval.has_value()) + { + auto& v{interval.value()}; + + for (const auto& c : children) + { + ScenarioComponent<>* s{static_cast*>(c.get())}; + + if (s->this_model(v)) + { + static_cast(s)->set_duration(t); + break; + } + } + } + + interval = state.nextInterval(); + + if (interval.has_value()) + { + auto& v{interval.value()}; + + for (const auto& c : children) + { + ScenarioComponent<>* s{static_cast*>(c.get())}; + + if (s->this_model(v)) + { + static_cast(s)->time_propagate(t); + break; + } + } + } +} + +void ScenarioWidget::time_propagate(const Scenario::IntervalModel& interval, const TimeVal& t) +{ + auto& es{interval.endState()}; + + for (const auto& s : states_proxy) + { + if (s->this_model(es)) + { + s->time_propagate(t); + break; + } + } +} + +void ScenarioWidget::change_previous(const Scenario::IntervalModel& interval) +{ + auto& es{interval.startState()}; + + for (const auto& s : states_proxy) + { + if (s->this_model(es)) + { + s->change_previous(interval); + break; + } + } } void ScenarioWidget::change_next(const Scenario::IntervalModel& interval) @@ -89,6 +156,27 @@ void ScenarioWidget::change_next(const Scenario::IntervalModel& interval) } } +void ScenarioWidget::change_previous(const Scenario::StateModel& state) +{ + auto& pi{state.previousInterval()}; + + if (pi) + { + auto& v{pi.value()}; + + for (const auto& c : children) + { + ScenarioComponent<>* s{static_cast*>(c.get())}; + + if (s->this_model(v)) + { + static_cast(s)->change_previous(state); + break; + } + } + } +} + void ScenarioWidget::change_next(const Scenario::StateModel& state) { auto& ni{state.nextInterval()}; @@ -110,39 +198,4 @@ void ScenarioWidget::change_next(const Scenario::StateModel& state) } } -void ScenarioWidget::change_previous(const Scenario::IntervalModel& interval) -{ - auto& es{interval.startState()}; - - for (const auto& s : states_proxy) - { - if (s->this_model(es)) - { - s->change_previous(interval); - break; - } - } -} - -void ScenarioWidget::change_previous(const Scenario::StateModel& state) -{ - auto& ni{state.previousInterval()}; - - if (ni) - { - auto& v{ni.value()}; - - for (const auto& c : children) - { - ScenarioComponent<>* s{static_cast*>(c.get())}; - - if (s->this_model(v)) - { - static_cast(s)->change_previous(state); - break; - } - } - } -} - } // namespace Hardware diff --git a/Hardware/Widgets/ScenarioWidget.hpp b/Hardware/Widgets/ScenarioWidget.hpp index ac578e3..699b8d8 100644 --- a/Hardware/Widgets/ScenarioWidget.hpp +++ b/Hardware/Widgets/ScenarioWidget.hpp @@ -32,10 +32,13 @@ public: void recursive_change(const Scenario::IntervalModel& interval); void change_previous(const Scenario::IntervalModel& interval); - void change_previous(const Scenario::StateModel& state); void change_next(const Scenario::IntervalModel& interval); + void change_previous(const Scenario::StateModel& state); void change_next(const Scenario::StateModel& state); + void time_propagate(const Scenario::StateModel& state, const TimeVal& t); + void time_propagate(const Scenario::IntervalModel& interval, const TimeVal& t); + bool changing{false}; private: diff --git a/Hardware/Widgets/StateWidget.cpp b/Hardware/Widgets/StateWidget.cpp index a567564..6dcf144 100644 --- a/Hardware/Widgets/StateWidget.cpp +++ b/Hardware/Widgets/StateWidget.cpp @@ -1,6 +1,7 @@ #include #include "ScenarioWidget.hpp" +#include "TimeSyncWidget.hpp" #include "EventWidget.hpp" #include "StateWidget.hpp" @@ -34,6 +35,24 @@ StateWidget::~StateWidget() scenario->remove_proxy(this); } +void StateWidget::set_absolute_y() +{ + m_absolute_y = model.heightPercentage() * scenario->height(); +} + +void StateWidget::set_y() +{ + m_y = m_absolute_y - + bugui::base_widget::parent->y() - + bugui::base_widget::parent->get_parent()->y(); +} + +void StateWidget::set_span_recursive() +{ + static_cast(bugui::base_widget::parent) + ->set_span_recursive(); +} + void StateWidget::change_previous(const Scenario::IntervalModel& interval) { model.setHeightPercentage(interval.heightPercentage()); @@ -49,6 +68,13 @@ void StateWidget::change_next(const Scenario::IntervalModel& interval) scenario->change_next(model); } +void StateWidget::time_propagate(const TimeVal& t) +{ + static_cast( + bugui::base_widget::parent->get_parent()) + ->time_propagate(t); +} + void StateWidget::paint(bugui::painter& painter) const { const auto col{model.metadata().getColor().getBrush().color()}; @@ -79,38 +105,40 @@ void StateWidget::on_double_press(int x, int y) void StateWidget::on_drag(int from_x, int from_y, int to_x, int to_y) { - double new_height{model.heightPercentage() + - to_y / static_cast(scenario->height())}; + bool update{false}; - // prevent dragging out of scenario - if (new_height >= 0 && new_height <= 1) + // handle vertical drag + if (from_y != to_y) + { + double new_height{model.heightPercentage() + + to_y / static_cast(scenario->height())}; + + // prevent dragging out of scenario + if (new_height >= 0 && new_height <= 1) + { + scenario->changing = true; + model.setHeightPercentage(new_height); + scenario->recursive_change(model); + set_absolute_y(); + set_span_recursive(); + scenario->changing = false; + update = true; + } + } + + if (from_x != to_x) { scenario->changing = true; - model.setHeightPercentage(new_height); - scenario->recursive_change(model); - set_absolute_y(); - set_span_recursive(); - scenario->update(); + TimeSyncWidget* sync{static_cast( + bugui::base_widget::parent->get_parent())}; + auto d{sync->get_model().date()}; + d.setMSecs(d.msec() + to_x * 1000); + sync->time_propagate(d); scenario->changing = false; + update = true; } -} -void StateWidget::set_absolute_y() -{ - m_absolute_y = model.heightPercentage() * scenario->height(); -} - -void StateWidget::set_y() -{ - m_y = m_absolute_y - - bugui::base_widget::parent->y() - - bugui::base_widget::parent->get_parent()->y(); -} - -void StateWidget::set_span_recursive() -{ - static_cast(bugui::base_widget::parent) - ->set_span_recursive(); + if (update) scenario->update(); } } // namespace Hardware diff --git a/Hardware/Widgets/StateWidget.hpp b/Hardware/Widgets/StateWidget.hpp index d191d59..ff93604 100644 --- a/Hardware/Widgets/StateWidget.hpp +++ b/Hardware/Widgets/StateWidget.hpp @@ -19,6 +19,7 @@ struct StateWidget final : ScenarioComponentSpec void set_y(); void change_previous(const Scenario::IntervalModel& interval); void change_next(const Scenario::IntervalModel& interval); + void time_propagate(const TimeVal& t); private: W_OBJECT(StateWidget) @@ -36,6 +37,7 @@ private: void on_drag(int from_x, int from_y, int to_x, int to_y) override; void set_absolute_y(); + int m_absolute_y; int m_y; }; diff --git a/Hardware/Widgets/TimeSyncWidget.cpp b/Hardware/Widgets/TimeSyncWidget.cpp index df2ab08..b94bf6f 100644 --- a/Hardware/Widgets/TimeSyncWidget.cpp +++ b/Hardware/Widgets/TimeSyncWidget.cpp @@ -24,7 +24,12 @@ TimeSyncWidget::TimeSyncWidget(Scenario::TimeSyncModel& timeSync, connect(&model, &Scenario::TimeSyncModel::dateChanged, this, - [scenario] (const TimeVal&) { scenario->update(); }); + [scenario] (const TimeVal&) + { + if (scenario->changing) return; + + scenario->update(); + }); } TimeSyncWidget::~TimeSyncWidget() @@ -58,6 +63,14 @@ void TimeSyncWidget::set_span() static_cast(e.get())->set_y(); } +void TimeSyncWidget::time_propagate(const TimeVal& t) +{ + model.setDate(t); + + for (auto& s : bugui::container_widget::children) + static_cast(s.get())->time_propagate(t); +} + void TimeSyncWidget::on_state_added(Scenario::EventModel& event) { if (event.timeSync() != model.id()) return; @@ -98,11 +111,6 @@ bool TimeSyncWidget::contains(int px, int py) const return false; } -void TimeSyncWidget::on_press(int x, int y, bool pressed) -{ - press = pressed; -} - } // namespace Hardware #include diff --git a/Hardware/Widgets/TimeSyncWidget.hpp b/Hardware/Widgets/TimeSyncWidget.hpp index 8d480a7..ed87bb1 100644 --- a/Hardware/Widgets/TimeSyncWidget.hpp +++ b/Hardware/Widgets/TimeSyncWidget.hpp @@ -23,6 +23,7 @@ struct TimeSyncWidget final : ScenarioComponentSpec< int height() const override { return m_height; } void set_span(); + void time_propagate(const TimeVal& t); private: W_OBJECT(TimeSyncWidget) @@ -33,7 +34,6 @@ private: bool contains(int px, int py) const override; void paint(bugui::painter& painter) const override; - void on_press(int x, int y, bool pressed) override; bool press{false};