TemporalConstraintPresenter::TemporalConstraintPresenter(
        const TemporalConstraintViewModel& cstr_model,
        QGraphicsObject *parentobject,
        QObject* parent) :
    AbstractConstraintPresenter {"TemporalConstraintPresenter",
                                 cstr_model,
                                 new TemporalConstraintView{*this, parentobject},
                                 parent}
{
    connect(::view(this), &TemporalConstraintView::constraintHoverEnter,
            this,       &TemporalConstraintPresenter::constraintHoverEnter);

    connect(::view(this), &TemporalConstraintView::constraintHoverLeave,
            this,       &TemporalConstraintPresenter::constraintHoverLeave);

    if(viewModel(this)->isRackShown())
    {
        on_rackShown(viewModel(this)->shownRack());
    }
    ::view(this)->setLabel(cstr_model.model().metadata.label());

    connect(&cstr_model.model().metadata, &ModelMetadata::labelChanged,
            ::view(this), &TemporalConstraintView::setLabel);
    connect(&cstr_model.model().metadata,   &ModelMetadata::colorChanged,
            ::view(this),   &TemporalConstraintView::setLabelColor);

    updateHeight();
}
ConstraintPresenter::ConstraintPresenter(
    const QString& name,
    const ConstraintViewModel& model,
    ConstraintView* view,
    ConstraintHeader* header,
    QObject* parent) :
    NamedObject {name, parent},
    m_viewModel {model},
    m_view {view},
    m_header{header}
{
    m_header->setParentItem(m_view);
    m_header->setConstraintView(m_view);

    con(m_viewModel.model().selection, &Selectable::changed,
        m_view, &ConstraintView::setSelected);

    con(m_viewModel.model().duration, &ConstraintDurations::minDurationChanged,
        this, [&] (const TimeValue& val)
    {
        on_minDurationChanged(val);
        updateChildren();
    });
    con(m_viewModel.model().duration, &ConstraintDurations::defaultDurationChanged,
        this,[&] (const TimeValue& val)
    {
        on_defaultDurationChanged(val);
        updateChildren();
    });
    con(m_viewModel.model().duration, &ConstraintDurations::maxDurationChanged,
        this, [&] (const TimeValue& val)
    {
        on_maxDurationChanged(val);
        updateChildren();
    });
    con(m_viewModel.model().duration, &ConstraintDurations::playPercentageChanged,
        this, &ConstraintPresenter::on_playPercentageChanged, Qt::QueuedConnection);

    con(m_viewModel.model(), &ConstraintModel::heightPercentageChanged,
        this, &ConstraintPresenter::heightPercentageChanged);

    con(m_viewModel, &ConstraintViewModel::rackShown,
        this,         &ConstraintPresenter::on_rackShown);
    con(m_viewModel, &ConstraintViewModel::rackHidden,
        this,         &ConstraintPresenter::on_rackHidden);
    con(m_viewModel, &ConstraintViewModel::rackRemoved,
        this,         &ConstraintPresenter::on_noRacks);


    con(m_viewModel.model().consistency, &ModelConsistency::validChanged,
        m_view, &ConstraintView::setValid);
    con(m_viewModel.model().consistency,   &ModelConsistency::warningChanged,
        m_view, &ConstraintView::setWarning);

    con(m_viewModel.model().racks, &NotifyingMap<RackModel>::removed,
    this, [&] (const auto&) {
        if(m_viewModel.model().racks.size() == 0)
        {
            this->on_noRacks();
        }
    });

    if(m_viewModel.isRackShown())
    {
        on_rackShown(m_viewModel.shownRack());
    }
    else if(!m_viewModel.model().processes.empty())
    {
        on_rackHidden();
    }
    else
    {
        on_noRacks();
    }
}