Warning, /maui/mauikit/src/controls.5/SelectionBar.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * Copyright 2018 Camilo Higuita <milo.h@aol.com> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU Library General Public License as 0006 * published by the Free Software Foundation; either version 2, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details 0013 * 0014 * You should have received a copy of the GNU Library General Public 0015 * License along with this program; if not, write to the 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0018 */ 0019 0020 import QtQuick 2.14 0021 import QtQuick.Controls 2.14 0022 import QtQuick.Layouts 1.3 0023 import QtQuick.Window 2.15 0024 0025 import org.mauikit.controls 1.3 as Maui 0026 0027 import QtGraphicalEffects 1.0 0028 import QtQuick.Templates 2.15 as T 0029 0030 /** 0031 * SelectionBar 0032 * 0033 * A bar to group selected items with a list of actions to perform to the selection. 0034 * The list of actions is positioned into a Kirigami ActionToolBar. 0035 * This control provides methods to append and query elements added to it. To add elements to it, it is necesary to map them, 0036 * so an item is mapped to an unique id refered here as an URI. 0037 */ 0038 Item 0039 { 0040 id: control 0041 0042 implicitHeight: _layout.implicitHeight + Maui.Style.space.big 0043 implicitWidth: _layout.implicitWidth 0044 0045 readonly property bool hidden : count === 0 0046 0047 onHiddenChanged: 0048 { 0049 if(hidden && !singleSelection) 0050 { 0051 control.close() 0052 }else 0053 { 0054 control.open() 0055 } 0056 } 0057 0058 visible: false 0059 focus: true 0060 Keys.enabled: true 0061 /** 0062 * actions : list<Action> 0063 * Default list of actions, the actions are positioned into a Kirigami ActionToolBar. 0064 */ 0065 default property list<Action> actions 0066 0067 /** 0068 * hiddenActions : list<Action> 0069 * List of action that wont be shown, and instead will always hidden and listed in the overflow menu. 0070 */ 0071 property list<Action> hiddenActions 0072 0073 0074 /** 0075 * display : int 0076 * Preferred display mode of the visible actions. As icons only, or text beside icons... etc. 0077 */ 0078 property int display : ToolButton.TextBesideIcon 0079 0080 /** 0081 * maxListHeight : int 0082 * The selectionbar can list the grouped items under a collapsable list. This property defines the maximum height the list can take. 0083 * This can be changed to avoid overlapping the list with other components. 0084 */ 0085 property int maxListHeight : 400 0086 0087 /** 0088 * radius : int 0089 * By default the selectionbar was designed to be floating and thus has a rounded border corners. 0090 * This property allows to change the border radius. 0091 */ 0092 property int radius: Maui.Style.radiusV 0093 0094 /** 0095 * singleSelection : bool 0096 * if singleSelection is set to true then only a single item can be appended, 0097 * if another item is added then it replaces the previous one. 0098 **/ 0099 property bool singleSelection: false 0100 0101 /** 0102 * uris : var 0103 * List of URIs associated to the grouped elements. 0104 */ 0105 readonly property alias uris: _private._uris 0106 0107 /** 0108 * items : var 0109 * List of items grouped. 0110 */ 0111 readonly property alias items: _private._items 0112 0113 /** 0114 * count : int 0115 * Size of the elements grouped. 0116 */ 0117 readonly property alias count : _urisModel.count 0118 0119 // /** 0120 // * background : Rectangle 0121 // * The default style of the background. This can be customized by changing its properties. 0122 // */ 0123 // property alias background : bg 0124 0125 /** 0126 * listDelegate : Component 0127 * Delegate to be used in the component where the grouped elements are listed. 0128 */ 0129 property Component listDelegate: Maui.ListBrowserDelegate 0130 { 0131 id: delegate 0132 height: Maui.Style.rowHeight * 1.5 0133 width: ListView.view.width 0134 0135 Maui.Theme.backgroundColor: "transparent" 0136 Maui.Theme.textColor: control.Maui.Theme.textColor 0137 0138 iconVisible: false 0139 label1.text: model.uri 0140 0141 checkable: true 0142 checked: true 0143 onToggled: control.removeAtIndex(index) 0144 0145 onClicked: control.itemClicked(index) 0146 onPressAndHold: control.itemPressAndHold(index) 0147 } 0148 0149 /** 0150 * cleared : 0151 * Triggered when the selection is cleared by using the close button or calling the clear method. 0152 */ 0153 signal cleared() 0154 0155 /** 0156 * exitClicked : 0157 * Triggered when the selection bar is closed by using the close button or the close method. 0158 */ 0159 signal exitClicked() 0160 0161 /** 0162 * itemClicked : 0163 * Triggered when an item in the selection list view is clicked. 0164 */ 0165 signal itemClicked(int index) 0166 0167 /** 0168 * itemPressAndHold : 0169 * Triggered when an item in the selection list view is pressed and hold. 0170 */ 0171 signal itemPressAndHold(int index) 0172 0173 /** 0174 * itemAdded : 0175 * Triggered when an item newly added to the selection. 0176 */ 0177 signal itemAdded(var item) 0178 0179 /** 0180 * itemRemoved : 0181 * Triggered when an item has been removed from the selection. 0182 */ 0183 signal itemRemoved(var item) 0184 0185 /** 0186 * uriAdded : 0187 * Triggered when an item newly added to the selection. This signal only sends the refered URI of the item. 0188 */ 0189 signal uriAdded(string uri) 0190 0191 /** uriRemoved: 0192 * Triggered when an item has been removed from the selection. This signal only sends the refered URI of the item. 0193 */ 0194 signal uriRemoved(string uri) 0195 0196 /** 0197 * clicked : 0198 * Triggered when an empty area of the selectionbar has been clicked. 0199 */ 0200 signal clicked(var mouse) 0201 0202 /** 0203 * rightClicked : 0204 * Triggered when an empty area of the selectionbar has been right clicked. 0205 */ 0206 signal rightClicked(var mouse) 0207 0208 /** 0209 * urisDropped : 0210 * Triggered when a group of URIs has been dropped. 0211 */ 0212 signal urisDropped(var uris) 0213 0214 property QtObject m_private : QtObject 0215 { 0216 id: _private 0217 property var _uris : [] 0218 property var _items : [] 0219 } 0220 0221 ListModel 0222 { 0223 id: _urisModel 0224 } 0225 0226 Loader 0227 { 0228 id: _loader 0229 active: control.visible 0230 } 0231 0232 Component 0233 { 0234 id: _listContainerComponent 0235 0236 Popup 0237 { 0238 parent: control 0239 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent 0240 modal: true 0241 height: Math.min(Math.min(400, control.maxListHeight), selectionList.contentHeight) + Maui.Style.space.big 0242 width: Math.min(600, control.Window.window.width) 0243 0244 y: ((height) * -1) - Maui.Style.space.big 0245 x: Math.round( parent.width / 2 - width / 2 ) 0246 0247 Maui.ListBrowser 0248 { 0249 id: selectionList 0250 0251 anchors.fill: parent 0252 model: _urisModel 0253 0254 delegate: control.listDelegate 0255 } 0256 } 0257 } 0258 0259 ParallelAnimation 0260 { 0261 id: _openAnimation 0262 NumberAnimation 0263 { 0264 target: _layout 0265 property: "y" 0266 from: _layout.height 0267 to: Maui.Style.space.big/2 0268 duration: Maui.Style.units.longDuration*1 0269 easing.type: Easing.OutBack 0270 0271 } 0272 0273 NumberAnimation 0274 { 0275 target: _layout 0276 property: "scale" 0277 from: 0.5 0278 to: 1 0279 duration: Maui.Style.units.longDuration*1 0280 easing.type: Easing.OutQuad 0281 } 0282 0283 //NumberAnimation 0284 //{ 0285 //target: _imp 0286 //property: "opacity" 0287 //from: 0 0288 //to: 1 0289 //duration: Maui.Style.units.longDuration*2 0290 //easing.type: Easing.InBack 0291 //} 0292 } 0293 0294 ParallelAnimation 0295 { 0296 id: _closeAnimation 0297 NumberAnimation 0298 { 0299 target: _layout 0300 property: "y" 0301 from: Maui.Style.space.big/2 0302 to: _layout.height 0303 duration: Maui.Style.units.longDuration*1 0304 easing.type: Easing.InBack 0305 0306 } 0307 0308 NumberAnimation 0309 { 0310 target: _layout 0311 property: "scale" 0312 from: 1 0313 to: 0.5 0314 duration: Maui.Style.units.longDuration*1 0315 easing.type: Easing.InQuad 0316 0317 } 0318 0319 //NumberAnimation 0320 //{ 0321 //target: _imp 0322 //property: "opacity" 0323 //from: 1 0324 //to: 0 0325 //duration: Maui.Style.units.longDuration*2 0326 //easing.type: Easing.OutBack 0327 0328 //} 0329 0330 onFinished: control.visible = false 0331 } 0332 0333 Maui.ToolBar 0334 { 0335 id: _layout 0336 width: control.width 0337 padding: Maui.Style.space.medium 0338 forceCenterMiddleContent: false 0339 position: ToolBar.Footer 0340 0341 leftContent: Maui.Badge 0342 { 0343 id: _counter 0344 text: control.count 0345 radius: Maui.Style.radiusV 0346 font.pointSize: Maui.Style.fontSizes.big 0347 Maui.Theme.colorSet: control.Maui.Theme.colorSet 0348 Maui.Theme.backgroundColor: _loader.item && _loader.item.visible ? 0349 Maui.Theme.highlightColor : Qt.tint(control.Maui.Theme.textColor, Qt.rgba(control.Maui.Theme.backgroundColor.r, control.Maui.Theme.backgroundColor.g, control.Maui.Theme.backgroundColor.b, 0.9)) 0350 border.color: "transparent" 0351 0352 // onTextChanged: _counterAnimation.start() 0353 // 0354 // ColorAnimation on color 0355 // { 0356 // id: _counterAnimation 0357 // 0358 // from: Maui.Theme.highlightColor 0359 // to: Maui.Theme.backgroundColor 0360 // loops:3 0361 // easing { 0362 // type: Easing.OutElastic 0363 // amplitude: 1.0 0364 // period: 0.5 0365 // } 0366 // } 0367 0368 onClicked: 0369 { 0370 _loader.sourceComponent = _listContainerComponent 0371 _loader.item.open() 0372 } 0373 0374 Maui.Rectangle 0375 { 0376 opacity: 0.3 0377 anchors.fill: parent 0378 anchors.margins: 4 0379 visible: _counter.hovered 0380 color: "transparent" 0381 borderColor: "white" 0382 solidBorder: false 0383 } 0384 0385 MouseArea 0386 { 0387 id: _mouseArea 0388 anchors.fill: parent 0389 propagateComposedEvents: true 0390 property int startX 0391 property int startY 0392 Drag.active: drag.active 0393 Drag.hotSpot.x: 0 0394 Drag.hotSpot.y: 0 0395 Drag.dragType: Drag.Automatic 0396 Drag.supportedActions: Qt.CopyAction 0397 Drag.keys: ["text/plain","text/uri-list"] 0398 0399 onPressed: 0400 { 0401 if( mouse.source !== Qt.MouseEventSynthesizedByQt) 0402 { 0403 drag.target = _counter 0404 _counter.grabToImage(function(result) 0405 { 0406 _mouseArea.Drag.imageSource = result.url 0407 }) 0408 0409 _mouseArea.Drag.mimeData = { "text/uri-list": control.uris.join("\n")} 0410 0411 startX = _counter.x 0412 startY = _counter.y 0413 0414 }else mouse.accepted = false 0415 } 0416 0417 onReleased : 0418 { 0419 _counter.x = startX 0420 _counter.y = startY 0421 } 0422 0423 } 0424 } 0425 0426 Repeater 0427 { 0428 model: control.actions 0429 0430 ToolButton 0431 { 0432 action: modelData 0433 display: control.display 0434 ToolTip.delay: 1000 0435 ToolTip.timeout: 5000 0436 ToolTip.visible: hovered || pressed && action.text 0437 ToolTip.text: action.text 0438 } 0439 } 0440 0441 Maui.ToolButtonMenu 0442 { 0443 icon.name: "overflow-menu" 0444 visible: control.hiddenActions.length > 0 0445 Repeater 0446 { 0447 model: control.hiddenActions 0448 delegate: MenuItem{ action: modelData} 0449 } 0450 } 0451 0452 rightContent: Maui.CloseButton 0453 { 0454 onClicked: 0455 { 0456 control.exitClicked() 0457 } 0458 } 0459 0460 background: Rectangle 0461 { 0462 id: bg 0463 color: Maui.Theme.backgroundColor 0464 radius: control.radius 0465 0466 Behavior on color 0467 { 0468 Maui.ColorTransition { } 0469 } 0470 0471 MouseArea 0472 { 0473 anchors.fill: parent 0474 acceptedButtons: Qt.RightButton | Qt.LeftButton 0475 propagateComposedEvents: false 0476 preventStealing: true 0477 0478 onClicked: 0479 { 0480 if(!Maui.Handy.isMobile && mouse.button === Qt.RightButton) 0481 control.rightClicked(mouse) 0482 else 0483 control.clicked(mouse) 0484 } 0485 0486 onPressAndHold : 0487 { 0488 if(Maui.Handy.isMobile) 0489 control.rightClicked(mouse) 0490 } 0491 } 0492 0493 Maui.Rectangle 0494 { 0495 opacity: 0.2 0496 anchors.fill: parent 0497 anchors.margins: 4 0498 visible: _dropArea.containsDrag 0499 color: "transparent" 0500 borderColor: Maui.Theme.textColor 0501 solidBorder: false 0502 } 0503 0504 DropArea 0505 { 0506 id: _dropArea 0507 anchors.fill: parent 0508 onDropped: 0509 { 0510 control.urisDropped(drop.urls) 0511 } 0512 } 0513 0514 layer.enabled: true 0515 layer.effect: DropShadow 0516 { 0517 cached: true 0518 horizontalOffset: 0 0519 verticalOffset: 0 0520 radius: 8.0 0521 samples: 16 0522 color: "#80000000" 0523 smooth: true 0524 } 0525 } 0526 } 0527 0528 Keys.onEscapePressed: 0529 { 0530 control.exitClicked(); 0531 } 0532 0533 Keys.onBackPressed: 0534 { 0535 control.exitClicked(); 0536 event.accepted = true 0537 } 0538 0539 /** 0540 * Removes all the items from the selection. 0541 */ 0542 function clear() 0543 { 0544 _private._uris = [] 0545 _private._items = [] 0546 _urisModel.clear() 0547 control.cleared() 0548 } 0549 0550 /** 0551 * Returns an item at a given index 0552 */ 0553 function itemAt(index) 0554 { 0555 if(index < 0 || index > control.count) 0556 { 0557 return 0558 } 0559 return _urisModel.get(index) 0560 } 0561 0562 /** 0563 * Remove a single item at a given index 0564 */ 0565 function removeAtIndex(index) 0566 { 0567 if(index < 0) 0568 { 0569 return 0570 } 0571 0572 const item = _urisModel.get(index) 0573 const uri = item.uri 0574 0575 if(contains(uri)) 0576 { 0577 _private._uris.splice(index, 1) 0578 _private._items.splice(index, 1) 0579 _urisModel.remove(index) 0580 control.itemRemoved(item) 0581 control.uriRemoved(uri) 0582 } 0583 } 0584 0585 /** 0586 * Removes an item from thge selection at a given URI 0587 */ 0588 function removeAtUri(uri) 0589 { 0590 removeAtIndex(indexOf(uri)) 0591 } 0592 0593 /** 0594 * Return the index of an item in the selection given its URI 0595 */ 0596 function indexOf(uri) 0597 { 0598 return _private._uris.indexOf(uri) 0599 } 0600 0601 /** 0602 * Append a new item to the selection associated to the given URI 0603 */ 0604 function append(uri, item) 0605 { 0606 if(control.singleSelection) 0607 { 0608 clear() 0609 } 0610 0611 if(!contains(uri) || control.singleSelection) 0612 { 0613 _private._items.push(item) 0614 _private._uris.push(uri) 0615 0616 item.uri = uri 0617 _urisModel.append(item) 0618 control.itemAdded(item) 0619 control.uriAdded(uri) 0620 } 0621 } 0622 0623 /** 0624 * Returns a single string with all the URIs separated by a comma. 0625 */ 0626 function getSelectedUrisString() 0627 { 0628 return String(""+_private._uris.join(",")) 0629 } 0630 0631 /** 0632 * Returns true if the selection contains an item associated to a given URI. 0633 */ 0634 function contains(uri) 0635 { 0636 return _private._uris.includes(uri) 0637 } 0638 0639 function open() 0640 { 0641 if(control.visible) 0642 { 0643 return; 0644 } 0645 0646 control.visible = true 0647 _openAnimation.start() 0648 } 0649 0650 function close() 0651 { 0652 if(!control.visible) 0653 { 0654 return 0655 } 0656 _closeAnimation.start() 0657 } 0658 }