[widgets] WIP on recursive_change

This commit is contained in:
thibaud keller 2025-01-21 00:10:21 +00:00
parent a6c770c4f8
commit 6375cb1558
10 changed files with 149 additions and 63 deletions

View file

@ -16,7 +16,7 @@ EventWidget::EventWidget(Scenario::EventModel& event,
Scenario::ProcessModel* scen{scenario->get_model()}; Scenario::ProcessModel* scen{scenario->get_model()};
scen->states.mutable_added.connect<&EventWidget::on_state_added>(this); scen->states.mutable_added.connect<&EventWidget::on_state_added>(this);
scen->states.removed.connect<&EventWidget::on_state_removed>(this); scen->states.removing.connect<&EventWidget::on_state_removed>(this);
for(Scenario::StateModel& s : scen->states) for(Scenario::StateModel& s : scen->states)
if (s.eventId() == model.id()) if (s.eventId() == model.id())
@ -56,7 +56,7 @@ void EventWidget::set_span_recursive()
void EventWidget::paint(bugui::painter& painter) const void EventWidget::paint(bugui::painter& painter) const
{ {
if (!press) return; if (!press && m_height == 0) return;
const auto col = model.metadata().getColor().getBrush().color(); const auto col = model.metadata().getColor().getBrush().color();
// const auto col = skin.StateSelected().color(); // const auto col = skin.StateSelected().color();

View file

@ -5,9 +5,10 @@
namespace Hardware namespace Hardware
{ {
struct EventWidget final : Nano::Observer struct EventWidget final : ScenarioComponentSpec<
, ScenarioComponentSpec<Scenario::EventModel, Scenario::EventModel,
bugui::container_widget> bugui::container_widget>
, Nano::Observer
{ {
explicit EventWidget(Scenario::EventModel& event, explicit EventWidget(Scenario::EventModel& event,
ScenarioWidget* scenario, ScenarioWidget* scenario,
@ -21,15 +22,15 @@ struct EventWidget final : Nano::Observer
void set_span_recursive(); void set_span_recursive();
private: private:
void on_state_added(Scenario::StateModel& state);
void on_state_removed(const Scenario::StateModel& state);
bool contains(int px, int py) const override; bool contains(int px, int py) const override;
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;
void on_state_added(Scenario::StateModel& state);
void on_state_removed(const Scenario::StateModel& state);
bool press{false}; bool press{false};
int m_absolute_y{0}; int m_absolute_y{0};

View file

@ -26,6 +26,16 @@ int IntervalWidget::width() const
return model.duration.defaultDuration().sec(); return model.duration.defaultDuration().sec();
} }
void IntervalWidget::change_previous(const Scenario::StateModel& state)
{
}
void IntervalWidget::change_next(const Scenario::StateModel& state)
{
model.setHeightPercentage(state.heightPercentage());
}
bool IntervalWidget::contains(int px, int py) const bool IntervalWidget::contains(int px, int py) const
{ {
// ignore first and last cell // ignore first and last cell

View file

@ -17,6 +17,9 @@ struct IntervalWidget final : ScenarioComponentSpec<Scenario::IntervalModel>
int y() const override; int y() const override;
int width() const override; int width() const override;
void change_previous(const Scenario::StateModel& state);
void change_next(const Scenario::StateModel& state);
private: private:
bool contains(int px, int py) const override; bool contains(int px, int py) const override;

View file

@ -12,18 +12,29 @@ ScenarioWidget::ScenarioWidget(Scenario::ProcessModel* scenario,
, skin{Process::Style::instance()} , skin{Process::Style::instance()}
{ {
model->intervals.mutable_added.connect<&ScenarioWidget::on_interval_added>(this); model->intervals.mutable_added.connect<&ScenarioWidget::on_interval_added>(this);
model->intervals.removed.connect<&ScenarioWidget::on_interval_removed>(this); model->intervals.removing.connect<&ScenarioWidget::on_interval_removed>(this);
for(Scenario::IntervalModel& i : model->intervals) for(Scenario::IntervalModel& i : model->intervals)
add_widget<IntervalWidget>(i, this); 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.removing.connect<&ScenarioWidget::on_time_sync_removed>(this);
for(Scenario::TimeSyncModel& t : model->timeSyncs) for(Scenario::TimeSyncModel& t : model->timeSyncs)
add_widget<TimeSyncWidget>(t, this); add_widget<TimeSyncWidget>(t, this);
} }
void ScenarioWidget::add_proxy(StateWidget* sw)
{
states_proxy.push_back(sw);
}
void ScenarioWidget::remove_proxy(StateWidget* sw)
{
std::erase_if(states_proxy,
[sw] (StateWidget* w) { return w == sw; });
}
void ScenarioWidget::on_interval_added(Scenario::IntervalModel& interval) void ScenarioWidget::on_interval_added(Scenario::IntervalModel& interval)
{ {
add_widget<IntervalWidget>(interval, this); add_widget<IntervalWidget>(interval, this);
@ -54,4 +65,31 @@ void ScenarioWidget::on_time_sync_removed(const Scenario::TimeSyncModel& timeSyn
update(); update();
} }
void ScenarioWidget::recursive_change(const Scenario::StateModel& state)
{
auto& ni{state.nextInterval()};
if (ni)
{
auto& v{ni.value()};
for (const auto& c : children)
{
ScenarioComponent<>* s{static_cast<ScenarioComponent<>*>(c.get())};
if (s->this_model(v))
{
static_cast<IntervalWidget*>(s)->change_next(state);
break;
}
}
}
update();
}
void ScenarioWidget::recursive_change(const Scenario::IntervalModel& interval)
{
}
} // namespace Hardware } // namespace Hardware

View file

@ -6,6 +6,8 @@
namespace Hardware namespace Hardware
{ {
struct StateWidget;
class ScenarioWidget final : public bugui::container_widget class ScenarioWidget final : public bugui::container_widget
, public Nano::Observer , public Nano::Observer
{ {
@ -23,6 +25,12 @@ public:
Scenario::ProcessModel* get_model() const { return model; } Scenario::ProcessModel* get_model() const { return model; }
void add_proxy(StateWidget* sw);
void remove_proxy(StateWidget* sw);
void recursive_change(const Scenario::StateModel& state);
void recursive_change(const Scenario::IntervalModel& interval);
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);
@ -30,6 +38,13 @@ private:
void on_time_sync_added(Scenario::TimeSyncModel& timeSync); void on_time_sync_added(Scenario::TimeSyncModel& timeSync);
void on_time_sync_removed(const Scenario::TimeSyncModel& timeSync); void on_time_sync_removed(const Scenario::TimeSyncModel& timeSync);
void move_previous(const Scenario::IntervalModel& interval);
void move_previous(const Scenario::StateModel& interval);
void move_next(const Scenario::IntervalModel& interval);
void move_next(const Scenario::StateModel& interval);
std::vector<StateWidget*> states_proxy;
Scenario::ProcessModel* model{nullptr}; Scenario::ProcessModel* model{nullptr};
const Process::Style& skin; const Process::Style& skin;
}; };

View file

@ -13,15 +13,32 @@ StateWidget::StateWidget(Scenario::StateModel& state,
{ {
set_absolute_y(); set_absolute_y();
con = connect(&model, // con = connect(&model,
&Scenario::StateModel::heightPercentageChanged, // &Scenario::StateModel::heightPercentageChanged,
this, // this,
[scenario, this] // [scenario, this]
// {
// set_absolute_y();
// set_span_recursive();
// scenario->update();
// });
scenario->add_proxy(this);
}
StateWidget::~StateWidget()
{ {
set_absolute_y(); disconnect(con);
set_span_recursive(); scenario->remove_proxy(this);
scenario->update(); }
});
void StateWidget::change_previous(const Scenario::IntervalModel& interval)
{
}
void StateWidget::change_next(const Scenario::IntervalModel& interval)
{
} }
void StateWidget::paint(bugui::painter& painter) const void StateWidget::paint(bugui::painter& painter) const
@ -43,7 +60,7 @@ bool StateWidget::contains(int px, int py) const
void StateWidget::on_press(int x, int y, bool pressed) void StateWidget::on_press(int x, int y, bool pressed)
{ {
update(); // update();
} }
void StateWidget::on_double_press(int x, int y) void StateWidget::on_double_press(int x, int y)
@ -58,8 +75,10 @@ void StateWidget::on_drag(int from_x, int from_y, int to_x, int to_y)
// prevent dragging out of scenario // prevent dragging out of scenario
if (new_height >= 0 && new_height <= 1) if (new_height >= 0 && new_height <= 1)
{
model.setHeightPercentage(new_height); model.setHeightPercentage(new_height);
scenario->recursive_change(model);
}
} }
void StateWidget::set_absolute_y() void StateWidget::set_absolute_y()

View file

@ -5,18 +5,20 @@
namespace Hardware namespace Hardware
{ {
struct StateWidget final : QObject struct StateWidget final : ScenarioComponentSpec<Scenario::StateModel>
, ScenarioComponentSpec<Scenario::StateModel> , QObject
{ {
explicit StateWidget(Scenario::StateModel& state, explicit StateWidget(Scenario::StateModel& state,
ScenarioWidget* scenario, ScenarioWidget* scenario,
bugui::container_widget* parent); bugui::container_widget* parent);
~StateWidget() override { disconnect(con); } ~StateWidget() override;
int y() const override { return m_y; } int y() const override { return m_y; }
int get_absolute_y() { return m_absolute_y; }; int get_absolute_y() { return m_absolute_y; };
void set_y(); void set_y();
void change_previous(const Scenario::IntervalModel& interval);
void change_next(const Scenario::IntervalModel& interval);
private: private:
W_OBJECT(StateWidget) W_OBJECT(StateWidget)

View file

@ -12,37 +12,19 @@ TimeSyncWidget::TimeSyncWidget(Scenario::TimeSyncModel& timeSync,
: ScenarioComponentSpec<Scenario::TimeSyncModel, : ScenarioComponentSpec<Scenario::TimeSyncModel,
bugui::container_widget>{timeSync, scenario, parent} bugui::container_widget>{timeSync, scenario, parent}
{ {
connect(&model,
&Scenario::TimeSyncModel::dateChanged,
this,
[scenario] (const TimeVal&) { scenario->update(); });
connect(&model,
&Scenario::TimeSyncModel::newEvent,
this,
[scenario, this] (const Id<Scenario::EventModel>& eventId)
{
add_widget<EventWidget>(scenario->get_model()->events.at(eventId), scenario);
});
connect(&model,
&Scenario::TimeSyncModel::eventRemoved,
this,
[scenario, this] (const Id<Scenario::EventModel>& eventId)
{
remove_widget([&eventId]
(const auto& w)
{ return static_cast<ScenarioComponent<>*>(w.get())->this_model(eventId); });
set_span();
update();
});
Scenario::ProcessModel* scen{scenario->get_model()}; Scenario::ProcessModel* scen{scenario->get_model()};
scen->events.mutable_added.connect<&TimeSyncWidget::on_state_added>(this);
scen->events.removing.connect<&TimeSyncWidget::on_state_removed>(this);
for(Scenario::EventModel& e : scen->events) for(Scenario::EventModel& e : scen->events)
if (e.timeSync() == model.id()) if (e.timeSync() == model.id())
add_widget<EventWidget>(e, scenario); add_widget<EventWidget>(e, scenario);
connect(&model,
&Scenario::TimeSyncModel::dateChanged,
this,
[scenario] (const TimeVal&) { scenario->update(); });
} }
TimeSyncWidget::~TimeSyncWidget() TimeSyncWidget::~TimeSyncWidget()
@ -50,14 +32,6 @@ TimeSyncWidget::~TimeSyncWidget()
disconnect(&model, disconnect(&model,
&Scenario::TimeSyncModel::dateChanged, &Scenario::TimeSyncModel::dateChanged,
this, 0); this, 0);
disconnect(&model,
&Scenario::TimeSyncModel::newEvent,
this, 0);
disconnect(&model,
&Scenario::TimeSyncModel::eventRemoved,
this, 0);
} }
void TimeSyncWidget::set_span() void TimeSyncWidget::set_span()
@ -84,9 +58,28 @@ void TimeSyncWidget::set_span()
static_cast<EventWidget*>(e.get())->set_y(); static_cast<EventWidget*>(e.get())->set_y();
} }
void TimeSyncWidget::on_state_added(Scenario::EventModel& event)
{
if (event.timeSync() != model.id()) return;
add_widget<EventWidget>(event, scenario);
}
void TimeSyncWidget::on_state_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); });
set_span();
update();
}
void TimeSyncWidget::paint(bugui::painter& painter) const void TimeSyncWidget::paint(bugui::painter& painter) const
{ {
if (!press) return; if (!press && m_height == 0) return;
const auto col = model.metadata().getColor().getBrush().color(); const auto col = model.metadata().getColor().getBrush().color();
// const auto col = skin.StateSelected().color(); // const auto col = skin.StateSelected().color();

View file

@ -6,9 +6,11 @@
namespace Hardware namespace Hardware
{ {
struct TimeSyncWidget final : QObject struct TimeSyncWidget final : ScenarioComponentSpec<
, ScenarioComponentSpec<Scenario::TimeSyncModel, Scenario::TimeSyncModel,
bugui::container_widget> bugui::container_widget>
, Nano::Observer
, QObject
{ {
explicit TimeSyncWidget(Scenario::TimeSyncModel& timeSync, explicit TimeSyncWidget(Scenario::TimeSyncModel& timeSync,
ScenarioWidget* scenario, ScenarioWidget* scenario,
@ -25,6 +27,9 @@ struct TimeSyncWidget final : QObject
private: private:
W_OBJECT(TimeSyncWidget) W_OBJECT(TimeSyncWidget)
void on_state_added(Scenario::EventModel& event);
void on_state_removed(const Scenario::EventModel& event);
bool contains(int px, int py) const override; bool contains(int px, int py) const override;
void paint(bugui::painter& painter) const override; void paint(bugui::painter& painter) const override;