Changeset View
Changeset View
Standalone View
Standalone View
src/controls/ActionToolBar.qml
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | 34 | Item { | |||
---|---|---|---|---|---|
61 | * permitted values are: | 61 | * permitted values are: | ||
62 | * * Button.IconOnly | 62 | * * Button.IconOnly | ||
63 | * * Button.TextOnly | 63 | * * Button.TextOnly | ||
64 | * * Button.TextBesideIcon | 64 | * * Button.TextBesideIcon | ||
65 | * * Button.TextUnderIcon | 65 | * * Button.TextUnderIcon | ||
66 | */ | 66 | */ | ||
67 | property int display: Controls.Button.TextBesideIcon | 67 | property int display: Controls.Button.TextBesideIcon | ||
68 | 68 | | |||
69 | property int alignment: Qt.AlignLeft | ||||
70 | | ||||
69 | /** | 71 | /** | ||
70 | * position enum | 72 | * position enum | ||
71 | * This property holds the position of the toolbar. | 73 | * This property holds the position of the toolbar. | ||
72 | * if this ActionToolBar is the contentItem of a QQC2 Toolbar, the position is binded to the ToolBar's position | 74 | * if this ActionToolBar is the contentItem of a QQC2 Toolbar, the position is binded to the ToolBar's position | ||
73 | * | 75 | * | ||
74 | * permitted values are: | 76 | * permitted values are: | ||
75 | * *ToolBar.Header: The toolbar is at the top, as a window or page header. | 77 | * *ToolBar.Header: The toolbar is at the top, as a window or page header. | ||
76 | * *ToolBar.Footer: The toolbar is at the bottom, as a window or page footer. | 78 | * *ToolBar.Footer: The toolbar is at the bottom, as a window or page footer. | ||
77 | */ | 79 | */ | ||
78 | property int position: parent && parent.hasOwnProperty("position") | 80 | property int position: parent && parent.hasOwnProperty("position") | ||
79 | ? parent.position | 81 | ? parent.position | ||
80 | : Controls.ToolBar.Header | 82 | : Controls.ToolBar.Header | ||
81 | 83 | | |||
82 | implicitHeight: actionsLayout.implicitHeight | 84 | implicitHeight: actionsLayout.implicitHeight | ||
83 | 85 | | |||
84 | implicitWidth: actionsLayout.implicitWidth | 86 | implicitWidth: actionsLayout.implicitWidth | ||
85 | 87 | | |||
86 | Layout.minimumWidth: moreButton.implicitWidth | 88 | Layout.minimumWidth: moreButton.implicitWidth | ||
89 | Layout.maximumWidth: placeholderLayout.implicitWidth + moreButton.width | ||||
87 | 90 | | |||
88 | RowLayout { | 91 | RowLayout { | ||
89 | id: actionsLayout | 92 | id: actionsLayout | ||
90 | anchors.fill: parent | 93 | anchors.fill: parent | ||
91 | //anchors.rightMargin: moreButton.width | 94 | spacing: 0 | ||
92 | | ||||
93 | spacing: Kirigami.Units.smallSpacing | | |||
94 | property var overflowSet: [] | | |||
95 | | ||||
96 | // TODO use Array.findIndex once we depend on Qt 5.9 | | |||
97 | function findIndex(array, cb) { | | |||
98 | for (var i = 0, length = array.length; i < length; ++i) { | | |||
99 | if (cb(array[i])) { | | |||
100 | return i; | | |||
101 | } | | |||
102 | } | | |||
103 | return -1; | | |||
104 | } | | |||
105 | 95 | | |||
106 | function isActionVisible(action) { | 96 | Item { | ||
107 | var index = actionsLayout.findIndex(actionsLayout.overflowSet, function(act){return act === action}); | 97 | Layout.fillWidth: root.alignment == Qt.AlignRight || root.alignment == Qt.AlignHCenter || root.alignment == Qt.AlignCenter; | ||
108 | if (index === -1) { | 98 | Layout.fillHeight: true | ||
109 | index = actionsLayout.findIndex(root.hiddenActions, function(act){return act === action}); | | |||
110 | if (index === -1) { | | |||
111 | return true | | |||
112 | } | | |||
113 | } | | |||
114 | return false | | |||
115 | } | 99 | } | ||
116 | 100 | | |||
117 | RowLayout { | | |||
118 | Layout.minimumWidth: 0 | | |||
119 | Layout.fillHeight: true | | |||
120 | Repeater { | 101 | Repeater { | ||
121 | model: root.actions | 102 | model: placeholderLayout.visibleActions | ||
103 | | ||||
122 | delegate: PrivateActionToolButton { | 104 | delegate: PrivateActionToolButton { | ||
123 | id: actionDelegate | 105 | id: actionDelegate | ||
124 | flat: root.flat | | |||
125 | opacity: x + width <= parent.width | | |||
126 | enabled: opacity > 0 && modelData.enabled | | |||
127 | 106 | | |||
128 | display: root.display | | |||
129 | visible: !modelData.hasOwnProperty("visible") || modelData.visible | | |||
130 | Layout.fillWidth: false | | |||
131 | Layout.alignment: Qt.AlignVCenter | 107 | Layout.alignment: Qt.AlignVCenter | ||
132 | Layout.minimumWidth: implicitWidth | 108 | Layout.minimumWidth: implicitWidth | ||
109 | // Use rightMargin instead of spacing on the layout to prevent spacer items | ||||
110 | // from creating useless spacing | ||||
111 | Layout.rightMargin: Kirigami.Units.smallSpacing | ||||
112 | | ||||
113 | flat: root.flat && !modelData.icon.color.a | ||||
114 | display: root.display | ||||
133 | kirigamiAction: modelData | 115 | kirigamiAction: modelData | ||
134 | onOpacityChanged: updateOverflowSet() | | |||
135 | function updateOverflowSet() { | | |||
136 | var index = actionsLayout.findIndex(actionsLayout.overflowSet, function(act) { | | |||
137 | return act === modelData}); | | |||
138 | | ||||
139 | if ((opacity > 0 || (modelData.hasOwnProperty("visible") || !modelData.visible)) && index > -1) { | | |||
140 | actionsLayout.overflowSet.splice(index, 1); | | |||
141 | } else if (opacity === 0 && (!modelData.hasOwnProperty("visible") || modelData.visible) && index === -1) { | | |||
142 | actionsLayout.overflowSet.push(modelData); | | |||
143 | } | | |||
144 | actionsLayout.overflowSetChanged(); | | |||
145 | } | | |||
146 | Connections { | | |||
147 | target: modelData | | |||
148 | ignoreUnknownSignals: !modelData.hasOwnProperty("visible") | | |||
149 | onVisibleChanged: actionDelegate.updateOverflowSet(); | | |||
150 | } | | |||
151 | Component.onCompleted: { | | |||
152 | actionDelegate.updateOverflowSet(); | | |||
153 | } | | |||
154 | } | | |||
155 | } | 116 | } | ||
156 | } | 117 | } | ||
157 | 118 | | |||
158 | Item { | 119 | Item { | ||
159 | Layout.fillWidth: true | 120 | Layout.fillWidth: root.alignment == Qt.AlignLeft || root.alignment == Qt.AlignHCenter || root.alignment == Qt.AlignCenter; | ||
160 | visible: root.Layout.fillWidth | 121 | Layout.fillHeight: true | ||
161 | } | 122 | } | ||
162 | 123 | | |||
163 | PrivateActionToolButton { | 124 | PrivateActionToolButton { | ||
164 | id: moreButton | 125 | id: moreButton | ||
165 | 126 | | |||
166 | Layout.alignment: Qt.AlignRight | 127 | Layout.alignment: Qt.AlignRight | ||
167 | 128 | | |||
168 | visible: hiddenActions.length > 0 || actionsLayout.overflowSet.length > 0 | 129 | visible: hiddenActions.length > 0 || placeholderLayout.hiddenActions.length > 0 | ||
169 | showMenuArrow: false | 130 | showMenuArrow: false | ||
170 | 131 | | |||
171 | kirigamiAction: Kirigami.Action { | 132 | kirigamiAction: Kirigami.Action { | ||
172 | icon.name: "overflow-menu" | 133 | icon.name: "overflow-menu" | ||
173 | children: Array.prototype.map.call(root.actions, function (i) { return i }).concat(Array.prototype.map.call(hiddenActions, function (i) { return i })) | 134 | children: Array.prototype.map.call(root.actions, function (i) { return i }).concat(Array.prototype.map.call(hiddenActions, function (i) { return i })) | ||
174 | } | 135 | } | ||
175 | 136 | | |||
176 | menu.submenuComponent: ActionsMenu { | 137 | menu.submenuComponent: ActionsMenu { | ||
177 | Binding { | 138 | Binding { | ||
178 | target: parentItem | 139 | target: parentItem | ||
179 | property: "visible" | 140 | property: "visible" | ||
180 | value: !actionsLayout.isActionVisible(parentAction) && (parentAction.visible === undefined || parentAction.visible) | 141 | value: placeholderLayout.visibleActions.indexOf(parentAction) == -1 && | ||
142 | (parentAction.visible === undefined || parentAction.visible) | ||||
181 | } | 143 | } | ||
182 | } | 144 | } | ||
183 | 145 | | |||
184 | menu.itemDelegate: ActionMenuItem { | 146 | menu.itemDelegate: ActionMenuItem { | ||
185 | visible: !actionsLayout.isActionVisible(action) && (action.visible === undefined || action.visible) | 147 | visible: placeholderLayout.visibleActions.indexOf(action) == -1 && | ||
148 | (action.visible === undefined || action.visible) | ||||
149 | } | ||||
150 | } | ||||
186 | } | 151 | } | ||
152 | | ||||
153 | RowLayout { | ||||
154 | id: placeholderLayout | ||||
155 | enabled: false | ||||
156 | opacity: 0 // Cannot use visible: false because then relayout doesn't happen correctly | ||||
157 | spacing: Kirigami.Units.smallSpacing | ||||
158 | | ||||
159 | property var visibleActions: [] | ||||
160 | property var hiddenActions: [] | ||||
161 | property real layoutWidth: root.width - moreButton.width - Kirigami.Units.smallSpacing | ||||
162 | | ||||
163 | Repeater { | ||||
164 | id: placeholderRepeater | ||||
165 | model: root.actions | ||||
166 | | ||||
167 | PrivateActionToolButton { | ||||
168 | flat: root.flat && !modelData.icon.color.a | ||||
169 | display: root.display | ||||
170 | visible: modelData.visible === undefined || modelData.visible | ||||
171 | kirigamiAction: modelData | ||||
172 | | ||||
173 | property bool actionVisible: x + width < placeholderLayout.layoutWidth | ||||
187 | } | 174 | } | ||
188 | } | 175 | } | ||
176 | | ||||
177 | Component.onCompleted: Qt.callLater(updateVisibleActions) | ||||
178 | onWidthChanged: Qt.callLater(updateVisibleActions) | ||||
179 | | ||||
180 | function updateVisibleActions() { | ||||
181 | var visible = [] | ||||
182 | var hidden = [] | ||||
183 | | ||||
184 | if (root.width >= placeholderLayout.width + moreButton.width + Kirigami.Units.smallSpacing) { | ||||
185 | visibleActions = Array.prototype.map.call(root.actions, function(item) { return item }) | ||||
186 | hiddenActions = [] | ||||
187 | return | ||||
188 | } | ||||
189 | | ||||
190 | for (var i = 0; i < root.actions.length; ++i) { | ||||
191 | var item = placeholderRepeater.itemAt(i) | ||||
192 | if (item.actionVisible) { | ||||
193 | visible.push(item.kirigamiAction) | ||||
194 | } else { | ||||
195 | hidden.push(item.kirigamiAction) | ||||
196 | | ||||
197 | } | ||||
198 | } | ||||
199 | | ||||
200 | visibleActions = visible | ||||
201 | hiddenActions = hidden | ||||
202 | } | ||||
203 | } | ||||
204 | | ||||
205 | onWidthChanged: Qt.callLater(placeholderLayout.updateVisibleActions) | ||||
189 | } | 206 | } |