|
|
@ -8,11 +8,7 @@ using namespace QtMvvm; |
|
|
|
QQmlViewPlaceholder::QQmlViewPlaceholder(QQuickItem *parent) : |
|
|
|
QQuickItem{parent} |
|
|
|
{ |
|
|
|
// auto presenting
|
|
|
|
connect(this, &QQmlViewPlaceholder::viewModelTypeChanged, |
|
|
|
this, &QQmlViewPlaceholder::presentIfReady); |
|
|
|
connect(this, &QQmlViewPlaceholder::autoPresentChanged, |
|
|
|
this, &QQmlViewPlaceholder::presentIfReady); |
|
|
|
setImplicitSize(0, 0); // init to 0
|
|
|
|
|
|
|
|
// size changes
|
|
|
|
connect(this, &QQmlViewPlaceholder::widthChanged, |
|
|
@ -23,18 +19,12 @@ QQmlViewPlaceholder::QQmlViewPlaceholder(QQuickItem *parent) : |
|
|
|
this, &QQmlViewPlaceholder::resizeView); |
|
|
|
} |
|
|
|
|
|
|
|
bool QQmlViewPlaceholder::presentItem(const QVariant &item) |
|
|
|
bool QQmlViewPlaceholder::presentItem(QQuickItem *item) |
|
|
|
{ |
|
|
|
// check if the parameter is valid
|
|
|
|
auto quickItem = item.value<QQuickItem*>(); |
|
|
|
if(!quickItem) { |
|
|
|
qmlWarning(this) << "presentItem called with invalid item of type: " << item.typeName(); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// handle already existing view case
|
|
|
|
if(_loadedView) { |
|
|
|
if(_replaceViews) { // quick discard without reenableing all children
|
|
|
|
disconnectSizeChanges(false); |
|
|
|
_loadedView->setVisible(false); |
|
|
|
_loadedView->deleteLater(); |
|
|
|
_loadedView = nullptr; |
|
|
@ -45,11 +35,12 @@ bool QQmlViewPlaceholder::presentItem(const QVariant &item) |
|
|
|
} |
|
|
|
|
|
|
|
// add
|
|
|
|
_loadedView = quickItem; |
|
|
|
quickItem->setParent(this); |
|
|
|
quickItem->setParentItem(this); |
|
|
|
_loadedView = item; |
|
|
|
_loadedView->setParent(this); |
|
|
|
_loadedView->setParentItem(this); |
|
|
|
connectSizeChanges(); |
|
|
|
resizeView(); |
|
|
|
quickItem->setVisible(true); |
|
|
|
_loadedView->setVisible(true); |
|
|
|
|
|
|
|
// hide all children
|
|
|
|
for(auto child : childItems()) { |
|
|
@ -87,52 +78,11 @@ bool QQmlViewPlaceholder::closeAction() |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::setParentViewModel(ViewModel *parentViewModel) |
|
|
|
{ |
|
|
|
// first: clear the auto-connected viewmodel, if required
|
|
|
|
if(_clearParentVmCon && _parentVmCon) |
|
|
|
disconnect(_parentVmCon); |
|
|
|
|
|
|
|
// then: set property as usual
|
|
|
|
if(_parentViewModel == parentViewModel) |
|
|
|
return; |
|
|
|
|
|
|
|
_parentViewModel = parentViewModel; |
|
|
|
emit parentViewModelChanged(_parentViewModel); |
|
|
|
|
|
|
|
// check the vm parent for a presenter method
|
|
|
|
auto view = qobject_cast<QQuickItem*>(_parentViewModel->parent()); |
|
|
|
if(view) { |
|
|
|
if(view->metaObject()->indexOfMethod("presentItem(QVariant)") == -1) |
|
|
|
qmlWarning(this) << R"(Parent item of "parentViewModel" does not have a "presentItem" method. Check the ViewPlaceholder documentation!)"; |
|
|
|
} else |
|
|
|
qmlWarning(this) << R"(Parent item of "parentViewModel" is not an Item)"; |
|
|
|
|
|
|
|
presentIfReady(); |
|
|
|
} |
|
|
|
|
|
|
|
QQuickItem *QQmlViewPlaceholder::loadedView() const |
|
|
|
{ |
|
|
|
return _loadedView; |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::componentComplete() |
|
|
|
{ |
|
|
|
// auto-set the vm if not already set
|
|
|
|
if(!_parentViewModel) |
|
|
|
getParentViewModel(); |
|
|
|
|
|
|
|
// last step: call base implementation, then present
|
|
|
|
QQuickItem::componentComplete(); |
|
|
|
_isReady = true; |
|
|
|
presentIfReady(); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::presentView() |
|
|
|
{ |
|
|
|
CoreApp::show(qUtf8Printable(_viewModelType), _showParams, _parentViewModel); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::discardView() |
|
|
|
{ |
|
|
|
// hide view
|
|
|
@ -145,57 +95,46 @@ void QQmlViewPlaceholder::discardView() |
|
|
|
} |
|
|
|
|
|
|
|
// now delete it
|
|
|
|
disconnectSizeChanges(true); |
|
|
|
_loadedView->deleteLater(); |
|
|
|
_loadedView = nullptr; |
|
|
|
emit loadedViewChanged(nullptr); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::parentItemVmChanged(ViewModel *viewModel) |
|
|
|
void QQmlViewPlaceholder::resizeView() |
|
|
|
{ |
|
|
|
// set vm without clearing the connection
|
|
|
|
_clearParentVmCon = false; |
|
|
|
setParentViewModel(viewModel); |
|
|
|
_clearParentVmCon = true; |
|
|
|
if(_loadedView && _autoResizeView) { |
|
|
|
_loadedView->setWidth(width()); |
|
|
|
_loadedView->setHeight(height()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::presentIfReady() |
|
|
|
void QQmlViewPlaceholder::updateImpHeight() |
|
|
|
{ |
|
|
|
if(_isReady && |
|
|
|
_autoPresent && |
|
|
|
!_loadedView && |
|
|
|
_parentViewModel && |
|
|
|
!_viewModelType.isEmpty()) |
|
|
|
presentView(); |
|
|
|
setImplicitHeight(_loadedView->implicitHeight()); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::resizeView() |
|
|
|
void QQmlViewPlaceholder::updateImpWidth() |
|
|
|
{ |
|
|
|
if(_loadedView && _autoResizeView) { |
|
|
|
_loadedView->setWidth(width()); |
|
|
|
_loadedView->setHeight(height()); |
|
|
|
} |
|
|
|
setImplicitWidth(_loadedView->implicitWidth()); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::connectSizeChanges() |
|
|
|
{ |
|
|
|
connect(_loadedView, &QQuickItem::implicitWidthChanged, |
|
|
|
this, &QQmlViewPlaceholder::updateImpWidth); |
|
|
|
connect(_loadedView, &QQuickItem::implicitHeightChanged, |
|
|
|
this, &QQmlViewPlaceholder::updateImpHeight); |
|
|
|
setImplicitSize(_loadedView->implicitWidth(), |
|
|
|
_loadedView->implicitHeight()); |
|
|
|
} |
|
|
|
|
|
|
|
void QQmlViewPlaceholder::getParentViewModel() |
|
|
|
void QQmlViewPlaceholder::disconnectSizeChanges(bool resetSize) |
|
|
|
{ |
|
|
|
auto pItem = parentItem(); |
|
|
|
if(!pItem) |
|
|
|
return; |
|
|
|
|
|
|
|
QQmlProperty vmProp{pItem, QStringLiteral("viewModel")}; |
|
|
|
if(!vmProp.isValid()) |
|
|
|
return; |
|
|
|
|
|
|
|
// set the vm from the property
|
|
|
|
auto vm = vmProp.read().value<ViewModel*>(); |
|
|
|
if(vm) |
|
|
|
setParentViewModel(vm); // no warning here - might be ok for lazy presented vms
|
|
|
|
|
|
|
|
// connect to further changes, via helper slot
|
|
|
|
auto cSlotIndex = metaObject()->indexOfSlot("parentItemVmChanged(QtMvvm::ViewModel*)"); |
|
|
|
Q_ASSERT(cSlotIndex != -1); |
|
|
|
if(_parentVmCon) |
|
|
|
disconnect(_parentVmCon); |
|
|
|
_parentVmCon = connect(pItem, vmProp.property().notifySignal(), |
|
|
|
this, metaObject()->method(cSlotIndex)); |
|
|
|
disconnect(_loadedView, &QQuickItem::implicitWidthChanged, |
|
|
|
this, &QQmlViewPlaceholder::updateImpWidth); |
|
|
|
disconnect(_loadedView, &QQuickItem::implicitHeightChanged, |
|
|
|
this, &QQmlViewPlaceholder::updateImpHeight); |
|
|
|
if(resetSize) |
|
|
|
setImplicitSize(0, 0); |
|
|
|
} |
|
|
|