1
0
Fork 0

UI: small fixes to various controls

Especially, add return key handling to many editing controls
This commit is contained in:
James Turner 2018-08-11 22:03:51 +02:00
parent f33b15575f
commit e062026d9c
7 changed files with 144 additions and 40 deletions

View file

@ -4,11 +4,16 @@ import FlightGear 1.0
import FlightGear.Launcher 1.0
import "."
LineEdit
FocusScope
{
id: root
placeholder: "KSFO"
suggestedWidthString: "XXXX"
readonly property Positioned airport: airport
implicitWidth: edit.implicitWidth + nameDisplay.width
implicitHeight: edit.implicitHeight
property alias label: edit.label
signal clickedName();
Positioned {
id: airport
@ -17,11 +22,48 @@ LineEdit
function selectAirport(guid)
{
airport.guid = guid
text = airport.ident
edit.text = airport.ident
// we don't want this to trigger a search ....
searchTimer.stop();
}
signal pickAirport(var guid);
NavaidSearch {
id: searchCompleter
airportsOnly: true
maxResults: 20
onSearchComplete: {
if (exactMatch !== 0) {
pickAirport(exactMatch)
return;
}
}
}
Timer {
id: searchTimer
interval: 400
onTriggered: {
if (edit.text.length >= 2) {
searchCompleter.setSearch(edit.text, _launcher.aircraftType)
} else {
// ensure we update with no search (cancel, effectively)
searchCompleter.clear();
}
}
}
LineEdit
{
id: edit
placeholder: "KSFO"
suggestedWidthString: "XXXX"
commitOnReturn: false
focus: true
onActiveFocusChanged: {
if (activeFocus) {
OverlayShared.globalOverlay.showOverlayAtItemOffset(overlay, root, Qt.point(xOffsetForEditFrame, root.height + Style.margin))
@ -36,44 +78,37 @@ LineEdit
}
}
NavaidSearch {
id: searchCompleter
airportsOnly: true
maxResults: 20
onSearchComplete: {
if (exactMatch !== 0) {
selectAirport(exactMatch)
return;
}
}
}
onTextChanged: {
searchTimer.restart();
}
Timer {
id: searchTimer
interval: 400
onTriggered: {
if (root.text.length >= 2) {
searchCompleter.setSearch(root.text, NavaidSearch.Airplane)
} else {
// ensure we update with no search (cancel, effectively)
searchCompleter.clear();
Keys.onReturnPressed: {
// start a search right now, if we don't have one active
if (!searchCompleter.haveExistingSearch && (edit.text.length >= 2)) {
searchCompleter.setSearch(edit.text, _launcher.aircraftType)
}
// if we have a search and at least one valid result, select it
// combined with the previous behaviour, this means entering an ICAO
// code (which are returend synchronously inside setSearch) and
// hitting enter/return works as expected
if (searchCompleter.haveExistingSearch && (searchCompleter.numResults > 0)) {
root.pickAirport(searchCompleter.guidAtIndex(0));
root.focus = false
}
}
}
StyledText {
anchors.left: parent.right
ClickableText {
id: nameDisplay
anchors.left: edit.right
anchors.leftMargin: Style.margin
anchors.verticalCenter: parent.verticalCenter
text: airport.name
visible: airport.valid
width: Style.strutSize * 3
elide: Text.ElideRight
onClicked: root.clickedName()
}
Component {
@ -84,7 +119,6 @@ LineEdit
color: "white"
height: choicesColumn.childrenRect.height + Style.margin * 2
width: choicesColumn.width + Style.margin * 2
visible: searchCompleter.haveExistingSearch
Rectangle {
@ -124,6 +158,8 @@ LineEdit
text: model.ident + " - " + model.name
height: implicitHeight + Style.margin
font.pixelSize: Style.baseFontPixelSize
readonly property bool isCurrent: (selectionPopup.currentIndex === model.index)
color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
MouseArea {
@ -133,7 +169,7 @@ LineEdit
hoverEnabled: true
onClicked: {
root.selectAirport(model.guid)
root.pickAirport(model.guid)
root.focus = false
}
}

View file

@ -81,6 +81,7 @@ FocusScope {
height: parent.height
width: metrics.width
maximumLength: fieldWidth
font.pixelSize: Style.baseFontPixelSize
Keys.onUpPressed: {
incrementValue();

View file

@ -8,6 +8,7 @@ FocusScope {
property alias validator: edit.validator
property alias text: edit.text
property bool enabled: true
property bool commitOnReturn: true
property alias suggestedWidthString: metrics.text
readonly property int suggestedWidth: useFullWidth ? root.width
@ -21,6 +22,12 @@ FocusScope {
implicitHeight: editFrame.height
implicitWidth: suggestedWidth + label.implicitWidth + (Style.margin * 3)
Keys.onReturnPressed: {
if (activeFocus && commitOnReturn) {
focus = false;
}
}
TextMetrics {
id: metrics
}

View file

@ -76,6 +76,31 @@ FocusScope {
}
}
function changeToUnits(unitIndex)
{
if (edit.activeFocus) {
// build up a quantity with the current text value, in the
// previous units. We need to parse as text before we
// change the selected unit
var q = root.quantity;
q.value = clampValue(parseTextAsValue());
// convert to the new quantity
units.selectedIndex = unitIndex;
var newQuantity = q.convertToUnit(units.selectedUnit)
console.info("Changing text to:" + newQuantity.value.toFixed(units.numDecimals));
edit.text = newQuantity.value.toFixed(units.numDecimals)
console.info("Change units commit:" + newQuantity.value)
commit(newQuantity);
} else {
// not focused, easy
units.selectedIndex = unitIndex;
root.commit(root.quantity.convertToUnit(units.selectedUnit));
}
}
Component.onCompleted: {
if (quantity.unit === Units.NoUnits) {
var q = quantity;
@ -187,6 +212,11 @@ FocusScope {
root.decrementValue();
}
Keys.onReturnPressed: {
root.focus = false;
// will trigger onActiveFocusChanged
}
onActiveFocusChanged: {
if (activeFocus) {
selectAll();
@ -347,8 +377,7 @@ FocusScope {
hoverEnabled: true
onClicked: {
units.selectedIndex = model.index;
root.commit(root.quantity.convertToUnit(units.selectedUnit));
root.changeToUnits(model.index);
unitSelectionPopup.visible = false;
}
}

View file

@ -13,6 +13,8 @@ Rectangle {
border.color: edit.activeFocus ? Style.frameColor : Style.minorFrameColor
border.width: 1
signal editingFinished();
TextEdit {
id: edit
enabled: editFrame.enabled
@ -20,7 +22,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Style.margin
height: Math.max(Style.strutSize * 4, implicitHeight)
height: Math.max(Style.strutSize * 2, implicitHeight)
textFormat: TextEdit.PlainText
font.family: "Courier"
selectByMouse: true
@ -34,5 +36,11 @@ Rectangle {
font.family: "Courier"
color: Style.disabledTextColor
}
onActiveFocusChanged: {
if (!activeFocus) {
editFrame.editingFinished()
}
}
}
}

View file

@ -16,7 +16,7 @@ Item {
property string headerText: ""
implicitHeight: Math.max(label.implicitHeight, currentChoiceFrame.height)
implicitWidth: label.implicitWidth + Style.margin + currentChoiceFrame.__naturalWidth
implicitWidth: label.implicitWidth + (Style.margin * 2) + currentChoiceFrame.__naturalWidth
function select(index)
{
@ -70,7 +70,7 @@ Item {
StyledText {
id: label
anchors.left: root.left
anchors.leftMargin: 8
anchors.leftMargin: Style.margin
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
enabled: root.enabled

View file

@ -7,8 +7,9 @@ FocusScope {
property alias label: label.text
property bool enabled: true
property var value: new Date()
property bool isDuration: true
implicitHeight: label.implicitHeight
implicitHeight: editFrame.height
implicitWidth: label.implicitWidth + Style.margin + editFrame.width
function updateCurrentTime()
@ -16,6 +17,12 @@ FocusScope {
root.value = new Date(0, 0, 0, hours.value, minutes.value);
}
function setDurationMinutes(minutes)
{
var d = new Date(0, 0, 0, 0, minutes);
setTime(d);
}
function setTime(date)
{
hours.value = date.getHours();
@ -32,13 +39,18 @@ FocusScope {
enabled: root.enabled
}
Keys.onReturnPressed: {
if (activeFocus) {
focus = false;
}
}
Rectangle {
id: editFrame
radius: Style.roundRadius
border.color: root.focus ? Style.themeColor : Style.minorFrameColor
clip: true
border.width: 1
height: 30
height: hours.height + Style.margin
anchors.left: label.right
anchors.leftMargin: Style.margin
@ -58,14 +70,14 @@ FocusScope {
DateTimeValueEdit {
id: hours
minValue: 0
maxValue: 23
maxValue: root.isDuration ? 9999 : 23
widthString: "00"
nextToFocus: minutes
anchors.verticalCenter: parent.verticalCenter
onCommit: updateCurrentTime();
}
Text {
StyledText {
text: " : "
anchors.verticalCenter: parent.verticalCenter
enabled: root.enabled
@ -81,6 +93,17 @@ FocusScope {
onCommit: updateCurrentTime();
}
} // of time elements row
// frame rectange - we need this so we can clip our children
// but ensure our frame also apepars on top
Rectangle {
z: 100
anchors.fill: parent
border.color: root.focus ? Style.themeColor : Style.minorFrameColor
border.width: 1
radius: Style.roundRadius
color: "transparent"
}
}
}