Merge remote-tracking branch 'origin/5.0'
Change-Id: I712fce3cc0171327de122a1cd53b5bae67541084
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 157 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 57 KiB |
@@ -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.
|
||||
|
||||
|
@@ -51,6 +51,8 @@
|
||||
#include <QtQuick/private/qsgcontext_p.h>
|
||||
#include <QtQuick/private/qsgrenderer_p.h>
|
||||
#include <QtQuick/private/qsgrhilayer_p.h>
|
||||
#else
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#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<QQuickShaderEffectSource *>() == 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<QQuickItem *>(childInstance.internalObject());
|
||||
if (childItem) {
|
||||
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
|
||||
pChild->refFromEffectItem(true);
|
||||
QSet<QQuickItem *> layerChildren;
|
||||
|
||||
if (instance.isValid()) { //Not valid for effect
|
||||
const auto childInstances = instance.childItems();
|
||||
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;
|
||||
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<QQuickItem *>(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<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
|
||||
Q_UNUSED(item)
|
||||
#endif
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -28,6 +28,9 @@
|
||||
|
||||
#include <qmlprivategate.h>
|
||||
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#include <QtQuick/private/qquickshadereffectsource_p.h>
|
||||
|
||||
#include <QQmlProperty>
|
||||
#include <QQmlExpression>
|
||||
#include <QQuickView>
|
||||
@@ -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<QQuickItem *> 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<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 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") {
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
});
|
||||
|
@@ -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
|
||||
}
|
||||
/*
|
||||
|
@@ -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());
|
||||
|
||||
|
@@ -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())) {
|
||||
|
@@ -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 {};
|
||||
|
@@ -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))
|
||||
|
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
|