[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 "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<Scenario::EventModel>{event, parent}
, bugui::container_widget{parent}
{ }
int EventWidget::x() const
: ScenarioComponentSpec<Scenario::EventModel,
bugui::container_widget>{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<StateWidget>(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<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
@ -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<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)
{
qDebug() << "is inside!";
}
const Scenario::EventModel& EventWidget::get_model() const
{
return model;
}
}

View file

@ -5,24 +5,29 @@
namespace Hardware
{
struct EventWidget final : virtual bugui::container_widget
, ScenarioComponentSpec<Scenario::EventModel>
struct EventWidget final : ScenarioComponentSpec<Scenario::EventModel,
bugui::container_widget>
{
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

View file

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

View file

@ -10,6 +10,7 @@ namespace Hardware
struct IntervalWidget final : ScenarioComponentSpec<Scenario::IntervalModel>
{
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<Scenario::IntervalModel>
int y() const override;
int width() const override;
const Scenario::IntervalModel& get_model() const;
protected:
bool contains(int px, int py) const override;
};

View file

@ -1,11 +1,19 @@
#pragma once
#include "widgets/base_widget.hpp"
#include <Process/Style/ScenarioStyle.hpp>
#include <Scenario/Process/ScenarioModel.hpp>
#include <Scenario/Document/Interval/IntervalModel.hpp>
namespace bugui
{
struct base_widget;
struct container_widget;
}
namespace Hardware
{
class ScenarioWidget;
template <typename T = bugui::base_widget>
requires (std::same_as<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; };
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 <typename T, typename Base = bugui::base_widget>
@ -30,17 +44,17 @@ template <typename T, typename Base = bugui::base_widget>
struct ScenarioComponentSpec : ScenarioComponent<Base>
{
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<Base>{parent}
: ScenarioComponent<Base>{scenario, parent}
, model{m}
, skin{Process::Style::instance()}
{ }
T& model;
const Process::Style& skin;
};
} // hardware

View file

@ -18,13 +18,13 @@ ScenarioWidget::ScenarioWidget(Scenario::ProcessModel* scenario,
[this] { update(); });
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.removed.connect<&ScenarioWidget::on_time_sync_removed>(this);
for(Scenario::TimeSyncModel& t : model->timeSyncs)
add_widget<TimeSyncWidget>(t);
add_widget<TimeSyncWidget>(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<IntervalWidget>(interval);
add_widget<IntervalWidget>(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<TimeSyncWidget>(timeSync);
update();
add_widget<TimeSyncWidget>(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<ScenarioComponent<>*>(w.get())->this_model(timeSync); });
update();
}
} // namespace Hardware

View file

@ -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);

View file

@ -1,22 +1,19 @@
#include <Scenario/Document/State/StateModel.hpp>
#include "StateWidget.hpp"
#include "Hardware/Widgets/ScenarioWidget.hpp"
namespace Hardware
{
StateWidget::StateWidget(Scenario::StateModel& state,
ScenarioWidget* scenario,
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
{
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<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>
{
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<Scenario::StateModel>
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;
};

View file

@ -1,14 +1,26 @@
#include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
#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<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
{
@ -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<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
@ -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<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)
{
qDebug() << "is inside!";
}
const Scenario::TimeSyncModel& TimeSyncWidget::get_model() const
{
return model;
}
}
} // namespace Hardware

View file

@ -10,6 +10,7 @@ struct TimeSyncWidget final : ScenarioComponentSpec<Scenario::TimeSyncModel,
bugui::container_widget>
{
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<Scenario::TimeSyncModel,
int y() 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;
void on_event_added(Scenario::EventModel& event);
void on_event_removed(const Scenario::EventModel& event);
int m_y;
int m_height;
};
} //namespace Hardware