Cura/resources/qml/Settings/SettingTextField.qml
Ghostkeeper 836e7c0c9b
Fix overlap of unit and setting value with RTL-languages
The unit was hard-coded to be anchored to the right. The text was getting the full width and aligned implicitly by the language. We'll keep the layout of the text properly internationalised, but make sure that the unit is opposite of wherever the text is.

Fixes CURA-8206.
Fixes #9667.
2021-06-07 18:00:59 +02:00

217 lines
7.5 KiB
QML

// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import UM 1.1 as UM
SettingItem
{
id: base
property var focusItem: input
property string textBeforeEdit
property bool textHasChanged
property bool focusGainedByClick: false
onFocusReceived:
{
textHasChanged = false;
textBeforeEdit = focusItem.text;
if(!focusGainedByClick)
{
// select all text when tabbing through fields (but not when selecting a field with the mouse)
focusItem.selectAll();
}
}
contents: Rectangle
{
id: control
anchors.fill: parent
radius: UM.Theme.getSize("setting_control_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!enabled)
{
return UM.Theme.getColor("setting_control_disabled_border")
}
switch(propertyProvider.properties.validationState)
{
case "ValidatorState.Invalid":
case "ValidatorState.Exception":
case "ValidatorState.MinimumError":
case "ValidatorState.MaximumError":
return UM.Theme.getColor("setting_validation_error");
case "ValidatorState.MinimumWarning":
case "ValidatorState.MaximumWarning":
return UM.Theme.getColor("setting_validation_warning");
}
//Validation is OK.
if(hovered || input.activeFocus)
{
return UM.Theme.getColor("setting_control_border_highlight")
}
return UM.Theme.getColor("setting_control_border")
}
color: {
if(!enabled)
{
return UM.Theme.getColor("setting_control_disabled")
}
switch(propertyProvider.properties.validationState)
{
case "ValidatorState.Invalid":
case "ValidatorState.Exception":
case "ValidatorState.MinimumError":
case "ValidatorState.MaximumError":
return UM.Theme.getColor("setting_validation_error_background")
case "ValidatorState.MinimumWarning":
case "ValidatorState.MaximumWarning":
return UM.Theme.getColor("setting_validation_warning_background")
case "ValidatorState.Valid":
return UM.Theme.getColor("setting_validation_ok")
default:
return UM.Theme.getColor("setting_control")
}
}
Rectangle
{
anchors.fill: parent
anchors.margins: Math.round(UM.Theme.getSize("default_lining").width)
color: UM.Theme.getColor("setting_control_highlight")
opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35
}
Label
{
anchors
{
left: parent.left
leftMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
right: parent.right
rightMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
verticalCenter: parent.verticalCenter
}
text: definition.unit
//However the setting value is aligned, align the unit opposite. That way it stays readable with right-to-left languages.
horizontalAlignment: (input.effectiveHorizontalAlignment == Text.AlignLeft) ? Text.AlignRight : Text.AlignLeft
textFormat: Text.PlainText
renderType: Text.NativeRendering
color: UM.Theme.getColor("setting_unit")
font: UM.Theme.getFont("default")
}
TextInput
{
id: input
anchors
{
left: parent.left
leftMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
right: parent.right
rightMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
verticalCenter: parent.verticalCenter
}
renderType: Text.NativeRendering
Keys.onTabPressed:
{
base.setActiveFocusToNextSetting(true)
}
Keys.onBacktabPressed:
{
base.setActiveFocusToNextSetting(false)
}
Keys.onReleased:
{
if (text != textBeforeEdit)
{
textHasChanged = true;
}
if (textHasChanged)
{
propertyProvider.setPropertyValue("value", text)
}
}
onActiveFocusChanged:
{
if(activeFocus)
{
base.focusReceived();
}
base.focusGainedByClick = false;
}
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
selectByMouse: true
maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10
// Since [int] & str don't have a max length, they need to be clipped (since clipping is expensive, this
// should be done as little as possible)
clip: definition.type == "str" || definition.type == "[int]"
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
Binding
{
target: input
property: "text"
value:
{
// Stacklevels
// 0: user -> unsaved change
// 1: quality changes -> saved change
// 2: quality
// 3: material -> user changed material in materialspage
// 4: variant
// 5: machine_changes
// 6: machine
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1))
{
// We have a resolve function. Indicates that the setting is not settable per extruder and that
// we have to choose between the resolved value (default) and the global value
// (if user has explicitly set this).
return base.resolve
}
else {
return propertyProvider.properties.value
}
}
when: !input.activeFocus
}
MouseArea
{
id: mouseArea
anchors.fill: parent
cursorShape: Qt.IBeamCursor
onPressed: {
if (!input.activeFocus)
{
base.focusGainedByClick = true
input.forceActiveFocus()
}
mouse.accepted = false
}
}
}
}
}