diff --git a/doc/qtdesignstudio/images/studio-bidirectional-binding.gif b/doc/qtdesignstudio/images/studio-bidirectional-binding.gif index b0c3ebdae3b..d456e98dfe4 100644 Binary files a/doc/qtdesignstudio/images/studio-bidirectional-binding.gif and b/doc/qtdesignstudio/images/studio-bidirectional-binding.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-and-checkbox3.png b/doc/qtdesignstudio/images/studio-logic-helper-and-checkbox3.png index 3b1c1120104..414cd705a65 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-and-checkbox3.png and b/doc/qtdesignstudio/images/studio-logic-helper-and-checkbox3.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-and-operator-multiselect.gif b/doc/qtdesignstudio/images/studio-logic-helper-and-operator-multiselect.gif deleted file mode 100644 index 03c3455b3ca..00000000000 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-and-operator-multiselect.gif and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-and-operator.gif b/doc/qtdesignstudio/images/studio-logic-helper-and-operator.gif index 4b74da7fbf2..14a8d4dded6 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-and-operator.gif and b/doc/qtdesignstudio/images/studio-logic-helper-and-operator.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-and.png b/doc/qtdesignstudio/images/studio-logic-helper-and.png index fff59d88817..0d32952fdd8 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-and.png and b/doc/qtdesignstudio/images/studio-logic-helper-and.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-bidirectional-binding.png b/doc/qtdesignstudio/images/studio-logic-helper-bidirectional-binding.png index db8f5c51177..39ca5af0f35 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-bidirectional-binding.png and b/doc/qtdesignstudio/images/studio-logic-helper-bidirectional-binding.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao1.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao1.png index 3c7bb83f1f4..cd59495a308 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao1.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao1.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao2.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao2.png index 6adb176158e..ce5a7e80618 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao2.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-ao2.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-mmm-blocked.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-mmm-blocked.png index 3e36482ab5c..66923aeaed1 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-mmm-blocked.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-mmm-blocked.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-rm.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-rm.png index 37cedadf886..db6afac1b60 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-rm.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-rm.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-toolow.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-toolow.png index 6ab739a12e0..b6225797fe2 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-toolow.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-toolow.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-undervalue.png b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-undervalue.png index f4b88c36165..a517b6a0e79 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-undervalue.png and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example-states-undervalue.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-combining-example.gif b/doc/qtdesignstudio/images/studio-logic-helper-combining-example.gif index ef4a970e54a..c958d6a38b3 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-combining-example.gif and b/doc/qtdesignstudio/images/studio-logic-helper-combining-example.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-input.png b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-input.png index 9ecffa95cc7..06e7e4c0cd9 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-input.png and b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-input.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-string-mapper-input.png b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-string-mapper-input.png index 6ab74422f85..0a21eaccd5c 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-string-mapper-input.png and b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper-string-mapper-input.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper.gif b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper.gif index 3a2c0bbb00c..d4bb79e2fca 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper.gif and b/doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-not-check-box.png b/doc/qtdesignstudio/images/studio-logic-helper-not-check-box.png index cc33e26e3de..9411437e9be 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-not-check-box.png and b/doc/qtdesignstudio/images/studio-logic-helper-not-check-box.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-not-operator.gif b/doc/qtdesignstudio/images/studio-logic-helper-not-operator.gif index 7104d97610a..a0418a20e3a 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-not-operator.gif and b/doc/qtdesignstudio/images/studio-logic-helper-not-operator.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-not.png b/doc/qtdesignstudio/images/studio-logic-helper-not.png index e17d53d781b..05ad631b622 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-not.png and b/doc/qtdesignstudio/images/studio-logic-helper-not.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-inputmin.png b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-inputmin.png index 6b821d82863..2144e58f927 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-inputmin.png and b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-inputmin.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-properties.png b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-properties.png index 7cd3c2771f0..38add8bc1fc 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-properties.png and b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper-properties.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper.gif b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper.gif index 1f9d0ed917b..7fcbf46fc3f 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-range-mapper.gif and b/doc/qtdesignstudio/images/studio-logic-helper-range-mapper.gif differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-input.png b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-input.png index a910f0b5a43..b9371de9586 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-input.png and b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-input.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-text.png b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-text.png index 99b0c308f33..43a240fc5b5 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-text.png and b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper-text.png differ diff --git a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper.gif b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper.gif index 6697b0ba6b0..0a81d3895c8 100644 Binary files a/doc/qtdesignstudio/images/studio-logic-helper-string-mapper.gif and b/doc/qtdesignstudio/images/studio-logic-helper-string-mapper.gif differ diff --git a/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc b/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc index 81908d7239d..f1b0fccb6be 100644 --- a/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc +++ b/doc/qtdesignstudio/src/qtquickdesigner-components/qtdesignstudio-logic-helpers.qdoc @@ -64,10 +64,11 @@ 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 - the checked state of a third one. First we drag-and-drop three - \uicontrol {Check Box} component and an \uicontrol {And Operator} to - \uicontrol Navigator (1). Then we select the \uicontrol {And Operator} - component (2) and set its properties in \l Properties (3). + the checked state of a third one. First, we drag-and-drop three instances of + the \uicontrol {Check Box} components and one instance of the + \uicontrol {And Operator} component to \uicontrol Navigator (1). Then, we + select the \uicontrol {And Operator} component instance (2) and set its + properties in \l Properties (3). We select \inlineimage icons/action-icon.png 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" - 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 property to the \uicontrol Output property of the AND operator. @@ -109,16 +103,17 @@ condition is not met. 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} - component and a \uicontrol {Not Operator} to \uicontrol Navigator. Then we - select \uicontrol {Not Operator} and set its properties in + one cannot be checked. First, we drag-and-drop two instances of the + \uicontrol {Check Box} component and one instance of the + \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 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" - 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 field of the \uicontrol {Not Operator} component. @@ -137,10 +132,11 @@ a slider and checkbox. Typically, it is used to bind a backend value to a control, such as a slider. - For example, to synchronize the values of two sliders, drag-and-drop two - \uicontrol Slider components and one \uicontrol {Bi Direct. Binding} - component to the same parent component in \uicontrol Navigator. Then select - the bi-directional binding and set its properties in \uicontrol Properties. + For example, to synchronize the values of two sliders, we drag-and-drop two + instances of the \uicontrol Slider component and one instance of the + \uicontrol {Bi Direct. Binding} component to the same parent component in + \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" @@ -158,7 +154,7 @@ \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 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 @@ -167,17 +163,17 @@ For example, to use a \l Text component to display the value of a slider, we drag-and-drop \uicontrol Text, \uicontrol Slider, and - \uicontrol {String Mapper} components to the same parent component. Then - we select \uicontrol {String Mapper} in \uicontrol Navigator to display - its properties in \uicontrol Properties. There we bind the value of the - \c input property of the string mapper to the value of the \c value - property of the slider. + \uicontrol {String Mapper} components to the same parent component. Then, + we select the \uicontrol {String Mapper} instance in \uicontrol Navigator + to display its properties in \uicontrol Properties. There we bind the value + of the \uicontrol Input field to the value of the \c value property of the + \uicontrol Slider instance. \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 - \uicontrol Text component to the value of the \uicontrol Text - field of the \uicontrol {String Mapper} component. + Next, we select the \uicontrol Text instance and bind the value of the + \uicontrol Text field to the value of the \uicontrol {Output text} field + (\c text property) of the \uicontrol {String Mapper} component. \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" - The value of the \uicontrol Decimals field determines the number of digits - after the decimal separator. + The value of the \uicontrol {Decimal places} field determines the number + of digits after the decimal separator. \section1 Minimum-Maximum Mapper @@ -205,7 +201,7 @@ 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 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" @@ -221,12 +217,12 @@ \image studio-logic-helper-minmax-mapper.gif "Previewing a minimum-maximum mapper" - The \uicontrol {Out of range}, \uicontrol {Above maximum} and - \uicontrol {Below minimum} check boxes are set to \c true if + The \uicontrol {Out of range}, \uicontrol {Above max} and + \uicontrol {Below min} check boxes are set to \c true if the value of the \uicontrol Input field is out of range. - For example, in the context of speed, \uicontrol {Above maximum} being - \c true would mean \e {too fast}, whereas \uicontrol {Below minimum} + For example, in the context of speed, \uicontrol {Above max} being + \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 {either too fast or too slow}. @@ -240,23 +236,23 @@ \image studio-logic-helper-range-mapper-properties.png "Range Mapper properties" Specify the minimum and maximum input and output values in the - \uicontrol {Input minimum}, \uicontrol {Input maximum}, - \uicontrol {Output minimum}, and \uicontrol {Output maximum} fields + \uicontrol {Input min}, \uicontrol {Input max}, + \uicontrol {Output min}, and \uicontrol {Output max} fields 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. - If we want to display values from 10 to 1000, instead, we can bind the + 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 100, instead, we can bind the values of the \uicontrol From and \uicontrol To fields of the \l Slider - component to the values of the \uicontrol {Input minimum} and - \uicontrol {Input maximum} fields of a \uicontrol {Range Mapper} component. - We then set the value of the \uicontrol {Output minimum} field to 10 and the - value of the \uicontrol {Output maximum} field to 1000. + component to the values of the \uicontrol {Input min} and + \uicontrol {Input max} fields of a \uicontrol {Range Mapper} component. + We then set the value of the \uicontrol {Output min} field to 10 and the + 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" 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 10 to 1000. + from the \l Slider component changes from 0 to 1, the output value changes + from 10 to 100. \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 property of the \uicontrol {Range Mapper} component to the slider value 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. \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 the minimum-maximum mapper to the \uicontrol Output value of the \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" We use two \uicontrol {And Operator} components to determine that 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 of the minimum-maximum mapper. We specify that when the value is not 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 - \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 \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} and \uicontrol {And Operator} components to apply different @@ -324,14 +320,14 @@ \image studio-logic-helper-combining-example.png 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 evaluates to \c true. \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 - 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 to \c true. diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 13cdb4b9b93..fe3e1edabd7 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -51,6 +51,8 @@ #include #include #include +#else +#include #endif namespace QmlDesigner { @@ -152,6 +154,7 @@ void Qt5NodeInstanceServer::resizeCanvasToRootItem() m_viewData.contentItem->setPosition(-m_viewData.rootItem->position()); #endif quickWindow()->resize(rootNodeInstance().boundingRect().size().toSize()); + DesignerSupport::addDirty(rootNodeInstance().rootQuickItem(), QQuickDesignerSupport::Size); } void Qt5NodeInstanceServer::resetAllItems() @@ -335,6 +338,44 @@ QImage Qt5NodeInstanceServer::grabWindow() 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() == sourceItem; +} + +static bool isLayerEnabled(QQuickItemPrivate *item) +{ + return item && item->layer() && item->layer()->enabled(); +} + QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) { QImage renderImage; @@ -343,18 +384,54 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) return {}; 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); - 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 // the parent item's content, as compositing is handled on creator side. - for (const auto &childInstance : childInstances) { - QQuickItem *childItem = qobject_cast(childInstance.internalObject()); - if (childItem) { - QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); - pChild->refFromEffectItem(true); + QSet layerChildren; + + if (instance.isValid()) { //Not valid for effect + const auto childInstances = instance.childItems(); + for (const auto &childInstance : childInstances) { + QQuickItem *childItem = qobject_cast(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; QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc); 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(); - layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())), - qMax(minSize.height(), int(itemSize.height())))); + layer->setSize(QSize(qMax(minSize.width(), int(renderBoundingRect.width())), + qMax(minSize.height(), int(renderBoundingRect.height())))); layer->scheduleUpdate(); if (layer->updateTexture()) @@ -394,15 +475,24 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) m_viewData.renderControl->endFrame(); - // Restore visibility of immediate children that have instances and are QQuickItems - for (const auto &childInstance : childInstances) { - QQuickItem *childItem = qobject_cast(childInstance.internalObject()); - if (childItem) { - QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); - pChild->derefFromEffectItem(true); + if (instance.isValid()) { //Not valid for effect + const auto childInstances = instance.childItems(); + + // Restore visibility of immediate children that have instances and are QQuickItems + for (const auto &childInstance : childInstances) { + QQuickItem *childItem = qobject_cast(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 Q_UNUSED(item) #endif diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h index 190a0012754..4af451b61ae 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h @@ -71,6 +71,8 @@ public: QImage grabWindow() override; QImage grabItem(QQuickItem *item) override; + static QQuickItem *parentEffectItem(QQuickItem *item); + protected: void initializeView() override; void resizeCanvasToRootItem() override; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 97e015b2e74..cf7ac105333 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -89,8 +89,20 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() if (hasInstanceForObject(item)) { if (DesignerSupport::isDirty(item, DesignerSupport::ContentUpdateMask)) 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)) { - ServerNodeInstance ancestorInstance = findNodeInstanceForItem(item->parentItem()); + ServerNodeInstance ancestorInstance = findNodeInstanceForItem( + item->parentItem()); if (ancestorInstance.isValid()) m_dirtyInstanceSet.insert(ancestorInstance); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index ab38b33aafe..7557e87ccee 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -28,6 +28,9 @@ #include +#include +#include + #include #include #include @@ -476,11 +479,12 @@ QImage QuickItemNodeInstance::renderImage() const } renderImage.setDevicePixelRatio(devicePixelRatio); #else - if (s_unifiedRenderPath) + if (s_unifiedRenderPath) { renderImage = nodeInstanceServer()->grabWindow(); - else + renderImage = renderImage.copy(renderBoundingRect.toRect()); + } else { renderImage = nodeInstanceServer()->grabItem(quickItem()); - renderImage = renderImage.copy(renderBoundingRect.toRect()); + } /* When grabbing an offscren window the device pixel ratio is 1 */ renderImage.setDevicePixelRatio(1); @@ -608,11 +612,51 @@ void QuickItemNodeInstance::updateAllDirtyNodesRecursive(QQuickItem *parentItem) updateDirtyNode(parentItem); } +void QuickItemNodeInstance::setAllNodesDirtyRecursive(QQuickItem *parentItem) const +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + Q_UNUSED(parentItem) +#else + const QList children = parentItem->childItems(); + for (QQuickItem *childItem : children) + setAllNodesDirtyRecursive(childItem); + DesignerSupport::addDirty(parentItem, QQuickDesignerSupport::Content); +#endif +} + static inline bool isRectangleSane(const QRectF &rect) { 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(item)) + return true; + + const auto propName = "source"; + + QQmlProperty prop(item, QString::fromLatin1(propName)); + if (!prop.isValid()) + return false; + + QQuickShaderEffectSource *source = prop.read().value(); + + 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 boundingRect = parentItem->boundingRect(); @@ -620,8 +664,9 @@ QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) boundingRect = boundingRect.united(QRectF(QPointF(0, 0), size())); for (QQuickItem *childItem : parentItem->childItems()) { - if (!nodeInstanceServer()->hasInstanceForObject(childItem)) { - QRectF transformedRect = childItem->mapRectToItem(parentItem, boundingRectWithStepChilds(childItem)); + if (!nodeInstanceServer()->hasInstanceForObject(childItem) && !isEffectItem(childItem)) { + QRectF transformedRect = childItem->mapRectToItem(parentItem, + boundingRectWithStepChilds(childItem)); if (isRectangleSane(transformedRect)) boundingRect = boundingRect.united(transformedRect); } @@ -780,6 +825,9 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q if (name == "y") m_y = value.toDouble(); + if (name == "layer.enabled" || name == "layer.effect") + setAllNodesDirtyRecursive(quickItem()); + ObjectNodeInstance::setPropertyVariant(name, value); refresh(); @@ -849,6 +897,9 @@ void QuickItemNodeInstance::resetProperty(const PropertyName &name) if (name == "y") m_y = 0.0; + if (name == "layer.enabled" || name == "layer.effect") + setAllNodesDirtyRecursive(quickItem()); + DesignerSupport::resetAnchor(quickItem(), QString::fromUtf8(name)); if (name == "anchors.fill") { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h index 5f2f2089135..77d3a3fc6b5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h @@ -118,6 +118,7 @@ protected: Qt5NodeInstanceServer *qt5NodeInstanceServer() const; void updateDirtyNodesRecursive(QQuickItem *parentItem) const; void updateAllDirtyNodesRecursive(QQuickItem *parentItem) const; + void setAllNodesDirtyRecursive(QQuickItem *parentItem) const; QRectF boundingRectWithStepChilds(QQuickItem *parentItem) const; void resetHorizontal(); void resetVertical(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index 51e4ef2ff5f..be4c3ea626c 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -221,6 +221,9 @@ QString static getErrorString(QQmlEngine *engine, 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 componentPath.startsWith(path); }); diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml index 6e63651539c..b1767d0691b 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml @@ -36,7 +36,7 @@ Section { anchors.left: parent.left 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() { return anchorBackend.isFilled || anchorBackend.isInLayout @@ -88,7 +88,7 @@ Section { ControlLabel { text: "X" - tooltip: xSpinBox.enabled ? "X" : root.disbaledTooltip + tooltip: xSpinBox.enabled ? "X" : root.disabledTooltip enabled: xSpinBox.enabled } @@ -109,7 +109,7 @@ Section { ControlLabel { text: "Y" - tooltip: xSpinBox.enabled ? "Y" : root.disbaledTooltip + tooltip: xSpinBox.enabled ? "Y" : root.disabledTooltip enabled: ySpinBox.enabled } /* @@ -143,7 +143,7 @@ Section { ControlLabel { //: The width of the object text: qsTr("W", "width") - tooltip: widthSpinBox.enabled ? qsTr("Width") : root.disbaledTooltip + tooltip: widthSpinBox.enabled ? qsTr("Width") : root.disabledTooltip enabled: widthSpinBox.enabled } @@ -165,7 +165,7 @@ Section { ControlLabel { //: The height of the object text: qsTr("H", "height") - tooltip: heightSpinBox.enabled ? qsTr("Height") : root.disbaledTooltip + tooltip: heightSpinBox.enabled ? qsTr("Height") : root.disabledTooltip enabled: heightSpinBox.enabled } /* diff --git a/src/libs/qlitehtml b/src/libs/qlitehtml index 6b189c66051..2fbaad08a01 160000 --- a/src/libs/qlitehtml +++ b/src/libs/qlitehtml @@ -1 +1 @@ -Subproject commit 6b189c6605129ed4c1e4e6d2f734bd95bdaa783f +Subproject commit 2fbaad08a01d611858bef5e747addea7f42318b3 diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index edcdc6807e2..e326796a072 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -556,11 +556,10 @@ void QtcProcess::start() qWarning("QtcProcess::start: Empty environment set when running '%s'.", qPrintable(d->m_commandLine.executable().toString())); env = d->m_environment; - - d->m_process->setProcessEnvironment(env.toProcessEnvironment()); } else { env = Environment::systemEnvironment(); } + d->m_process->setProcessEnvironment(env.toProcessEnvironment()); d->m_process->setWorkingDirectory(d->m_workingDirectory.path()); diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp index 232de2334d6..3eee21ff241 100644 --- a/src/plugins/coreplugin/mimetypesettings.cpp +++ b/src/plugins/coreplugin/mimetypesettings.cpp @@ -502,8 +502,7 @@ void MimeTypeSettingsPrivate::ensurePendingMimeType(const Utils::MimeType &mimeT void MimeTypeSettingsPrivate::writeUserModifiedMimeTypes() { - static Utils::FilePath modifiedMimeTypesFile = ICore::userResourcePath() - + kModifiedMimeTypesFile; + static Utils::FilePath modifiedMimeTypesFile = ICore::userResourcePath(kModifiedMimeTypesFile); if (QFile::exists(modifiedMimeTypesFile.toString()) || QDir().mkpath(modifiedMimeTypesFile.parentDir().toString())) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp index f0bfeab9294..9a73fa39ab3 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp @@ -200,7 +200,7 @@ QVariant ItemLibraryAssetsModel::data(const QModelIndex &index, int role) const } 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); return {}; diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index c423323de66..41563efd417 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -493,6 +493,7 @@ QProcessEnvironment PuppetCreator::processEnvironment() const environment.set("QML_BAD_GUI_RENDER_LOOP", "true"); environment.set("QML_PUPPET_MODE", "true"); environment.set("QML_DISABLE_DISK_CACHE", "true"); + environment.set("QMLPUPPET_RENDER_EFFECTS", "true"); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (!environment.hasKey("QT_SCREEN_SCALE_FACTORS") && !environment.hasKey("QT_SCALE_FACTOR") && QApplication::testAttribute(Qt::AA_EnableHighDpiScaling)) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index f3fb6f5cfda..67ec00e1212 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -329,10 +329,11 @@ bool isComponentType(const QmlDesigner::TypeName &type) bool isCustomParserType(const QmlDesigner::TypeName &type) { - return type == "QtQuick.VisualItemModel" || type == "Qt.VisualItemModel" || - type == "QtQuick.VisualDataModel" || type == "Qt.VisualDataModel" || - type == "QtQuick.ListModel" || type == "Qt.ListModel" || - type == "QtQuick.XmlListModel" || type == "Qt.XmlListModel"; + return type == "QtQuick.VisualItemModel" || type == "Qt.VisualItemModel" + || type == "QtQuick.VisualDataModel" || type == "Qt.VisualDataModel" + || type == "QtQuick.ListModel" || type == "Qt.ListModel" + || type == "QtQml.Models.ListModel" || type == "QtQuick.XmlListModel" + || type == "Qt.XmlListModel"; } diff --git a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml index f372165a784..a6042e24ccf 100644 --- a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml +++ b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml @@ -35,23 +35,20 @@ Controls.ScrollBar { implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding) - padding: control.interactive ? 1 : 2 - visible: control.policy !== Controls.ScrollBar.AlwaysOff - minimumSize: orientation == Qt.Horizontal ? height / width : width / height + padding: active ? 1 : 2 + visible: orientation === Qt.Horizontal ? contentWidth > width : contentHeight > height + minimumSize: orientation === Qt.Horizontal ? height / width : width / height contentItem: Rectangle { implicitWidth: 13 implicitHeight: 13 - - color: Constants.textDefaultColor + color: active ? Constants.textHoverColor : Constants.textDefaultColor } background: Rectangle { implicitWidth: 16 implicitHeight: 16 - color: "#2d2e30" - visible: control.interactive + color: "#3b3c3d" + visible: active } } - - diff --git a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml index a440cc68aff..0fbdfa9f00f 100644 --- a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml +++ b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml @@ -33,10 +33,5 @@ Controls.ScrollView { x: control.mirrored ? 0 : control.width - width y: control.topPadding height: control.availableHeight - active: control.ScrollBar.horizontal.active - } - - Controls.ScrollBar.horizontal: CustomScrollBar { - visible: false } } diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index 90965fbd1cd..880430e3654 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -17,17 +17,8 @@ endif() option(BUILD_QBS "Build Qbs together with Qt Creator" ${BUILD_QBS_DEFAULT}) +add_feature_info("Build Qbs" 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}") set(QBS_OUTPUT_PREFIX "${_REL_PATH_TO_QTC}/" CACHE STRING "" FORCE) set(QBS_APP_INSTALL_DIR "${IDE_BIN_PATH}" CACHE STRING "" FORCE) diff --git a/src/shared/qbs b/src/shared/qbs index 893e985449b..24924ce845f 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 893e985449b1db91195966884f4b743bf08b3f9c +Subproject commit 24924ce845f09281fdfcb9b02784d23326bdd2bd