Merge "Merge remote-tracking branch 'origin/5.0'"

This commit is contained in:
The Qt Project
2021-09-01 10:56:08 +00:00
43 changed files with 257 additions and 119 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -64,10 +64,11 @@
The output is evaluated as \c true if both inputs are \c true. The output is evaluated as \c true if both inputs are \c true.
For example, we could use the checked state of two check boxes to determine For example, we could use the checked state of two check boxes to determine
the checked state of a third one. First we drag-and-drop three the checked state of a third one. First, we drag-and-drop three instances of
\uicontrol {Check Box} component and an \uicontrol {And Operator} to the \uicontrol {Check Box} components and one instance of the
\uicontrol Navigator (1). Then we select the \uicontrol {And Operator} \uicontrol {And Operator} component to \uicontrol Navigator (1). Then, we
component (2) and set its properties in \l Properties (3). select the \uicontrol {And Operator} component instance (2) and set its
properties in \l Properties (3).
We select \inlineimage icons/action-icon.png We select \inlineimage icons/action-icon.png
next to the \uicontrol {Input 01} field to display the \uicontrol Actions next to the \uicontrol {Input 01} field to display the \uicontrol Actions
@@ -80,13 +81,6 @@
\image studio-logic-helper-and.png "AND operator properties" \image studio-logic-helper-and.png "AND operator properties"
Then, we select the first and second check box, and set their
\uicontrol Checked property to \c true in \uicontrol Properties.
We can multiselect the controls and make the change simultaneously
for both of them.
\image studio-logic-helper-and-operator-multiselect.gif "Multiselecting check boxes and changing Checked property"
Finally, we select the third check box and bind its \uicontrol Checked Finally, we select the third check box and bind its \uicontrol Checked
property to the \uicontrol Output property of the AND operator. property to the \uicontrol Output property of the AND operator.
@@ -109,16 +103,17 @@
condition is not met. condition is not met.
For example, we could specify that if one check box is checked, another For example, we could specify that if one check box is checked, another
one cannot be checked. First we drag-and-drop two \uicontrol {Check Box} one cannot be checked. First, we drag-and-drop two instances of the
component and a \uicontrol {Not Operator} to \uicontrol Navigator. Then we \uicontrol {Check Box} component and one instance of the
select \uicontrol {Not Operator} and set its properties in \uicontrol {Not Operator} component to \uicontrol Navigator. Then, we select
the \uicontrol {Not Operator} component instance and set its properties in
\uicontrol Properties. In the \uicontrol {Binding Editor}, we bind the \uicontrol Properties. In the \uicontrol {Binding Editor}, we bind the
value of the \c input property of the NOT operator to the value of the value of the \c input property of the NOT operator to the value of the
\c checked property of the check box. \c checked property of one check box instance.
\image studio-logic-helper-not.png "NOT operator properties" \image studio-logic-helper-not.png "NOT operator properties"
We then select the second check box and bind the value of its We then select the other check box instance and bind the value of its
\uicontrol Checked field to the value of of \uicontrol Output \uicontrol Checked field to the value of of \uicontrol Output
field of the \uicontrol {Not Operator} component. field of the \uicontrol {Not Operator} component.
@@ -137,10 +132,11 @@
a slider and checkbox. Typically, it is used to bind a backend value a slider and checkbox. Typically, it is used to bind a backend value
to a control, such as a slider. to a control, such as a slider.
For example, to synchronize the values of two sliders, drag-and-drop two For example, to synchronize the values of two sliders, we drag-and-drop two
\uicontrol Slider components and one \uicontrol {Bi Direct. Binding} instances of the \uicontrol Slider component and one instance of the
component to the same parent component in \uicontrol Navigator. Then select \uicontrol {Bi Direct. Binding} component to the same parent component in
the bi-directional binding and set its properties in \uicontrol Properties. \uicontrol Navigator. Then, we select the bi-directional binding instance
and set its properties in \uicontrol Properties.
\image studio-logic-helper-bidirectional-binding.png "Bi-directional binding properties" \image studio-logic-helper-bidirectional-binding.png "Bi-directional binding properties"
@@ -158,7 +154,7 @@
\section1 String Mapper \section1 String Mapper
The \uicontrol {String Mapper} component maps numbers to strings. First you The \uicontrol {String Mapper} component maps numbers to strings. First, you
\l{Adding Bindings Between Properties}{add a binding} between the string \l{Adding Bindings Between Properties}{add a binding} between the string
mapper \c input property and the \c value property of the control that you mapper \c input property and the \c value property of the control that you
want to fetch the values from. Then, you add a binding between the \c text want to fetch the values from. Then, you add a binding between the \c text
@@ -167,17 +163,17 @@
For example, to use a \l Text component to display the value of a For example, to use a \l Text component to display the value of a
slider, we drag-and-drop \uicontrol Text, \uicontrol Slider, and slider, we drag-and-drop \uicontrol Text, \uicontrol Slider, and
\uicontrol {String Mapper} components to the same parent component. Then \uicontrol {String Mapper} components to the same parent component. Then,
we select \uicontrol {String Mapper} in \uicontrol Navigator to display we select the \uicontrol {String Mapper} instance in \uicontrol Navigator
its properties in \uicontrol Properties. There we bind the value of the to display its properties in \uicontrol Properties. There we bind the value
\c input property of the string mapper to the value of the \c value of the \uicontrol Input field to the value of the \c value property of the
property of the slider. \uicontrol Slider instance.
\image studio-logic-helper-string-mapper-input.png "Binding slider value property to string mapper" \image studio-logic-helper-string-mapper-input.png "Binding slider value property to string mapper"
Next, we bind the value of the \uicontrol Text field of the Next, we select the \uicontrol Text instance and bind the value of the
\uicontrol Text component to the value of the \uicontrol Text \uicontrol Text field to the value of the \uicontrol {Output text} field
field of the \uicontrol {String Mapper} component. (\c text property) of the \uicontrol {String Mapper} component.
\image studio-logic-helper-string-mapper-text.png "Binding text property value to string mapper" \image studio-logic-helper-string-mapper-text.png "Binding text property value to string mapper"
@@ -186,8 +182,8 @@
\image studio-logic-helper-string-mapper.gif "Previewing text property binding to string mapper" \image studio-logic-helper-string-mapper.gif "Previewing text property binding to string mapper"
The value of the \uicontrol Decimals field determines the number of digits The value of the \uicontrol {Decimal places} field determines the number
after the decimal separator. of digits after the decimal separator.
\section1 Minimum-Maximum Mapper \section1 Minimum-Maximum Mapper
@@ -205,7 +201,7 @@
above. We select it to display its properties in \uicontrol Properties. above. We select it to display its properties in \uicontrol Properties.
Then, we bind the value of the \uicontrol Input property of the mapper to Then, we bind the value of the \uicontrol Input property of the mapper to
the value of the \c value property of the slider and set the value the value of the \c value property of the slider and set the value
of the \uicontrol Maximum field to 0.60. of the \uicontrol Max field to 0.60.
\image studio-logic-helper-minmax-mapper-input.png "Binding slider value property to string mapper" \image studio-logic-helper-minmax-mapper-input.png "Binding slider value property to string mapper"
@@ -221,12 +217,12 @@
\image studio-logic-helper-minmax-mapper.gif "Previewing a minimum-maximum mapper" \image studio-logic-helper-minmax-mapper.gif "Previewing a minimum-maximum mapper"
The \uicontrol {Out of range}, \uicontrol {Above maximum} and The \uicontrol {Out of range}, \uicontrol {Above max} and
\uicontrol {Below minimum} check boxes are set to \c true if \uicontrol {Below min} check boxes are set to \c true if
the value of the \uicontrol Input field is out of range. the value of the \uicontrol Input field is out of range.
For example, in the context of speed, \uicontrol {Above maximum} being For example, in the context of speed, \uicontrol {Above max} being
\c true would mean \e {too fast}, whereas \uicontrol {Below minimum} \c true would mean \e {too fast}, whereas \uicontrol {Below min}
being \c true, would mean \e {too slow}, and \uicontrol {Out of range} being \c true, would mean \e {too slow}, and \uicontrol {Out of range}
being \c true would mean \e {either too fast or too slow}. being \c true would mean \e {either too fast or too slow}.
@@ -240,23 +236,23 @@
\image studio-logic-helper-range-mapper-properties.png "Range Mapper properties" \image studio-logic-helper-range-mapper-properties.png "Range Mapper properties"
Specify the minimum and maximum input and output values in the Specify the minimum and maximum input and output values in the
\uicontrol {Input minimum}, \uicontrol {Input maximum}, \uicontrol {Input min}, \uicontrol {Input max},
\uicontrol {Output minimum}, and \uicontrol {Output maximum} fields \uicontrol {Output min}, and \uicontrol {Output max} fields
and the original value in the \uicontrol Output field. and the original value in the \uicontrol Output field.
For example, we can specify that the values of a slider range from -1 to 1. For example, we can specify that the values of a slider range from 0 to 1.
If we want to display values from 10 to 1000, instead, we can bind the If we want to display values from 10 to 100, instead, we can bind the
values of the \uicontrol From and \uicontrol To fields of the \l Slider values of the \uicontrol From and \uicontrol To fields of the \l Slider
component to the values of the \uicontrol {Input minimum} and component to the values of the \uicontrol {Input min} and
\uicontrol {Input maximum} fields of a \uicontrol {Range Mapper} component. \uicontrol {Input max} fields of a \uicontrol {Range Mapper} component.
We then set the value of the \uicontrol {Output minimum} field to 10 and the We then set the value of the \uicontrol {Output min} field to 10 and the
value of the \uicontrol {Output maximum} field to 1000. value of the \uicontrol {Output max} field to 100.
\image studio-logic-helper-range-mapper-inputmin.png "Binding range mapper minimum input to slider.from property" \image studio-logic-helper-range-mapper-inputmin.png "Binding range mapper minimum input to slider.from property"
When we move the slider handle in the preview, so that the input value When we move the slider handle in the preview, so that the input value
from the \l Slider component changes from -1 to 1, the output value changes from the \l Slider component changes from 0 to 1, the output value changes
from 10 to 1000. from 10 to 100.
\image studio-logic-helper-range-mapper.gif "Previewing a range mapper" \image studio-logic-helper-range-mapper.gif "Previewing a range mapper"
@@ -281,7 +277,7 @@
To define a price range from 0 to 1000, we bind the \uicontrol Input To define a price range from 0 to 1000, we bind the \uicontrol Input
property of the \uicontrol {Range Mapper} component to the slider value property of the \uicontrol {Range Mapper} component to the slider value
and set the maximum input value for the price range in the and set the maximum input value for the price range in the
\uicontrol {Input maximum} field to 1000. The minimum input value is 0 \uicontrol {Input max} field to 1000. The minimum input value is 0
by default, so we don't need to change it. by default, so we don't need to change it.
\image studio-logic-helper-combining-example-rm.png "Range Mapper properties" \image studio-logic-helper-combining-example-rm.png "Range Mapper properties"
@@ -294,26 +290,26 @@
For the blocked range, we bind the \uicontrol Input property of For the blocked range, we bind the \uicontrol Input property of
the minimum-maximum mapper to the \uicontrol Output value of the the minimum-maximum mapper to the \uicontrol Output value of the
\uicontrol {Range Mapper} component and specify the maximum input \uicontrol {Range Mapper} component and specify the maximum input
value in the \uicontrol Maximum field. value in the \uicontrol Max field.
\image studio-logic-helper-combining-example-mmm-blocked.png "Blocked range mapper properties" \image studio-logic-helper-combining-example-mmm-blocked.png "Blocked range mapper properties"
We use two \uicontrol {And Operator} components to determine that We use two \uicontrol {And Operator} components to determine that
the sell button should be hidden when the value is in the blocked the sell button should be hidden when the value is in the blocked
range. We do this by binding the value of the \uicontrol {Output 01} range. We do this by binding the value of the \uicontrol {Input 02}
field to an evaluation of the value of \uicontrol {Out of range} field field to an evaluation of the value of \uicontrol {Out of range} field
of the minimum-maximum mapper. We specify that when the value is not of the minimum-maximum mapper. We specify that when the value is not
out of range, it evaluates to \e true. out of range, it evaluates to \e true.
\image studio-logic-helper-combining-example-ao1.png "Under value minimum-maximum mapper Output 01" \image studio-logic-helper-combining-example-ao1.png "Under value minimum-maximum mapper Input 02"
For the \e underValueAnd operator, we additionally bind the value of the For the \e underValueAnd operator, we additionally bind the value of the
\uicontrol {Output 02} field to the value of the \uicontrol {Below minimum} \uicontrol {Input 01} field to the value of the \uicontrol {Below min}
field of the minimum-maximum mapper for the bad value range. For the field of the minimum-maximum mapper for the bad value range. For the
\e overValueAnd operator, we bind it to the value of the \e overValueAnd operator, we bind it to the value of the
\uicontrol {Above maximum} field of the the same mapper. \uicontrol {Above max} field of the the same mapper.
\image studio-logic-helper-combining-example-ao2.png "Under value minimum-maximum mapper Output 02" \image studio-logic-helper-combining-example-ao2.png "Under value minimum-maximum mapper Input 01"
We can now evaluate values of the \uicontrol {Min Max Mapper} We can now evaluate values of the \uicontrol {Min Max Mapper}
and \uicontrol {And Operator} components to apply different and \uicontrol {And Operator} components to apply different
@@ -324,14 +320,14 @@
\image studio-logic-helper-combining-example.png \image studio-logic-helper-combining-example.png
First, we create a \e tooLow state and set a \c when condition to First, we create a \e tooLow state and set a \c when condition to
apply it when the value of the \uicontrol {Below minimum} field of apply it when the value of the \uicontrol {Below min} field of
the \uicontrol {Min Max Mapper} component for the blocked range the \uicontrol {Min Max Mapper} component for the blocked range
evaluates to \c true. evaluates to \c true.
\image studio-logic-helper-combining-example-states-toolow.png "Setting when condition of tooLow state" \image studio-logic-helper-combining-example-states-toolow.png "Setting when condition of tooLow state"
For the \e tooHigh state at the other end of the scale, we set the \c when For the \e tooHigh state at the other end of the scale, we set the \c when
condition to apply it when the value of the \uicontrol {Below minimum} field condition to apply it when the value of the \uicontrol {Above max} field
of the \uicontrol {Min Max Mapper} component for the blocked range evaluates of the \uicontrol {Min Max Mapper} component for the blocked range evaluates
to \c true. to \c true.

View File

@@ -51,6 +51,8 @@
#include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgrenderer_p.h> #include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgrhilayer_p.h> #include <QtQuick/private/qsgrhilayer_p.h>
#else
#include <QtQuick/private/qquickitem_p.h>
#endif #endif
namespace QmlDesigner { namespace QmlDesigner {
@@ -152,6 +154,7 @@ void Qt5NodeInstanceServer::resizeCanvasToRootItem()
m_viewData.contentItem->setPosition(-m_viewData.rootItem->position()); m_viewData.contentItem->setPosition(-m_viewData.rootItem->position());
#endif #endif
quickWindow()->resize(rootNodeInstance().boundingRect().size().toSize()); quickWindow()->resize(rootNodeInstance().boundingRect().size().toSize());
DesignerSupport::addDirty(rootNodeInstance().rootQuickItem(), QQuickDesignerSupport::Size);
} }
void Qt5NodeInstanceServer::resetAllItems() void Qt5NodeInstanceServer::resetAllItems()
@@ -335,6 +338,44 @@ QImage Qt5NodeInstanceServer::grabWindow()
return {}; return {};
} }
static bool hasEffect(QQuickItem *item)
{
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
return pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect();
}
QQuickItem *Qt5NodeInstanceServer::parentEffectItem(QQuickItem *item)
{
QQuickItem *parent = item->parentItem();
while (parent) {
if (hasEffect(parent))
return parent;
parent = parent->parentItem();
}
return nullptr;
}
static bool isEffectItem(QQuickItem *item, QQuickShaderEffectSource *sourceItem)
{
QQuickItemPrivate *pItem = QQuickItemPrivate::get(sourceItem);
if (!pItem || !pItem->layer())
return false;
const auto propName = pItem->layer()->name();
QQmlProperty prop(item, QString::fromLatin1(propName));
if (!prop.isValid())
return false;
return prop.read().value<QQuickShaderEffectSource *>() == sourceItem;
}
static bool isLayerEnabled(QQuickItemPrivate *item)
{
return item && item->layer() && item->layer()->enabled();
}
QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
{ {
QImage renderImage; QImage renderImage;
@@ -343,18 +384,54 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
return {}; return {};
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item); QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
pItem->refFromEffectItem(false);
const bool renderEffects = qEnvironmentVariableIsSet("QMLPUPPET_RENDER_EFFECTS");
if (renderEffects) {
if (parentEffectItem(item))
return renderImage;
// Effects are actually implemented as a separate item we have to find first
if (hasEffect(item)) {
if (auto parent = item->parentItem()) {
const auto siblings = parent->childItems();
for (auto sibling : siblings) {
if (isEffectItem(sibling, pItem->layer()->effectSource()))
return grabItem(sibling);
}
}
}
}
if (!isLayerEnabled(pItem))
pItem->refFromEffectItem(false);
ServerNodeInstance instance = instanceForObject(item); ServerNodeInstance instance = instanceForObject(item);
const auto childInstances = instance.childItems();
// Setting layer enabled to false messes up the bounding rect.
// Therefore we calculate it upfront.
QRectF renderBoundingRect;
if (instance.isValid())
renderBoundingRect = instance.boundingRect();
else
renderBoundingRect = item->boundingRect();
// Hide immediate children that have instances and are QQuickItems so we get only // Hide immediate children that have instances and are QQuickItems so we get only
// the parent item's content, as compositing is handled on creator side. // the parent item's content, as compositing is handled on creator side.
for (const auto &childInstance : childInstances) { QSet<QQuickItem *> layerChildren;
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
if (childItem) { if (instance.isValid()) { //Not valid for effect
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); const auto childInstances = instance.childItems();
pChild->refFromEffectItem(true); for (const auto &childInstance : childInstances) {
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
if (childItem) {
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
if (pChild->layer() && pChild->layer()->enabled()) {
layerChildren.insert(childItem);
pChild->layer()->setEnabled(false);
}
pChild->refFromEffectItem(true);
}
} }
} }
@@ -372,11 +449,15 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context; QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context;
QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc); QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc);
layer->setItem(pItem->itemNode()); layer->setItem(pItem->itemNode());
QSizeF itemSize = QSizeF(item->width(), item->height());
layer->setRect(QRectF(0, itemSize.height(), itemSize.width(), -itemSize.height())); layer->setRect(QRectF(renderBoundingRect.x(),
renderBoundingRect.y() + renderBoundingRect.height(),
renderBoundingRect.width(),
-renderBoundingRect.height()));
const QSize minSize = rc->sceneGraphContext()->minimumFBOSize(); const QSize minSize = rc->sceneGraphContext()->minimumFBOSize();
layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())), layer->setSize(QSize(qMax(minSize.width(), int(renderBoundingRect.width())),
qMax(minSize.height(), int(itemSize.height())))); qMax(minSize.height(), int(renderBoundingRect.height()))));
layer->scheduleUpdate(); layer->scheduleUpdate();
if (layer->updateTexture()) if (layer->updateTexture())
@@ -394,15 +475,24 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
m_viewData.renderControl->endFrame(); m_viewData.renderControl->endFrame();
// Restore visibility of immediate children that have instances and are QQuickItems if (instance.isValid()) { //Not valid for effect
for (const auto &childInstance : childInstances) { const auto childInstances = instance.childItems();
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
if (childItem) { // Restore visibility of immediate children that have instances and are QQuickItems
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); for (const auto &childInstance : childInstances) {
pChild->derefFromEffectItem(true); QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
if (childItem) {
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
pChild->derefFromEffectItem(true);
if (pChild->layer() && layerChildren.contains(childItem))
pChild->layer()->setEnabled(true);
}
} }
} }
pItem->derefFromEffectItem(false);
if (!isLayerEnabled(pItem))
pItem->derefFromEffectItem(false);
#else #else
Q_UNUSED(item) Q_UNUSED(item)
#endif #endif

View File

@@ -71,6 +71,8 @@ public:
QImage grabWindow() override; QImage grabWindow() override;
QImage grabItem(QQuickItem *item) override; QImage grabItem(QQuickItem *item) override;
static QQuickItem *parentEffectItem(QQuickItem *item);
protected: protected:
void initializeView() override; void initializeView() override;
void resizeCanvasToRootItem() override; void resizeCanvasToRootItem() override;

View File

@@ -89,8 +89,20 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
if (hasInstanceForObject(item)) { if (hasInstanceForObject(item)) {
if (DesignerSupport::isDirty(item, DesignerSupport::ContentUpdateMask)) if (DesignerSupport::isDirty(item, DesignerSupport::ContentUpdateMask))
m_dirtyInstanceSet.insert(instanceForObject(item)); m_dirtyInstanceSet.insert(instanceForObject(item));
if (QQuickItem *effectParent = parentEffectItem(item)) {
if ((DesignerSupport::isDirty(
item,
DesignerSupport::DirtyType(
DesignerSupport::TransformUpdateMask
| DesignerSupport::Visible
| DesignerSupport::ContentUpdateMask)))
&& hasInstanceForObject(effectParent)) {
m_dirtyInstanceSet.insert(instanceForObject(effectParent));
}
}
} else if (DesignerSupport::isDirty(item, DesignerSupport::AllMask)) { } else if (DesignerSupport::isDirty(item, DesignerSupport::AllMask)) {
ServerNodeInstance ancestorInstance = findNodeInstanceForItem(item->parentItem()); ServerNodeInstance ancestorInstance = findNodeInstanceForItem(
item->parentItem());
if (ancestorInstance.isValid()) if (ancestorInstance.isValid())
m_dirtyInstanceSet.insert(ancestorInstance); m_dirtyInstanceSet.insert(ancestorInstance);
} }

View File

@@ -28,6 +28,9 @@
#include <qmlprivategate.h> #include <qmlprivategate.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickshadereffectsource_p.h>
#include <QQmlProperty> #include <QQmlProperty>
#include <QQmlExpression> #include <QQmlExpression>
#include <QQuickView> #include <QQuickView>
@@ -476,11 +479,12 @@ QImage QuickItemNodeInstance::renderImage() const
} }
renderImage.setDevicePixelRatio(devicePixelRatio); renderImage.setDevicePixelRatio(devicePixelRatio);
#else #else
if (s_unifiedRenderPath) if (s_unifiedRenderPath) {
renderImage = nodeInstanceServer()->grabWindow(); renderImage = nodeInstanceServer()->grabWindow();
else renderImage = renderImage.copy(renderBoundingRect.toRect());
} else {
renderImage = nodeInstanceServer()->grabItem(quickItem()); renderImage = nodeInstanceServer()->grabItem(quickItem());
renderImage = renderImage.copy(renderBoundingRect.toRect()); }
/* When grabbing an offscren window the device pixel ratio is 1 */ /* When grabbing an offscren window the device pixel ratio is 1 */
renderImage.setDevicePixelRatio(1); renderImage.setDevicePixelRatio(1);
@@ -608,11 +612,51 @@ void QuickItemNodeInstance::updateAllDirtyNodesRecursive(QQuickItem *parentItem)
updateDirtyNode(parentItem); updateDirtyNode(parentItem);
} }
void QuickItemNodeInstance::setAllNodesDirtyRecursive(QQuickItem *parentItem) const
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_UNUSED(parentItem)
#else
const QList<QQuickItem *> children = parentItem->childItems();
for (QQuickItem *childItem : children)
setAllNodesDirtyRecursive(childItem);
DesignerSupport::addDirty(parentItem, QQuickDesignerSupport::Content);
#endif
}
static inline bool isRectangleSane(const QRectF &rect) static inline bool isRectangleSane(const QRectF &rect)
{ {
return rect.isValid() && (rect.width() < 10000) && (rect.height() < 10000); return rect.isValid() && (rect.width() < 10000) && (rect.height() < 10000);
} }
static bool isEffectItem(QQuickItem *item)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_UNUSED(item)
return false;
#else
if (qobject_cast<QQuickShaderEffectSource *>(item))
return true;
const auto propName = "source";
QQmlProperty prop(item, QString::fromLatin1(propName));
if (!prop.isValid())
return false;
QQuickShaderEffectSource *source = prop.read().value<QQuickShaderEffectSource *>();
if (source && source->sourceItem()) {
QQuickItemPrivate *pItem = QQuickItemPrivate::get(source->sourceItem());
if (pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect())
return true;
}
return false;
#endif
}
QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) const QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) const
{ {
QRectF boundingRect = parentItem->boundingRect(); QRectF boundingRect = parentItem->boundingRect();
@@ -620,8 +664,9 @@ QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem)
boundingRect = boundingRect.united(QRectF(QPointF(0, 0), size())); boundingRect = boundingRect.united(QRectF(QPointF(0, 0), size()));
for (QQuickItem *childItem : parentItem->childItems()) { for (QQuickItem *childItem : parentItem->childItems()) {
if (!nodeInstanceServer()->hasInstanceForObject(childItem)) { if (!nodeInstanceServer()->hasInstanceForObject(childItem) && !isEffectItem(childItem)) {
QRectF transformedRect = childItem->mapRectToItem(parentItem, boundingRectWithStepChilds(childItem)); QRectF transformedRect = childItem->mapRectToItem(parentItem,
boundingRectWithStepChilds(childItem));
if (isRectangleSane(transformedRect)) if (isRectangleSane(transformedRect))
boundingRect = boundingRect.united(transformedRect); boundingRect = boundingRect.united(transformedRect);
} }
@@ -780,6 +825,9 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q
if (name == "y") if (name == "y")
m_y = value.toDouble(); m_y = value.toDouble();
if (name == "layer.enabled" || name == "layer.effect")
setAllNodesDirtyRecursive(quickItem());
ObjectNodeInstance::setPropertyVariant(name, value); ObjectNodeInstance::setPropertyVariant(name, value);
refresh(); refresh();
@@ -849,6 +897,9 @@ void QuickItemNodeInstance::resetProperty(const PropertyName &name)
if (name == "y") if (name == "y")
m_y = 0.0; m_y = 0.0;
if (name == "layer.enabled" || name == "layer.effect")
setAllNodesDirtyRecursive(quickItem());
DesignerSupport::resetAnchor(quickItem(), QString::fromUtf8(name)); DesignerSupport::resetAnchor(quickItem(), QString::fromUtf8(name));
if (name == "anchors.fill") { if (name == "anchors.fill") {

View File

@@ -118,6 +118,7 @@ protected:
Qt5NodeInstanceServer *qt5NodeInstanceServer() const; Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
void updateDirtyNodesRecursive(QQuickItem *parentItem) const; void updateDirtyNodesRecursive(QQuickItem *parentItem) const;
void updateAllDirtyNodesRecursive(QQuickItem *parentItem) const; void updateAllDirtyNodesRecursive(QQuickItem *parentItem) const;
void setAllNodesDirtyRecursive(QQuickItem *parentItem) const;
QRectF boundingRectWithStepChilds(QQuickItem *parentItem) const; QRectF boundingRectWithStepChilds(QQuickItem *parentItem) const;
void resetHorizontal(); void resetHorizontal();
void resetVertical(); void resetVertical();

View File

@@ -221,6 +221,9 @@ QString static getErrorString(QQmlEngine *engine, const QString &componentPath)
bool isInPathList(const QStringList &pathList, const QString &componentPath) bool isInPathList(const QStringList &pathList, const QString &componentPath)
{ {
if (componentPath.indexOf("qml/QtQuick/Controls") > 0)
return true;
return std::any_of(pathList.begin(), pathList.end(), [&](auto &&path) { return std::any_of(pathList.begin(), pathList.end(), [&](auto &&path) {
return componentPath.startsWith(path); return componentPath.startsWith(path);
}); });

View File

@@ -36,7 +36,7 @@ Section {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
readonly property string disbaledTooltip: qsTr("This property is defined by an anchor or a layout.") readonly property string disabledTooltip: qsTr("This property is defined by an anchor or a layout.")
function positionDisabled() { function positionDisabled() {
return anchorBackend.isFilled || anchorBackend.isInLayout return anchorBackend.isFilled || anchorBackend.isInLayout
@@ -88,7 +88,7 @@ Section {
ControlLabel { ControlLabel {
text: "X" text: "X"
tooltip: xSpinBox.enabled ? "X" : root.disbaledTooltip tooltip: xSpinBox.enabled ? "X" : root.disabledTooltip
enabled: xSpinBox.enabled enabled: xSpinBox.enabled
} }
@@ -109,7 +109,7 @@ Section {
ControlLabel { ControlLabel {
text: "Y" text: "Y"
tooltip: xSpinBox.enabled ? "Y" : root.disbaledTooltip tooltip: xSpinBox.enabled ? "Y" : root.disabledTooltip
enabled: ySpinBox.enabled enabled: ySpinBox.enabled
} }
/* /*
@@ -143,7 +143,7 @@ Section {
ControlLabel { ControlLabel {
//: The width of the object //: The width of the object
text: qsTr("W", "width") text: qsTr("W", "width")
tooltip: widthSpinBox.enabled ? qsTr("Width") : root.disbaledTooltip tooltip: widthSpinBox.enabled ? qsTr("Width") : root.disabledTooltip
enabled: widthSpinBox.enabled enabled: widthSpinBox.enabled
} }
@@ -165,7 +165,7 @@ Section {
ControlLabel { ControlLabel {
//: The height of the object //: The height of the object
text: qsTr("H", "height") text: qsTr("H", "height")
tooltip: heightSpinBox.enabled ? qsTr("Height") : root.disbaledTooltip tooltip: heightSpinBox.enabled ? qsTr("Height") : root.disabledTooltip
enabled: heightSpinBox.enabled enabled: heightSpinBox.enabled
} }
/* /*

View File

@@ -697,11 +697,10 @@ void QtcProcess::start()
qWarning("QtcProcess::start: Empty environment set when running '%s'.", qWarning("QtcProcess::start: Empty environment set when running '%s'.",
qPrintable(d->m_commandLine.executable().toString())); qPrintable(d->m_commandLine.executable().toString()));
env = d->m_environment; env = d->m_environment;
d->m_process->setProcessEnvironment(env.toProcessEnvironment());
} else { } else {
env = Environment::systemEnvironment(); env = Environment::systemEnvironment();
} }
d->m_process->setProcessEnvironment(env.toProcessEnvironment());
d->m_process->setWorkingDirectory(d->m_workingDirectory.path()); d->m_process->setWorkingDirectory(d->m_workingDirectory.path());

View File

@@ -502,8 +502,7 @@ void MimeTypeSettingsPrivate::ensurePendingMimeType(const Utils::MimeType &mimeT
void MimeTypeSettingsPrivate::writeUserModifiedMimeTypes() void MimeTypeSettingsPrivate::writeUserModifiedMimeTypes()
{ {
static Utils::FilePath modifiedMimeTypesFile = ICore::userResourcePath() static Utils::FilePath modifiedMimeTypesFile = ICore::userResourcePath(kModifiedMimeTypesFile);
+ kModifiedMimeTypesFile;
if (QFile::exists(modifiedMimeTypesFile.toString()) if (QFile::exists(modifiedMimeTypesFile.toString())
|| QDir().mkpath(modifiedMimeTypesFile.parentDir().toString())) { || QDir().mkpath(modifiedMimeTypesFile.parentDir().toString())) {

View File

@@ -200,7 +200,7 @@ QVariant ItemLibraryAssetsModel::data(const QModelIndex &index, int role) const
} }
if (m_roleNames.contains(role)) if (m_roleNames.contains(role))
return m_assetsDir ? m_assetsDir->property(m_roleNames.value(role)) : QVariant(); return m_assetsDir ? m_assetsDir->property(m_roleNames.value(role)) : QVariant("");
qWarning() << Q_FUNC_INFO << "Invalid role requested: " << QString::number(role); qWarning() << Q_FUNC_INFO << "Invalid role requested: " << QString::number(role);
return {}; return {};

View File

@@ -493,6 +493,7 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
environment.set("QML_BAD_GUI_RENDER_LOOP", "true"); environment.set("QML_BAD_GUI_RENDER_LOOP", "true");
environment.set("QML_PUPPET_MODE", "true"); environment.set("QML_PUPPET_MODE", "true");
environment.set("QML_DISABLE_DISK_CACHE", "true"); environment.set("QML_DISABLE_DISK_CACHE", "true");
environment.set("QMLPUPPET_RENDER_EFFECTS", "true");
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (!environment.hasKey("QT_SCREEN_SCALE_FACTORS") && !environment.hasKey("QT_SCALE_FACTOR") if (!environment.hasKey("QT_SCREEN_SCALE_FACTORS") && !environment.hasKey("QT_SCALE_FACTOR")
&& QApplication::testAttribute(Qt::AA_EnableHighDpiScaling)) && QApplication::testAttribute(Qt::AA_EnableHighDpiScaling))

View File

@@ -329,10 +329,11 @@ bool isComponentType(const QmlDesigner::TypeName &type)
bool isCustomParserType(const QmlDesigner::TypeName &type) bool isCustomParserType(const QmlDesigner::TypeName &type)
{ {
return type == "QtQuick.VisualItemModel" || type == "Qt.VisualItemModel" || return type == "QtQuick.VisualItemModel" || type == "Qt.VisualItemModel"
type == "QtQuick.VisualDataModel" || type == "Qt.VisualDataModel" || || type == "QtQuick.VisualDataModel" || type == "Qt.VisualDataModel"
type == "QtQuick.ListModel" || type == "Qt.ListModel" || || type == "QtQuick.ListModel" || type == "Qt.ListModel"
type == "QtQuick.XmlListModel" || type == "Qt.XmlListModel"; || type == "QtQml.Models.ListModel" || type == "QtQuick.XmlListModel"
|| type == "Qt.XmlListModel";
} }

View File

@@ -35,23 +35,20 @@ Controls.ScrollBar {
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding) implicitContentHeight + topPadding + bottomPadding)
padding: control.interactive ? 1 : 2 padding: active ? 1 : 2
visible: control.policy !== Controls.ScrollBar.AlwaysOff visible: orientation === Qt.Horizontal ? contentWidth > width : contentHeight > height
minimumSize: orientation == Qt.Horizontal ? height / width : width / height minimumSize: orientation === Qt.Horizontal ? height / width : width / height
contentItem: Rectangle { contentItem: Rectangle {
implicitWidth: 13 implicitWidth: 13
implicitHeight: 13 implicitHeight: 13
color: active ? Constants.textHoverColor : Constants.textDefaultColor
color: Constants.textDefaultColor
} }
background: Rectangle { background: Rectangle {
implicitWidth: 16 implicitWidth: 16
implicitHeight: 16 implicitHeight: 16
color: "#2d2e30" color: "#3b3c3d"
visible: control.interactive visible: active
} }
} }

View File

@@ -33,10 +33,5 @@ Controls.ScrollView {
x: control.mirrored ? 0 : control.width - width x: control.mirrored ? 0 : control.width - width
y: control.topPadding y: control.topPadding
height: control.availableHeight height: control.availableHeight
active: control.ScrollBar.horizontal.active
}
Controls.ScrollBar.horizontal: CustomScrollBar {
visible: false
} }
} }

View File

@@ -17,17 +17,8 @@ endif()
option(BUILD_QBS "Build Qbs together with Qt Creator" ${BUILD_QBS_DEFAULT}) option(BUILD_QBS "Build Qbs together with Qt Creator" ${BUILD_QBS_DEFAULT})
add_feature_info("Build Qbs" BUILD_QBS "")
if (BUILD_QBS) if (BUILD_QBS)
find_package(Qt5 COMPONENTS Script QUIET)
if (TARGET Qt5::Script)
set(ENABLE_BUILD_QBS YES)
endif()
else()
set(ENABLE_BUILD_QBS NO)
endif()
add_feature_info("Build Qbs" ENABLE_BUILD_QBS "with CONDITION TARGET Qt5::Script")
if (ENABLE_BUILD_QBS)
file(RELATIVE_PATH _REL_PATH_TO_QTC "${CMAKE_BINARY_DIR}" "${PROJECT_BINARY_DIR}") file(RELATIVE_PATH _REL_PATH_TO_QTC "${CMAKE_BINARY_DIR}" "${PROJECT_BINARY_DIR}")
set(QBS_OUTPUT_PREFIX "${_REL_PATH_TO_QTC}/" CACHE STRING "" FORCE) set(QBS_OUTPUT_PREFIX "${_REL_PATH_TO_QTC}/" CACHE STRING "" FORCE)
set(QBS_APP_INSTALL_DIR "${IDE_BIN_PATH}" CACHE STRING "" FORCE) set(QBS_APP_INSTALL_DIR "${IDE_BIN_PATH}" CACHE STRING "" FORCE)