plasmoid: Customize buttons

* Use less space
* Fix iconSource when menu present
This commit is contained in:
Martchus 2017-09-12 00:00:16 +02:00
parent ee5c38dd7d
commit d3b1da2def
9 changed files with 488 additions and 24 deletions

View File

@ -19,6 +19,9 @@ set(PLASMOID_FILES
../package/contents/ui/DetailView.qml
../package/contents/ui/DetailItem.qml
../package/contents/ui/ToolTipView.qml
../package/contents/ui/TinyButton.qml
../package/contents/ui/TinyButtonStyle.qml
../package/contents/ui/ButtonShadow.qml
../package/contents/ui/main.qml
)
list(APPEND QML_SRC_FILES ${PLASMOID_FILES})

View File

@ -0,0 +1,138 @@
// Imported from Plasma 5.38.0 for TinyButtonStyle.qml which is a customized
// version of Plasma's ToolButtonStyle.qml
/*
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
/**Documented API
Inherits:
Item
Imports:
QtQuick 2.1
org.kde.plasma.core
Description:
TODO i need more info here
Properties:
**/
import QtQuick 2.1
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
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
anchors {
fill: parent
leftMargin: -margins.left
topMargin: -margins.top
rightMargin: -margins.right
bottomMargin: -margins.bottom
}
imagePath: "widgets/button"
prefix: "shadow"
}
states: [
State {
name: "shadow"
PropertyChanges {
target: shadow
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
opacity: 0
}
PropertyChanges {
target: hover
opacity: 0
prefix: "hover"
}
}
]
transitions: [
Transition {
PropertyAnimation {
properties: "opacity"
duration: units.longDuration
easing.type: Easing.OutQuad
}
}
]
}

View File

@ -8,14 +8,12 @@ RowLayout {
Layout.leftMargin: units.iconSizes.smallMedium
text: name
font.pointSize: theme.defaultFont.pointSize * 0.8
height: contentHeight
elide: Text.ElideRight
}
PlasmaComponents.Label {
Layout.fillWidth: true
text: detail
font.pointSize: theme.defaultFont.pointSize * 0.8
height: contentHeight
elide: Text.ElideRight
}
}

View File

@ -28,8 +28,8 @@ Item {
RowLayout {
PlasmaCore.IconItem {
Layout.preferredWidth: units.iconSizes.smallMedium * 1.1
Layout.preferredHeight: units.iconSizes.smallMedium * 1.1
Layout.preferredWidth: units.iconSizes.small
Layout.preferredHeight: units.iconSizes.small
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
@ -51,7 +51,7 @@ Item {
Item {
width: 3
}
PlasmaComponents.ToolButton {
TinyButton {
id: barcodeToolButton
iconSource: paused ? "media-playback-start" : "media-playback-pause"
tooltip: paused ? qsTr("Resume") : qsTr("Pause")

View File

@ -30,8 +30,8 @@ Item {
id: itemSummary
PlasmaCore.IconItem {
Layout.preferredWidth: units.iconSizes.smallMedium * 1.1
Layout.preferredHeight: units.iconSizes.smallMedium * 1.1
Layout.preferredWidth: units.iconSizes.small
Layout.preferredHeight: units.iconSizes.small
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
@ -54,7 +54,7 @@ Item {
Item {
width: units.smallSpacing
}
PlasmaComponents.ToolButton {
TinyButton {
iconSource: "emblem-important"
tooltip: qsTr("Show errors")
// 5 stands for SyncthingDirStatus::OutOfSync, unfortunately there is currently
@ -66,13 +66,13 @@ Item {
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
TinyButton {
iconSource: "view-refresh"
tooltip: qsTr("Rescan")
onClicked: plasmoid.nativeInterface.connection.rescan(
dirId)
}
PlasmaComponents.ToolButton {
TinyButton {
id: barcodeToolButton
iconSource: paused ? "media-playback-start" : "media-playback-pause"
tooltip: paused ? qsTr("Resume") : qsTr("Pause")
@ -82,7 +82,7 @@ Item {
[dirId])
}
}
PlasmaComponents.ToolButton {
TinyButton {
iconSource: "folder"
tooltip: qsTr("Open in file browser")
onClicked: {

View File

@ -56,7 +56,7 @@ Item {
Item {
width: 3
}
PlasmaComponents.ToolButton {
TinyButton {
iconSource: "folder"
tooltip: qsTr("Open in file browser")
onClicked: {
@ -111,7 +111,7 @@ Item {
value: percentage
}
}
PlasmaComponents.ToolButton {
TinyButton {
iconSource: "folder"
tooltip: qsTr("Open in file browser")
onClicked: {

View File

@ -3,9 +3,9 @@ import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQml 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 2.0 as PlasmaComponents
import martchus.syncthingplasmoid 0.6 as SyncthingPlasmoid
ColumnLayout {
@ -56,8 +56,9 @@ ColumnLayout {
id: toolBar
Layout.fillWidth: true
PlasmaComponents.ToolButton {
TinyButton {
id: connectButton
states: [
State {
name: "disconnected"
@ -113,7 +114,7 @@ ColumnLayout {
}
}
}
PlasmaComponents.ToolButton {
TinyButton {
id: startStopButton
states: [
@ -161,13 +162,14 @@ ColumnLayout {
}
return service.running ? "running" : "stopped"
}
onClicked: plasmoid.nativeInterface.service.toggleRunning()
style: TinyButtonStyle {
}
}
Item {
Layout.fillWidth: true
}
PlasmaComponents.ToolButton {
TinyButton {
tooltip: qsTr("Show own device ID")
iconSource: "view-barcode"
onClicked: {
@ -175,7 +177,7 @@ ColumnLayout {
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
TinyButton {
tooltip: qsTr("Show Syncthing log")
iconSource: "text-x-generic"
onClicked: {
@ -183,12 +185,12 @@ ColumnLayout {
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
TinyButton {
tooltip: qsTr("Rescan all directories")
iconSource: "view-refresh"
onClicked: plasmoid.nativeInterface.connection.rescanAllDirs()
}
PlasmaComponents.ToolButton {
TinyButton {
tooltip: qsTr("Settings")
iconSource: "preferences-other"
onClicked: {
@ -196,7 +198,7 @@ ColumnLayout {
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
TinyButton {
tooltip: qsTr("Web UI")
iconSource: "internet-web-browser"
onClicked: {
@ -251,10 +253,10 @@ ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
}
ToolButton {
TinyButton {
text: plasmoid.nativeInterface.currentConnectionConfigName
// FIXME: iconSource doesn't work
iconSource: "network-connect"
paddingEnabled: true
// FIXME: figure out why menu doesn't work in plasmoidviewer using NVIDIA driver
// (works with plasmawindowed or Intel graphics)
menu: Menu {

View File

@ -0,0 +1,9 @@
import org.kde.plasma.components 2.0 as PlasmaComponents
PlasmaComponents.ToolButton {
property int iconSize: units.iconSizes.small
property bool paddingEnabled: false
style: TinyButtonStyle {
}
}

View File

@ -0,0 +1,314 @@
// This is a simplified and adjusted version of Plasma's ToolButtonStyle.
// It will make the button only as big as required and allows to disable
// padding. This makes the button a little bit more compact. Additionally,
// the iconSource works also when a menu is present. The ButtonShadow.qml
// file is still used (version from Plasma 5.38.0).
import QtQuick 2.0
import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle
import QtQuick.Layouts 1.1
import QtQuick.Controls.Private 1.0 as QtQuickControlsPrivate
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 2.0 as PlasmaComponents
QtQuickControlStyle.ButtonStyle {
id: style
property int minimumWidth
property int minimumHeight
property bool flat: control.flat !== undefined ? control.flat : !(control.checkable
&& control.checked)
property bool controlHovered: control.hovered
&& !(QtQuickControlsPrivate.Settings.hasTouchScreen
&& QtQuickControlsPrivate.Settings.isMobile)
label: RowLayout {
id: buttonContent
spacing: units.smallSpacing
Layout.preferredWidth: Math.max(control.iconSize, label.implicitWidth)
Layout.preferredHeight: Math.max(control.iconSize, label.implicitHeight)
PlasmaCore.IconItem {
id: icon
source: control.iconName || control.iconSource
Layout.preferredWidth: control.iconSize
Layout.preferredHeight: control.iconSize
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
active: style.controlHovered
colorGroup: controlHovered
|| !flat ? PlasmaCore.Theme.ButtonColorGroup : PlasmaCore.ColorScope.colorGroup
}
//NOTE: this is used only to check elements existence
PlasmaCore.FrameSvgItem {
id: buttonsurfaceChecker
visible: false
imagePath: "widgets/button"
prefix: style.flat ? ["toolbutton-hover", "normal"] : "normal"
}
PlasmaComponents.Label {
id: label
anchors.verticalCenter: parent.verticalCenter
text: control.text
textFormat: Text.StyledText
font: control.font || theme.defaultFont
visible: control.text !== ""
Layout.fillWidth: true
color: (controlHovered || !flat) && buttonsurfaceChecker.usedPrefix
!== "toolbutton-hover" ? theme.buttonTextColor : PlasmaCore.ColorScope.textColor
horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter
elide: Text.ElideRight
}
PlasmaExtras.ConditionalLoader {
id: arrow
when: control.menu !== null
visible: when
Layout.preferredWidth: units.iconSizes.small
Layout.preferredHeight: units.iconSizes.small
source: Component {
PlasmaCore.SvgItem {
visible: control.menu !== null
svg: PlasmaCore.Svg {
imagePath: "widgets/arrows"
colorGroup: (style.controlHovered || !style.flat)
&& buttonsurfaceChecker.usedPrefix
!== "toolbutton-hover" ? PlasmaCore.Theme.ButtonColorGroup : PlasmaCore.ColorScope.colorGroup
}
elementId: "down-arrow"
}
}
}
}
background: Item {
id: buttonSurface
Connections {
target: control
onHoveredChanged: {
if (style.controlHovered) {
control.z += 2
} else {
control.z -= 2
}
}
}
ButtonShadow {
id: shadow
visible: !style.flat || control.activeFocus
anchors.fill: parent
enabledBorders: surfaceNormal.enabledBorders
state: {
if (control.pressed) {
return "hidden"
} else if (style.controlHovered) {
return "hover"
} else if (control.activeFocus) {
return "focus"
} else {
return "shadow"
}
}
}
PlasmaCore.FrameSvgItem {
id: surfaceNormal
anchors.fill: parent
imagePath: "widgets/button"
prefix: style.flat ? ["toolbutton-hover", "normal"] : "normal"
enabledBorders: {
if (style.flat || !control.parent
|| control.parent.width < control.parent.implicitWidth
|| control.parent.spacing !== 0
|| !bordersSvg.hasElement(
"pressed-hint-compose-over-border")) {
if (shadows !== null) {
shadows.destroy()
}
return "AllBorders"
}
var borders = new Array()
if (control.x == 0) {
borders.push("LeftBorder")
shadow.anchors.leftMargin = 0
} else {
shadow.anchors.leftMargin = -1
}
if (control.y == 0) {
borders.push("TopBorder")
shadow.anchors.topMargin = 0
} else {
shadow.anchors.topMargin = -1
}
if (control.x + control.width >= control.parent.width) {
borders.push("RightBorder")
shadow.anchors.rightMargin = 0
} else {
shadow.anchors.rightMargin = -1
}
if (control.y + control.height >= control.parent.height) {
borders.push("BottomBorder")
shadow.anchors.bottomMargin = 0
} else {
shadow.anchors.bottomMargin = -1
}
if (shadows === null) {
shadows = shadowsComponent.createObject(buttonSurface)
}
return borders.join("|")
}
PlasmaCore.Svg {
id: bordersSvg
imagePath: "widgets/button"
}
}
PlasmaCore.FrameSvgItem {
id: surfacePressed
anchors.fill: parent
imagePath: "widgets/button"
prefix: style.flat ? ["toolbutton-pressed", "pressed"] : "pressed"
enabledBorders: surfaceNormal.enabledBorders
opacity: 0
}
property Item shadows
Component {
id: shadowsComponent
Item {
anchors.fill: parent
PlasmaCore.SvgItem {
svg: bordersSvg
width: naturalSize.width
elementId: (buttonSurface.state == "pressed" ? surfacePressed.prefix : surfaceNormal.prefix) + "-left"
visible: button.x > 0
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
margins: 1
leftMargin: -1
}
}
PlasmaCore.SvgItem {
svg: bordersSvg
width: naturalSize.width
elementId: (buttonSurface.state == "pressed" ? surfacePressed.prefix : surfaceNormal.prefix) + "-right"
visible: button.x + button.width < button.parent.width
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
margins: 1
rightMargin: -1
}
}
PlasmaCore.SvgItem {
svg: bordersSvg
height: naturalSize.height
elementId: (buttonSurface.state == "pressed" ? surfacePressed.prefix : surfaceNormal.prefix) + "-top"
visible: button.y > 0
anchors {
left: parent.left
top: parent.top
right: parent.right
margins: 1
topMargin: -1
}
}
PlasmaCore.SvgItem {
svg: bordersSvg
height: naturalSize.height
elementId: (buttonSurface.state == "pressed" ? surfacePressed.prefix : surfaceNormal.prefix) + "-bottom"
visible: button.y + button.height < button.parent.height
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
margins: 1
bottomMargin: -1
}
}
}
}
state: (control.pressed
|| control.checked ? "pressed" : (style.controlHovered ? "hover" : "normal"))
states: [
State {
name: "normal"
PropertyChanges {
target: surfaceNormal
opacity: style.flat ? 0 : 1
}
PropertyChanges {
target: surfacePressed
opacity: 0
}
},
State {
name: "hover"
PropertyChanges {
target: surfaceNormal
opacity: 1
}
PropertyChanges {
target: surfacePressed
opacity: 0
}
},
State {
name: "pressed"
PropertyChanges {
target: surfaceNormal
opacity: 0
}
PropertyChanges {
target: surfacePressed
opacity: 1
}
}
]
transitions: [
Transition {
// Cross fade from pressed to normal
ParallelAnimation {
NumberAnimation {
target: surfaceNormal
property: "opacity"
duration: 100
}
NumberAnimation {
target: surfacePressed
property: "opacity"
duration: 100
}
}
}
]
Component.onCompleted: {
if (control.paddingEnabled) {
padding.top = surfaceNormal.margins.top
padding.left = surfaceNormal.margins.left
padding.right = surfaceNormal.margins.right
padding.bottom = surfaceNormal.margins.bottom
}
}
}
}