Unify the flat/normal behavior of PC3 Buttons/ToolButtons
Rather than duplicating the behaviors in both Button.qml and ToolButton.qml, leading to bugs and inconsistencies, the Button/ToolButton background code is split into separate reusable files. The correct background is used depending on whether or not flat mode is enabled. BUG: 425174
This commit is contained in:
parent
13882a60e1
commit
7574eee24e
@ -21,10 +21,10 @@ T.Button {
|
||||
|
||||
Layout.minimumWidth: contentItem.implicitWidth + leftPadding + rightPadding
|
||||
|
||||
leftPadding: surfaceNormal.margins.left
|
||||
topPadding: surfaceNormal.margins.top
|
||||
rightPadding: surfaceNormal.margins.right
|
||||
bottomPadding: surfaceNormal.margins.bottom
|
||||
leftPadding: background.leftMargin
|
||||
topPadding: background.topMargin
|
||||
rightPadding: background.rightMargin
|
||||
bottomPadding: background.bottomMargin
|
||||
|
||||
hoverEnabled: !Kirigami.Settings.tabletMode
|
||||
|
||||
@ -36,7 +36,16 @@ T.Button {
|
||||
PlasmaCore.ColorScope.colorGroup: flat ? parent.PlasmaCore.ColorScope.colorGroup : PlasmaCore.Theme.ButtonColorGroup
|
||||
|
||||
contentItem: GridLayout {
|
||||
|
||||
/* Even though keyboardFocus is already defined as a property
|
||||
* in the background, it's null when it reaches the contentItem.
|
||||
* That means it has to be created here too unless a solution is found.
|
||||
*/
|
||||
property bool keyboardFocus: control.activeFocus &&
|
||||
(control.focusReason == Qt.TabFocusReason || control.focusReason == Qt.BacktabFocusReason)
|
||||
|
||||
columns: control.display == T.AbstractButton.TextBesideIcon ? 2 : 1
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
|
||||
@ -57,7 +66,7 @@ T.Button {
|
||||
colorGroup: PlasmaCore.Theme.ButtonColorGroup
|
||||
visible: source.length > 0 && control.display !== T.Button.TextOnly
|
||||
source: control.icon ? (control.icon.name || control.icon.source) : ""
|
||||
status: !control.flat && buttonSvg.hasElement("hint-focus-highlighted-background") && control.activeFocus && !control.pressed && !control.checked ? PlasmaCore.Svg.Selected : PlasmaCore.Svg.Normal
|
||||
status: !control.flat && buttonSvg.hasElement("hint-focus-highlighted-background") && contentItem.keyboardFocus && !control.pressed && !control.checked ? PlasmaCore.Svg.Selected : PlasmaCore.Svg.Normal
|
||||
}
|
||||
Label {
|
||||
id: label
|
||||
@ -66,57 +75,18 @@ T.Button {
|
||||
text: control.Kirigami.MnemonicData.richTextLabel
|
||||
font: control.font
|
||||
opacity: enabled || control.highlighted || control.checked ? 1 : 0.4
|
||||
color: buttonSvg.hasElement("hint-focus-highlighted-background") && control.activeFocus && !control.down ? theme.highlightedTextColor : theme.buttonTextColor
|
||||
color: buttonSvg.hasElement("hint-focus-highlighted-background") && contentItem.keyboardFocus && !control.down ? PlasmaCore.Theme.highlightedTextColor : PlasmaCore.Theme.buttonTextColor
|
||||
horizontalAlignment: control.display !== T.Button.TextUnderIcon && icon.visible ? Text.AlignLeft : Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
background: Item {
|
||||
Private.ButtonShadow {
|
||||
anchors.fill: parent
|
||||
visible: (!control.flat || control.hovered) && (!control.pressed || !control.checked)
|
||||
state: {
|
||||
if (control.pressed) {
|
||||
return "hidden"
|
||||
} else if (control.hovered) {
|
||||
return "hover"
|
||||
} else if (control.activeFocus) {
|
||||
return "focus"
|
||||
} else {
|
||||
return "shadow"
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaCore.Svg {
|
||||
id: buttonSvg
|
||||
imagePath: "widgets/button"
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfaceNormal
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: control.activeFocus ? ["focus-background", "normal"] : "normal"
|
||||
opacity: (!control.flat || control.hovered) && (!control.pressed || !control.checked) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: "pressed"
|
||||
opacity: control.checked || control.pressed ? 1 : 0
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Private.ButtonBackground {
|
||||
parentControl: control
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.kirigami 2.5 as Kirigami
|
||||
import "private" as Private
|
||||
|
||||
|
||||
T.ToolButton {
|
||||
id: control
|
||||
|
||||
@ -20,14 +19,12 @@ T.ToolButton {
|
||||
implicitHeight: Math.max(units.gridUnit, contentItem.implicitHeight)
|
||||
+ topPadding + bottomPadding
|
||||
|
||||
// for flat toolbuttons, we want to use margins from the pressed state since
|
||||
// those are the ones which are appropriate for a button without a buttonlike
|
||||
// appearance where we increase the size of the icon compared to buttonlike
|
||||
// buttons
|
||||
leftPadding: control.flat ? surfacePressed.margins.left : surfaceNormal.margins.left
|
||||
topPadding: control.flat ? surfacePressed.margins.top : surfaceNormal.margins.top
|
||||
rightPadding: control.flat ? surfacePressed.margins.right : surfaceNormal.margins.right
|
||||
bottomPadding: control.flat ? surfacePressed.margins.bottom : surfaceNormal.margins.bottom
|
||||
Layout.minimumWidth: contentItem.implicitWidth + leftPadding + rightPadding
|
||||
|
||||
leftPadding: background.leftMargin
|
||||
topPadding: background.topMargin
|
||||
rightPadding: background.rightMargin
|
||||
bottomPadding: background.bottomMargin
|
||||
|
||||
hoverEnabled: !Kirigami.Settings.tabletMode
|
||||
|
||||
@ -41,6 +38,14 @@ T.ToolButton {
|
||||
PlasmaCore.ColorScope.colorGroup: flat ? parent.PlasmaCore.ColorScope.colorGroup : PlasmaCore.Theme.ButtonColorGroup
|
||||
|
||||
contentItem: GridLayout {
|
||||
|
||||
/* Even though keyboardFocus is already defined as a property
|
||||
* in the background, it's null when it reaches the contentItem.
|
||||
* That means it has to be created here too unless a solution is found.
|
||||
*/
|
||||
property bool keyboardFocus: control.activeFocus &&
|
||||
(control.focusReason == Qt.TabFocusReason || control.focusReason == Qt.BacktabFocusReason)
|
||||
|
||||
columns: control.display == T.AbstractButton.TextBesideIcon ? 2 : 1
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
@ -65,12 +70,12 @@ T.ToolButton {
|
||||
implicitWidth: control.icon.width > 0 ? control.icon.width : units.iconSizes.smallMedium
|
||||
implicitHeight: control.icon.height > 0 ? control.icon.height : units.iconSizes.smallMedium
|
||||
|
||||
colorGroup: control.PlasmaCore.ColorScope.colorGroup
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
visible: source.length > 0 && control.display !== T.AbstractButton.TextOnly
|
||||
source: control.icon ? (control.icon.name || control.icon.source) : ""
|
||||
status: !control.flat && control.activeFocus && !control.pressed && !control.checked ? PlasmaCore.Svg.Selected : PlasmaCore.Svg.Normal
|
||||
status: !control.flat && contentItem.keyboardFocus && !control.pressed && !control.checked ? PlasmaCore.Svg.Selected : PlasmaCore.Svg.Normal
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
@ -82,7 +87,6 @@ T.ToolButton {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonsurfaceChecker
|
||||
visible: false
|
||||
@ -92,52 +96,7 @@ T.ToolButton {
|
||||
}
|
||||
}
|
||||
|
||||
background: Item {
|
||||
Private.ButtonShadow {
|
||||
anchors.fill: parent
|
||||
readonly property bool keyboardFocus: control.activeFocus &&
|
||||
(control.focusReason == Qt.TabFocusReason || control.focusReason == Qt.BacktabFocusReason)
|
||||
visible: (!control.flat || control.hovered || keyboardFocus) && (!control.pressed || !control.checked)
|
||||
|
||||
state: {
|
||||
if (control.pressed) {
|
||||
return "hidden"
|
||||
} else if (control.hovered) {
|
||||
return "hover"
|
||||
} else if (keyboardFocus) {
|
||||
return "focus"
|
||||
} else if (control.flat) {
|
||||
return "hidden"
|
||||
} else {
|
||||
return "shadow"
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfaceNormal
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: "normal"
|
||||
opacity: !control.flat && (!control.pressed || !control.checked) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfacePressed
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: control.flat ? "toolbutton-pressed" : "pressed"
|
||||
opacity: control.checked || control.pressed ? 1 : 0
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Private.ButtonBackground {
|
||||
parentControl: control
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Templates @QQC2_VERSION@ as T
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: root
|
||||
// TODO: mark this required when our minimum Qt version is new enough
|
||||
property T.AbstractButton parentControl
|
||||
|
||||
// These should be used as the padding for the parent control
|
||||
property real leftMargin
|
||||
property real topMargin
|
||||
property real rightMargin
|
||||
property real bottomMargin
|
||||
/* FIXME: This is null when passed to the parent control's contentItem.
|
||||
* This is meant to be used to pass information about the current
|
||||
* appearance of the button to the contentItem of the Button or
|
||||
* ToolButton so that the icon and label can use the right color.
|
||||
*/
|
||||
property string usedPrefix
|
||||
|
||||
readonly property bool keyboardFocus: parentControl.activeFocus &&
|
||||
(parentControl.focusReason == Qt.TabFocusReason || parentControl.focusReason == Qt.BacktabFocusReason)
|
||||
|
||||
FlatButtonBackground {
|
||||
id: flatButtonBackground
|
||||
anchors.fill: parent
|
||||
hovered: parentControl.hovered
|
||||
pressed: parentControl.pressed
|
||||
checked: parentControl.checked
|
||||
focused: root.keyboardFocus
|
||||
}
|
||||
|
||||
RaisedButtonBackground {
|
||||
id: raisedButtonBackground
|
||||
anchors.fill: parent
|
||||
hovered: parentControl.hovered
|
||||
pressed: parentControl.pressed
|
||||
checked: parentControl.checked
|
||||
focused: root.keyboardFocus
|
||||
}
|
||||
|
||||
state: parentControl.flat ? "flat" : "raised"
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "flat"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: flatButtonBackground.leftMargin
|
||||
topMargin: flatButtonBackground.topMargin
|
||||
rightMargin: flatButtonBackground.rightMargin
|
||||
bottomMargin: flatButtonBackground.bottomMargin
|
||||
usedPrefix: flatButtonBackground.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: flatButtonBackground
|
||||
visible: true
|
||||
}
|
||||
PropertyChanges {
|
||||
target: raisedButtonBackground
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "raised"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: raisedButtonBackground.leftMargin
|
||||
topMargin: raisedButtonBackground.topMargin
|
||||
rightMargin: raisedButtonBackground.rightMargin
|
||||
bottomMargin: raisedButtonBackground.bottomMargin
|
||||
usedPrefix: raisedButtonBackground.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: flatButtonBackground
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: raisedButtonBackground
|
||||
visible: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool showFocus: false
|
||||
property bool flat: false
|
||||
|
||||
property alias enabledBorders: focusEffect.enabledBorders
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: focusEffect
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: -margins.left
|
||||
topMargin: -margins.top
|
||||
rightMargin: -margins.right
|
||||
bottomMargin: -margins.bottom
|
||||
}
|
||||
opacity: 0
|
||||
imagePath: "widgets/button"
|
||||
prefix: flat ? ["toolbutton-focus", "focus"] : "focus"
|
||||
}
|
||||
|
||||
state: root.showFocus ? "focused" : "hidden"
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "focused"
|
||||
PropertyChanges {
|
||||
target: focusEffect
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hidden"
|
||||
PropertyChanges {
|
||||
target: focusEffect
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hidden"
|
||||
SequentialAnimation {
|
||||
OpacityAnimator {
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "focused"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
OpacityAnimator {
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool showHover: false
|
||||
// TODO KF6: If "toolbutton-hover" is made to behave like "hover",
|
||||
// put the logic for flat button hover effects here.
|
||||
|
||||
//used to tell apart this implementation with the touch components one
|
||||
property bool hasOverState: true
|
||||
property alias enabledBorders: hoverEffect.enabledBorders
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: hoverEffect
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: -margins.left
|
||||
topMargin: -margins.top
|
||||
rightMargin: -margins.right
|
||||
bottomMargin: -margins.bottom
|
||||
}
|
||||
opacity: 0
|
||||
imagePath: "widgets/button"
|
||||
prefix: "hover"
|
||||
}
|
||||
|
||||
state: root.showHover ? "hovered" : "hidden"
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hovered"
|
||||
PropertyChanges {
|
||||
target: hoverEffect
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hidden"
|
||||
PropertyChanges {
|
||||
target: hoverEffect
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hidden"
|
||||
SequentialAnimation {
|
||||
OpacityAnimator {
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hovered"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
OpacityAnimator {
|
||||
// Using a shorter duration here makes things feel more responsive.
|
||||
duration: units.shortDuration/2
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
@ -20,34 +21,17 @@ TODO i need more info here
|
||||
Properties:
|
||||
**/
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick 2.12
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: main
|
||||
state: parent.state
|
||||
//used to tell apart this implementation with the touch components one
|
||||
property bool hasOverState: true
|
||||
property alias enabledBorders: shadow.enabledBorders
|
||||
id: root
|
||||
property bool showShadow: true
|
||||
|
||||
property alias enabledBorders: shadowEffect.enabledBorders
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: hover
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: -margins.left
|
||||
topMargin: -margins.top
|
||||
rightMargin: -margins.right
|
||||
bottomMargin: -margins.bottom
|
||||
}
|
||||
opacity: 0
|
||||
imagePath: "widgets/button"
|
||||
prefix: "hover"
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: shadow
|
||||
|
||||
id: shadowEffect
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: -margins.left
|
||||
@ -59,63 +43,54 @@ Item {
|
||||
prefix: "shadow"
|
||||
}
|
||||
|
||||
state: showShadow ? "shown" : "hidden"
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "shadow"
|
||||
name: "shown"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
target: shadowEffect
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 0
|
||||
prefix: "hover"
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hover"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 1
|
||||
prefix: "hover"
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "focus"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 1
|
||||
prefix: "focus"
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hidden"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
target: shadowEffect
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 0
|
||||
prefix: "hover"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
PropertyAnimation {
|
||||
properties: "opacity"
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.OutQuad
|
||||
from: "*"
|
||||
to: "shown"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
OpacityAnimator {
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hidden"
|
||||
SequentialAnimation {
|
||||
OpacityAnimator {
|
||||
// Same duration as pressed and flat background hovered state animations
|
||||
duration: units.shortDuration/2
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: root
|
||||
// TODO: Mark these required when our minimum Qt version is new enough.
|
||||
property bool hovered
|
||||
property bool pressed
|
||||
property bool checked
|
||||
property bool focused
|
||||
|
||||
property real leftMargin: surfaceHover.margins.left
|
||||
property real topMargin: surfaceHover.margins.top
|
||||
property real rightMargin: surfaceHover.margins.right
|
||||
property real bottomMargin: surfaceHover.margins.bottom
|
||||
property string usedPrefix: surfaceHover.usedPrefix
|
||||
|
||||
ButtonShadow {
|
||||
anchors.fill: parent
|
||||
showShadow: !(root.checked || root.pressed) && root.usedPrefix === "normal"
|
||||
}
|
||||
|
||||
ButtonFocus {
|
||||
anchors.fill: parent
|
||||
showFocus: root.focused && !root.pressed
|
||||
flat: true
|
||||
}
|
||||
|
||||
// TODO: Maybe add a way to customize the look of normal state flat buttons with "toolbutton-normal"?
|
||||
// TODO: Maybe add a way to customize the background of focused flat buttons with "toolbutton-focus-background"?
|
||||
// TODO KF6: "flat" would be a more logical name than "toolbutton" since toolbuttons can be non-flat.
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfaceHover
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
/* TODO KF6: making "toolbutton-hover" margins work like "hover"
|
||||
* and using "hover" as a fallback would make more sense.
|
||||
* If that is done, make ButtonHover handle flat button hover effects.
|
||||
*/
|
||||
// The fallback is "normal" to match PC2 behavior. Some 3rd party themes depend on this.
|
||||
prefix: ["toolbutton-hover", "normal"]
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfacePressed
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: ["toolbutton-pressed", "pressed"]
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
state: {
|
||||
if (root.checked || root.pressed) {
|
||||
return "pressed";
|
||||
} else if (root.hovered) {
|
||||
return "hovered";
|
||||
} else {
|
||||
return "normal";
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "normal"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfaceHover.margins.left
|
||||
topMargin: surfaceHover.margins.top
|
||||
rightMargin: surfaceHover.margins.right
|
||||
bottomMargin: surfaceHover.margins.bottom
|
||||
usedPrefix: surfaceHover.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceHover
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hovered"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfaceHover.margins.left
|
||||
topMargin: surfaceHover.margins.top
|
||||
rightMargin: surfaceHover.margins.right
|
||||
bottomMargin: surfaceHover.margins.bottom
|
||||
usedPrefix: surfaceHover.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceHover
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "pressed"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfacePressed.margins.left
|
||||
topMargin: surfacePressed.margins.top
|
||||
rightMargin: surfacePressed.margins.right
|
||||
bottomMargin: surfacePressed.margins.bottom
|
||||
usedPrefix: surfacePressed.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceHover
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
/* FIXME: For some reason, one of the surfaces will stop working when
|
||||
* OpacityAnimator is used.
|
||||
* OpacityAnimator would be more efficient.
|
||||
*/
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "normal"
|
||||
SequentialAnimation {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
targets: [surfaceHover, surfacePressed]
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hovered"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: surfaceHover
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
// Using a shorter duration here makes things feel more responsive.
|
||||
duration: units.shortDuration/2
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: surfacePressed
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "pressed"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: surfacePressed
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
// Using a shorter duration here makes things feel more responsive.
|
||||
duration: units.shortDuration/2
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: surfaceHover
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
id: root
|
||||
// TODO: Mark these required when our minimum Qt version is new enough.
|
||||
property bool hovered
|
||||
property bool pressed
|
||||
property bool checked
|
||||
property bool focused
|
||||
|
||||
property real leftMargin: surfaceNormal.margins.left
|
||||
property real topMargin: surfaceNormal.margins.top
|
||||
property real rightMargin: surfaceNormal.margins.right
|
||||
property real bottomMargin: surfaceNormal.margins.bottom
|
||||
property string usedPrefix: surfaceNormal.usedPrefix
|
||||
|
||||
ButtonShadow {
|
||||
anchors.fill: parent
|
||||
showShadow: !(root.checked || root.pressed)
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfaceNormal
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: "normal"
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
// Intentionally lower than surfacePressed, surfaceFocused
|
||||
ButtonFocus {
|
||||
anchors.fill: parent
|
||||
showFocus: root.focused && !root.pressed
|
||||
}
|
||||
|
||||
// Intentionally lower than surfacePressed and surfaceFocused
|
||||
ButtonHover {
|
||||
anchors.fill: parent
|
||||
showHover: root.hovered && !root.pressed
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfacePressed
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: "pressed"
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: surfaceFocused
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: ["focus-background", "normal"]
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
state: {
|
||||
if (root.checked || root.pressed) {
|
||||
return "pressed";
|
||||
} else if (focused && surfaceFocused.usedPrefix != "normal") {
|
||||
return "focused";
|
||||
} else {
|
||||
return "normal";
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "normal"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfaceNormal.margins.left
|
||||
topMargin: surfaceNormal.margins.top
|
||||
rightMargin: surfaceNormal.margins.right
|
||||
bottomMargin: surfaceNormal.margins.bottom
|
||||
usedPrefix: surfaceNormal.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceNormal
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceFocused
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "pressed"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfacePressed.margins.left
|
||||
topMargin: surfacePressed.margins.top
|
||||
rightMargin: surfacePressed.margins.right
|
||||
bottomMargin: surfacePressed.margins.bottom
|
||||
usedPrefix: surfacePressed.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceNormal
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceFocused
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "focused"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
leftMargin: surfaceFocused.margins.left
|
||||
topMargin: surfaceFocused.margins.top
|
||||
rightMargin: surfaceFocused.margins.right
|
||||
bottomMargin: surfaceFocused.margins.bottom
|
||||
usedPrefix: surfaceFocused.usedPrefix
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceNormal
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfacePressed
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: surfaceFocused
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
/* FIXME: For some reason, one of the surfaces will stop working when
|
||||
* OpacityAnimator is used.
|
||||
* OpacityAnimator would be more efficient.
|
||||
*/
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "normal"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: surfaceNormal
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
targets: [surfacePressed, surfaceFocused]
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "pressed"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: surfacePressed
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
// Using a shorter duration here makes things feel more responsive.
|
||||
duration: units.shortDuration/2
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
targets: [surfaceNormal, surfaceFocused]
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "focused"
|
||||
SequentialAnimation {
|
||||
PropertyAction {
|
||||
target: surfaceFocused
|
||||
property: "visible"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: units.shortDuration
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
targets: [surfaceNormal, surfacePressed]
|
||||
property: "visible"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
|
||||
ButtonBackground 1.0 ButtonBackground.qml
|
||||
ButtonFocus 1.0 ButtonFocus.qml
|
||||
ButtonHoverFocus 1.0 ButtonHoverFocus.qml
|
||||
ButtonShadow 1.0 ButtonShadow.qml
|
||||
DefaultListItemBackground 1.0 DefaultListItemBackground.qml
|
||||
FlatButtonBackground 1.0 FlatButtonBackground.qml
|
||||
RaisedButtonBackground 1.0 RaisedButtonBackground.qml
|
||||
RoundShadow 1.0 RoundShadow.qml
|
||||
TextFieldFocus 1.0 TextFieldFocus.qml
|
||||
|
Loading…
Reference in New Issue
Block a user