Merge branch 'mart/QtControlsButton'
REVIEW:119455
This commit is contained in:
commit
a059748fbc
@ -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 {
|
||||
|
@ -91,6 +91,14 @@ void IconItem::setSource(const QVariant &source)
|
||||
m_svgIcon = 0;
|
||||
|
||||
} else if (source.canConvert<QString>()) {
|
||||
if (source.toString().isEmpty()) {
|
||||
delete m_svgIcon;
|
||||
m_svgIcon = 0;
|
||||
m_loadPixmapTimer.start();
|
||||
emit validChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_svgIcon) {
|
||||
m_svgIcon = new Plasma::Svg(this);
|
||||
m_svgIcon->setColorGroup(m_colorGroup);
|
||||
|
@ -29,63 +29,20 @@
|
||||
* 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 {
|
||||
id: root
|
||||
/**
|
||||
* type:font
|
||||
*
|
||||
@ -93,198 +50,26 @@ Item {
|
||||
*
|
||||
* See also Qt documentation for font type.
|
||||
*/
|
||||
property alias font: label.font
|
||||
property font font: theme.defaultFont
|
||||
|
||||
//icon + label + left margin + right margin + spacing between icon and text
|
||||
/**
|
||||
* Smallest width this button can be to show all the contents
|
||||
/*
|
||||
* overrides iconsource for compatibility
|
||||
*/
|
||||
property real minimumWidth: icon.width + label.implicitWidth + surfaceNormal.margins.left + surfaceNormal.margins.right + ((icon.valid) ? surfaceNormal.margins.left : 0)
|
||||
property alias iconSource: root.iconName
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
/**
|
||||
* 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: Math.max(units.iconSizes.small, label.implicitHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom
|
||||
property real minimumHeight: 0
|
||||
|
||||
/**
|
||||
* 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 {}
|
||||
}
|
||||
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2014 by Marco Martin <mart@kde.org>
|
||||
* Copyright 2014 by David Edmundson <davidedmundson@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.
|
||||
*/
|
||||
|
||||
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
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
|
||||
import "../private" as Private
|
||||
|
||||
QtQuickControlStyle.ButtonStyle {
|
||||
id: style
|
||||
|
||||
property int minimumWidth
|
||||
property int minimumHeight
|
||||
|
||||
label: RowLayout {
|
||||
id: buttonContent
|
||||
spacing: units.smallSpacing
|
||||
Layout.preferredHeight: Math.max(units.iconSizes.small, label.implicitHeight)
|
||||
|
||||
property real minimumWidth: Layout.minimumWidth + style.padding.left + style.padding.right
|
||||
onMinimumWidthChanged: {
|
||||
if (control.minimumWidth !== undefined) {
|
||||
style.minimumWidth = minimumWidth;
|
||||
control.minimumWidth = minimumWidth;
|
||||
}
|
||||
}
|
||||
|
||||
property real minimumHeight: Layout.preferredHeight + style.padding.top + style.padding.bottom
|
||||
onMinimumHeightChanged: {
|
||||
if (control.minimumHeight !== undefined) {
|
||||
style.minimumHeight = minimumHeight;
|
||||
control.minimumHeight = minimumHeight;
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
source: control.iconName || control.iconSource
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.minimumWidth: valid ? parent.height: 0
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
visible: valid
|
||||
Layout.minimumHeight: Layout.minimumWidth
|
||||
Layout.maximumHeight: Layout.minimumWidth
|
||||
active: control.hovered
|
||||
colorGroup: PlasmaCore.Theme.ButtonColorGroup
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: label
|
||||
Layout.minimumWidth: implicitWidth
|
||||
text: control.text
|
||||
font: control.font
|
||||
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
|
||||
}
|
||||
|
||||
PlasmaExtras.ConditionalLoader {
|
||||
id: arrow
|
||||
when: control.menu !== null
|
||||
visible: when
|
||||
Layout.minimumWidth: units.iconSizes.small
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
height: width
|
||||
|
||||
source: Component {
|
||||
PlasmaCore.SvgItem {
|
||||
visible: control.menu !== null
|
||||
anchors.fill: parent
|
||||
svg: PlasmaCore.Svg { imagePath: "widgets/arrows" }
|
||||
elementId: "down-arrow"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Item {
|
||||
|
||||
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, style.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 || control.checked ? "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 }
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Component.onCompleted: {
|
||||
padding.top = surfaceNormal.margins.top
|
||||
padding.left = surfaceNormal.margins.left
|
||||
padding.right = surfaceNormal.margins.right
|
||||
padding.bottom = surfaceNormal.margins.bottom
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user