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

This commit is contained in:
The Qt Project
2019-08-29 11:09:16 +00:00
18 changed files with 190 additions and 118 deletions

View File

@@ -57,21 +57,21 @@ StudioControls.ComboBox {
actionIndicator.icon.text: extFuncLogic.glyph
actionIndicator.onClicked: extFuncLogic.show()
actionIndicator.visible: showExtendedFunctionButton
actionIndicator.visible: comboBox.showExtendedFunctionButton
ColorLogic {
id: colorLogic
backendValue: comboBox.backendValue
onValueFromBackendChanged: invalidate()
onValueFromBackendChanged: colorLogic.invalidate()
function invalidate() {
if (block)
if (comboBox.block)
return
block = true
comboBox.block = true
if (manualMapping) {
if (comboBox.manualMapping) {
comboBox.valueFromBackendChanged()
} else if (!comboBox.useInteger) {
var enumString = comboBox.backendValue.enumeration
@@ -88,33 +88,33 @@ StudioControls.ComboBox {
comboBox.currentIndex = index
} else {
if (comboBox.currentIndex !== backendValue.value)
comboBox.currentIndex = backendValue.value
if (comboBox.currentIndex !== comboBox.backendValue.value)
comboBox.currentIndex = comboBox.backendValue.value
}
block = false
comboBox.block = false
}
}
onActivated: {
if (!__isCompleted)
onCompressedActivated: {
if (!comboBox.__isCompleted)
return
if (backendValue === undefined)
if (comboBox.backendValue === undefined)
return
if (manualMapping)
if (comboBox.manualMapping)
return
if (!comboBox.useInteger) {
backendValue.setEnumeration(comboBox.scope, comboBox.currentText)
comboBox.backendValue.setEnumeration(comboBox.scope, comboBox.currentText)
} else {
backendValue.value = comboBox.currentIndex
comboBox.backendValue.value = comboBox.currentIndex
}
}
Component.onCompleted: {
colorLogic.invalidate()
__isCompleted = true
comboBox.__isCompleted = true
}
}

View File

@@ -75,11 +75,11 @@ Item {
}
}
labelColor: edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor
labelColor: spinBox.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor
onCompressedRealValueModified: {
if (backendValue.value !== realValue)
backendValue.value = realValue;
if (spinBox.backendValue.value !== spinBox.realValue)
spinBox.backendValue.value = spinBox.realValue;
}
}
}

View File

@@ -110,7 +110,7 @@ RowLayout {
comboBox.handleActivate(comboBox.currentIndex)
}
onActivated: comboBox.handleActivate(index)
onCompressedActivated: comboBox.handleActivate(index)
function handleActivate(index)
{

View File

@@ -1,3 +1,5 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
@@ -22,7 +24,6 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Templates 2.12 as T
@@ -37,17 +38,19 @@ T.ComboBox {
property bool hover: false // This property is used to indicate the global hover state
property bool edit: myComboBox.activeFocus
property bool dirty: false // user modification flag
property alias actionIndicatorVisible: actionIndicator.visible
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
property real __actionIndicatorHeight: StudioTheme.Values.height
property string __lastAcceptedText: ""
signal compressedActivated
signal compressedActivated(int index)
width: StudioTheme.Values.squareComponentWidth * 5
height: StudioTheme.Values.height
leftPadding: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
leftPadding: actionIndicator.width
- (myComboBox.actionIndicatorVisible ? StudioTheme.Values.border : 0)
rightPadding: popupIndicator.width - StudioTheme.Values.border
font.pixelSize: StudioTheme.Values.myFontSize
wheelEnabled: false
@@ -62,14 +65,24 @@ T.ComboBox {
myControl: myComboBox
x: 0
y: 0
width: actionIndicator.visible ? __actionIndicatorWidth : 0
height: actionIndicator.visible ? __actionIndicatorHeight : 0
width: actionIndicator.visible ? myComboBox.__actionIndicatorWidth : 0
height: actionIndicator.visible ? myComboBox.__actionIndicatorHeight : 0
}
contentItem: ComboBoxInput {
id: comboBoxInput
myControl: myComboBox
text: myComboBox.editText
onEditingFinished: {
// Only trigger the signal, if the value was modified
if (myComboBox.dirty) {
myTimer.stop()
myComboBox.dirty = false
myComboBox.compressedActivated(myComboBox.find(myComboBox.editText))
}
}
onTextEdited: myComboBox.dirty = true
}
indicator: CheckIndicator {
@@ -87,31 +100,25 @@ T.ComboBox {
color: StudioTheme.Values.themeControlOutline
border.color: StudioTheme.Values.themeControlOutline
border.width: StudioTheme.Values.border
x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
x: actionIndicator.width
- (myComboBox.actionIndicatorVisible ? StudioTheme.Values.border : 0)
width: myComboBox.width - actionIndicator.width
height: myComboBox.height
}
// Set the initial value for __lastAcceptedText
Component.onCompleted: __lastAcceptedText = myComboBox.editText
onAccepted: {
if (myComboBox.editText != __lastAcceptedText) {
var pos = find(myComboBox.editText)
activated(pos)
}
__lastAcceptedText = myComboBox.editText
}
Timer {
id: myTimer
property int activatedIndex
repeat: false
running: false
interval: 100
onTriggered: myComboBox.compressedActivated()
onTriggered: myComboBox.compressedActivated(myTimer.activatedIndex)
}
onActivated: myTimer.restart()
onActivated: {
myTimer.activatedIndex = index
myTimer.restart()
}
delegate: ItemDelegate {
id: myItemDelegate

View File

@@ -53,7 +53,9 @@ T.SpinBox {
property bool hover: false // This property is used to indicate the global hover state
property bool drag: false
property real realDragRange: realTo - realFrom
property bool dirty: false // user modification flag
property real realDragRange: mySpinBox.realTo - mySpinBox.realFrom
property alias actionIndicatorVisible: actionIndicator.visible
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
@@ -115,13 +117,13 @@ T.SpinBox {
id: spinBoxIndicatorUp
myControl: mySpinBox
iconFlip: -1
visible: spinBoxIndicatorVisible
visible: mySpinBox.spinBoxIndicatorVisible
onRealReleased: mySpinBox.realIncrease()
onRealPressAndHold: mySpinBox.realIncrease()
x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
x: actionIndicator.width + (mySpinBox.actionIndicatorVisible ? 0 : StudioTheme.Values.border)
y: StudioTheme.Values.border
width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
width: mySpinBox.spinBoxIndicatorVisible ? mySpinBox.__spinBoxIndicatorWidth : 0
height: mySpinBox.spinBoxIndicatorVisible ? mySpinBox.__spinBoxIndicatorHeight : 0
realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue < mySpinBox.realTo) : (mySpinBox.realValue > mySpinBox.realTo)
}
@@ -129,13 +131,13 @@ T.SpinBox {
down.indicator: RealSpinBoxIndicator {
id: spinBoxIndicatorDown
myControl: mySpinBox
visible: spinBoxIndicatorVisible
visible: mySpinBox.spinBoxIndicatorVisible
onRealReleased: mySpinBox.realDecrease()
onRealPressAndHold: mySpinBox.realDecrease()
x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
x: actionIndicator.width + (mySpinBox.actionIndicatorVisible ? 0 : StudioTheme.Values.border)
y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height
width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
width: mySpinBox.spinBoxIndicatorVisible ? mySpinBox.__spinBoxIndicatorWidth : 0
height: mySpinBox.spinBoxIndicatorVisible ? mySpinBox.__spinBoxIndicatorHeight : 0
realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue > mySpinBox.realFrom) : (mySpinBox.realValue < mySpinBox.realFrom)
}
@@ -144,6 +146,20 @@ T.SpinBox {
id: spinBoxInput
myControl: mySpinBox
validator: doubleValidator
onEditingFinished: {
// Keep the dirty state before calling setValueFromInput(),
// it will be set to false (cleared) internally
var valueModified = mySpinBox.dirty
mySpinBox.setValueFromInput()
myTimer.stop()
// Only trigger the signal, if the value was modified
if (valueModified)
mySpinBox.compressedRealValueModified()
}
onTextEdited: mySpinBox.dirty = true
}
background: Rectangle {
@@ -151,7 +167,7 @@ T.SpinBox {
color: StudioTheme.Values.themeControlOutline
border.color: StudioTheme.Values.themeControlOutline
border.width: StudioTheme.Values.border
x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
x: actionIndicator.width - (mySpinBox.actionIndicatorVisible ? StudioTheme.Values.border : 0)
width: mySpinBox.width - actionIndicator.width
height: mySpinBox.height
}
@@ -161,8 +177,8 @@ T.SpinBox {
myControl: mySpinBox
myPopup: sliderPopup
x: spinBoxInput.x + spinBoxInput.width - StudioTheme.Values.border
width: sliderIndicator.visible ? __sliderIndicatorWidth : 0
height: sliderIndicator.visible ? __sliderIndicatorHeight : 0
width: sliderIndicator.visible ? mySpinBox.__sliderIndicatorWidth : 0
height: sliderIndicator.visible ? mySpinBox.__sliderIndicatorHeight : 0
visible: false // reasonable default
}
@@ -259,7 +275,10 @@ T.SpinBox {
// the indicator will be disabled due to range logic.
}
onRealValueModified: myTimer.restart()
onFocusChanged: mySpinBox.setValueFromInput()
onFocusChanged: {
if (mySpinBox.focus)
mySpinBox.dirty = false
}
onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText
onActiveFocusChanged: {
if (mySpinBox.activeFocus)
@@ -295,10 +314,6 @@ T.SpinBox {
if (event.key === Qt.Key_Escape)
mySpinBox.focus = false
// FIX: This is a temporary fix for QTBUG-74239
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
mySpinBox.setValueFromInput()
}
function clamp(v, lo, hi) {
@@ -306,6 +321,10 @@ T.SpinBox {
}
function setValueFromInput() {
if (!mySpinBox.dirty)
return
// FIX: This is a temporary fix for QTBUG-74239
var currValue = mySpinBox.realValue
@@ -322,10 +341,12 @@ T.SpinBox {
if (tmpInputValue !== spinBoxInput.text)
spinBoxInput.text = tmpInputValue
}
mySpinBox.dirty = false
}
function setRealValue(value) {
mySpinBox.realValue = clamp(value,
mySpinBox.realValue = mySpinBox.clamp(value,
mySpinBox.validator.bottom,
mySpinBox.validator.top)
}
@@ -335,7 +356,7 @@ T.SpinBox {
var currValue = mySpinBox.realValue
mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale)
setRealValue(mySpinBox.realValue - realStepSize)
mySpinBox.setRealValue(mySpinBox.realValue - mySpinBox.realStepSize)
if (mySpinBox.realValue !== currValue)
mySpinBox.realValueModified()
@@ -346,7 +367,7 @@ T.SpinBox {
var currValue = mySpinBox.realValue
mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale)
setRealValue(mySpinBox.realValue + realStepSize)
mySpinBox.setRealValue(mySpinBox.realValue + mySpinBox.realStepSize)
if (mySpinBox.realValue !== currValue)
mySpinBox.realValueModified()

View File

@@ -46,16 +46,18 @@ Rectangle {
color: StudioTheme.Values.themeControlBackground
border.width: 0
onEnabledChanged: invalidateEnabled()
onEnabledChanged: syncEnabled()
onRealEnabledChanged: {
invalidateEnabled()
if (spinBoxIndicator.realEnabled === false)
syncEnabled()
if (spinBoxIndicator.realEnabled === false) {
pressAndHoldTimer.stop()
spinBoxIndicatorMouseArea.pressedAndHeld = false
}
}
// This function is meant to synchronize enabled with realEnabled to avoid
// the internal logic messing with the actual state.
function invalidateEnabled() {
function syncEnabled() {
spinBoxIndicator.enabled = spinBoxIndicator.realEnabled
}

View File

@@ -92,28 +92,6 @@ static inline QList<QmlItemNode> siblingsForNode(const QmlItemNode &itemNode)
return siblingList;
}
static signed int getMaxZValue(const QList<QmlItemNode> &siblingList)
{
signed int maximum = INT_MIN;
foreach (const QmlItemNode &node, siblingList) {
signed int z = node.instanceValue("z").toInt();
if (z > maximum)
maximum = z;
}
return maximum;
}
static signed int getMinZValue(const QList<QmlItemNode> &siblingList)
{
signed int minimum = INT_MAX;
foreach (const QmlItemNode &node, siblingList) {
signed int z = node.instanceValue("z").toInt();
if (z < minimum)
minimum = z;
}
return minimum;
}
static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
{

View File

@@ -31,6 +31,8 @@
#include <QLineF>
#include <QPainterPath>
#include <sstream>
namespace DesignTools {
AnimationCurve::AnimationCurve()
@@ -127,6 +129,21 @@ double AnimationCurve::maximumValue() const
return m_maxY;
}
std::string AnimationCurve::string() const
{
std::stringstream sstream;
sstream << "{ ";
for (size_t i = 0; i < m_frames.size(); ++i) {
if (i == m_frames.size() - 1)
sstream << m_frames[i].string();
else
sstream << m_frames[i].string() << ", ";
}
sstream << " }";
return sstream.str();
}
CurveSegment AnimationCurve::segment(double time) const
{
CurveSegment seg;

View File

@@ -58,6 +58,8 @@ public:
double maximumValue() const;
std::string string() const;
CurveSegment segment(double time) const;
std::vector<CurveSegment> segments() const;

View File

@@ -34,6 +34,7 @@
#include <algorithm>
#include <cmath>
#include <sstream>
namespace DesignTools {
@@ -251,9 +252,8 @@ void CurveItem::restore()
Keyframe curr = currItem->keyframe();
CurveSegment segment(prev, curr);
segment.setInterpolation(segment.interpolation());
prevItem->setRightHandle(segment.left().rightHandle());
currItem->setInterpolation(segment.interpolation());
currItem->setLeftHandle(segment.right().leftHandle());
prevItem = currItem;
@@ -329,12 +329,12 @@ void CurveItem::setInterpolation(Keyframe::Interpolation interpolation)
segment.setInterpolation(interpolation);
prevItem->setKeyframe(segment.left());
currItem->setKeyframe(segment.right());
setDirty(true);
}
prevItem = currItem;
}
setDirty(false);
emit curveChanged(id(), curve());
}
void CurveItem::connect(GraphicsScene *scene)
@@ -358,6 +358,8 @@ void CurveItem::insertKeyframeByTime(double time)
AnimationCurve acurve = curve();
acurve.insert(time);
setCurve(acurve);
emit curveChanged(id(), curve());
}
void CurveItem::deleteSelectedKeyframes()

View File

@@ -31,6 +31,7 @@
#include "selectableitem.h"
#include "treeitem.h"
#include <string>
#include <QGraphicsObject>
namespace DesignTools {
@@ -43,6 +44,9 @@ class CurveItem : public QGraphicsObject
{
Q_OBJECT
signals:
void curveChanged(unsigned int id, const AnimationCurve &curve);
public:
CurveItem(QGraphicsItem *parent = nullptr);

View File

@@ -69,6 +69,8 @@ void GraphicsScene::addCurveItem(CurveItem *item)
m_dirty = true;
item->setDirty(false);
connect(item, &CurveItem::curveChanged, this, &GraphicsScene::curveChanged);
addItem(item);
item->connect(this);
}

View File

@@ -174,6 +174,11 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe)
setPos(m_transform.map(m_frame.position()));
}
void KeyframeItem::setInterpolation(Keyframe::Interpolation interpolation)
{
m_frame.setInterpolation(interpolation);
}
void KeyframeItem::setLeftHandle(const QPointF &pos)
{
m_frame.setLeftHandle(pos);

View File

@@ -75,6 +75,8 @@ public:
void setKeyframe(const Keyframe &keyframe);
void setInterpolation(Keyframe::Interpolation interpolation);
void setLeftHandle(const QPointF &pos);
void setRightHandle(const QPointF &pos);

View File

@@ -25,6 +25,8 @@
#include "keyframe.h"
#include <sstream>
namespace DesignTools {
Keyframe::Keyframe()
@@ -101,6 +103,31 @@ QVariant Keyframe::data() const
return m_data;
}
std::string Keyframe::string() const
{
std::stringstream istream;
if (m_interpolation == Interpolation::Linear)
istream << "L";
else if (m_interpolation == Interpolation::Bezier)
istream << "B";
else if (m_interpolation == Interpolation::Easing)
istream << "E";
std::stringstream sstream;
sstream << "[" << istream.str() << (hasData() ? "*" : "") << "Frame P: " << m_position.x()
<< ", " << m_position.y();
if (hasLeftHandle())
sstream << " L: " << m_leftHandle.x() << ", " << m_leftHandle.y();
if (hasRightHandle())
sstream << " R: " << m_rightHandle.x() << ", " << m_rightHandle.y();
sstream << "]";
return sstream.str();
}
Keyframe::Interpolation Keyframe::interpolation() const
{
return m_interpolation;

View File

@@ -33,20 +33,13 @@ namespace DesignTools {
class Keyframe
{
public:
enum class Interpolation
{
Undefined,
Step,
Linear,
Bezier,
Easing
};
enum class Interpolation { Undefined, Step, Linear, Bezier, Easing };
Keyframe();
Keyframe(const QPointF &position);
Keyframe(const QPointF &position, const QVariant& data);
Keyframe(const QPointF &position, const QVariant &data);
Keyframe(const QPointF &position, const QPointF &leftHandle, const QPointF &rightHandle);
@@ -66,6 +59,8 @@ public:
QVariant data() const;
std::string string() const;
Interpolation interpolation() const;
void setPosition(const QPointF &pos);
@@ -74,7 +69,7 @@ public:
void setRightHandle(const QPointF &pos);
void setData(const QVariant& data);
void setData(const QVariant &data);
void setInterpolation(Interpolation interpol);

View File

@@ -389,6 +389,8 @@ void PropertyEditorView::resetView()
if (model() == nullptr)
return;
setSelelectedModelNode();
m_locked = true;
if (debug)
@@ -526,21 +528,16 @@ void PropertyEditorView::removePropertyFromModel(const PropertyName &propertyNam
m_locked = false;
}
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList)
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &,
const QList<ModelNode> &)
{
Q_UNUSED(lastSelectedNodeList)
if (selectedNodeList.isEmpty())
select(ModelNode());
else
select(selectedNodeList.constFirst());
select();
}
void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
if (m_selectedNode.isValid() && removedNode.isValid() && m_selectedNode == removedNode)
select(m_selectedNode.parentProperty().parentModelNode());
select();
}
void PropertyEditorView::modelAttached(Model *model)
@@ -686,17 +683,27 @@ void PropertyEditorView::nodeIdChanged(const ModelNode& node, const QString& new
}
}
void PropertyEditorView::select(const ModelNode &node)
void PropertyEditorView::select()
{
if (m_qmlBackEndForCurrentType)
m_qmlBackEndForCurrentType->emitSelectionToBeChanged();
if (QmlObjectNode(node).isValid())
m_selectedNode = node;
else
delayedResetView();
}
void PropertyEditorView::setSelelectedModelNode()
{
const auto selectedNodeList = selectedModelNodes();
m_selectedNode = ModelNode();
delayedResetView();
if (selectedNodeList.isEmpty())
return;
const ModelNode node = selectedNodeList.constFirst();
if (QmlObjectNode(node).isValid())
m_selectedNode = node;
}
bool PropertyEditorView::hasWidget() const
@@ -782,7 +789,7 @@ void PropertyEditorView::reloadQml()
}
m_qmlBackEndForCurrentType = nullptr;
delayedResetView();
resetView();
}

View File

@@ -105,7 +105,8 @@ private: //functions
void updateSize();
void setupPanes();
void select(const ModelNode& node);
void select();
void setSelelectedModelNode();
void delayedResetView();
void setupQmlBackend();