diff --git a/kirigami.qrc b/kirigami.qrc
--- a/kirigami.qrc
+++ b/kirigami.qrc
@@ -13,6 +13,7 @@
src/controls/CardsLayout.qml
src/controls/CardsListView.qml
src/controls/CardsGridView.qml
+ src/controls/ActionToolBar.qml
src/controls/templates/AbstractCard.qml
src/controls/InlineMessage.qml
src/controls/ToolBarApplicationHeader.qml
diff --git a/src/controls/ActionToolBar.qml b/src/controls/ActionToolBar.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/ActionToolBar.qml
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2018 Marco Martin
+ *
+ * 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 02110-1301, USA.
+ */
+
+import QtQuick 2.6
+import QtQuick.Layouts 1.2
+import QtQuick.Controls 2.0 as Controls
+import org.kde.kirigami 2.5 as Kirigami
+import "private"
+
+/**
+ * This is a simple toolbar built out of a list of actions
+ * each action is represented by a ToolButton, those that won't fit
+ * the size will go in a menu under a button with the overflow ... icon
+ *
+ * @inherits RowLayout
+ * @since 2.5
+ */
+Item {
+ id: root
+ /**
+ * actions: list
+ * if the card should provide clickable actions, put them in this property,
+ * they will be put in the footer as a list of ToolButtons plus an optional
+ * overflow menu, when not all of them will fit in the available Card width.
+ */
+ property list actions
+
+ /**
+ * flat: bool
+ * Wether we want our buttons to have a flat appearance. Default: true
+ */
+ property bool flat: true
+
+ implicitHeight: actionsLayout.implicitHeight
+
+ implicitWidth: {
+ var width = 0;
+ for (var i = 0; i < actionsLayout.children.length; ++i) {
+ if (actionsLayout.children[i].kirigamiAction && actionsLayout.children[i].kirigamiAction.visible) {
+ width += actionsLayout.children[i].implicitWidth + actionsLayout.spacing;
+ }
+ }
+ width += moreButton.width;
+ return width;
+ }
+
+ RowLayout {
+ id: actionsLayout
+ anchors.fill: parent
+ //anchors.rightMargin: moreButton.width
+
+ spacing: Kirigami.Units.smallSpacing
+ property var overflowSet: []
+
+ // TODO use Array.findIndex once we depend on Qt 5.9
+ function findIndex(array, cb) {
+ for (var i = 0, length = array.length; i < length; ++i) {
+ if (cb(array[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ Repeater {
+ model: root.actions
+ delegate: PrivateActionToolButton {
+ id: actionDelegate
+ flat: root.flat
+ readonly property bool fits: {
+ var minX = 0;
+ for (var i = 0; i < index; ++i) {
+ if (actionsLayout.children[i].visible) {
+ minX += actionsLayout.children[i].implicitWidth + actionsLayout.spacing;
+ }
+ }
+ return minX + implicitWidth < actionsLayout.width - moreButton.width
+ }
+
+ visible: modelData.visible && fits
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignVCenter
+ Layout.minimumWidth: implicitWidth
+ kirigamiAction: modelData
+ onFitsChanged: updateOverflowSet()
+ function updateOverflowSet() {
+ var index = actionsLayout.findIndex(actionsLayout.overflowSet, function(act) {
+ return act == modelData});
+
+ if ((fits || !modelData.visible) && index > -1) {
+ actionsLayout.overflowSet.splice(index, 1);
+ } else if (!fits && modelData.visible && index == -1) {
+ actionsLayout.overflowSet.push(modelData);
+ }
+ actionsLayout.overflowSetChanged();
+ }
+ Connections {
+ target: modelData
+ onVisibleChanged: actionDelegate.updateOverflowSet();
+ }
+ Component.onCompleted: {
+ actionDelegate.updateOverflowSet();
+ }
+ }
+ }
+ Controls.ToolButton {
+ id: moreButton
+
+ Layout.alignment: Qt.AlignRight
+ Kirigami.Icon {
+ anchors.fill: parent
+ source: "overflow-menu"
+ anchors.margins: 4
+ }
+
+ //checkable: true
+ checked: menu.visible
+ visible: actionsLayout.overflowSet.length > 0;
+ onClicked: menu.visible ? menu.close() : menu.open()
+
+ ActionsMenu {
+ id: menu
+ y: -height
+ x: -width + moreButton.width
+ actions: root.actions
+ submenuComponent: Component {
+ ActionsMenu {}
+ }
+ itemDelegate: ActionMenuItem {
+ visible: actionsLayout.findIndex(actionsLayout.overflowSet, function(act) {return act == ourAction}) > -1 && (ourAction.visible == undefined || ourAction.visible)
+ }
+ }
+ }
+ }
+}
diff --git a/src/controls/Card.qml b/src/controls/Card.qml
--- a/src/controls/Card.qml
+++ b/src/controls/Card.qml
@@ -20,7 +20,7 @@
import QtQuick 2.6
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.0 as Controls
-import org.kde.kirigami 2.4 as Kirigami
+import org.kde.kirigami 2.5 as Kirigami
import "private"
/**
@@ -96,98 +96,9 @@
header.anchors.bottomMargin = Qt.binding(function() {return root.headerOrientation == Qt.Horizontal ? -root.bottomPadding : 0});
}
- footer: RowLayout {
- id: actionsLayout
- spacing: Kirigami.Units.smallSpacing
- property var overflowSet: []
- visible: root.footer == actionsLayout
-
- // TODO use Array.findIndex once we depend on Qt 5.9
- function findIndex(array, cb) {
- for (var i = 0, length = array.length; i < length; ++i) {
- if (cb(array[i])) {
- return i;
- }
- }
- return -1;
- }
-
- Repeater {
- model: root.actions
- delegate: PrivateActionToolButton {
- id: actionDelegate
- readonly property bool fits: {
- var minX = 0;
- for (var i = 0; i < index; ++i) {
- if (actionsLayout.children[i].visible) {
- minX += actionsLayout.children[i].implicitWidth + actionsLayout.spacing;
- }
- }
- return minX + implicitWidth < root.width - root.leftPadding - root.rightPadding - moreButton.width;
- }
- visible: modelData.visible && fits
- Layout.fillWidth: true
- Layout.minimumWidth: implicitWidth
- kirigamiAction: modelData
- onFitsChanged: updateOverflowSet()
- function updateOverflowSet() {
- var index = actionsLayout.findIndex(actionsLayout.overflowSet, function(act){
- return act == modelData});
-
- if ((fits || !modelData.visible) && index > -1) {
- actionsLayout.overflowSet.splice(index, 1);
- } else if (!fits && modelData.visible && index == -1) {
- actionsLayout.overflowSet.push(modelData);
- }
- actionsLayout.overflowSetChanged();
- }
- Connections {
- target: modelData
- onVisibleChanged: actionDelegate.updateOverflowSet();
- }
- Component.onCompleted: {
- actionDelegate.updateOverflowSet();
- }
- }
- }
- Controls.ToolButton {
- id: moreButton
-
- Kirigami.Icon {
- anchors.fill: parent
- source: "overflow-menu"
- anchors.margins: 4
- }
- Layout.alignment: Qt.AlignRight
- //checkable: true
- checked: menu.visible
- visible: actionsLayout.overflowSet.length > 0;
- onClicked: menu.visible ? menu.close() : menu.open()
-
- Controls.Menu {
- id: menu
- y: -height
- x: -width + moreButton.width
-
- Repeater {
- model: root.actions
- delegate: BasicListItem {
- text: modelData ? modelData.text : ""
- icon: modelData.icon
- checkable: modelData.checkable
- checked: modelData.checked
- onClicked: {
- modelData.trigger();
- menu.visible = false;
- }
- separatorVisible: false
- backgroundColor: "transparent"
- visible: actionsLayout.findIndex(actionsLayout.overflowSet, function(act) {
- return act == modelData}) > -1 && modelData.visible
- enabled: modelData.enabled
- }
- }
- }
- }
+ footer: Kirigami.ActionToolBar {
+ id: actionsToolBar
+ actions: root.actions
+ visible: root.footer == actionsToolBar
}
}
diff --git a/src/controls/InlineMessage.qml b/src/controls/InlineMessage.qml
--- a/src/controls/InlineMessage.qml
+++ b/src/controls/InlineMessage.qml
@@ -23,7 +23,7 @@
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.0 as Controls
-import org.kde.kirigami 2.4 as Kirigami
+import org.kde.kirigami 2.5 as Kirigami
import "private"
import "templates" as T
@@ -246,13 +246,14 @@
}
}
- RowLayout {
+ Kirigami.ActionToolBar {
id: actionsLayout
+ flat: false
+ actions: root.actions
visible: root.actions.length
Layout.alignment: Qt.AlignRight
- Layout.fillWidth: true
Layout.row: {
if (messageTextMetrics.width + Kirigami.Units.smallSpacing >
@@ -266,125 +267,12 @@
Layout.column: Layout.row ? 0 : 2
Layout.columnSpan: Layout.row ? (closeButton.visible ? 3 : 2) : 1
- property var overflowSet: []
-
- spacing: Kirigami.Units.smallSpacing
-
- // TODO Use Array.findIndex once we depend on Qt 5.9+.
- function findIndex(array, cb) {
- for (var i = 0, length = array.length; i < length; ++i) {
- if (cb(array[i])) {
- return i;
- }
- }
- return -1;
- }
-
TextMetrics {
id: messageTextMetrics
font: text.font
text: text.text
}
-
- Repeater {
- model: root.actions
-
- //TODO: use a normal button when we can depend from Qt 5.10
- delegate: PrivateActionToolButton {
- id: actionButton
-
- flat: false
- kirigamiAction: modelData
- visible: modelData.visible && fits
-
- Layout.alignment: Qt.AlignVCenter
- Layout.minimumWidth: implicitWidth
-
- readonly property bool fits: {
- var minX = 0;
-
- for (var i = 0; i < index; ++i) {
- if (actionsLayout.children[i].visible) {
- minX += actionsLayout.children[i].implicitWidth + actionsLayout.spacing;
- }
- }
-
- return minX + implicitWidth < contentLayout.width - moreButton.width;
- }
-
- onFitsChanged: updateOverflowSet()
-
- function updateOverflowSet() {
- var index = actionsLayout.findIndex(actionsLayout.overflowSet, function(act){
- return act == modelData});
-
- if ((fits || !modelData.visible) && index > -1) {
- actionsLayout.overflowSet.splice(index, 1);
- } else if (!fits && modelData.visible && index == -1) {
- actionsLayout.overflowSet.push(modelData);
- }
-
- actionsLayout.overflowSetChanged();
- }
-
- Connections {
- target: modelData
-
- onVisibleChanged: actionButton.updateOverflowSet();
- }
-
- Component.onCompleted: updateOverflowSet();
- }
- }
-
- Controls.ToolButton {
- id: moreButton
-
- visible: actionsLayout.overflowSet.length > 0
-
- checked: menu.visible
-
- onClicked: menu.visible ? menu.close() : menu.open()
-
- Kirigami.Icon {
- anchors.fill: parent
- source: "overflow-menu"
- anchors.margins: 4
- }
-
- Controls.Menu {
- id: menu
- y: -height
- x: -width + moreButton.width
-
- Repeater {
- model: root.actions
-
- delegate: BasicListItem {
- enabled: modelData.enabled
-
- checkable: modelData.checkable
- checked: modelData.checked
-
- text: modelData ? modelData.text : ""
- icon: modelData.icon
-
- onClicked: {
- modelData.trigger();
- menu.visible = false;
- }
-
- separatorVisible: false
-
- backgroundColor: "transparent"
-
- visible: actionsLayout.findIndex(actionsLayout.overflowSet, function(act) {
- return act == modelData}) > -1 && modelData.visible
- }
- }
- }
- }
}
Controls.ToolButton {
diff --git a/src/controls/private/ActionMenuItemBase.qml b/src/controls/private/ActionMenuItemBase.qml
--- a/src/controls/private/ActionMenuItemBase.qml
+++ b/src/controls/private/ActionMenuItemBase.qml
@@ -33,6 +33,4 @@
onTriggered: {
ourAction.trigger()
}
-
- readonly property var ourMenu: theMenu.submenuComponent ? theMenu.submenuComponent.createObject(menuItem, { actions: ourAction.children }) : null
}
diff --git a/src/controls/private/ActionsMenu.qml b/src/controls/private/ActionsMenu.qml
--- a/src/controls/private/ActionsMenu.qml
+++ b/src/controls/private/ActionsMenu.qml
@@ -25,11 +25,9 @@
id: theMenu
property alias actions: actionsInstantiator.model
property Component submenuComponent
+ //renamed to work on both Qt 5.9 and 5.10
+ property Component itemDelegate: Component {ActionMenuItem {}}
- Component {
- id: menuItemComponent
- ActionMenuItem {}
- }
Instantiator {
id: actionsInstantiator
@@ -41,7 +39,7 @@
function create() {
if (!action.children || action.children.length === 0) {
- item = menuItemComponent.createObject(null, { ourAction: action });
+ item = theMenu.itemDelegate.createObject(null, { ourAction: action });
theMenu.addItem(item)
} else if (theMenu.submenuComponent) {
item = theMenu.submenuComponent.createObject(null, { title: action.text, actions: action.children });
diff --git a/src/kirigamiplugin.cpp b/src/kirigamiplugin.cpp
--- a/src/kirigamiplugin.cpp
+++ b/src/kirigamiplugin.cpp
@@ -170,6 +170,7 @@
//2.5
qmlRegisterType(componentUrl(QStringLiteral("ListItemDragHandle.qml")), uri, 2, 5, "ListItemDragHandle");
+ qmlRegisterType(componentUrl(QStringLiteral("ActionToolBar.qml")), uri, 2, 5, "ActionToolBar");
qmlProtectModule(uri, 2);
}