Skip to content

Commit

Permalink
Merge pull request #5352 from opengisch/variable-editor-polish
Browse files Browse the repository at this point in the history
Variable Editor: First step of redesign
  • Loading branch information
nirvn authored Jun 20, 2024
2 parents f292ac1 + 6580daf commit e065e51
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 118 deletions.
259 changes: 141 additions & 118 deletions src/qml/VariableEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,132 +6,155 @@ import org.qfield 1.0
import Theme 1.0

ColumnLayout {
function reset() {
Qt.inputMethod.hide()
table.model.reloadVariables()
}
function reset() {
Qt.inputMethod.hide()
table.model.reloadVariables()
}

function apply() {
table.model.save()
}
function apply() {
table.model.save()
}

anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 4

anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 4

Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: Theme.mainBackgroundColor
border.color: Theme.controlBorderColor
border.width: 1

ListView {
id: table
model: ExpressionVariableModel {}
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
clip: true
spacing: 1

anchors.fill: parent
anchors.margins: 3

delegate: Rectangle {
property var itemRow: index
property bool canDelete: table.model.isEditable( index )

id: rectangle
width: parent ? parent.width : 0
height: line.height
color: "transparent"

Row {
id: line
leftPadding: 4
spacing: 5

TextField {
id: variableNameText
width: 0.35 * table.width - 10
topPadding: 10
bottomPadding: 10
leftPadding: 5
rightPadding: 5
text: VariableName
enabled: table.model.isEditable(index)
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText == '' ? qsTr( "Enter name" ) : ''

background: Rectangle {
y: variableNameText.height - height - variableNameText.bottomPadding / 2
implicitWidth: 120
height: variableNameText.activeFocus ? 2: variableNameText.enabled ? 1: 0
color: variableNameText.activeFocus ? Theme.accentColor : Theme.accentLightColor
}

onTextChanged: {
table.model.setName( index, text )
}
}

TextField {
id: variableValueText
width: 0.65 * table.width - 10- (canDelete ? deleteVariableButton.width: 0)
topPadding: 10
bottomPadding: 10
leftPadding: 5
rightPadding: 5
text: VariableValue
enabled: table.model.isEditable(index)
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText == '' ? qsTr( "Enter value" ) : ''

background: Rectangle {
y: variableValueText.height - height - variableValueText.bottomPadding / 2
implicitWidth: 120
height: variableValueText.activeFocus ? 2: variableNameText.enabled ? 1: 0
color: variableValueText.activeFocus ? Theme.accentColor : Theme.accentLightColor
}

onTextChanged: {
table.model.setValue( index, text )
}
}

QfToolButton {
id: deleteVariableButton
width: 36
height: 36
anchors.verticalCenter: parent.verticalCenter
visible: canDelete

iconSource: Theme.getThemeIcon( 'ic_delete_forever_white_24dp' )
iconColor: Theme.mainTextColor
bgcolor: "transparent"

onClicked: {
table.model.removeCustomVariable( index );
}
}
}
color: Theme.mainBackgroundColor
border.color: Theme.controlBorderColor
border.width: 1

ListView {
id: table
model: ExpressionVariableModel {}
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
clip: true
spacing: 1
anchors.fill: parent
anchors.margins: 3
anchors.leftMargin: 9
anchors.rightMargin: 5
delegate: Rectangle {
id: rectangle
width: parent ? parent.width : 0
height: line.height
color: "transparent"

property var itemRow: index
property bool canDelete: table.model.isEditable(index)

Row {
id: line
spacing: 5

QfSwipeAnimator {
id: variableNameTextAnimator
width: 0.35 * table.width - 10
height: 40
shouldAutoFlick: (width < variableNameText.implicitWidth) && !dragging && !variableNameText.activeFocus
contentImplicitWidth: variableNameText.implicitWidth
contentWidth: variableNameText.implicitWidth
duration: shouldAutoFlick ? Math.abs(variableNameText.width - width) * 100 + 10 : 10000

TextField {
id: variableNameText
topPadding: 10
bottomPadding: 10
leftPadding: 1
rightPadding: 1
text: VariableName
enabled: table.model.isEditable(index)
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText === '' ? qsTr("Enter name") : ''
background: Rectangle {
y: variableNameText.height - height - variableNameText.bottomPadding / 2
height: variableNameText.activeFocus ? 2 : variableNameText.enabled ? 1 : 0
width: Math.max(variableNameTextAnimator.width, variableNameText.implicitWidth)
color: variableNameText.activeFocus ? Theme.accentColor : "transparent"
}

onTextChanged: {
table.model.setName(index, text)
}

onCursorRectangleChanged: {
variableNameTextAnimator.ensureCursorVisible(cursorRectangle)
}
}
}

QfSwipeAnimator {
id: variableValueTextAnimator
width: 0.65 * table.width - 10 - (canDelete ? deleteVariableButton.width : 0)
height: 40
shouldAutoFlick: (width < variableValueText.implicitWidth) && !dragging && !variableValueText.activeFocus
contentImplicitWidth: variableValueText.implicitWidth
contentWidth: variableValueText.implicitWidth
duration: shouldAutoFlick ? Math.abs(variableValueText.width - width) * 100 + 10 : 10000

TextField {
id: variableValueText
topPadding: 10
bottomPadding: 10
leftPadding: 1
rightPadding: 1
text: VariableValue
enabled: table.model.isEditable(index)
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText === '' ? qsTr("Enter value") : ''
background: Rectangle {
y: variableValueText.height - height - variableValueText.bottomPadding / 2
height: variableValueText.activeFocus ? 2 : variableNameText.enabled ? 1 : 0
width: Math.max(variableValueTextAnimator.width, variableValueText.implicitWidth)
color: variableValueText.activeFocus ? Theme.accentColor : "transparent"
}

onTextChanged: {
table.model.setValue(index, text)
}

onCursorRectangleChanged: {
variableValueTextAnimator.ensureCursorVisible(cursorRectangle)
}
}
}

QfToolButton {
id: deleteVariableButton
width: 36
height: 36
anchors.verticalCenter: parent.verticalCenter
visible: canDelete

iconSource: Theme.getThemeIcon('ic_delete_forever_white_24dp')
iconColor: Theme.mainTextColor
bgcolor: "transparent"

onClicked: {
table.model.removeCustomVariable(index)
}
}
}
}
}
}

QfButton {
id: addCustomVariableButton
Layout.fillWidth: true
text: qsTr( "Add a new variable" )
QfButton {
id: addCustomVariableButton
Layout.fillWidth: true
text: qsTr("Add a new variable")

onClicked: {
table.model.addCustomVariable( "new_variable" , "" );
table.positionViewAtIndex( table.count - 1, ListView.visible );
// TODO: Use Qt 5.13 itemAtIndex( index )
table.children[0].children[table.count].children[0].children[0].forceActiveFocus();
}
onClicked: {
table.model.addCustomVariable("new_variable", "")
table.positionViewAtIndex(table.count - 1, ListView.visible)
// TODO: Use Qt 5.13 itemAtIndex( index )
table.children[0].children[table.count].children[0].children[0].forceActiveFocus()
}
}
}
56 changes: 56 additions & 0 deletions src/qml/imports/Theme/QfSwipeAnimator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import QtQuick 2.14
import Theme 1.0

Flickable {
id: flick
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.HorizontalFlick
clip: true

required property real contentImplicitWidth
default property alias contents: containerLayout.children
property bool shouldAutoFlick: false
property real duration: 3000

SequentialAnimation {
id: mainAnim
loops: 10
running: flick.shouldAutoFlick

NumberAnimation {
target: flick
property: "contentX"
to: -(flick.width - contentImplicitWidth)
duration: flick.duration
}

PauseAnimation {
duration: 1000
}

NumberAnimation {
target: flick
property: "contentX"
to: 0
duration: flick.duration
}

PauseAnimation {
duration: 1000
}
}

Item {
id: containerLayout
}

// if containerLayout is TextArea or TextField this function could be used to
// handle text selection and showing cursor rectangle
function ensureCursorVisible(cursorRectangle) {
if (contentX >= cursorRectangle.x) {
contentX = cursorRectangle.x
} else if (contentX + width <= cursorRectangle.x + cursorRectangle.width) {
contentX = cursorRectangle.x + cursorRectangle.width - width
}
}
}
1 change: 1 addition & 0 deletions src/qml/imports/Theme/qmldir
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ QfCalendarPanel 1.0 QfCalendarPanel.qml
QfPageHeader 1.0 QfPageHeader.qml
QfOverlayContainer 1.0 QfOverlayContainer.qml
QfTabBar 1.0 QfTabBar.qml
QfSwipeAnimator 1.0 QfSwipeAnimator.qml
1 change: 1 addition & 0 deletions src/qml/qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
<file>imports/Theme/QfOverlayContainer.qml</file>
<file>imports/Theme/QfTabBar.qml</file>
<file>imports/Theme/qmldir</file>
<file>imports/Theme/QfSwipeAnimator.qml</file>
<file>TrackerSettings.qml</file>
<file>TrackingSession.qml</file>
<file>EmbeddedFeatureForm.qml</file>
Expand Down

1 comment on commit e065e51

@qfield-fairy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.