forked from qt-creator/qt-creator
QmlDesigner: Fix stacked container UI
* Add a new check for stacked container and index property being either a variant or a resolvable binding. * Decrease/increase checks read resolvable bindings if applicable and use model value if not. * Increase/decrease functions use resolvable bindings if applicable and use model value if not. * Fix FormEditorToolButton opacity being set on the widget instead of the painter. Task-number: QDS-15274 Change-Id: Ia8c95b900204d3d4041cda7f60534eb3a52c3f65 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
1a3998e51c
commit
a80281c6ed
@@ -25,6 +25,7 @@
|
|||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <qmldesignertr.h>
|
#include <qmldesignertr.h>
|
||||||
#include <theme.h>
|
#include <theme.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
|
||||||
#include <formeditortoolbutton.h>
|
#include <formeditortoolbutton.h>
|
||||||
|
|
||||||
@@ -1161,6 +1162,38 @@ bool isStackedContainer(const SelectionContext &context)
|
|||||||
return NodeHints::fromModelNode(currentSelectedNode).isStackedContainer();
|
return NodeHints::fromModelNode(currentSelectedNode).isStackedContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isStackedContainerAndIndexIsVariantOrResolvableBinding(const SelectionContext &context)
|
||||||
|
{
|
||||||
|
if (!isStackedContainer(context))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ModelNode currentSelectedNode = context.currentSingleSelectedNode();
|
||||||
|
|
||||||
|
const PropertyName propertyName = ModelNodeOperations::getIndexPropertyName(currentSelectedNode);
|
||||||
|
|
||||||
|
QTC_ASSERT(currentSelectedNode.metaInfo().hasProperty(propertyName), return false);
|
||||||
|
|
||||||
|
QmlItemNode containerItemNode(currentSelectedNode);
|
||||||
|
|
||||||
|
QTC_ASSERT(containerItemNode.isValid(), return false);
|
||||||
|
|
||||||
|
if (containerItemNode.hasBindingProperty(propertyName)) {
|
||||||
|
const AbstractProperty resolvedProperty = containerItemNode.bindingProperty(propertyName)
|
||||||
|
.resolveToProperty();
|
||||||
|
if (resolvedProperty.isValid() && resolvedProperty.isVariantProperty()) {
|
||||||
|
auto variantProperty = resolvedProperty.toVariantProperty();
|
||||||
|
if (!variantProperty.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return containerItemNode.modelNode().hasVariantProperty(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
bool isStackedContainerWithoutTabBar(const SelectionContext &context)
|
bool isStackedContainerWithoutTabBar(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
if (!isStackedContainer(context))
|
if (!isStackedContainer(context))
|
||||||
@@ -1196,11 +1229,38 @@ bool isStackedContainerAndIndexCanBeDecreased(const SelectionContext &context)
|
|||||||
QTC_ASSERT(currentSelectedNode.metaInfo().hasProperty(propertyName), return false);
|
QTC_ASSERT(currentSelectedNode.metaInfo().hasProperty(propertyName), return false);
|
||||||
|
|
||||||
QmlItemNode containerItemNode(currentSelectedNode);
|
QmlItemNode containerItemNode(currentSelectedNode);
|
||||||
|
|
||||||
QTC_ASSERT(containerItemNode.isValid(), return false);
|
QTC_ASSERT(containerItemNode.isValid(), return false);
|
||||||
|
|
||||||
const int value = containerItemNode.instanceValue(propertyName).toInt();
|
auto isMoreThan = [](const QVariant &variant, int min) -> bool {
|
||||||
|
if (!variant.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
return value > 0;
|
bool ok = false;
|
||||||
|
int value = variant.toInt(&ok);
|
||||||
|
return ok && value > min;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (currentSelectedNode.hasBindingProperty(propertyName)) {
|
||||||
|
const AbstractProperty resolvedProperty = currentSelectedNode.bindingProperty(propertyName)
|
||||||
|
.resolveToProperty();
|
||||||
|
if (resolvedProperty.isValid() && resolvedProperty.isVariantProperty()) {
|
||||||
|
const auto variantProperty = resolvedProperty.toVariantProperty();
|
||||||
|
if (!variantProperty.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isMoreThan(variantProperty.value(), 0))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant modelValue = containerItemNode.modelValue(propertyName);
|
||||||
|
if (isMoreThan(modelValue, 0))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isStackedContainerAndIndexCanBeIncreased(const SelectionContext &context)
|
bool isStackedContainerAndIndexCanBeIncreased(const SelectionContext &context)
|
||||||
@@ -1215,13 +1275,40 @@ bool isStackedContainerAndIndexCanBeIncreased(const SelectionContext &context)
|
|||||||
QTC_ASSERT(currentSelectedNode.metaInfo().hasProperty(propertyName), return false);
|
QTC_ASSERT(currentSelectedNode.metaInfo().hasProperty(propertyName), return false);
|
||||||
|
|
||||||
QmlItemNode containerItemNode(currentSelectedNode);
|
QmlItemNode containerItemNode(currentSelectedNode);
|
||||||
|
|
||||||
QTC_ASSERT(containerItemNode.isValid(), return false);
|
QTC_ASSERT(containerItemNode.isValid(), return false);
|
||||||
|
|
||||||
const int value = containerItemNode.instanceValue(propertyName).toInt();
|
auto isLessThan = [](const QVariant &variant, int max) -> bool {
|
||||||
|
if (!variant.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
int value = variant.toInt(&ok);
|
||||||
|
return ok && value < max;
|
||||||
|
};
|
||||||
|
|
||||||
const int maxValue = currentSelectedNode.directSubModelNodes().size() - 1;
|
const int maxValue = currentSelectedNode.directSubModelNodes().size() - 1;
|
||||||
|
|
||||||
return value < maxValue;
|
if (currentSelectedNode.hasBindingProperty(propertyName)) {
|
||||||
|
const AbstractProperty resolvedProperty = currentSelectedNode.bindingProperty(propertyName)
|
||||||
|
.resolveToProperty();
|
||||||
|
if (resolvedProperty.isValid() && resolvedProperty.isVariantProperty()) {
|
||||||
|
const auto variantProperty = resolvedProperty.toVariantProperty();
|
||||||
|
if (!variantProperty.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isLessThan(variantProperty.value(), maxValue))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant modelValue = containerItemNode.modelValue(propertyName);
|
||||||
|
if (isLessThan(modelValue, maxValue))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isGroup(const SelectionContext &context)
|
bool isGroup(const SelectionContext &context)
|
||||||
@@ -1851,8 +1938,7 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
&isStackedContainer,
|
&isStackedContainer,
|
||||||
&isStackedContainer));
|
&isStackedContainer));
|
||||||
|
|
||||||
addDesignerAction(new ModelNodeContextMenuAction(
|
addDesignerAction(new ModelNodeContextMenuAction(addTabBarToStackedContainerCommandId,
|
||||||
addTabBarToStackedContainerCommandId,
|
|
||||||
addTabBarToStackedContainerDisplayName,
|
addTabBarToStackedContainerDisplayName,
|
||||||
{},
|
{},
|
||||||
stackedContainerCategory,
|
stackedContainerCategory,
|
||||||
@@ -1862,8 +1948,8 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
&isStackedContainerWithoutTabBar,
|
&isStackedContainerWithoutTabBar,
|
||||||
&isStackedContainer));
|
&isStackedContainer));
|
||||||
|
|
||||||
addDesignerAction(new ModelNodeFormEditorAction(
|
addDesignerAction(
|
||||||
decreaseIndexOfStackedContainerCommandId,
|
new ModelNodeFormEditorAction(decreaseIndexOfStackedContainerCommandId,
|
||||||
decreaseIndexToStackedContainerDisplayName,
|
decreaseIndexToStackedContainerDisplayName,
|
||||||
prevIcon.icon(),
|
prevIcon.icon(),
|
||||||
decreaseIndexOfStackedContainerToolTip,
|
decreaseIndexOfStackedContainerToolTip,
|
||||||
@@ -1872,10 +1958,9 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
3,
|
3,
|
||||||
&decreaseIndexOfStackedContainer,
|
&decreaseIndexOfStackedContainer,
|
||||||
&isStackedContainerAndIndexCanBeDecreased,
|
&isStackedContainerAndIndexCanBeDecreased,
|
||||||
&isStackedContainer));
|
&isStackedContainerAndIndexIsVariantOrResolvableBinding));
|
||||||
|
addDesignerAction(
|
||||||
addDesignerAction(new ModelNodeFormEditorAction(
|
new ModelNodeFormEditorAction(increaseIndexOfStackedContainerCommandId,
|
||||||
increaseIndexOfStackedContainerCommandId,
|
|
||||||
increaseIndexToStackedContainerDisplayName,
|
increaseIndexToStackedContainerDisplayName,
|
||||||
nextIcon.icon(),
|
nextIcon.icon(),
|
||||||
increaseIndexOfStackedContainerToolTip,
|
increaseIndexOfStackedContainerToolTip,
|
||||||
@@ -1884,7 +1969,7 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
4,
|
4,
|
||||||
&increaseIndexOfStackedContainer,
|
&increaseIndexOfStackedContainer,
|
||||||
&isStackedContainerAndIndexCanBeIncreased,
|
&isStackedContainerAndIndexCanBeIncreased,
|
||||||
&isStackedContainer));
|
&isStackedContainerAndIndexIsVariantOrResolvableBinding));
|
||||||
|
|
||||||
addDesignerAction(
|
addDesignerAction(
|
||||||
new ModelNodeAction(layoutRowLayoutCommandId,
|
new ModelNodeAction(layoutRowLayoutCommandId,
|
||||||
|
@@ -1132,6 +1132,46 @@ static void setIndexProperty(const AbstractProperty &property, const QVariant &v
|
|||||||
Core::AsynchronousMessageBox::warning(title, description);
|
Core::AsynchronousMessageBox::warning(title, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::optional<int> getIndexProperty(const AbstractProperty &property)
|
||||||
|
{
|
||||||
|
if (property.isBindingProperty()) {
|
||||||
|
const AbstractProperty resolvedProperty = property.toBindingProperty().resolveToProperty();
|
||||||
|
if (resolvedProperty.isValid() && resolvedProperty.isVariantProperty()) {
|
||||||
|
const auto variantProperty = resolvedProperty.toVariantProperty();
|
||||||
|
if (!variantProperty.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
auto variant = variantProperty.value();
|
||||||
|
if (!variant.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
int value = variant.toInt(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QmlItemNode itemNode(property.parentModelNode());
|
||||||
|
if (!itemNode.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QVariant modelValue(itemNode.modelValue(property.name()));
|
||||||
|
if (!modelValue.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
int value = modelValue.toInt(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
||||||
{
|
{
|
||||||
AbstractView *view = selectionContext.view();
|
AbstractView *view = selectionContext.view();
|
||||||
@@ -1144,17 +1184,16 @@ void increaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
|||||||
const PropertyName propertyName = getIndexPropertyName(container);
|
const PropertyName propertyName = getIndexPropertyName(container);
|
||||||
QTC_ASSERT(container.metaInfo().hasProperty(propertyName), return);
|
QTC_ASSERT(container.metaInfo().hasProperty(propertyName), return);
|
||||||
|
|
||||||
QmlItemNode containerItemNode(container);
|
std::optional<int> value = getIndexProperty(container.property(propertyName));
|
||||||
QTC_ASSERT(containerItemNode.isValid(), return);
|
QTC_ASSERT(value, return);
|
||||||
|
|
||||||
int value = containerItemNode.instanceValue(propertyName).toInt();
|
++*value;
|
||||||
++value;
|
|
||||||
|
|
||||||
const int maxValue = container.directSubModelNodes().size();
|
const int maxValue = container.directSubModelNodes().size();
|
||||||
|
|
||||||
QTC_ASSERT(value < maxValue, return);
|
QTC_ASSERT(value < maxValue, return);
|
||||||
|
|
||||||
setIndexProperty(container.property(propertyName), value);
|
setIndexProperty(container.property(propertyName), *value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
||||||
@@ -1169,15 +1208,14 @@ void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext)
|
|||||||
const PropertyName propertyName = getIndexPropertyName(container);
|
const PropertyName propertyName = getIndexPropertyName(container);
|
||||||
QTC_ASSERT(container.metaInfo().hasProperty(propertyName), return);
|
QTC_ASSERT(container.metaInfo().hasProperty(propertyName), return);
|
||||||
|
|
||||||
QmlItemNode containerItemNode(container);
|
std::optional<int> value = getIndexProperty(container.property(propertyName));
|
||||||
QTC_ASSERT(containerItemNode.isValid(), return);
|
QTC_ASSERT(value, return);
|
||||||
|
|
||||||
int value = containerItemNode.instanceValue(propertyName).toInt();
|
--*value;
|
||||||
--value;
|
|
||||||
|
|
||||||
QTC_ASSERT(value > -1, return);
|
QTC_ASSERT(value > -1, return);
|
||||||
|
|
||||||
setIndexProperty(container.property(propertyName), value);
|
setIndexProperty(container.property(propertyName), *value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTabBarToStackedContainer(const SelectionContext &selectionContext)
|
void addTabBarToStackedContainer(const SelectionContext &selectionContext)
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
#include <utils/theme/theme.h>
|
|
||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
@@ -19,7 +19,9 @@ static const auto category = FormEditorTracing::category;
|
|||||||
|
|
||||||
const int toolButtonSize = 14;
|
const int toolButtonSize = 14;
|
||||||
|
|
||||||
FormEditorToolButton::FormEditorToolButton(QAction *action, QGraphicsItem *parent) : QGraphicsWidget(parent), m_action(action)
|
FormEditorToolButton::FormEditorToolButton(QAction *action, QGraphicsItem *parent)
|
||||||
|
: QGraphicsWidget(parent)
|
||||||
|
, m_action(action)
|
||||||
{
|
{
|
||||||
NanotraceHR::Tracer tracer{"form editor tool button constructor", category()};
|
NanotraceHR::Tracer tracer{"form editor tool button constructor", category()};
|
||||||
|
|
||||||
@@ -29,6 +31,9 @@ FormEditorToolButton::FormEditorToolButton(QAction *action, QGraphicsItem *paren
|
|||||||
connect(action, &QAction::changed, this, [this]() {
|
connect(action, &QAction::changed, this, [this]() {
|
||||||
setEnabled(m_action->isEnabled());
|
setEnabled(m_action->isEnabled());
|
||||||
setVisible(m_action->isVisible());
|
setVisible(m_action->isVisible());
|
||||||
|
// Reset to Normal. When action isn't enabled anymore and therefor the button too, it
|
||||||
|
// doesn't receives events anymore, which leaves the state in Hover.
|
||||||
|
m_state = Normal;
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,10 +51,14 @@ void FormEditorToolButton::paint(QPainter *painter, const QStyleOptionGraphicsIt
|
|||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
QRectF adjustedRect(size().width() - toolButtonSize, size().height() - toolButtonSize, toolButtonSize, toolButtonSize);
|
QRectF adjustedRect(size().width() - toolButtonSize,
|
||||||
|
size().height() - toolButtonSize,
|
||||||
|
toolButtonSize,
|
||||||
|
toolButtonSize);
|
||||||
painter->setPen(Qt::NoPen);
|
painter->setPen(Qt::NoPen);
|
||||||
|
|
||||||
static QColor selectionColor = Utils::creatorColor(Utils::Theme::QmlDesigner_FormEditorSelectionColor);
|
static QColor selectionColor = Utils::creatorColor(
|
||||||
|
Utils::Theme::QmlDesigner_FormEditorSelectionColor);
|
||||||
|
|
||||||
if (m_state == Hovered)
|
if (m_state == Hovered)
|
||||||
painter->setBrush(selectionColor.lighter(110));
|
painter->setBrush(selectionColor.lighter(110));
|
||||||
@@ -60,9 +69,11 @@ void FormEditorToolButton::paint(QPainter *painter, const QStyleOptionGraphicsIt
|
|||||||
painter->drawRoundedRect(adjustedRect, 1, 1, Qt::AbsoluteSize);
|
painter->drawRoundedRect(adjustedRect, 1, 1, Qt::AbsoluteSize);
|
||||||
|
|
||||||
if (!isEnabled())
|
if (!isEnabled())
|
||||||
setOpacity(0.5);
|
painter->setOpacity(0.5);
|
||||||
|
|
||||||
painter->drawPixmap(size().width() - toolButtonSize, size().height() - toolButtonSize, m_action->icon().pixmap(toolButtonSize, toolButtonSize));
|
painter->drawPixmap(size().width() - toolButtonSize,
|
||||||
|
size().height() - toolButtonSize,
|
||||||
|
m_action->icon().pixmap(toolButtonSize, toolButtonSize));
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
@@ -122,4 +133,4 @@ void FormEditorToolButton::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
|
|||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
} //QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -212,7 +212,8 @@ void SelectionIndicator::adjustAnnotationPosition(const QRectF &itemRect, const
|
|||||||
{
|
{
|
||||||
NanotraceHR::Tracer tracer{"selection indicator adjust annotation position", category()};
|
NanotraceHR::Tracer tracer{"selection indicator adjust annotation position", category()};
|
||||||
|
|
||||||
if (!m_annotationItem) return;
|
if (!m_annotationItem)
|
||||||
|
return;
|
||||||
|
|
||||||
const qreal iconWShift = m_annotationItem->iconWidth() * 0.5;
|
const qreal iconWShift = m_annotationItem->iconWidth() * 0.5;
|
||||||
const qreal iconHShift = (m_annotationItem->iconHeight() * 0.45) / scaleFactor;
|
const qreal iconHShift = (m_annotationItem->iconHeight() * 0.45) / scaleFactor;
|
||||||
@@ -229,6 +230,5 @@ void SelectionIndicator::adjustAnnotationPosition(const QRectF &itemRect, const
|
|||||||
|
|
||||||
m_annotationItem->setPos(iconX * scaleFactor, iconY * scaleFactor);
|
m_annotationItem->setPos(iconX * scaleFactor, iconY * scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user