parent
06484ec2c0
commit
cbdbb6eb8b
|
@ -382,6 +382,7 @@ DISTFILES += \
|
||||||
shared/CropCornerRectangle.qml \
|
shared/CropCornerRectangle.qml \
|
||||||
shared/DelegateModelGeneralized.qml \
|
shared/DelegateModelGeneralized.qml \
|
||||||
shared/FormGroup.qml \
|
shared/FormGroup.qml \
|
||||||
|
shared/GasSelectorButton.qml \
|
||||||
shared/IconButton.qml \
|
shared/IconButton.qml \
|
||||||
shared/ImageCropper.qml \
|
shared/ImageCropper.qml \
|
||||||
shared/ImageCropperModal.qml \
|
shared/ImageCropperModal.qml \
|
||||||
|
|
|
@ -7,9 +7,10 @@ import "./"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
anchors.left: parent.left
|
width: parent.width
|
||||||
anchors.right: parent.right
|
height: Style.current.smallPadding + prioritytext.height +
|
||||||
height: sliderWrapper.height + Style.current.smallPadding + txtNetworkFee.height + buttonAdvanced.height
|
(advancedMode ? advancedModeItemGroup.height : selectorButtons.height)
|
||||||
|
|
||||||
property double slowestGasPrice: 0
|
property double slowestGasPrice: 0
|
||||||
property double fastestGasPrice: 100
|
property double fastestGasPrice: 100
|
||||||
property double stepSize: ((root.fastestGasPrice - root.slowestGasPrice) / 10).toFixed(1)
|
property double stepSize: ((root.fastestGasPrice - root.slowestGasPrice) / 10).toFixed(1)
|
||||||
|
@ -29,6 +30,8 @@ Item {
|
||||||
property bool isValid: true
|
property bool isValid: true
|
||||||
readonly property string uuid: Utils.uuid()
|
readonly property string uuid: Utils.uuid()
|
||||||
|
|
||||||
|
property bool advancedMode: false
|
||||||
|
|
||||||
function defaultGasPrice() {
|
function defaultGasPrice() {
|
||||||
return ((50 * (root.fastestGasPrice - root.slowestGasPrice) / 100) + root.slowestGasPrice)
|
return ((50 * (root.fastestGasPrice - root.slowestGasPrice) / 100) + root.slowestGasPrice)
|
||||||
}
|
}
|
||||||
|
@ -40,247 +43,194 @@ Item {
|
||||||
}
|
}
|
||||||
let ethValue = root.getGasEthValue(inputGasPrice.text, inputGasLimit.text)
|
let ethValue = root.getGasEthValue(inputGasPrice.text, inputGasLimit.text)
|
||||||
let fiatValue = root.getFiatValue(ethValue, "ETH", root.defaultCurrency)
|
let fiatValue = root.getFiatValue(ethValue, "ETH", root.defaultCurrency)
|
||||||
let summary = Utils.stripTrailingZeros(ethValue) + " ETH ~" + fiatValue + " " + root.defaultCurrency.toUpperCase()
|
|
||||||
labelGasPriceSummary.text = summary
|
|
||||||
labelGasPriceSummaryAdvanced.text = summary
|
|
||||||
selectedGasEthValue = ethValue
|
selectedGasEthValue = ethValue
|
||||||
selectedGasFiatValue = fiatValue
|
selectedGasFiatValue = fiatValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
// causes error on application load without a null check
|
||||||
|
if (!inputGasLimit || !inputGasPrice) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inputGasLimit.validationError = ""
|
||||||
|
inputGasPrice.validationError = ""
|
||||||
|
const noInputLimit = inputGasLimit.text === ""
|
||||||
|
const noInputPrice = inputGasPrice.text === ""
|
||||||
|
if (noInputLimit) {
|
||||||
|
inputGasLimit.validationError = root.noInputErrorMessage
|
||||||
|
}
|
||||||
|
if (noInputPrice) {
|
||||||
|
inputGasPrice.validationError = root.noInputErrorMessage
|
||||||
|
}
|
||||||
|
if (isNaN(inputGasLimit.text)) {
|
||||||
|
inputGasLimit.validationError = invalidInputErrorMessage
|
||||||
|
}
|
||||||
|
if (isNaN(inputGasPrice.text)) {
|
||||||
|
inputGasPrice.validationError = invalidInputErrorMessage
|
||||||
|
}
|
||||||
|
let inputLimit = parseFloat(inputGasLimit.text || "0.00")
|
||||||
|
let inputPrice = parseFloat(inputGasPrice.text || "0.00")
|
||||||
|
if (inputLimit === 0.00) {
|
||||||
|
inputGasLimit.validationError = root.greaterThan0ErrorMessage
|
||||||
|
}
|
||||||
|
if (inputPrice === 0.00) {
|
||||||
|
inputGasPrice.validationError = root.greaterThan0ErrorMessage
|
||||||
|
}
|
||||||
|
const isValid = inputGasLimit.validationError === "" && inputGasPrice.validationError === ""
|
||||||
|
return isValid
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: txtNetworkFee
|
id: prioritytext
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
//% "Network fee"
|
text: qsTr("Priority")
|
||||||
text: qsTrId("network-fee")
|
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
color: Style.current.textColor
|
color: Style.current.textColor
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StatusButton {
|
||||||
id: labelGasPriceSummary
|
id: buttonAdvanced
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: prioritytext.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
font.weight: Font.Medium
|
text: advancedMode ? qsTr("Use suggestions") : qsTr("Use custom")
|
||||||
|
flat: true
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
color: Style.current.secondaryText
|
onClicked: advancedMode = !advancedMode
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: selectorButtons
|
||||||
|
visible: !advancedMode
|
||||||
|
anchors.top: prioritytext.bottom
|
||||||
|
anchors.topMargin: Style.current.halfPadding
|
||||||
|
spacing: 11
|
||||||
|
|
||||||
|
ButtonGroup {
|
||||||
|
id: gasGroup
|
||||||
|
onClicked: updateGasEthValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
GasSelectorButton {
|
||||||
|
buttonGroup: gasGroup
|
||||||
|
text: qsTr("Low")
|
||||||
|
price: slowestGasPrice
|
||||||
|
gasLimit: inputGasLimit ? inputGasLimit.text : ""
|
||||||
|
getGasEthValue: root.getGasEthValue
|
||||||
|
getFiatValue: root.getFiatValue
|
||||||
|
defaultCurrency: root.defaultCurrency
|
||||||
|
onChecked: inputGasPrice.text = price
|
||||||
|
}
|
||||||
|
GasSelectorButton {
|
||||||
|
buttonGroup: gasGroup
|
||||||
|
checkedByDefault: true
|
||||||
|
text: qsTr("Optimal")
|
||||||
|
price: (fastestGasPrice + slowestGasPrice) / 2
|
||||||
|
gasLimit: inputGasLimit ? inputGasLimit.text : ""
|
||||||
|
getGasEthValue: root.getGasEthValue
|
||||||
|
getFiatValue: root.getFiatValue
|
||||||
|
defaultCurrency: root.defaultCurrency
|
||||||
|
onChecked: inputGasPrice.text = price
|
||||||
|
}
|
||||||
|
|
||||||
|
GasSelectorButton {
|
||||||
|
buttonGroup: gasGroup
|
||||||
|
text: qsTr("High")
|
||||||
|
price: fastestGasPrice
|
||||||
|
gasLimit: inputGasLimit ? inputGasLimit.text : ""
|
||||||
|
getGasEthValue: root.getGasEthValue
|
||||||
|
getFiatValue: root.getFiatValue
|
||||||
|
defaultCurrency: root.defaultCurrency
|
||||||
|
onChecked: inputGasPrice.text = price
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sliderWrapper
|
id: advancedModeItemGroup
|
||||||
anchors.topMargin: Style.current.smallPadding
|
anchors.top: prioritytext.bottom
|
||||||
anchors.top: labelGasPriceSummary.bottom
|
anchors.topMargin: 14
|
||||||
height: sliderWrapper.visible ? gasSlider.height + labelSlow.height + Style.current.padding : 0
|
visible: root.advancedMode
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: Number(root.selectedGasPrice) >= Number(root.slowestGasPrice) && Number(root.selectedGasPrice) <= Number(root.fastestGasPrice)
|
height: childrenRect.height
|
||||||
|
|
||||||
StatusSlider {
|
Input {
|
||||||
id: gasSlider
|
id: inputGasLimit
|
||||||
minimumValue: root.slowestGasPrice
|
label: qsTr("Gas amount limit")
|
||||||
maximumValue: root.fastestGasPrice
|
text: "21000"
|
||||||
stepSize: root.stepSize
|
customHeight: 56
|
||||||
value: root.defaultGasPrice()
|
anchors.top: parent.top
|
||||||
onValueChanged: {
|
anchors.left: parent.left
|
||||||
if (!isNaN(gasSlider.value)) {
|
anchors.right: inputGasPrice.left
|
||||||
inputGasPrice.text = gasSlider.value + ""
|
anchors.rightMargin: Style.current.padding
|
||||||
|
placeholderText: "21000"
|
||||||
|
validationErrorAlignment: TextEdit.AlignRight
|
||||||
|
validationErrorTopMargin: 8
|
||||||
|
onTextChanged: {
|
||||||
|
if (root.validate()) {
|
||||||
root.updateGasEthValue()
|
root.updateGasEthValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visible: parent.visible
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
Input {
|
||||||
id: labelSlow
|
id: inputGasPrice
|
||||||
anchors.top: gasSlider.bottom
|
label: qsTr("Per-gas overall limit")
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: undefined
|
||||||
//% "Slow"
|
|
||||||
text: qsTrId("slow")
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: Style.current.textColor
|
|
||||||
visible: parent.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: labelOptimal
|
|
||||||
anchors.top: gasSlider.bottom
|
|
||||||
anchors.topMargin: Style.current.padding
|
|
||||||
anchors.horizontalCenter: gasSlider.horizontalCenter
|
|
||||||
//% "Optimal"
|
|
||||||
text: qsTrId("optimal")
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: Style.current.textColor
|
|
||||||
visible: parent.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: labelFast
|
|
||||||
anchors.top: gasSlider.bottom
|
|
||||||
anchors.topMargin: Style.current.padding
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
//% "Fast"
|
width: 130
|
||||||
text: qsTrId("fast")
|
customHeight: 56
|
||||||
font.pixelSize: 15
|
text: root.defaultGasPrice()
|
||||||
color: Style.current.textColor
|
placeholderText: "20"
|
||||||
visible: parent.visible
|
onTextChanged: {
|
||||||
}
|
if (root.validate()) {
|
||||||
}
|
root.updateGasEthValue()
|
||||||
|
}
|
||||||
StatusButton {
|
}
|
||||||
id: buttonReset
|
|
||||||
anchors.top: sliderWrapper.bottom
|
|
||||||
anchors.topMargin: sliderWrapper.visible ? Style.current.smallPadding : 0
|
|
||||||
anchors.right: buttonAdvanced.left
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
//% "Reset"
|
|
||||||
text: qsTrId("reset")
|
|
||||||
flat: true
|
|
||||||
font.pixelSize: 13
|
|
||||||
visible: !sliderWrapper.visible
|
|
||||||
onClicked: {
|
|
||||||
gasSlider.value = root.defaultGasPrice()
|
|
||||||
inputGasPrice.text = root.defaultGasPrice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
id: buttonAdvanced
|
|
||||||
anchors.top: sliderWrapper.bottom
|
|
||||||
anchors.topMargin: sliderWrapper.visible ? Style.current.smallPadding : 0
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: -Style.current.padding
|
|
||||||
//% "Advanced"
|
|
||||||
text: qsTrId("advanced")
|
|
||||||
flat: true
|
|
||||||
font.pixelSize: 13
|
|
||||||
onClicked: {
|
|
||||||
customNetworkFeeDialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModalPopup {
|
|
||||||
id: customNetworkFeeDialog
|
|
||||||
//% "Custom Network Fee"
|
|
||||||
title: qsTrId("custom-network-fee")
|
|
||||||
height: 286
|
|
||||||
width: 400
|
|
||||||
property bool isValid: true
|
|
||||||
|
|
||||||
onIsValidChanged: {
|
|
||||||
root.isValid = isValid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate() {
|
StyledText {
|
||||||
// causes error on application load without a null check
|
color: Style.current.secondaryText
|
||||||
if (!inputGasLimit || !inputGasPrice) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
inputGasLimit.validationError = ""
|
|
||||||
inputGasPrice.validationError = ""
|
|
||||||
const noInputLimit = inputGasLimit.text === ""
|
|
||||||
const noInputPrice = inputGasPrice.text === ""
|
|
||||||
if (noInputLimit) {
|
|
||||||
inputGasLimit.validationError = root.noInputErrorMessage
|
|
||||||
}
|
|
||||||
if (noInputPrice) {
|
|
||||||
inputGasPrice.validationError = root.noInputErrorMessage
|
|
||||||
}
|
|
||||||
if (isNaN(inputGasLimit.text)) {
|
|
||||||
inputGasLimit.validationError = invalidInputErrorMessage
|
|
||||||
}
|
|
||||||
if (isNaN(inputGasPrice.text)) {
|
|
||||||
inputGasPrice.validationError = invalidInputErrorMessage
|
|
||||||
}
|
|
||||||
let inputLimit = parseFloat(inputGasLimit.text || "0.00")
|
|
||||||
let inputPrice = parseFloat(inputGasPrice.text || "0.00")
|
|
||||||
if (inputLimit === 0.00) {
|
|
||||||
inputGasLimit.validationError = root.greaterThan0ErrorMessage
|
|
||||||
}
|
|
||||||
if (inputPrice === 0.00) {
|
|
||||||
inputGasPrice.validationError = root.greaterThan0ErrorMessage
|
|
||||||
}
|
|
||||||
const isValid = inputGasLimit.validationError === "" && inputGasPrice.validationError === ""
|
|
||||||
customNetworkFeeDialog.isValid = isValid
|
|
||||||
return isValid
|
|
||||||
}
|
|
||||||
|
|
||||||
Input {
|
|
||||||
id: inputGasLimit
|
|
||||||
//% "Gas limit"
|
|
||||||
label: qsTrId("gas-limit")
|
|
||||||
text: "21000"
|
|
||||||
customHeight: 56
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: inputGasPrice.left
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
placeholderText: "21000"
|
|
||||||
validationErrorAlignment: TextEdit.AlignRight
|
|
||||||
validationErrorTopMargin: 8
|
|
||||||
onTextChanged: {
|
|
||||||
if (customNetworkFeeDialog.validate()) {
|
|
||||||
root.updateGasEthValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Input {
|
|
||||||
id: inputGasPrice
|
|
||||||
//% "Gas price"
|
|
||||||
label: qsTrId("gas-price")
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: undefined
|
|
||||||
anchors.right: parent.right
|
|
||||||
width: 130
|
|
||||||
customHeight: 56
|
|
||||||
text: root.defaultGasPrice()
|
|
||||||
placeholderText: "20"
|
|
||||||
onTextChanged: {
|
|
||||||
if (inputGasPrice.text.trim() === "") {
|
|
||||||
inputGasPrice.text = root.defaultGasPrice()
|
|
||||||
}
|
|
||||||
if (customNetworkFeeDialog.validate()) {
|
|
||||||
root.updateGasEthValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
color: Style.current.darkGrey
|
|
||||||
//% "Gwei"
|
//% "Gwei"
|
||||||
text: qsTrId("gwei")
|
text: qsTrId("gwei")
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 42
|
anchors.topMargin: 42
|
||||||
anchors.right: parent.right
|
anchors.right: inputGasPrice.right
|
||||||
anchors.rightMargin: Style.current.padding
|
anchors.rightMargin: Style.current.padding
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: labelGasPriceSummaryAdvanced
|
id: maxPriorityFeeText
|
||||||
anchors.bottom: parent.bottom
|
text: qsTr("Maximum priority fee: %1 ETH").arg(selectedGasEthValue)
|
||||||
anchors.bottomMargin: Style.current.smallPadding
|
anchors.top: inputGasLimit.bottom
|
||||||
anchors.right: parent.right
|
anchors.topMargin: 19
|
||||||
font.weight: Font.Medium
|
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
color: Style.current.secondaryText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: StatusButton {
|
StyledText {
|
||||||
id: applyButton
|
id: maxPriorityFeeFiatText
|
||||||
anchors.right: parent.right
|
text: `${selectedGasFiatValue} ${root.defaultCurrency}`
|
||||||
anchors.rightMargin: Style.current.smallPadding
|
anchors.verticalCenter: maxPriorityFeeText.verticalCenter
|
||||||
//% "Apply"
|
anchors.left: maxPriorityFeeText.right
|
||||||
text: qsTrId("invalid-key-confirm")
|
anchors.leftMargin: 6
|
||||||
anchors.bottom: parent.bottom
|
color: Style.current.secondaryText
|
||||||
enabled: customNetworkFeeDialog.isValid
|
anchors.topMargin: 19
|
||||||
onClicked: {
|
font.pixelSize: 13
|
||||||
if (customNetworkFeeDialog.validate()) {
|
}
|
||||||
root.updateGasEthValue()
|
|
||||||
}
|
StyledText {
|
||||||
customNetworkFeeDialog.close()
|
id: maxPriorityFeeDetailsText
|
||||||
}
|
text: qsTr("Maximum overall price for the transaction. If the block base fee exceeds this, it will be included in a following block with a lower base fee.")
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: maxPriorityFeeText.bottom
|
||||||
|
anchors.topMargin: Style.current.smallPadding
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import "../imports"
|
||||||
|
import "./status"
|
||||||
|
import "./"
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property var buttonGroup
|
||||||
|
property string text: qsTr("Low")
|
||||||
|
property string gasLimit
|
||||||
|
property double price: 1
|
||||||
|
property string defaultCurrency: "USD"
|
||||||
|
property bool hovered: false
|
||||||
|
property bool checkedByDefault: false
|
||||||
|
property var getGasEthValue: function () {}
|
||||||
|
property var getFiatValue: function () {}
|
||||||
|
property double ethValue: {
|
||||||
|
if (!gasLimit) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return getGasEthValue(price, gasLimit)
|
||||||
|
}
|
||||||
|
property double fiatValue: getFiatValue(ethValue, "ETH", defaultCurrency)
|
||||||
|
signal checked()
|
||||||
|
|
||||||
|
id: gasRectangle
|
||||||
|
border.color: hovered || gasRadioBtn.checked ? Style.current.primary : Style.current.border
|
||||||
|
border.width: 1
|
||||||
|
color: Style.current.transparent
|
||||||
|
width: 130
|
||||||
|
height: 120
|
||||||
|
clip: true
|
||||||
|
radius: Style.current.radius
|
||||||
|
|
||||||
|
StatusRadioButton {
|
||||||
|
id: gasRadioBtn
|
||||||
|
ButtonGroup.group: buttonGroup
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 14
|
||||||
|
checked: gasRectangle.checkedByDefault
|
||||||
|
onCheckedChanged: {
|
||||||
|
if (checked) {
|
||||||
|
gasRectangle.checked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: gasText
|
||||||
|
text: gasRectangle.text
|
||||||
|
font.pixelSize: 15
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: gasRadioBtn.bottom
|
||||||
|
anchors.topMargin: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: ethText
|
||||||
|
text: gasRectangle.ethValue + " ETH"
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: gasText.bottom
|
||||||
|
anchors.topMargin: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: fiatText
|
||||||
|
text: `${gasRectangle.fiatValue} ${gasRectangle.defaultCurrency}`
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: ethText.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: gasRectangle.hovered = true
|
||||||
|
onExited: gasRectangle.hovered = false
|
||||||
|
onClicked: gasRadioBtn.toggle()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue