[ScenarioWidget] design mostly there but models get deleted seemingly without notifications

This commit is contained in:
thibaud keller 2025-01-11 11:56:26 +00:00
parent 8c9eef1959
commit c1d7604799
12 changed files with 169 additions and 68 deletions

@ -1 +1 @@
Subproject commit 08fcc660909bfb688156904cf520d150e3b426f6 Subproject commit 9a0bded62d9632d05fac99988a8c53bb5e42b7a4

View file

@ -1,28 +1,56 @@
#include <Scenario/Document/Event/EventModel.hpp> #include <Scenario/Document/Event/EventModel.hpp>
#include "TimeSyncWidget.hpp"
#include "StateWidget.hpp"
#include "ScenarioWidget.hpp"
#include "EventWidget.hpp" #include "EventWidget.hpp"
namespace Hardware namespace Hardware
{ {
EventWidget::EventWidget(Scenario::EventModel& event, EventWidget::EventWidget(Scenario::EventModel& event,
ScenarioWidget* scenario,
bugui::container_widget* parent) bugui::container_widget* parent)
: ScenarioComponentSpec<Scenario::EventModel>{event, parent} : ScenarioComponentSpec<Scenario::EventModel,
, bugui::container_widget{parent} bugui::container_widget>{event, scenario, parent}
{ }
int EventWidget::x() const
{ {
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<StateWidget>(s, scenario);
set_y_height();
update();
} }
int EventWidget::y() const int EventWidget::y() const
{ {
return 0; return m_y;
} }
int EventWidget::height() const int EventWidget::height() const
{ {
return 1; return m_height;
}
void EventWidget::set_y_height()
{
m_y = std::numeric_limits<int>::max();
m_height = std::numeric_limits<int>::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<TimeSyncWidget*>(parent)->set_y_height();
} }
void EventWidget::paint(bugui::painter& painter) const void EventWidget::paint(bugui::painter& painter) const
@ -41,14 +69,30 @@ bool EventWidget::contains(int px, int py) const
return false; return false;
} }
void EventWidget::on_state_added(Scenario::StateModel& state)
{
if (state.eventId() != model.id()) return;
add_widget<StateWidget>(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<ScenarioComponent<>*>(w.get())->this_model(state); });
set_y_height();
}
void EventWidget::on_press(int x, int y, bool pressed) void EventWidget::on_press(int x, int y, bool pressed)
{ {
qDebug() << "is inside!"; qDebug() << "is inside!";
} }
const Scenario::EventModel& EventWidget::get_model() const
{
return model;
}
} }

View file

@ -5,24 +5,29 @@
namespace Hardware namespace Hardware
{ {
struct EventWidget final : virtual bugui::container_widget struct EventWidget final : ScenarioComponentSpec<Scenario::EventModel,
, ScenarioComponentSpec<Scenario::EventModel> bugui::container_widget>
{ {
explicit EventWidget(Scenario::EventModel& event, explicit EventWidget(Scenario::EventModel& event,
ScenarioWidget* scenario,
bugui::container_widget* parent); bugui::container_widget* parent);
void paint(bugui::painter& painter) const override; void paint(bugui::painter& painter) const override;
void on_press(int x, int y, bool pressed) override; void on_press(int x, int y, bool pressed) override;
int x() const override;
int y() const override; int y() const override;
int height() const override; int height() const override;
const Scenario::EventModel& get_model() const; void set_y_height();
protected: protected:
bool contains(int px, int py) const override; 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 } //namespace Hardware

View file

@ -1,12 +1,14 @@
#include <widgets/container_widget.hpp> #include <widgets/container_widget.hpp>
#include "IntervalWidget.hpp" #include "IntervalWidget.hpp"
#include "Hardware/Widgets/ScenarioWidget.hpp"
namespace Hardware namespace Hardware
{ {
IntervalWidget::IntervalWidget(Scenario::IntervalModel& interval, IntervalWidget::IntervalWidget(Scenario::IntervalModel& interval,
ScenarioWidget* scenario,
bugui::container_widget* parent) bugui::container_widget* parent)
: ScenarioComponentSpec<Scenario::IntervalModel>{interval, parent} : ScenarioComponentSpec<Scenario::IntervalModel>{interval, scenario, parent}
{ } { }
int IntervalWidget::x() const int IntervalWidget::x() const
@ -16,7 +18,7 @@ int IntervalWidget::x() const
int IntervalWidget::y() const int IntervalWidget::y() const
{ {
return model.heightPercentage() * parent->height(); return model.heightPercentage() * scenario->height();
} }
int IntervalWidget::width() const 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) void IntervalWidget::on_drag(int from_x, int from_y, int to_x, int to_y)
{ {
double increment{to_y / static_cast<double>(parent->height())}; double increment{to_y / static_cast<double>(scenario->height())};
model.requestHeightChange(model.heightPercentage() + increment); model.requestHeightChange(model.heightPercentage() + increment);
} }
const Scenario::IntervalModel& IntervalWidget::get_model() const
{
return model;
}
} // namespace hardware } // namespace hardware

View file

@ -10,6 +10,7 @@ namespace Hardware
struct IntervalWidget final : ScenarioComponentSpec<Scenario::IntervalModel> struct IntervalWidget final : ScenarioComponentSpec<Scenario::IntervalModel>
{ {
explicit IntervalWidget(Scenario::IntervalModel& interval, explicit IntervalWidget(Scenario::IntervalModel& interval,
ScenarioWidget* scenario,
bugui::container_widget* parent); bugui::container_widget* parent);
void paint(bugui::painter& painter) const override; void paint(bugui::painter& painter) const override;
@ -21,8 +22,6 @@ struct IntervalWidget final : ScenarioComponentSpec<Scenario::IntervalModel>
int y() const override; int y() const override;
int width() const override; int width() const override;
const Scenario::IntervalModel& get_model() const;
protected: protected:
bool contains(int px, int py) const override; bool contains(int px, int py) const override;
}; };

View file

@ -1,11 +1,19 @@
#pragma once #pragma once
#include "widgets/base_widget.hpp"
#include <Process/Style/ScenarioStyle.hpp> #include <Process/Style/ScenarioStyle.hpp>
#include <Scenario/Process/ScenarioModel.hpp>
#include <Scenario/Document/Interval/IntervalModel.hpp> #include <Scenario/Document/Interval/IntervalModel.hpp>
namespace bugui
{
struct base_widget;
struct container_widget;
}
namespace Hardware namespace Hardware
{ {
class ScenarioWidget;
template <typename T = bugui::base_widget> template <typename T = bugui::base_widget>
requires (std::same_as<T, bugui::base_widget> || requires (std::same_as<T, bugui::base_widget> ||
std::derived_from<T, bugui::base_widget>) std::derived_from<T, bugui::base_widget>)
@ -17,9 +25,15 @@ struct ScenarioComponent : T
virtual bool this_model(const Scenario::StateModel&) const { return false; }; virtual bool this_model(const Scenario::StateModel&) const { return false; };
protected: protected:
explicit ScenarioComponent(bugui::container_widget* parent) explicit ScenarioComponent(ScenarioWidget* s,
bugui::container_widget* parent)
: T{parent} : T{parent}
, scenario{s}
, skin{Process::Style::instance()}
{ } { }
ScenarioWidget* scenario;
const Process::Style& skin;
}; };
template <typename T, typename Base = bugui::base_widget> template <typename T, typename Base = bugui::base_widget>
@ -30,17 +44,17 @@ template <typename T, typename Base = bugui::base_widget>
struct ScenarioComponentSpec : ScenarioComponent<Base> struct ScenarioComponentSpec : ScenarioComponent<Base>
{ {
bool this_model(const T& m) const override { return m.id() == model.id(); }; bool this_model(const T& m) const override { return m.id() == model.id(); };
const T& get_model() const { return model; }
protected: protected:
explicit ScenarioComponentSpec(T& m, explicit ScenarioComponentSpec(T& m,
ScenarioWidget* scenario,
bugui::container_widget* parent) bugui::container_widget* parent)
: ScenarioComponent<Base>{parent} : ScenarioComponent<Base>{scenario, parent}
, model{m} , model{m}
, skin{Process::Style::instance()}
{ } { }
T& model; T& model;
const Process::Style& skin;
}; };
} // hardware } // hardware

View file

@ -18,13 +18,13 @@ ScenarioWidget::ScenarioWidget(Scenario::ProcessModel* scenario,
[this] { update(); }); [this] { update(); });
for(Scenario::IntervalModel& i : model->intervals) for(Scenario::IntervalModel& i : model->intervals)
add_widget<IntervalWidget>(i); add_widget<IntervalWidget>(i, this);
model->timeSyncs.mutable_added.connect<&ScenarioWidget::on_time_sync_added>(this); model->timeSyncs.mutable_added.connect<&ScenarioWidget::on_time_sync_added>(this);
model->timeSyncs.removed.connect<&ScenarioWidget::on_time_sync_removed>(this); model->timeSyncs.removed.connect<&ScenarioWidget::on_time_sync_removed>(this);
for(Scenario::TimeSyncModel& t : model->timeSyncs) for(Scenario::TimeSyncModel& t : model->timeSyncs)
add_widget<TimeSyncWidget>(t); add_widget<TimeSyncWidget>(t, this);
} }
int ScenarioWidget::x() const int ScenarioWidget::x() const
@ -47,9 +47,14 @@ int ScenarioWidget::height() const
return bugui::base_widget::parent->height(); return bugui::base_widget::parent->height();
} }
Scenario::ProcessModel *ScenarioWidget::get_model() const
{
return model;
}
void ScenarioWidget::on_interval_added(Scenario::IntervalModel& interval) void ScenarioWidget::on_interval_added(Scenario::IntervalModel& interval)
{ {
add_widget<IntervalWidget>(interval); add_widget<IntervalWidget>(interval, this);
update(); update();
} }
@ -69,8 +74,7 @@ void ScenarioWidget::on_interval_changed(const Scenario::IntervalModel&)
void ScenarioWidget::on_time_sync_added(Scenario::TimeSyncModel& timeSync) void ScenarioWidget::on_time_sync_added(Scenario::TimeSyncModel& timeSync)
{ {
add_widget<TimeSyncWidget>(timeSync); add_widget<TimeSyncWidget>(timeSync, this);
update();
} }
void ScenarioWidget::on_time_sync_removed(const Scenario::TimeSyncModel& timeSync) 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] remove_widget([&timeSync]
(const auto& w) (const auto& w)
{ return static_cast<ScenarioComponent<>*>(w.get())->this_model(timeSync); }); { return static_cast<ScenarioComponent<>*>(w.get())->this_model(timeSync); });
update();
} }
} // namespace Hardware } // namespace Hardware

View file

@ -23,6 +23,8 @@ public:
int width() const override; int width() const override;
int height() const override; int height() const override;
Scenario::ProcessModel* get_model() const;
private: private:
void on_interval_added(Scenario::IntervalModel& interval); void on_interval_added(Scenario::IntervalModel& interval);
void on_interval_removed(const Scenario::IntervalModel& interval); void on_interval_removed(const Scenario::IntervalModel& interval);

View file

@ -1,22 +1,19 @@
#include <Scenario/Document/State/StateModel.hpp> #include <Scenario/Document/State/StateModel.hpp>
#include "StateWidget.hpp" #include "StateWidget.hpp"
#include "Hardware/Widgets/ScenarioWidget.hpp"
namespace Hardware namespace Hardware
{ {
StateWidget::StateWidget(Scenario::StateModel& state, StateWidget::StateWidget(Scenario::StateModel& state,
ScenarioWidget* scenario,
bugui::container_widget* parent) bugui::container_widget* parent)
: ScenarioComponentSpec<Scenario::StateModel>{state, parent} : ScenarioComponentSpec<Scenario::StateModel>{state, scenario, parent}
{ } { }
int StateWidget::x() const
{
return parent->x();
}
int StateWidget::y() const int StateWidget::y() const
{ {
return model.heightPercentage() * parent->height(); return model.heightPercentage() * scenario->height();
} }
void StateWidget::paint(bugui::painter& painter) const 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<double>(parent->height())); model.setHeightPercentage(to_y / static_cast<double>(parent->height()));
} }
const Scenario::StateModel& StateWidget::get_model() const
{
return model;
}
} }

View file

@ -8,6 +8,7 @@ namespace Hardware
struct StateWidget final : ScenarioComponentSpec<Scenario::StateModel> struct StateWidget final : ScenarioComponentSpec<Scenario::StateModel>
{ {
explicit StateWidget(Scenario::StateModel& state, explicit StateWidget(Scenario::StateModel& state,
ScenarioWidget* scenario,
bugui::container_widget* parent); bugui::container_widget* parent);
void paint(bugui::painter& painter) const override; void paint(bugui::painter& painter) const override;
@ -15,11 +16,8 @@ struct StateWidget final : ScenarioComponentSpec<Scenario::StateModel>
void on_double_press(int x, int y) override; 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; void on_drag(int from_x, int from_y, int to_x, int to_y) override;
int x() const override;
int y() const override; int y() const override;
const Scenario::StateModel& get_model() const;
protected: protected:
bool contains(int px, int py) const override; bool contains(int px, int py) const override;
}; };

View file

@ -1,14 +1,26 @@
#include <Scenario/Document/TimeSync/TimeSyncModel.hpp> #include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
#include "Hardware/Widgets/EventWidget.hpp"
#include "ScenarioWidget.hpp"
#include "TimeSyncWidget.hpp" #include "TimeSyncWidget.hpp"
namespace Hardware namespace Hardware
{ {
TimeSyncWidget::TimeSyncWidget(Scenario::TimeSyncModel& timeSync, TimeSyncWidget::TimeSyncWidget(Scenario::TimeSyncModel& timeSync,
ScenarioWidget* scenario,
bugui::container_widget* parent) bugui::container_widget* parent)
: ScenarioComponentSpec<Scenario::TimeSyncModel, : ScenarioComponentSpec<Scenario::TimeSyncModel,
bugui::container_widget>{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<EventWidget>(e, scenario);
}
int TimeSyncWidget::x() const int TimeSyncWidget::x() const
{ {
@ -17,12 +29,29 @@ int TimeSyncWidget::x() const
int TimeSyncWidget::y() const int TimeSyncWidget::y() const
{ {
return 0; return m_y;
} }
int TimeSyncWidget::height() const int TimeSyncWidget::height() const
{ {
return 1; return m_height;
}
void TimeSyncWidget::set_y_height()
{
m_y = std::numeric_limits<int>::max();
m_height = std::numeric_limits<int>::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 void TimeSyncWidget::paint(bugui::painter& painter) const
@ -41,14 +70,26 @@ bool TimeSyncWidget::contains(int px, int py) const
return false; return false;
} }
void TimeSyncWidget::on_event_added(Scenario::EventModel& event)
{
if (event.timeSync() != model.id()) return;
add_widget<EventWidget>(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<ScenarioComponent<>*>(w.get())->this_model(event); });
}
void TimeSyncWidget::on_press(int x, int y, bool pressed) void TimeSyncWidget::on_press(int x, int y, bool pressed)
{ {
qDebug() << "is inside!"; qDebug() << "is inside!";
} }
const Scenario::TimeSyncModel& TimeSyncWidget::get_model() const } // namespace Hardware
{
return model;
}
}

View file

@ -10,6 +10,7 @@ struct TimeSyncWidget final : ScenarioComponentSpec<Scenario::TimeSyncModel,
bugui::container_widget> bugui::container_widget>
{ {
explicit TimeSyncWidget(Scenario::TimeSyncModel& timeSync, explicit TimeSyncWidget(Scenario::TimeSyncModel& timeSync,
ScenarioWidget* scenario,
bugui::container_widget* parent); bugui::container_widget* parent);
void paint(bugui::painter& painter) const override; void paint(bugui::painter& painter) const override;
@ -19,10 +20,16 @@ struct TimeSyncWidget final : ScenarioComponentSpec<Scenario::TimeSyncModel,
int y() const override; int y() const override;
int height() const override; int height() const override;
const Scenario::TimeSyncModel& get_model() const; void set_y_height();
protected: private:
bool contains(int px, int py) const override; bool contains(int px, int py) const override;
void on_event_added(Scenario::EventModel& event);
void on_event_removed(const Scenario::EventModel& event);
int m_y;
int m_height;
}; };
} //namespace Hardware } //namespace Hardware