From 02c6bba518352dde5cea446e5b8ca3e9cea6d91f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 15:58:14 +0200 Subject: [PATCH 01/12] initial port of Button to QtControls still loads of layout problems --- src/declarativeimports/core/iconitem.cpp | 7 + .../plasmacomponents/qml/Button.qml | 259 ++---------------- .../qml/styles/ButtonStyle.qml | 147 ++++++++++ 3 files changed, 172 insertions(+), 241 deletions(-) create mode 100644 src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml diff --git a/src/declarativeimports/core/iconitem.cpp b/src/declarativeimports/core/iconitem.cpp index 38012cc0b..2695728e6 100644 --- a/src/declarativeimports/core/iconitem.cpp +++ b/src/declarativeimports/core/iconitem.cpp @@ -91,6 +91,13 @@ void IconItem::setSource(const QVariant &source) m_svgIcon = 0; } else if (source.canConvert()) { + if (source.toString().isEmpty()) { + delete m_svgIcon; + m_svgIcon = 0; + emit validChanged(); + return; + } + if (!m_svgIcon) { m_svgIcon = new Plasma::Svg(this); m_svgIcon->setColorGroup(m_colorGroup); diff --git a/src/declarativeimports/plasmacomponents/qml/Button.qml b/src/declarativeimports/plasmacomponents/qml/Button.qml index 262e20fd0..5a15b65f0 100644 --- a/src/declarativeimports/plasmacomponents/qml/Button.qml +++ b/src/declarativeimports/plasmacomponents/qml/Button.qml @@ -29,63 +29,19 @@ * theme. */ import QtQuick 2.1 -import org.kde.plasma.core 2.0 as PlasmaCore -import QtQuick.Controls.Private 1.0 -import QtQuick.Controls 1.0 -import "private" as Private - - -Item { - id: button - - - // Commmon API - /** - * This property holds whether this button is checked or not. - * The button must be in the checkable state to enable users to check or - * uncheck it. - * - * The default value is false. - * - * @see checkable - */ - property bool checked: false - - /** - * This property holds if the button is acting like a checkable button or - * not. - * - * The default value is false. - */ - property bool checkable: false - - /** - * type:bool - * This property holds if the button is pressed or not. - * Read-only. - */ - property alias pressed: mouse.pressed - - /** - * type:string - * This property holds the text label for the button. - */ - property alias text: label.text - - /*! This property holds the button tooltip. */ - property string tooltip - - /** - * type:string - * - * This property holds the source url for the Button's icon. - * It can be any image from any protocol supported by the Image element, or - * a freedesktop-compatible icon name - * - * The default value is an empty url, which displays no icon. - */ - property alias iconSource: icon.source +import QtQuick.Controls 1.2 as QtControls +import "styles" as Styles +/** + * The push button is perhaps the most commonly used widget in any graphical user interface. + * Pushing (or clicking) a button commands the computer to perform some action + * or answer a question. Common examples of buttons are OK, Apply, Cancel, + * Close, Yes, No, and Help buttons. + * + * Properties and signals are the same as QtQuickControls Button + * @see http://qt-project.org/doc/qt-5/qml-qtquick-controls-button.html + */ +QtControls.Button { /** * type:font * @@ -93,198 +49,19 @@ Item { * * See also Qt documentation for font type. */ - property alias font: label.font + property font font: theme.defaultFont + + property string iconSource: "" - //icon + label + left margin + right margin + spacing between icon and text /** * Smallest width this button can be to show all the contents */ - property real minimumWidth: icon.width + label.implicitWidth + surfaceNormal.margins.left + surfaceNormal.margins.right + ((icon.valid) ? surfaceNormal.margins.left : 0) + property real minimumWidth: icon.width + style.label.implicitWidth + surfaceNormal.margins.left + surfaceNormal.margins.right + ((icon.valid) ? surfaceNormal.margins.left : 0) /** * Smallest height this button can be to show all the contents */ - property real minimumHeight: Math.max(units.iconSizes.small, label.implicitHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom + property real minimumHeight: Math.max(units.iconSizes.small, style.label.implicitHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom - /** - * This signal is emitted when the button is clicked. - */ - signal clicked() - - implicitWidth: { - if (label.text.length == 0) { - height; - } else { - Math.max(theme.mSize(theme.defaultFont).width*12, minimumWidth); - } - } - - LayoutMirroring.enabled: (Qt.application.layoutDirection === Qt.RightToLeft) - LayoutMirroring.childrenInherit: true - implicitHeight: Math.floor(Math.max(theme.mSize(theme.defaultFont).height*1.6, minimumHeight)) - - // TODO: needs to define if there will be specific graphics for - // disabled buttons - opacity: enabled ? 1.0 : 0.5 - - activeFocusOnTab: true - - - QtObject { - id: internal - property bool userPressed: false - - function belongsToButtonGroup() - { - return button.parent - && button.parent.hasOwnProperty("checkedButton") - && button.parent.exclusive - } - - function clickButton() - { - userPressed = false - if (!button.enabled) { - return - } - - if ((!belongsToButtonGroup() || !button.checked) && button.checkable) { - button.checked = !button.checked - } - - button.forceActiveFocus() - button.clicked() - } - } - - Keys.onSpacePressed: internal.userPressed = true - Keys.onReturnPressed: internal.userPressed = true - Keys.onReleased: { - internal.userPressed = false - if (event.key == Qt.Key_Space || - event.key == Qt.Key_Return) - internal.clickButton(); - } - - Private.ButtonShadow { - id: shadow - anchors.fill: parent - state: { - if (internal.userPressed || checked) { - return "hidden" - } else if (mouse.containsMouse) { - return "hover" - } else if (button.activeFocus) { - return "focus" - } else { - return "shadow" - } - } - } - - // The normal button state - PlasmaCore.FrameSvgItem { - id: surfaceNormal - - anchors.fill: parent - imagePath: "widgets/button" - prefix: "normal" - } - - // The pressed state - PlasmaCore.FrameSvgItem { - id: surfacePressed - - anchors.fill: parent - imagePath: "widgets/button" - prefix: "pressed" - opacity: 0 - } - - Row { - id: buttonContent - state: (internal.userPressed || checked) ? "pressed" : "normal" - spacing: icon.valid ? surfaceNormal.margins.left : 0 - - states: [ - State { name: "normal" }, - State { name: "pressed" - PropertyChanges { - target: surfaceNormal - opacity: 0 - } - PropertyChanges { - target: surfacePressed - opacity: 1 - } - } - ] - transitions: [ - Transition { - to: "normal" - // Cross fade from pressed to normal - ParallelAnimation { - NumberAnimation { target: surfaceNormal; property: "opacity"; to: 1; duration: units.shortDuration * 2 } - NumberAnimation { target: surfacePressed; property: "opacity"; to: 0; duration: units.shortDuration * 2 } - } - } - ] - - anchors { - fill: parent - leftMargin: surfaceNormal.margins.left - topMargin: surfaceNormal.margins.top - rightMargin: surfaceNormal.margins.right - bottomMargin: surfaceNormal.margins.bottom - } - - PlasmaCore.IconItem { - id: icon - anchors.verticalCenter: parent.verticalCenter - width: valid? parent.height: 0 - height: width - active: shadow.hasOverState && mouse.containsMouse - colorGroup: PlasmaCore.Theme.ButtonColorGroup - } - - Label { - id: label - width: parent.width - icon.width - parent.spacing - height: parent.height - color: theme.buttonTextColor - horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - } - } - - MouseArea { - id: mouse - - anchors.fill: parent - hoverEnabled: true - onPressed: internal.userPressed = true - onReleased: internal.userPressed = false - onCanceled: { - internal.userPressed = false - Tooltip.hideText() - } - onClicked: internal.clickButton() - onExited: Tooltip.hideText() - - Timer { - interval: 1000 - running: mouse.containsMouse && !pressed && tooltip.length - onTriggered: Tooltip.showText(mouse, Qt.point(mouse.mouseX, mouse.mouseY), tooltip) - } - } - - Accessible.role: Accessible.Button - Accessible.name: text - Accessible.description: tooltip - Accessible.checkable: checkable - Accessible.checked: checked - function accessiblePressAction() { - internal.clickButton() - } + style: Styles.ButtonStyle {} } diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml new file mode 100644 index 000000000..934b000a0 --- /dev/null +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -0,0 +1,147 @@ +/* + * Copyright 2014 by Marco Martin + * Copyright 2014 by David Edmundson + * + * 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. + */ + +import QtQuick 2.0 +import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +import "../private" as Private + +QtQuickControlStyle.ButtonStyle { + id: style + + label: Row { + id: buttonContent + spacing: icon.valid ? units.smallSpacing : 0 + + PlasmaCore.IconItem { + id: icon + source: control.iconSource + anchors.verticalCenter: parent.verticalCenter + width: valid ? parent.height: 0 + visible: valid + height: width + active: shadow.hasOverState && mouse.containsMouse + colorGroup: PlasmaCore.Theme.ButtonColorGroup + } + + PlasmaComponents.Label { + id: label + text: control.text + font: control.font + width: parent.width - icon.width - parent.spacing + height: parent.height + color: theme.buttonTextColor + horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + background: Item { + + + implicitHeight: Math.floor(Math.max(theme.mSize(theme.defaultFont).height*1.6, control.minimumHeight)) + + implicitWidth: { + if (control.text.length == 0) { + height; + } else { + Math.max(theme.mSize(theme.defaultFont).width*12, control.minimumWidth); + } + } + + Private.ButtonShadow { + anchors.fill: parent + state: { + if (control.pressed) { + return "hidden" + } else if (control.hovered) { + return "hover" + } else if (control.activeFocus) { + return "focus" + } else { + return "shadow" + } + } + } + + + //This code is duplicated here and Button and ToolButton + //maybe we can make an AbstractButton class? + PlasmaCore.FrameSvgItem { + id: surfaceNormal + anchors.fill: parent + imagePath: "widgets/button" + prefix: "normal" + } + + PlasmaCore.FrameSvgItem { + id: surfacePressed + anchors.fill: parent + imagePath: "widgets/button" + prefix: "pressed" + opacity: 0 + } + + state: control.pressed ? "pressed" : "normal" + + states: [ + State { name: "normal" }, + State { name: "pressed" + PropertyChanges { + target: surfaceNormal + opacity: 0 + } + PropertyChanges { + target: surfacePressed + opacity: 1 + } + } + ] + + transitions: [ + Transition { + to: "normal" + //Cross fade from pressed to normal + ParallelAnimation { + NumberAnimation { target: surfaceNormal; property: "opacity"; to: 1; duration: 100 } + NumberAnimation { target: surfacePressed; property: "opacity"; to: 0; duration: 100 } + } + } + ] + + //TODO: create on demand? + PlasmaCore.SvgItem { + visible: control.menu !== null + width: drowDownButtonWidth + height: drowDownButtonWidth + anchors { + right: parent.right + rightMargin: surfaceNormal.margins.right + verticalCenter: parent.verticalCenter + } + svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } + elementId: "down-arrow" + } + } +} From 9365123152c2ff447c03aa8e27fe0bcb7b609543 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 17:11:19 +0200 Subject: [PATCH 02/12] fix minimumWidth/height don't try to access undefined properties make the style and the control as independent as possible --- .../plasmacomponents/qml/Button.qml | 4 +-- .../qml/styles/ButtonStyle.qml | 29 ++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/Button.qml b/src/declarativeimports/plasmacomponents/qml/Button.qml index 5a15b65f0..cc430d292 100644 --- a/src/declarativeimports/plasmacomponents/qml/Button.qml +++ b/src/declarativeimports/plasmacomponents/qml/Button.qml @@ -56,12 +56,12 @@ QtControls.Button { /** * Smallest width this button can be to show all the contents */ - property real minimumWidth: icon.width + style.label.implicitWidth + surfaceNormal.margins.left + surfaceNormal.margins.right + ((icon.valid) ? surfaceNormal.margins.left : 0) + property real minimumWidth: 0//__style.minimumWidth /** * Smallest height this button can be to show all the contents */ - property real minimumHeight: Math.max(units.iconSizes.small, style.label.implicitHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom + property real minimumHeight: 0//__style.minimumHeight style: Styles.ButtonStyle {} } diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 934b000a0..d6bf144aa 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -33,6 +33,20 @@ QtQuickControlStyle.ButtonStyle { id: buttonContent spacing: icon.valid ? units.smallSpacing : 0 + property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) + onMinimumWidthChanged: { + if (control.minimumWidth !== undefined) { + control.minimumWidth = minimumWidth; + } + } + + property real minimumHeight: Math.max(units.iconSizes.small, label.implicitHeight) + style.padding.top + style.padding.bottom + onMinimumHeightChanged: { + if (control.minimumHeight !== undefined) { + control.minimumHeight = minimumHeight + } + } + PlasmaCore.IconItem { id: icon source: control.iconSource @@ -40,7 +54,7 @@ QtQuickControlStyle.ButtonStyle { width: valid ? parent.height: 0 visible: valid height: width - active: shadow.hasOverState && mouse.containsMouse + active: control.hovered colorGroup: PlasmaCore.Theme.ButtonColorGroup } @@ -54,12 +68,13 @@ QtQuickControlStyle.ButtonStyle { horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight + onImplicitHeightChanged: style.labelImplicitHeight = implicitHeight + onImplicitWidthChanged: style.labelImplicitWidth = implicitWidth } } background: Item { - implicitHeight: Math.floor(Math.max(theme.mSize(theme.defaultFont).height*1.6, control.minimumHeight)) implicitWidth: { @@ -133,8 +148,8 @@ QtQuickControlStyle.ButtonStyle { //TODO: create on demand? PlasmaCore.SvgItem { visible: control.menu !== null - width: drowDownButtonWidth - height: drowDownButtonWidth + width: units.iconSizes.small + height: width anchors { right: parent.right rightMargin: surfaceNormal.margins.right @@ -143,5 +158,11 @@ QtQuickControlStyle.ButtonStyle { svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } elementId: "down-arrow" } + Component.onCompleted: { + padding.top = surfaceNormal.margins.top + padding.left = surfaceNormal.margins.left + padding.right = surfaceNormal.margins.right + padding.bottom = surfaceNormal.margins.bottom + } } } From a39c8898b32eb4a628d6312e917d14e1bf843c2a Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 17:38:13 +0200 Subject: [PATCH 03/12] don't redefine iconSource --- src/declarativeimports/plasmacomponents/qml/Button.qml | 2 -- .../plasmacomponents/qml/styles/ButtonStyle.qml | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/Button.qml b/src/declarativeimports/plasmacomponents/qml/Button.qml index cc430d292..607778cd0 100644 --- a/src/declarativeimports/plasmacomponents/qml/Button.qml +++ b/src/declarativeimports/plasmacomponents/qml/Button.qml @@ -51,8 +51,6 @@ QtControls.Button { */ property font font: theme.defaultFont - property string iconSource: "" - /** * Smallest width this button can be to show all the contents */ diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index d6bf144aa..419598a3d 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -49,7 +49,13 @@ QtQuickControlStyle.ButtonStyle { PlasmaCore.IconItem { id: icon - source: control.iconSource + //control.iconSource is an url: you pass a freedesktop icon, + //and it inteprets it as an url in the local qml file filesystem path + //in order to work also with upstream controls, grossly parse the url + source: { + var url = String(control.iconSource); + return url.substring(url.lastIndexOf("/") + 1); + } anchors.verticalCenter: parent.verticalCenter width: valid ? parent.height: 0 visible: valid From 9b06cbc39234e7e4f08ef6b701a7779944f2a5c4 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 17:47:19 +0200 Subject: [PATCH 04/12] style doesn't depend from control properties --- .../plasmacomponents/qml/Button.qml | 10 +++++++--- .../plasmacomponents/qml/styles/ButtonStyle.qml | 11 ++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/Button.qml b/src/declarativeimports/plasmacomponents/qml/Button.qml index 607778cd0..0a55a518e 100644 --- a/src/declarativeimports/plasmacomponents/qml/Button.qml +++ b/src/declarativeimports/plasmacomponents/qml/Button.qml @@ -52,14 +52,18 @@ QtControls.Button { property font font: theme.defaultFont /** - * Smallest width this button can be to show all the contents + * Smallest width this button can be to show all the contents. + * Compatibility with old Button control. + * The plasma style will update this property */ - property real minimumWidth: 0//__style.minimumWidth + property real minimumWidth: 0 /** * Smallest height this button can be to show all the contents + * Compatibility with old Button control. + * The plasma style will update this property */ - property real minimumHeight: 0//__style.minimumHeight + property real minimumHeight: 0 style: Styles.ButtonStyle {} } diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 419598a3d..0175bb3d3 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -29,6 +29,9 @@ import "../private" as Private QtQuickControlStyle.ButtonStyle { id: style + property int minimumWidth + property int minimumHeight + label: Row { id: buttonContent spacing: icon.valid ? units.smallSpacing : 0 @@ -36,6 +39,7 @@ QtQuickControlStyle.ButtonStyle { property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) onMinimumWidthChanged: { if (control.minimumWidth !== undefined) { + style.minimumWidth = minimumWidth; control.minimumWidth = minimumWidth; } } @@ -43,7 +47,8 @@ QtQuickControlStyle.ButtonStyle { property real minimumHeight: Math.max(units.iconSizes.small, label.implicitHeight) + style.padding.top + style.padding.bottom onMinimumHeightChanged: { if (control.minimumHeight !== undefined) { - control.minimumHeight = minimumHeight + style.minimumHeight = minimumHeight; + control.minimumHeight = minimumHeight; } } @@ -81,13 +86,13 @@ QtQuickControlStyle.ButtonStyle { background: Item { - implicitHeight: Math.floor(Math.max(theme.mSize(theme.defaultFont).height*1.6, control.minimumHeight)) + implicitHeight: Math.floor(Math.max(theme.mSize(theme.defaultFont).height*1.6, style.minimumHeight)) implicitWidth: { if (control.text.length == 0) { height; } else { - Math.max(theme.mSize(theme.defaultFont).width*12, control.minimumWidth); + Math.max(theme.mSize(theme.defaultFont).width*12, style.minimumWidth); } } From 2e06bb3214c847d75b7e7c4b1b7e2302dd42e987 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 18:29:48 +0200 Subject: [PATCH 05/12] create arrow on demand, layout it correctly --- .../widgetgallery/contents/ui/Buttons.qml | 6 +++ .../qml/styles/ButtonStyle.qml | 38 +++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/examples/applets/widgetgallery/contents/ui/Buttons.qml b/examples/applets/widgetgallery/contents/ui/Buttons.qml index 9134df9cc..9bae08503 100644 --- a/examples/applets/widgetgallery/contents/ui/Buttons.qml +++ b/examples/applets/widgetgallery/contents/ui/Buttons.qml @@ -18,6 +18,7 @@ */ import QtQuick 2.0 +import QtQuick.Controls 1.2 as QtControls import org.kde.plasma.components 2.0 as PlasmaComponents PlasmaComponents.Page { @@ -105,6 +106,11 @@ PlasmaComponents.Page { iconSource: "konqueror" Keys.onTabPressed: bt5.forceActiveFocus(); + menu: QtControls.Menu { + QtControls.MenuItem { text: "This Button" } + QtControls.MenuItem { text: "Happens To Have" } + QtControls.MenuItem { text: "A Menu Assigned" } + } } PlasmaComponents.Button { diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 0175bb3d3..c0fd750ef 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -22,6 +22,7 @@ import QtQuick 2.0 import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle 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 "../private" as Private @@ -34,9 +35,9 @@ QtQuickControlStyle.ButtonStyle { label: Row { id: buttonContent - spacing: icon.valid ? units.smallSpacing : 0 + spacing: units.smallSpacing - property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) + property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) + (arrow.visible ? arrow.width : 0) onMinimumWidthChanged: { if (control.minimumWidth !== undefined) { style.minimumWidth = minimumWidth; @@ -73,7 +74,7 @@ QtQuickControlStyle.ButtonStyle { id: label text: control.text font: control.font - width: parent.width - icon.width - parent.spacing + width: parent.width - icon.width - parent.spacing - (arrow.visible ? arrow.width + parent.spacing : 0) height: parent.height color: theme.buttonTextColor horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter @@ -82,6 +83,24 @@ QtQuickControlStyle.ButtonStyle { onImplicitHeightChanged: style.labelImplicitHeight = implicitHeight onImplicitWidthChanged: style.labelImplicitWidth = implicitWidth } + + PlasmaExtras.ConditionalLoader { + id: arrow + when: control.menu !== null + visible: when + width: units.iconSizes.small + height: width + anchors.verticalCenter: parent.verticalCenter + + source: Component { + PlasmaCore.SvgItem { + visible: control.menu !== null + anchors.fill: parent + svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } + elementId: "down-arrow" + } + } + } } background: Item { @@ -156,19 +175,6 @@ QtQuickControlStyle.ButtonStyle { } ] - //TODO: create on demand? - PlasmaCore.SvgItem { - visible: control.menu !== null - width: units.iconSizes.small - height: width - anchors { - right: parent.right - rightMargin: surfaceNormal.margins.right - verticalCenter: parent.verticalCenter - } - svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } - elementId: "down-arrow" - } Component.onCompleted: { padding.top = surfaceNormal.margins.top padding.left = surfaceNormal.margins.left From 9301163142a15035522b867432df4caacdbdeee5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 18:30:55 +0200 Subject: [PATCH 06/12] support checked buttons --- .../plasmacomponents/qml/styles/ButtonStyle.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index c0fd750ef..bc3f39ea0 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -148,7 +148,7 @@ QtQuickControlStyle.ButtonStyle { opacity: 0 } - state: control.pressed ? "pressed" : "normal" + state: control.pressed || control.checked ? "pressed" : "normal" states: [ State { name: "normal" }, From b538a1dca92ea1f20e09e9fff1359d3f12d52108 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 19:19:26 +0200 Subject: [PATCH 07/12] override iconSource for compatibility --- src/declarativeimports/plasmacomponents/qml/Button.qml | 6 ++++++ .../plasmacomponents/qml/styles/ButtonStyle.qml | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/Button.qml b/src/declarativeimports/plasmacomponents/qml/Button.qml index 0a55a518e..b5ef4c4fc 100644 --- a/src/declarativeimports/plasmacomponents/qml/Button.qml +++ b/src/declarativeimports/plasmacomponents/qml/Button.qml @@ -42,6 +42,7 @@ import "styles" as Styles * @see http://qt-project.org/doc/qt-5/qml-qtquick-controls-button.html */ QtControls.Button { + id: root /** * type:font * @@ -51,6 +52,11 @@ QtControls.Button { */ property font font: theme.defaultFont + /* + * overrides iconsource for compatibility + */ + property alias iconSource: root.iconName + /** * Smallest width this button can be to show all the contents. * Compatibility with old Button control. diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index bc3f39ea0..832c74d8e 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -58,10 +58,7 @@ QtQuickControlStyle.ButtonStyle { //control.iconSource is an url: you pass a freedesktop icon, //and it inteprets it as an url in the local qml file filesystem path //in order to work also with upstream controls, grossly parse the url - source: { - var url = String(control.iconSource); - return url.substring(url.lastIndexOf("/") + 1); - } + source: control.iconName || control.iconSource anchors.verticalCenter: parent.verticalCenter width: valid ? parent.height: 0 visible: valid From 0c2138916e90a8a3561d58341f7a9f3f95651b12 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 20:11:31 +0200 Subject: [PATCH 08/12] use RowLayout --- .../qml/styles/ButtonStyle.qml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 832c74d8e..9a04ab0db 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -20,6 +20,7 @@ import QtQuick 2.0 import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle +import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras @@ -33,9 +34,10 @@ QtQuickControlStyle.ButtonStyle { property int minimumWidth property int minimumHeight - label: Row { + label: RowLayout { id: buttonContent spacing: units.smallSpacing + Layout.preferredHeight: Math.max(units.iconSizes.small, label.implicitHeight) property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) + (arrow.visible ? arrow.width : 0) onMinimumWidthChanged: { @@ -60,9 +62,11 @@ QtQuickControlStyle.ButtonStyle { //in order to work also with upstream controls, grossly parse the url source: control.iconName || control.iconSource anchors.verticalCenter: parent.verticalCenter - width: valid ? parent.height: 0 + Layout.minimumWidth: valid ? parent.height: 0 + Layout.maximumWidth: Layout.minimumWidth visible: valid - height: width + Layout.minimumHeight: Layout.minimumWidth + Layout.maximumHeight: Layout.minimumWidth active: control.hovered colorGroup: PlasmaCore.Theme.ButtonColorGroup } @@ -71,21 +75,21 @@ QtQuickControlStyle.ButtonStyle { id: label text: control.text font: control.font - width: parent.width - icon.width - parent.spacing - (arrow.visible ? arrow.width + parent.spacing : 0) + visible: control.text != "" + Layout.fillWidth: true height: parent.height color: theme.buttonTextColor horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight - onImplicitHeightChanged: style.labelImplicitHeight = implicitHeight - onImplicitWidthChanged: style.labelImplicitWidth = implicitWidth } PlasmaExtras.ConditionalLoader { id: arrow when: control.menu !== null visible: when - width: units.iconSizes.small + Layout.minimumWidth: units.iconSizes.small + Layout.maximumWidth: Layout.minimumWidth height: width anchors.verticalCenter: parent.verticalCenter From 7538c3292c8180a31882bcda672e4d207599810d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 24 Jul 2014 20:16:46 +0200 Subject: [PATCH 09/12] don't compute two times the same thing --- .../plasmacomponents/qml/styles/ButtonStyle.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 9a04ab0db..6e75f1841 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -47,7 +47,7 @@ QtQuickControlStyle.ButtonStyle { } } - property real minimumHeight: Math.max(units.iconSizes.small, label.implicitHeight) + style.padding.top + style.padding.bottom + property real minimumHeight: Layout.preferredHeight + style.padding.top + style.padding.bottom onMinimumHeightChanged: { if (control.minimumHeight !== undefined) { style.minimumHeight = minimumHeight; From d29b3f051df85036ea4852dd9fc0e913fb73535f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 25 Jul 2014 11:20:26 +0200 Subject: [PATCH 10/12] don't mix anchors and layouts --- src/declarativeimports/core/iconitem.cpp | 1 + .../plasmacomponents/qml/styles/ButtonStyle.qml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarativeimports/core/iconitem.cpp b/src/declarativeimports/core/iconitem.cpp index 2695728e6..744021406 100644 --- a/src/declarativeimports/core/iconitem.cpp +++ b/src/declarativeimports/core/iconitem.cpp @@ -94,6 +94,7 @@ void IconItem::setSource(const QVariant &source) if (source.toString().isEmpty()) { delete m_svgIcon; m_svgIcon = 0; + m_loadPixmapTimer.start(); emit validChanged(); return; } diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 6e75f1841..c994f87cf 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -90,8 +90,8 @@ QtQuickControlStyle.ButtonStyle { visible: when Layout.minimumWidth: units.iconSizes.small Layout.maximumWidth: Layout.minimumWidth + Layout.alignment: Qt.AlignVCenter height: width - anchors.verticalCenter: parent.verticalCenter source: Component { PlasmaCore.SvgItem { From dbbb8056f5c686345f6a9fbe2bf543744aab2135 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 25 Jul 2014 11:26:41 +0200 Subject: [PATCH 11/12] use the minimumWidth gave by the Layout --- .../plasmacomponents/qml/styles/ButtonStyle.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index c994f87cf..31171d567 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -39,7 +39,7 @@ QtQuickControlStyle.ButtonStyle { spacing: units.smallSpacing Layout.preferredHeight: Math.max(units.iconSizes.small, label.implicitHeight) - property real minimumWidth: icon.width + label.implicitWidth + style.padding.left + style.padding.right + ((icon.valid) ? style.padding.left : 0) + (arrow.visible ? arrow.width : 0) + property real minimumWidth: Layout.minimumWidth + style.padding.left + style.padding.right onMinimumWidthChanged: { if (control.minimumWidth !== undefined) { style.minimumWidth = minimumWidth; @@ -73,6 +73,7 @@ QtQuickControlStyle.ButtonStyle { PlasmaComponents.Label { id: label + Layout.minimumWidth: Math.min(implicitWidth, theme.mSize(theme.defaultFont).width * 10) text: control.text font: control.font visible: control.text != "" From 05f4a44059e7082a67c680e4f2e3c62f04e4d175 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 25 Jul 2014 12:54:27 +0200 Subject: [PATCH 12/12] use implicitWidth as label minimum width --- .../plasmacomponents/qml/styles/ButtonStyle.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml index 31171d567..d92a6621e 100644 --- a/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml +++ b/src/declarativeimports/plasmacomponents/qml/styles/ButtonStyle.qml @@ -57,9 +57,6 @@ QtQuickControlStyle.ButtonStyle { PlasmaCore.IconItem { id: icon - //control.iconSource is an url: you pass a freedesktop icon, - //and it inteprets it as an url in the local qml file filesystem path - //in order to work also with upstream controls, grossly parse the url source: control.iconName || control.iconSource anchors.verticalCenter: parent.verticalCenter Layout.minimumWidth: valid ? parent.height: 0 @@ -73,7 +70,7 @@ QtQuickControlStyle.ButtonStyle { PlasmaComponents.Label { id: label - Layout.minimumWidth: Math.min(implicitWidth, theme.mSize(theme.defaultFont).width * 10) + Layout.minimumWidth: implicitWidth text: control.text font: control.font visible: control.text != ""