diff --git a/CMakeLists.txt b/CMakeLists.txt index 66d6c30..921d3f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,85 +1,85 @@ cmake_minimum_required(VERSION 3.10) set(REQUIRED_QT_VERSION 5.10.0) set(REQUIRED_KF5_VERSION 5.60.0) set(CMAKE_CXX_STANDARD 17) -set(MAUIKIT_VERSION 1.1.1) +set(MAUIKIT_VERSION 1.2.0) set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.maui) project(mauikit VERSION ${MAUIKIT_VERSION}) find_package(ECM 5.45.0 NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) #DEFAULT COMPONENTS DEFINITIONS option(COMPONENT_EDITOR "Build editor component" ON) option(COMPONENT_FM "Build filemanager component" ON) option(COMPONENT_ACCOUNTS "Build accounts component" ON) option(COMPONENT_TERMINAL "Build terminal component" ON) option(COMPONENT_STORE "Build store component" ON) option(COMPONENT_TAGGING "Build tagging component" ON) option(COMPONENT_SYNCING "Build syncing component" ON) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) include(ECMPoQmTools) include(ECMQMLModules) include(KDEClangFormat) include(KDEInstallDirs) include(KDECMakeSettings) include(ECMQtDeclareLoggingCategory) include(ECMAddQch) include(KDECompilerSettings NO_POLICY_SCOPE) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Qml Sql Core Quick Gui Svg QuickControls2 Network DBus Xml) ecm_find_qmlmodule(QtGraphicalEffects 1.0) ecm_find_qmlmodule(QtQuick.Shapes 1.0) if(ANDROID) find_package(Qt5 REQUIRED COMPONENTS AndroidExtras) find_package(Gradle REQUIRED) endif() find_package(KF5 ${REQUIRED_KF5_VERSION} REQUIRED COMPONENTS I18n Notifications Config Service KIO ConfigWidgets) add_subdirectory(src) ##CMAKE PARTS set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/MauiKit") ecm_setup_version(${MAUIKIT_VERSION} VARIABLE_PREFIX MAUIKIT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/mauikit_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" SOVERSION 5 ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/MauiKitConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} PATH_VARS KF5_INCLUDE_INSTALL_DIR CMAKE_INSTALL_PREFIX ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT MauiKitTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE MauiKitTargets.cmake ) file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) diff --git a/src/controls/labs/AltBrowser.qml b/src/controls/AltBrowser.qml similarity index 100% rename from src/controls/labs/AltBrowser.qml rename to src/controls/AltBrowser.qml diff --git a/src/controls/labs/AppViewLoader.qml b/src/controls/AppViewLoader.qml similarity index 100% rename from src/controls/labs/AppViewLoader.qml rename to src/controls/AppViewLoader.qml diff --git a/src/controls/labs/AppViews.qml b/src/controls/AppViews.qml similarity index 99% rename from src/controls/labs/AppViews.qml rename to src/controls/AppViews.qml index 58d6247..982c654 100644 --- a/src/controls/labs/AppViews.qml +++ b/src/controls/AppViews.qml @@ -1,186 +1,186 @@ /* * Copyright 2020 Camilo Higuita * * 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 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.10 import QtQuick.Controls 2.10 import org.kde.mauikit 1.0 as Maui import org.kde.mauikit 1.1 as MauiLab -import "../private" as Private +import "private" as Private SwipeView { id: control interactive: Maui.Handy.isTouch clip: true focus: true property int maxViews : 4 property Maui.ToolBar toolbar : window().headBar readonly property int index : -1 readonly property QtObject actionGroup : Private.ActionGroup { id: _actionGroup currentIndex : control.currentIndex onCurrentIndexChanged: { control.currentIndex = currentIndex _actionGroup.currentIndex = control.currentIndex } Component.onCompleted: { control.toolbar.middleContent.push(_actionGroup) } } currentIndex: _actionGroup.currentIndex onCurrentIndexChanged: { _actionGroup.currentIndex = currentIndex control.currentIndex = _actionGroup.currentIndex } onCurrentItemChanged: { currentItem.forceActiveFocus() _listView.positionViewAtIndex(control.currentIndex , ListView.SnapPosition) history.push(control.currentIndex) } Keys.onBackPressed: { control.goBack() } Shortcut { sequence: StandardKey.Back onActivated: control.goBack() } contentItem: ListView { id: _listView model: control.contentModel interactive: control.interactive currentIndex: control.currentIndex spacing: control.spacing orientation: control.orientation snapMode: ListView.SnapOneItem boundsBehavior: Flickable.StopAtBounds highlightRangeMode: ListView.StrictlyEnforceRange preferredHighlightBegin: 0 highlightMoveDuration: 0 highlightFollowsCurrentItem: true highlightResizeDuration: 0 preferredHighlightEnd: width // highlight: Item {} highlightMoveVelocity: -1 highlightResizeVelocity: -1 maximumFlickVelocity: 4 * (control.orientation === Qt.Horizontal ? width : height) } Keys.enabled: true Keys.onPressed: { if((event.key == Qt.Key_1) && (event.modifiers & Qt.ControlModifier)) { if(control.count > -1 ) { control.currentIndex = 0 } } if((event.key == Qt.Key_2) && (event.modifiers & Qt.ControlModifier)) { if(control.count > 0 ) { control.currentIndex = 1 } } if((event.key == Qt.Key_3) && (event.modifiers & Qt.ControlModifier)) { if(control.count > 1 ) { control.currentIndex = 2 } } if((event.key == Qt.Key_4) && (event.modifiers & Qt.ControlModifier)) { if(control.count > 2 ) { control.currentIndex = 3 } } } Component.onCompleted: { for(var i in control.contentChildren) { const obj = control.contentChildren[i] if(obj.MauiLab.AppView.title || obj.MauiLab.AppView.iconName) { if(control.actionGroup.items.length < control.maxViews) { control.actionGroup.items.push(obj) }else { control.actionGroup.hiddenItems.push(obj) } } } } readonly property QtObject history : QtObject { property var historyIndexes : [] function pop() { historyIndexes.pop() return historyIndexes.pop() } function push(index) { historyIndexes.push(index) } function indexes() { return historyIndexes } } function goBack() { console.log("TRYING TO GO BACK", history.indexes()) control.setCurrentIndex(history.pop()) } } diff --git a/src/controls/Dialog.qml b/src/controls/Dialog.qml index e405348..b345ad5 100644 --- a/src/controls/Dialog.qml +++ b/src/controls/Dialog.qml @@ -1,280 +1,279 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.5 import QtQuick.Controls 2.10 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.7 as Kirigami import QtGraphicalEffects 1.0 Maui.Popup { id: control + default property alias content : _pageContent.data + property string message : "" property string title: "" - property string acceptText: "Yes" - property string rejectText: "No" - property bool defaultButtons: true - property bool confirmationDialog: false + property bool persistent : true - default property alias content : _pageContent.data - - property alias acceptButton : _acceptButton - property alias rejectButton : _rejectButton + property alias acceptButton : _acceptButton + property alias rejectButton : _rejectButton + + property alias textEntry : _textEntry + property alias entryField: _textEntry.visible + + property alias page : _page + property alias footBar : _page.footBar + property alias headBar: _page.headBar + property alias closeButton: _closeButton + + signal accepted() + signal rejected() + + closePolicy: control.persistent ? Popup.NoAutoClose | Popup.CloseOnEscape : Popup.CloseOnEscape | Popup.CloseOnPressOutside + + maxWidth: Maui.Style.unit * 300 + maxHeight: implicitHeight + implicitHeight: _layout.implicitHeight + widthHint: 0.9 + heightHint: 0.9 + clip: false + + Maui.Badge + { + id: _closeButton + visible: control.persistent - property alias textEntry : _textEntry - property alias entryField: _textEntry.visible + color: hovered || pressed ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.backgroundColor - property alias page : _page - property alias footBar : _page.footBar - property alias headBar: _page.headBar - property alias closeButton: _closeButton + property int position : Maui.App.leftWindowControls.includes("X") ? Qt.AlignLeft : Qt.AlignRight - signal accepted() - signal rejected() - - closePolicy: Popup.NoAutoClose | Popup.CloseOnEscape + Maui.X + { + height: Maui.Style.iconSizes.tiny + width: height + anchors.centerIn: parent + color: Kirigami.Theme.textColor + } - maxWidth: Maui.Style.unit * 300 - maxHeight: implicitHeight - implicitHeight: _layout.implicitHeight - widthHint: 0.9 - heightHint: 0.9 - clip: false + border.color: Kirigami.Theme.textColor - Maui.Badge + anchors { - id: _closeButton - color: hovered || pressed ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.backgroundColor - - property int position : Maui.App.leftWindowControls.includes("X") ? Qt.AlignLeft : Qt.AlignRight - - Maui.X - { - height: Maui.Style.iconSizes.tiny - width: height - anchors.centerIn: parent - color: Kirigami.Theme.textColor - } - - border.color: Kirigami.Theme.textColor - - anchors - { - verticalCenter: parent.top - horizontalCenter: _closeButton.position === Qt.AlignLeft ? parent.left : parent.right - horizontalCenterOffset: control.width === control.parent.width ? _closeButton.width : 0 - } - - z: control.z+999 - onClicked: close() + verticalCenter: parent.top + horizontalCenter: _closeButton.position === Qt.AlignLeft ? parent.left : parent.right + horizontalCenterOffset: control.width === control.parent.width ? _closeButton.width : 0 } + z: control.z+999 + onClicked: close() + } + + + ColumnLayout + { + id: _layout + anchors.fill: parent + spacing: 0 - ColumnLayout + Maui.Page { - id: _layout - anchors.fill: parent - spacing: 0 + id: _page + Layout.fillWidth: true + Layout.fillHeight: true + padding: 0 + clip: true - Maui.Page + implicitHeight: Maui.Style.space.big + _pageContent.implicitHeight + topPadding + bottomPadding + topMargin + bottomMargin + footer.height + _pageContent.spacing + header.height + + ColumnLayout { - id: _page - Layout.fillWidth: true - Layout.fillHeight: true - padding: 0 - clip: true - - implicitHeight: Maui.Style.space.big + _pageContent.implicitHeight + topPadding + bottomPadding + topMargin + bottomMargin + footer.height + _pageContent.spacing + header.height + id: _pageContent + anchors.fill: parent + spacing: Maui.Style.space.medium - ColumnLayout + Label { - id: _pageContent - anchors.fill: parent - spacing: Maui.Style.space.medium + visible: title.length > 0 - Label - { - visible: title.length > 0 - - Layout.fillWidth: true - Layout.alignment: Qt.AlignCenter - - color: Kirigami.Theme.textColor - text: title - font.weight: Font.Thin - font.bold: true - font.pointSize:Maui.Style.fontSizes.huge - elide: Qt.ElideRight - wrapMode: Text.Wrap - } + Layout.fillWidth: true + Layout.alignment: Qt.AlignCenter - Kirigami.ScrollablePage - { - id: _scrollable - visible: message.length > 0 - Layout.maximumHeight: Math.min(_scrollable.contentHeight, 500) - Layout.fillWidth: true - Layout.alignment: Qt.AlignCenter - - Kirigami.Theme.backgroundColor: "transparent" - padding: 0 - leftPadding: padding - rightPadding: padding - topPadding: padding - bottomPadding: padding - - Label - { - id: body - width: parent.width - padding: 0 - text: message - textFormat : TextEdit.AutoText - color: Kirigami.Theme.textColor - font.pointSize:Maui.Style.fontSizes.default - wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere - elide: Text.ElideLeft - verticalAlignment: Qt.AlignVCenter - } - } + color: Kirigami.Theme.textColor + text: title + font.weight: Font.Thin + font.bold: true + font.pointSize:Maui.Style.fontSizes.huge + elide: Qt.ElideRight + wrapMode: Text.Wrap + } + + Kirigami.ScrollablePage + { + id: _scrollable + visible: message.length > 0 + Layout.maximumHeight: Math.min(_scrollable.contentHeight, 500) + Layout.fillWidth: true + Layout.alignment: Qt.AlignCenter + + Kirigami.Theme.backgroundColor: "transparent" + padding: 0 + leftPadding: padding + rightPadding: padding + topPadding: padding + bottomPadding: padding - Maui.TextField + Label { - id: _textEntry - visible: false - Layout.fillWidth: true - Layout.alignment: Qt.AlignCenter - focus: visible - onAccepted: control.accepted() + id: body + width: parent.width + padding: 0 + text: message + textFormat : TextEdit.AutoText + color: Kirigami.Theme.textColor + font.pointSize:Maui.Style.fontSizes.default + wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere + elide: Text.ElideLeft + verticalAlignment: Qt.AlignVCenter } } - /* - * layer.enabled: control.background.radius - * layer.samples: 4 - * layer.effect: OpacityMask - * { - * maskSource: Item - * { - * width: _page.width - * height: _page.height - * - * Rectangle - * { - * anchors.centerIn: parent - * width: _page.width - * height: _page.height - * radius: control.background.radius - } + + Maui.TextField + { + id: _textEntry + visible: false + Layout.fillWidth: true + Layout.alignment: Qt.AlignCenter + focus: visible + onAccepted: control.accepted() + } } - }*/ + /* + * layer.enabled: control.background.radius + * layer.samples: 4 + * layer.effect: OpacityMask + * { + * maskSource: Item + * { + * width: _page.width + * height: _page.height + * + * Rectangle + * { + * anchors.centerIn: parent + * width: _page.width + * height: _page.height + * radius: control.background.radius + } + } + }*/ + } + + Kirigami.Separator + { + Layout.fillWidth: true + visible: control.defaultButtons + } + + RowLayout + { + id: _defaultButtonsLayout + spacing: 0 + Layout.fillWidth: true + Layout.preferredHeight: Maui.Style.toolBarHeightAlt - Maui.Style.space.medium + Layout.maximumHeight: Maui.Style.toolBarHeightAlt - Maui.Style.space.medium + visible: control.defaultButtons + + Button + { + Layout.fillWidth: true + Layout.fillHeight: true + implicitWidth: width + id: _rejectButton + text: qsTr("Cancel") + background: Rectangle + { + color: _rejectButton.hovered || _rejectButton.down || _rejectButton.pressed ? "#da4453" : Kirigami.Theme.backgroundColor + } + + contentItem: Label + { + text: _rejectButton.text + color: _rejectButton.hovered || _rejectButton.down || _rejectButton.pressed ? "#fafafa" : Kirigami.Theme.textColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } + /*property color color : Kirigami.Theme.negativeBackgroundColor + * property alias text : _rejectLabel.text + * + * Rectangle + * { + * anchors.fill: parent + * color: _rejectButton.color + * Kirigami.Theme.textColor: Kirigami.Theme.negativeTextColor + * Label + * { + * id: _rejectLabel + * anchors.fill: parent + * anchors.margins: Maui.Style.space.small + * text: _rejectButton.text + * color: "#fafafa" } + } */ + + onClicked: rejected() + } Kirigami.Separator { - Layout.fillWidth: true - visible: control.defaultButtons + Layout.fillHeight: true + visible: _defaultButtonsLayout.visibleChildren.length > 1 } - RowLayout + Button { - id: _defaultButtonsLayout - spacing: 0 Layout.fillWidth: true - Layout.preferredHeight: Maui.Style.toolBarHeightAlt - Maui.Style.space.medium - Layout.maximumHeight: Maui.Style.toolBarHeightAlt - Maui.Style.space.medium - visible: control.defaultButtons + Layout.fillHeight: true + implicitWidth: width + text: qsTr("Accept") + id: _acceptButton - Button + background: Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - implicitWidth: width - id: _rejectButton - text: control.rejectText - background: Rectangle - { - color: _rejectButton.hovered || _rejectButton.down || _rejectButton.pressed ? "#da4453" : Kirigami.Theme.backgroundColor - } - - contentItem: Label - { - text: _rejectButton.text - color: _rejectButton.hovered || _rejectButton.down || _rejectButton.pressed ? "#fafafa" : Kirigami.Theme.textColor - horizontalAlignment: Qt.AlignHCenter - verticalAlignment: Qt.AlignVCenter - } - /*property color color : Kirigami.Theme.negativeBackgroundColor - * property alias text : _rejectLabel.text - * - * Rectangle - * { - * anchors.fill: parent - * color: _rejectButton.color - * Kirigami.Theme.textColor: Kirigami.Theme.negativeTextColor - * Label - * { - * id: _rejectLabel - * anchors.fill: parent - * anchors.margins: Maui.Style.space.small - * text: _rejectButton.text - * color: "#fafafa" + color: _acceptButton.hovered || _acceptButton.down || _acceptButton.pressed ? "#26c6da" : Kirigami.Theme.backgroundColor } - } */ - - onClicked: rejected() - } - Kirigami.Separator + contentItem: Label { - Layout.fillHeight: true - visible: _defaultButtonsLayout.visibleChildren.length > 1 - } + text: _acceptButton.text + color: _acceptButton.hovered || _acceptButton.down || _acceptButton.pressed ? "#fafafa" : Kirigami.Theme.textColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } - Button - { - Layout.fillWidth: true - Layout.fillHeight: true - implicitWidth: width - text: acceptText - id: _acceptButton - - background: Rectangle - { - color: _acceptButton.hovered || _acceptButton.down || _acceptButton.pressed ? "#26c6da" : Kirigami.Theme.backgroundColor - } - - contentItem: Label - { - text: _acceptButton.text - color: _acceptButton.hovered || _acceptButton.down || _acceptButton.pressed ? "#fafafa" : Kirigami.Theme.textColor - horizontalAlignment: Qt.AlignHCenter - verticalAlignment: Qt.AlignVCenter - } - - onClicked: accepted() - } + onClicked: accepted() } } + } } diff --git a/src/controls/FileBrowser.qml b/src/controls/FileBrowser.qml index d14dacd..6d58e2d 100644 --- a/src/controls/FileBrowser.qml +++ b/src/controls/FileBrowser.qml @@ -1,971 +1,971 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.10 import QtQuick.Controls 2.10 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.8 as Kirigami import org.kde.mauikit 1.0 as Maui import org.kde.mauikit 1.1 as MauiLab import "private" as Private Maui.Page { id: control //aliases property alias currentPath : _browser.path onCurrentPathChanged : _filterField.clear() property alias settings : _browser.settings property alias view : _stackView.currentItem readonly property QtObject currentView : _stackView.currentItem.currentView readonly property Maui.FMList currentFMList : view.currentFMList readonly property Maui.BaseModel currentFMModel : view.currentFMModel readonly property bool isSearchView : _stackView.currentItem.objectName === "searchView" // custom props property bool selectionMode: false property bool showStatusBar : Maui.FM.loadSettings("StatusBar", "SETTINGS", false) == "true" property int thumbnailsSize : Maui.Style.iconSizes.large * 1.7 property var indexHistory : [] // need to be set by the implementation as features property MauiLab.SelectionBar selectionBar : null property Maui.FilePreviewer previewer : null property Maui.TagsDialog tagsDialog : null property MauiLab.ShareDialog shareDialog : null property Maui.OpenWithDialog openWithDialog : null //relevant menus to file item and the browserview property alias browserMenu: browserMenu property alias itemMenu: itemMenu //access to the loaded the dialog components property alias dialog : dialogLoader.item //signals signal itemClicked(int index) signal itemDoubleClicked(int index) signal itemRightClicked(int index) signal itemLeftEmblemClicked(int index) signal itemRightEmblemClicked(int index) signal rightClicked() signal keyPress(var event) signal urlsDropped(var urls) //color scheme Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.inherit: false //catch inherited signals from page onGoBackTriggered: control.goBack() onGoForwardTriggered: control.goNext() title: view.title focus: true flickable: control.currentView.flickable showTitle: false headBar.visible: false headBar.leftContent: ToolButton { text: i18n("Back") icon.name: "go-previous" onClicked: control.quitSearch() visible: control.isSearchView } headBar.middleContent: Maui.TextField { id: _searchField Layout.fillWidth: true placeholderText: i18n("Search") onAccepted: control.search(text) } footBar.visible: control.showStatusBar || String(control.currentPath).startsWith("trash:/") footBar.leftSretch: false footerPositioning: ListView.InlineFooter footBar.middleContent: Maui.TextField { id: _filterField Layout.fillWidth: true enabled: control.currentFMList.count > 0 placeholderText: String("Filter %1 files").arg(control.currentFMList ? control.currentFMList.count : 0) onAccepted: control.view.filter = text onCleared: control.view.filter = "" inputMethodHints: Qt.ImhNoAutoUppercase onTextChanged: { if(control.currentFMList.count < 50) _filterField.accepted() } Keys.enabled: true Keys.onPressed: { // Shortcut for clearing selection if(event.key == Qt.Key_Up) { // _filterField.clear() // footBar.visible = false control.currentView.forceActiveFocus() } } } footBar.rightContent: ToolButton { visible: String(control.currentPath).startsWith("trash:/") icon.name: "trash-empty" text: i18n("Empty Trash") onClicked: Maui.FM.emptyTrash() } Loader { id: dialogLoader // active: item && item.visible } Component { id: removeDialogComponent Maui.Dialog { id: _removeDialog property var urls: [] title: "Removing %1 files".arg(urls.length) message: Maui.Handy.isAndroid ? i18n("This action will completely remove your files from your system. This action can not be undone.") : i18n("You can move the file to the trash or delete it completely from your system. Which one do you prefer?") rejectButton.text: i18n("Delete") acceptButton.text: i18n("Trash") acceptButton.visible: Maui.Handy.isLinux page.margins: Maui.Style.space.huge ColumnLayout { Layout.fillWidth: true CheckBox { id: _removeDialogFilesCheckBox Layout.fillWidth: true text: i18n("List files") } Kirigami.ScrollablePage { visible: _removeDialogFilesCheckBox.checked Layout.fillWidth: true Layout.maximumHeight: 200 padding: 0 topPadding: 0 leftPadding: 0 rightPadding: 0 TextArea { wrapMode: Text.WordWrap text: urls.join("\n\n") readOnly: true background: null } } } onRejected: { if(control.selectionBar && control.selectionBar.visible) { control.selectionBar.animate() control.clearSelection() } Maui.FM.removeFiles(urls) close() } onAccepted: { if(control.selectionBar && control.selectionBar.visible) { control.selectionBar.animate() control.clearSelection() } Maui.FM.moveToTrash(urls) close() } } } Component { id: newFolderDialogComponent Maui.NewDialog { title: i18n("New Folder") message: i18n("Create a new folder with a custom name") acceptButton.text: i18n("Create") onFinished: control.currentFMList.createDir(text) rejectButton.visible: false textEntry.placeholderText: i18n("Folder name") } } Component { id: newFileDialogComponent Maui.NewDialog { title: i18n("New File") message: i18n("Create a new file with a custom name and extension") acceptButton.text: i18n("Create") onFinished: Maui.FM.createFile(control.currentPath, text) rejectButton.visible: false textEntry.placeholderText: i18n("Filename") } } Component { id: renameDialogComponent Maui.NewDialog { property var item : control.currentFMList ? control.currentFMList.get(control.currentView.currentIndex) : ({}) title: i18n("Rename File") message: i18n("Rename a file or folder") textEntry.text: item.label textEntry.placeholderText: i18n("New name") onFinished: Maui.FM.rename(item.path, textEntry.text) onRejected: close() - acceptText: i18n("Rename") - rejectText: i18n("Cancel") + acceptButton.text: i18n("Rename") + rejectButton.text: i18n("Cancel") } } Private.BrowserMenu { id: browserMenu } Private.FileMenu { id: itemMenu width: Maui.Style.unit * 200 onBookmarkClicked: control.bookmarkFolder([item.path]) onCopyClicked: { if(item) control.copy([item.path]) } onCutClicked: { if(item) control.cut([item.path]) } onTagsClicked: { if(item && control.tagsDialog) { control.tagsDialog.composerList.urls = [item.path] control.tagsDialog.open() } } onRenameClicked: { dialogLoader.sourceComponent = renameDialogComponent dialog.open() } onRemoveClicked: { console.log("REMOVE", item.path) control.remove([item.path]) } onOpenWithClicked: control.openWith([item.path]) onShareClicked: control.shareFiles([item.path]) } Connections { target: control.previewer.tagBar enabled: control.previewer && control.tagsDialog onAddClicked: { if(control.tagsDialog) { control.tagsDialog.composerList.urls = [ control.previewer.currentUrl] control.tagsDialog.open() } } } Connections { target: control.tagsDialog enabled: control.tagsDialog && control.previewer onTagsReady: { control.tagsDialog.composerList.updateToUrls(tags) if(control.previewer && control.previewer.visible) control.previewer.tagBar.list.refresh() } } Connections { target: control.previewer enabled: control.previewer onShareButtonClicked: control.shareFiles([url]) onOpenButtonClicked: control.openFile(url) } Connections { enabled: control.currentView target: control.currentView onKeyPress: { const index = control.currentView.currentIndex const item = control.currentFMList.get(index) // Shortcuts for refreshing if((event.key == Qt.Key_F5)) { control.currentFMList.refresh() } // Shortcuts for renaming if((event.key == Qt.Key_F2)) { dialogLoader.sourceComponent = renameDialogComponent dialog.open() } // Shortcuts for selecting file if((event.key == Qt.Key_A) && (event.modifiers & Qt.ControlModifier)) { control.selectAll() } if(event.key == Qt.Key_S) { if(control.selectionBar && control.selectionBar.contains(item.path)) { control.selectionBar.removeAtUri(item.path) }else { control.addToSelection(item) } } if((event.key == Qt.Key_Left || event.key == Qt.Key_Right || event.key == Qt.Key_Down || event.key == Qt.Key_Up) && (event.modifiers & Qt.ControlModifier) && (event.modifiers & Qt.ShiftModifier)) { if(control.selectionBar && control.selectionBar.contains(item.path)) { control.selectionBar.removeAtUri(item.path) }else { control.addToSelection(item) } } //shortcut for opening files if((event.key == Qt.Key_Return) && (event.modifiers & Qt.AltModifier)) { if(control.previewer) { control.previewer.show(currentFMModel, index) } }else if(event.key == Qt.Key_Return) { indexHistory.push(index) control.openItem(index) } // Shortcut for pasting an item if((event.key == Qt.Key_V) && (event.modifiers & Qt.ControlModifier)) { control.paste(Maui.Handy.getClipboard().urls) } // Shortcut for cutting an item if((event.key == Qt.Key_X) && (event.modifiers & Qt.ControlModifier)) { var urls = [] if(control.selectionBar && control.selectionBar.count > 0) { urls = control.selectionBar.uris } else { urls = [item.path] } control.cut(urls) } // Shortcut for copying an item if((event.key == Qt.Key_C) && (event.modifiers & Qt.ControlModifier)) { var urls = [] if(control.selectionBar && control.selectionBar.count > 0) { urls = control.selectionBar.uris } else { urls = [item.path] } control.copy(urls) } // Shortcut for removing an item if(event.key == Qt.Key_Delete) { var urls = [] if(control.selectionBar && control.selectionBar.count > 0) { urls = control.selectionBar.uris } else { urls = [item.path] } control.remove(urls) } // Shortcut for going back in browsing history if(event.key == Qt.Key_Backspace || event.key == Qt.Key_Back) { if(control.selectionBar && control.selectionBar.count> 0) { control.clearSelection() } else { control.goBack() } } // Shortcut for clearing selection and filtering if(event.key == Qt.Key_Escape) //TODO not working, the event is not catched or emitted or is being accepted else where? { if(control.selectionBar && control.selectionBar.count > 0) control.clearSelection() control.view.filter = "" } //Shortcut for opening filtering if((event.key == Qt.Key_F) && (event.modifiers & Qt.ControlModifier)) { control.toggleStatusBar() } if(event.key == Qt.Key_Space) { if(control.previewer) control.previewer.show(currentFMModel, index) } control.keyPress(event) } onItemsSelected: { control.selectIndexes(indexes) } onItemClicked: { control.currentView.currentIndex = index indexHistory.push(index) control.itemClicked(index) control.currentView.forceActiveFocus() } onItemDoubleClicked: { control.currentView.currentIndex = index indexHistory.push(index) control.itemDoubleClicked(index) control.currentView.forceActiveFocus() } onItemRightClicked: { if(control.currentFMList.pathType !== Maui.FMList.TRASH_PATH && control.currentFMList.pathType !== Maui.FMList.REMOTE_PATH) { itemMenu.show(index) } control.itemRightClicked(index) control.currentView.forceActiveFocus() } onItemToggled: { const item = control.currentFMList.get(index) if(control.selectionBar && control.selectionBar.contains(item.path)) { control.selectionBar.removeAtUri(item.path) }else { control.addToSelection(item) } control.itemLeftEmblemClicked(index) control.currentView.forceActiveFocus() } onAreaClicked: { if(!Kirigami.Settings.isMobile && mouse.button === Qt.RightButton) browserMenu.show(control) else return control.rightClicked() control.currentView.forceActiveFocus() } onAreaRightClicked: browserMenu.show(control) // onWarning: // { // notify("dialog-information", "An error happened", message) // } // onProgress: // { // if(percent === 100) // _progressBar.value = 0 // else // _progressBar.value = percent/100 // } } StackView { id: _stackView anchors.fill: parent clip: true initialItem: DropArea { id: _dropArea property alias currentView : _browser.currentView property alias currentFMList : _browser.currentFMList property alias currentFMModel: _browser.currentFMModel property alias filter: _browser.filter property alias title : _browser.title onDropped: { if(drop.urls) { _dropMenu.urls = drop.urls.join(",") _dropMenu.popup() control.urlsDropped(drop.urls) } } opacity: _dropArea.containsDrag ? 0.5 : 1 Private.BrowserView { id: _browser anchors.fill: parent } Menu { id: _dropMenu property string urls enabled: Maui.FM.getFileInfo(control.currentPath).isdir == "true" MenuItem { text: i18n("Copy here") onTriggered: { const urls = _dropMenu.urls.split(",") Maui.FM.copy(urls, control.currentPath, false) } } MenuItem { text: i18n("Move here") onTriggered: { const urls = _dropMenu.urls.split(",") Maui.FM.cut(urls, control.currentPath) } } MenuItem { text: i18n("Link here") onTriggered: { const urls = _dropMenu.urls.split(",") for(var i in urls) Maui.FM.createSymlink(urls[i], control.currentPath) } } } } Component { id: _searchBrowserComponent Private.BrowserView { id: _searchBrowser objectName: "searchView" settings.viewType: control.settings.viewType === Maui.FMList.MILLERS_VIEW ? Maui.FMList.LIST_VIEW : control.settings.viewType // do not use millersview it does not makes sense since search does not follow a path url structures } } } Component.onCompleted: { control.currentView.forceActiveFocus() } // onThumbnailsSizeChanged: // { // if(settings.trackChanges && settings.saveDirProps) // Maui.FM.setDirConf(currentPath+"/.directory", "MAUIFM", "IconSize", thumbnailsSize) // else // Maui.FM.saveSettings("IconSize", thumbnailsSize, "SETTINGS") // // if(view.viewType === Maui.FMList.ICON_VIEW) // control.currentView.adaptGrid() // } function tagFiles(urls) { if(urls.length <= 0) { return } if(control.tagsDialog) { control.tagsDialog.composerList.urls = urls control.tagsDialog.open() } } function openWith(urls) { if(urls.length <= 0) { return } if(control.openWithDialog) { openWithDialog.urls = urls openWithDialog.open() } } function shareFiles(urls) { if(urls.length <= 0) { return } if(control.shareDialog) { control.shareDialog.urls = urls control.shareDialog.open() } } function copy(urls) { if(urls.length <= 0) { return } Maui.Handy.copyToClipboard({"urls": urls}, false) } function cut(urls) { if(urls.length <= 0) { return } Maui.Handy.copyToClipboard({"urls": urls}, true) } function paste() { const data = Maui.Handy.getClipboard() const urls = data.urls if(!urls) { return } if(data.cut) { control.currentFMList.cutInto(urls) control.clearSelection() }else { control.currentFMList.copyInto(urls) } } function remove(urls) { if(urls.length <= 0) { return } dialogLoader.sourceComponent= removeDialogComponent dialog.urls = urls dialog.open() } function openItem(index) { const item = control.currentFMList.get(index) const path = item.path switch(control.currentFMList.pathType) { case Maui.FMList.CLOUD_PATH: //TODO deprecrated and needs to be removed or clean up for 1.1 if(item.isdir === "true") { control.openFolder(path) } else { Maui.FM.openCloudItem(item) } break; default: if(control.selectionMode && item.isdir == "false") { if(control.selectionBar && control.selectionBar.contains(item.path)) { control.selectionBar.removeAtPath(item.path) }else { control.addToSelection(item) } } else { if(item.isdir == "true") { control.openFolder(path) } else { if (Kirigami.Settings.isMobile && control.previewer) { control.previewer.show(currentFMModel, index) } else { control.openFile(path) } } } } } function openFile(path) { Maui.FM.openUrl(path) } function openFolder(path) { if(!String(path).length) { return; } if(control.isSearchView) { control.quitSearch() } control.currentPath = path } function goBack() { openFolder(control.currentFMList.previousPath) // control.currentView.currentIndex = indexHistory.pop() } function goNext() { openFolder(control.currentFMList.posteriorPath) } function goUp() { openFolder(control.currentFMList.parentPath) } // for this to work the implementation needs to have passed a selectionBar function addToSelection(item) { if(control.selectionBar == null || item.path.startsWith("tags://") || item.path.startsWith("applications://")) { return } control.selectionBar.append(item.path, item) } function clearSelection() { if(control.selectionBar) { control.selectionBar.clear() } } //given a list inf indexes add them to the selectionBar function selectIndexes(indexes) { if(control.selectionBar == null) { return } for(var i in indexes) addToSelection(control.currentFMList.get(indexes[i])) } function selectAll() //TODO for now dont select more than 100 items so things dont freeze or break { if(control.selectionBar == null) { return } selectIndexes([...Array( Math.min(control.currentFMList.count, 100)).keys()]) } function bookmarkFolder(paths) //multiple paths { for(var i in paths) { Maui.FM.bookmark(paths[i]) } } function zoomIn() { control.currentView.resizeContent(1.2) } function zoomOut() { control.currentView.resizeContent(0.8) } function toggleStatusBar() { control.footBar.visible = !control.footBar.visible Maui.FM.saveSettings("StatusBar", control.footBar.visible, "SETTINGS") if(control.footBar.visible) { _filterField.forceActiveFocus() }else { control.currentView.forceActiveFocus() } } function openSearch() { if(!control.isSearchView) { _stackView.push(_searchBrowserComponent, StackView.Immediate) } _searchField.forceActiveFocus() } function quitSearch() { _stackView.pop(StackView.Immediate) control.headBar.visible = false } function search(query) { openSearch() _stackView.currentItem.title = i18n("Search: %1").arg(query) _stackView.currentItem.currentFMList.search(query, _browser.currentFMList) } function newFile() { dialogLoader.sourceComponent= newFileDialogComponent dialog.open() dialog.forceActiveFocus() } function newFolder() { dialogLoader.sourceComponent= newFolderDialogComponent dialog.open() dialog.forceActiveFocus() } } diff --git a/src/controls/FilePreviewer.qml b/src/controls/FilePreviewer.qml index cd9d427..68bddce 100644 --- a/src/controls/FilePreviewer.qml +++ b/src/controls/FilePreviewer.qml @@ -1,296 +1,289 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami -import org.kde.mauikit 1.0 as Maui +import org.kde.mauikit 1.2 as Maui import "private" Maui.Dialog { id: control property url currentUrl: "" property alias model : _listView.model property bool isFav : false property bool isDir : false property bool showInfo: true property alias tagBar : _tagsBar property Maui.TagsDialog tagsDialog : null signal shareButtonClicked(url url) signal openButtonClicked(url url) maxHeight: Maui.Style.unit * 800 maxWidth: Maui.Style.unit * 500 defaultButtons: false page.padding: 0 footBar.visible: true footBar.leftContent: ToolButton { icon.name: "document-open" onClicked: { openButtonClicked(control.currentUrl) control.close() } } footBar.middleContent: [ ToolButton { visible: !isDir icon.name: "document-share" onClicked: { shareButtonClicked(control.currentUrl) control.close() } }, ToolButton { icon.name: "love" checkable: true checked: control.isFav onClicked: { if(control.isFav) _tagsBar.list.removeFromUrls("fav") else _tagsBar.list.insertToUrls("fav") control.isFav = !control.isFav } } ] footBar.rightContent: ToolButton { icon.name: "documentinfo" checkable: true checked: control.showInfo onClicked: control.showInfo = !control.showInfo } ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true spacing: 0 ListView { id: _listView Layout.fillWidth: true Layout.fillHeight: true orientation: ListView.Horizontal clip: true focus: true interactive: true highlightFollowsCurrentItem: true highlightMoveDuration: 0 highlightResizeDuration : 0 snapMode: ListView.SnapOneItem cacheBuffer: 0 keyNavigationEnabled : true keyNavigationWraps : true onMovementEnded: currentIndex = indexAt(contentX, contentY) delegate: Maui.Page { id: _delegate property bool isCurrentItem : ListView.isCurrentItem property url currentUrl: model.path property var iteminfo : model property alias infoModel : _infoModel height: _listView.height width: _listView.width title: model.label headBar.visible: true autoHideHeader: true floatingHeader: false //TODO needs some upstream fixes to work properly Loader { id: previewLoader active: _delegate.isCurrentItem && control.visible visible: !control.showInfo anchors.fill: parent clip: false onActiveChanged: if(active) show(currentUrl) } Kirigami.ScrollablePage { id: _infoContent anchors.fill: parent visible: control.showInfo Kirigami.Theme.backgroundColor: "transparent" padding: 0 leftPadding: padding rightPadding: padding topPadding: padding bottomPadding: padding ColumnLayout { width: parent.width spacing: 0 Rectangle { Layout.fillWidth: true Layout.preferredHeight: 100 color: Qt.darker(Kirigami.Theme.backgroundColor, 1.1) Kirigami.Icon { height: Maui.Style.iconSizes.large width: height anchors.centerIn: parent source: iteminfo.icon } } Kirigami.Separator { Layout.fillWidth: true } ListView { Layout.preferredHeight: contentHeight Layout.fillWidth: true Layout.margins: 0 spacing: 0 model: ListModel { id: _infoModel } - delegate: Rectangle + delegate: Maui.AlternateListItem { visible: model.value.length width: visible ? parent.width : 0 height: visible ? _delegateColumnInfo.implicitHeight + Maui.Style.space.large : 0 - color: index % 2 === 0 ? Kirigami.Theme.backgroundColor : Qt.darker(Kirigami.Theme.backgroundColor, 1.1) - - Kirigami.Separator - { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - } - + alt: index % 2 === 0 + Maui.ListItemTemplate { id: _delegateColumnInfo width: parent.width iconSource: "documentinfo" iconSizeHint: Maui.Style.iconSizes.medium anchors.centerIn: parent anchors.margins: Maui.Style.space.medium label1.text: model.key label1.font.weight: Font.Bold label1.font.bold: true label2.text: model.value label2.elide: Qt.ElideMiddle label2.wrapMode: Text.Wrap label2.font.weight: Font.Light } } } } } function show(path) { initModel() control.isDir = model.isdir == "true" control.currentUrl = path control.isFav = _tagsBar.list.contains("fav") var source = "private/DefaultPreview.qml" if(Maui.FM.checkFileType(Maui.FMList.AUDIO, iteminfo.mime)) { source = "private/AudioPreview.qml" } if(Maui.FM.checkFileType(Maui.FMList.VIDEO, iteminfo.mime)) { source = "private/VideoPreview.qml" } if(Maui.FM.checkFileType(Maui.FMList.TEXT, iteminfo.mime)) { source = "private/TextPreview.qml" } if(Maui.FM.checkFileType(Maui.FMList.IMAGE, iteminfo.mime)) { source = "private/ImagePreview.qml" } if(Maui.FM.checkFileType(Maui.FMList.DOCUMENT, iteminfo.mime) && !isAndroid) { source = "private/DocumentPreview.qml" } console.log("previe mime", iteminfo.mime) previewLoader.source = source control.showInfo = source === "private/DefaultPreview.qml" } function initModel() { infoModel.clear() infoModel.append({key: "Type", value: iteminfo.mime}) infoModel.append({key: "Date", value: iteminfo.date}) infoModel.append({key: "Modified", value: iteminfo.modified}) infoModel.append({key: "Last Read", value: iteminfo.lastread}) infoModel.append({key: "Owner", value: iteminfo.owner}) infoModel.append({key: "Group", value: iteminfo.group}) infoModel.append({key: "Size", value: Maui.FM.formatSize(iteminfo.size)}) infoModel.append({key: "Symbolic Link", value: iteminfo.symlink}) infoModel.append({key: "Path", value: iteminfo.path}) infoModel.append({key: "Icon Name", value: iteminfo.icon}) } } } Maui.TagsBar { id: _tagsBar position: ToolBar.Footer Layout.fillWidth: true Layout.margins: 0 list.urls: [control.currentUrl] list.strict: false allowEditMode: true onTagRemovedClicked: list.removeFromUrls(index) onTagsEdited: list.updateToUrls(tags) Kirigami.Theme.textColor: control.Kirigami.Theme.textColor Kirigami.Theme.backgroundColor: control.Kirigami.Theme.backgroundColor } } function show(model, index) { control.model = model _listView.currentIndex = index _listView.positionViewAtIndex(index,ListView.Center ) open() _listView.forceActiveFocus() } } diff --git a/src/controls/ListItemTemplate.qml b/src/controls/ListItemTemplate.qml index f19546d..f6153bf 100644 --- a/src/controls/ListItemTemplate.qml +++ b/src/controls/ListItemTemplate.qml @@ -1,327 +1,333 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.9 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.3 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import org.kde.mauikit 1.1 as MauiLab Item -{ +{ id: control default property alias content: _layout.data implicitHeight: Maui.Style.rowHeight // implicitWidth: _layout.implicitWidth property alias text1 : _label1.text property alias text2 : _label2.text property alias text3 : _label3.text property alias text4 : _label4.text property alias label1 : _label1 property alias label2 : _label2 property alias label3 : _label3 property alias label4 : _label4 property alias iconItem : _iconLoader.item property alias iconVisible : _iconContainer.visible property alias leftLabels : _leftLabels property alias rightLabels : _rightLabels + property alias spacing : _layout.spacing + property alias layout : _layout + property int iconSizeHint : Maui.Style.iconSizes.big property int imageSizeHint : iconSizeHint property int imageWidth : imageSizeHint property int imageHeight : imageSizeHint property string imageSource property string iconSource property bool checkable : false property bool checked : false property bool isCurrentItem: false property bool labelsVisible: true property bool hovered : false property int fillMode : Image.PreserveAspectCrop property int maskRadius: Maui.Style.radiusV - + + property bool imageBorder: true + signal toggled(bool state) Component { id: _imgComponent Image { id: img anchors.centerIn: parent source: control.imageSource height: Math.min(parent.height, control.imageSizeHint) width: height sourceSize.width:control.imageWidth sourceSize.height: control.imageHeight horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter fillMode: control.fillMode cache: true asynchronous: true smooth: false layer.enabled: control.maskRadius layer.effect: OpacityMask { maskSource: Item { width: img.width height: img.height Rectangle { anchors.fill: parent radius: control.maskRadius } } } Rectangle { anchors.fill: parent - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.8) + border.color: control.imageBorder ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.8) : "transparent" radius: control.maskRadius opacity: 0.2 color: control.hovered ? control.Kirigami.Theme.highlightColor : "transparent" Kirigami.Icon { anchors.centerIn: parent height: Math.min(22, parent.height * 0.7) width: height source: "folder-images" isMask: true color: parent.border.color opacity: 1 - img.progress } } } } Component { id: _iconComponent Item { Kirigami.Icon { source: control.iconSource anchors.centerIn: parent fallback: "qrc:/assets/application-x-zerosize.svg" height: Math.min(parent.height, control.iconSizeHint) width: height color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor ColorOverlay { visible: control.hovered opacity: 0.3 anchors.fill: parent source: parent color: control.Kirigami.Theme.highlightColor } } } } RowLayout { id: _layout anchors.fill: parent spacing: Maui.Style.space.tiny + Item {Layout.fillHeight: true} + Item { id: _checkBoxContainer visible: control.checkable || control.checked Layout.fillHeight: true Layout.preferredWidth: _emblem.size * 2 Maui.Badge { id: _emblem size: Math.min(Maui.Style.iconSizes.medium, parent.height) anchors.centerIn: parent color: control.checked ? Kirigami.Theme.highlightColor : Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.8) border.color: Kirigami.Theme.textColor - onClicked: { control.checked = !control.checked control.toggled(control.checked) } MauiLab.CheckMark { visible: opacity > 0 color: Kirigami.Theme.highlightedTextColor anchors.centerIn: parent height: control.checked ? 10 : 0 width: height opacity: control.checked ? 1 : 0 Behavior on height { NumberAnimation { duration: Kirigami.Units.shortDuration easing.type: Easing.InOutQuad } } Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration easing.type: Easing.InOutQuad } } } } } Item { id: _iconContainer visible: (control.width > Kirigami.Units.gridUnit * 10) && (iconSource.length > 0 || imageSource.length > 0) Layout.fillHeight: true Layout.fillWidth: !control.labelsVisible Layout.leftMargin: _checkBoxContainer.visible ? 0 : Maui.Style.space.tiny Layout.preferredWidth: Math.min(parent.height, Math.max(control.iconSizeHint, imageSizeHint) + Maui.Style.space.medium) Loader { id: _iconLoader width: Math.min(parent.height, Math.max(control.iconSizeHint, imageSizeHint) ) height: width anchors.centerIn: parent sourceComponent: _iconContainer.visible ? (control.imageSource ? _imgComponent : (control.iconSource ? _iconComponent : null) ): null } } ColumnLayout { id: _leftLabels visible: control.labelsVisible Layout.fillHeight: true Layout.fillWidth: true Layout.margins: Maui.Style.space.tiny Layout.leftMargin: _iconContainer.visible || _checkBoxContainer.visible ? 0 : Maui.Style.space.small spacing: 0 Label { id: _label1 visible: text.length Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: _label2.visible ? Qt.AlignBottom : Qt.AlignVCenter elide: Text.ElideMiddle wrapMode: Text.NoWrap color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor font.weight: Font.Normal font.pointSize: Maui.Style.fontSizes.default } Label { id: _label2 visible: text.length Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: _label1.visible ? Qt.AlignTop : Qt.AlignVCenter elide: Text.ElideRight wrapMode: Text.NoWrap color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 font.weight: Font.Normal font.pointSize: Maui.Style.fontSizes.medium } } ColumnLayout { id: _rightLabels visible: control.width > Kirigami.Units.gridUnit * 15 && control.labelsVisible Layout.fillHeight: true Layout.fillWidth: true Layout.margins: Maui.Style.space.tiny spacing: 0 Label { id: _label3 visible: text.length > 0 Layout.fillHeight: true Layout.fillWidth: true Layout.alignment: Qt.AlignRight horizontalAlignment: Qt.AlignRight font.pointSize: Maui.Style.fontSizes.small font.weight: Font.Light wrapMode: Text.NoWrap elide: Text.ElideMiddle color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 } Label { id: _label4 visible: text.length > 0 Layout.fillHeight: true Layout.fillWidth: true Layout.alignment: Qt.AlignRight horizontalAlignment: Qt.AlignRight font.pointSize: Maui.Style.fontSizes.small font.weight: Font.Light wrapMode: Text.NoWrap elide: Text.ElideMiddle color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 } } } } diff --git a/src/controls/NewDialog.qml b/src/controls/NewDialog.qml index 5699a58..245c2cc 100644 --- a/src/controls/NewDialog.qml +++ b/src/controls/NewDialog.qml @@ -1,24 +1,25 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import org.kde.kirigami 2.2 as Kirigami import org.kde.mauikit 1.0 as Maui Maui.Dialog { entryField: true signal finished(string text) - acceptText: i18n("Accept") - rejectText: i18n("Cancel") + acceptButton.text: i18n("Accept") + rejectButton.text: i18n("Cancel") + onAccepted: done() onRejected: textEntry.clear() page.margins: Maui.Style.space.huge function done() { finished(textEntry.text) textEntry.clear() close() } } diff --git a/src/controls/Page.qml b/src/controls/Page.qml index 97711ad..2b60aa5 100644 --- a/src/controls/Page.qml +++ b/src/controls/Page.qml @@ -1,24 +1,760 @@ /* * Copyright 2019 Camilo Higuita * * 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 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.13 +import QtQuick.Controls 2.13 +import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.0 -import org.kde.mauikit 1.1 as MauiLab +import org.kde.mauikit 1.2 as Maui +import org.kde.kirigami 2.7 as Kirigami -MauiLab.Page -{ } +Pane +{ + id: control + focus: true + + padding: 0 + leftPadding: control.padding + rightPadding: control.padding + topPadding: control.padding + bottomPadding: control.padding + + default property alias content: _content.data + property alias headerBackground : _headerBackground + readonly property alias internalHeight : _content.height + property Flickable flickable : null + property int footerPositioning : ListView.InlineFooter + property int headerPositioning : Kirigami.Settings.isMobile && flickable ? ListView.PullBackHeader : ListView.InlineHeader + + property string title + + property int margins: 0 + property int leftMargin : margins + property int rightMargin: margins + property int topMargin: margins + property int bottomMargin: margins + + property bool altHeader : false + + property bool autoHideHeader : false + property bool autoHideFooter : false + + property int autoHideHeaderMargins : Maui.Style.toolBarHeight + property int autoHideFooterMargins : Maui.Style.toolBarHeight + + property int autoHideFooterDelay : 1000 + property int autoHideHeaderDelay : 1000 + + property bool floatingHeader : control.flickable && control.flickable.contentHeight > control.height && !altHeader ? !_private.flickableAtStart : false + + property bool floatingFooter: control.flickable + + QtObject + { + id: _private + property bool flickableAtStart : control.flickable ? true : true + + property int topMargin : !control.altHeader ? (control.floatingHeader ? 0 : _headerContent.height) : 0 + property int bottomMargin: control.floatingFooter && control.footerPositioning === ListView.InlineFooter ? control.bottomMargin : control.bottomMargin + _footerContent.height + + Behavior on topMargin + { + enabled: control.header.visible && control.headerPositioning === ListView.InlineHeader && control.floatingHeader + NumberAnimation + { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + + } + + Binding + { + delayed: false + when: control.floatingFooter + target: control.flickable + property: "bottomMargin" + value: control.flickable && control.footer.visible && control.footerPositioning === ListView.InlineFooter ? _footerContent.height : 0 +// restoreMode: Binding.RestoreBindingOrValue + } + + Connections + { + target: control.flickable + enabled: control.flickable && control.flickable.contentHeight > _content.height + + onAtYBeginningChanged: + { + + if(control.headerPositioning !== ListView.InlineHeader || !control.header.visible || control.altHeader || control.flickable.contentHeight <= control.height) + { + return + } + + if(control.flickable.atYBeginning && !control.floatingHeader) + { + return + } + + if(!control.flickable.atYBeginning && control.floatingHeader) + { + return + } + + if(_private.flickableAtStart === control.flickable.atYBeginning) + { + return + } + + _private.flickableAtStart = flickable.atYBeginning + + console.log("AT START CHANGES", _private.flickableAtStart, control.flickable.atYBeginning, control.floatingHeader) + + } + } + + property bool showTitle : true + property alias headBar : _headBar + property alias footBar: _footBar + + Kirigami.Theme.colorSet: Kirigami.Theme.View + + signal goBackTriggered() + signal goForwardTriggered() + + background: Rectangle + { + color: Kirigami.Theme.backgroundColor + } + + onFlickableChanged: + { +// control.flickable.bottomMargin += control.floatingFooter && control.footer.visible ? _footerContent.height : 0 + returnToBounds() + } + + Connections + { + target: control.flickable ? control.flickable : null + enabled: control.flickable && ((control.header && control.headerPositioning === ListView.PullBackHeader) || (control.footer && control.footerPositioning === ListView.PullBackFooter)) + property int oldContentY + property bool updatingContentY: false + + onContentYChanged: + { + _headerAnimation.enabled = false + _footerAnimation.enabled = false + + if(!control.flickable.dragging && control.flickable.atYBeginning) + { + control.returnToBounds() + } + + if (updatingContentY || !control.flickable || !control.flickable.dragging) + { + oldContentY = control.flickable.contentY; + return; + //TODO: merge + //if moves but not dragging, just update oldContentY + } + + if(control.flickable.contentHeight < control.height) + { + return + } + + var oldFHeight + var oldHHeight + + if (control.footer && control.footerPositioning === ListView.PullBackFooter && control.footer.visible) + { + oldFHeight = control.footer.height + control.footer.height = Math.max(0, + Math.min(control.footer.implicitHeight, + control.footer.height + oldContentY - control.flickable.contentY)); + } + + if (control.header && control.headerPositioning === ListView.PullBackHeader && control.header.visible && !control.altHeader) + { + oldHHeight = control.header.height + control.header.height = Math.max(0, + Math.min(control.header.implicitHeight, + control.header.height + oldContentY - control.flickable.contentY)); + } + + //if the implicitHeight is changed, use that to simulate scroll + if (control.header && oldHHeight !== control.header.height && control.header.visible && !control.altHeader) + { + updatingContentY = true + control.flickable.contentY -= (oldHHeight - control.header.height) + updatingContentY = false + + } else { + oldContentY = control.flickable.contentY + } + } + + onMovementEnded: + { + if (control.header && control.header.visible && control.headerPositioning === ListView.PullBackHeader && !control.altHeader) + { + _headerAnimation.enabled = true + + if (control.header.height >= (control.header.implicitHeight/2) || control.flickable.atYBeginning ) + { + control.header.height = control.header.implicitHeight + + } else + { + control.header.height = 0 + } + } + + if (control.footer && control.footer.visible && control.footerPositioning === ListView.PullBackFooter) + { + _footerAnimation.enabled = true + + if (control.footer.height >= (control.footer.implicitHeight/2) || control.flickable.atYEnd) + { + if(control.flickable.atYEnd) + { + control.footer.height = control.footer.implicitHeight + + control.flickable.contentY = control.flickable.contentHeight - control.flickable.height + oldContentY = control.flickable.contentY + }else + { + control.footer.height = control.footer.implicitHeight + + } + + } else + { + control.footer.height = 0 + } + } + } + } + /* + Component.onCompleted: + { + if(control.header && control.header instanceof Maui.ToolBar) + { + control.header.visible = header.visibleCount > 0 + } + }*/ + + property Item header : Maui.ToolBar + { + id: _headBar + visible: visibleCount > 0 + width: visible ? parent.width : 0 + height: visible ? implicitHeight : 0 + + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Maui.Handy.isWindows ? Kirigami.Theme.View : Kirigami.Theme.Window + + /** to not break the visible binding just check the count state of the header and act upon it **/ +// readonly property bool hide : visibleCount === 0 +// onHideChanged: +// { +// if(!header.visible) +// { +// return +// } +// +// if(hide) +// { +// pullBackHeader() +// }else +// { +// pullDownHeader() +// } +// } + +// Label +// { +// visible: false +// color: "yellow" +// text: _headBar.visibleCount + " / " + _headBar.count + " - " + _headBar.height + " / " + header.height + " - " + _headBar.visible + " / " + header.visible +// } + + Behavior on height + { + id: _headerAnimation + enabled: false + NumberAnimation + { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + + Behavior on opacity + { + NumberAnimation + { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + + Component + { + id: _titleComponent + Label + { + text: control.title + elide : Text.ElideRight + font.bold : false + font.weight: Font.Bold + color : Kirigami.Theme.textColor + font.pointSize: Maui.Style.fontSizes.big + horizontalAlignment : Text.AlignHCenter + verticalAlignment : Text.AlignVCenter + } + } + + middleContent: Loader + { + visible: item + Layout.fillWidth: sourceComponent === _titleComponent + Layout.fillHeight: sourceComponent === _titleComponent + sourceComponent: control.title && control.showTitle ? _titleComponent : null + } + + background: Rectangle + { + id: _headerBackground + color: _headBar.Kirigami.Theme.backgroundColor + + Kirigami.Separator + { + id: _border + opacity: 0.6 + color: Qt.darker(parent.color, 2) + anchors.left: parent.left + anchors.right: parent.right + } + + Kirigami.Separator + { + id: _border2 + opacity: 0.4 + color: Qt.lighter(parent.color, 2.5) + anchors.left: parent.left + anchors.right: parent.right + anchors.bottomMargin: 1 + } + + FastBlur + { + anchors.fill: parent + visible: control.floatingHeader && !altHeader + opacity: 0.25 + + transparentBorder: false + source: ShaderEffectSource + { + samples : 0 + recursive: true + sourceItem: _content + sourceRect: Qt.rect(0, 0-control.topMargin, headBar.width, headBar.height) + } + radius: 64 + } + } + + } + +// Label +// { +// // visible: false +// z: 999999999999 +// color: "yellow" +// text: _footBar.visibleCount + " / " + _footBar.count + " - " + _footBar.height + " / " + footer.height + " - " + _footBar.visible + " / " + footer.visible +// } + + property Item footer : Maui.ToolBar + { + id: _footBar + visible: visibleCount > 0 + width: visible ? parent.width : 0 + height: visible ? implicitHeight : 0 + + position: ToolBar.Footer + + Behavior on height + { + id: _footerAnimation + enabled: false + NumberAnimation + { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + + background: Rectangle + { + color: _footBar.Kirigami.Theme.backgroundColor + + Kirigami.Separator + { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + } + + FastBlur + { + anchors.fill: parent + visible: control.floatingFooter + opacity: 0.4 + transparentBorder: false + source: ShaderEffectSource + { + samples : 0 + recursive: true + sourceItem: _content + sourceRect: Qt.rect(0, control.height - (footBar.height), footBar.width, footBar.height) + } + radius: 64 + } + } + } + + states: [ State + { + when: !altHeader && header.visible + + AnchorChanges + { + target: _headerContent + anchors.top: parent.top + anchors.bottom: undefined + } + + AnchorChanges + { + target: _border + anchors.top: undefined + anchors.bottom: parent.bottom + } + + AnchorChanges + { + target: _border2 + anchors.top: undefined + anchors.bottom: parent.bottom + } + + PropertyChanges + { + target: _headBar + position: ToolBar.Header + } + }, + + State + { + when: altHeader && header.visible + + AnchorChanges + { + target: _headerContent + anchors.top: undefined + anchors.bottom: parent.bottom + } + + AnchorChanges + { + target: _border + anchors.top: parent.top + anchors.bottom: undefined + } + + AnchorChanges + { + target: _border2 + anchors.top: parent.top + anchors.bottom: undefined + } + + + PropertyChanges + { + target: header + height: header.implicitHeight + } + + PropertyChanges + { + target: _headBar + position: ToolBar.Footer + } + } ] + + + onAutoHideHeaderChanged: pullDownHeader() + onAutoHideFooterChanged: pullDownFooter() + onAltHeaderChanged: pullDownHeader() + + + Column + { + id: _headerContent + anchors.left: parent.left + anchors.right: parent.right + children: header + z: _content.z+1 + } + +// Label +// { +// anchors.centerIn: _headerContent +// text: header.height + "/" + _headerContent.height + " - " + _layout.anchors.topMargin +// color: "orange" +// z: _headerContent.z + 1 +// visible: header.visible +// } + + Item + { + id: _layout + anchors.fill: parent + + anchors.bottomMargin: control.altHeader ? _headerContent.height : 0 + anchors.topMargin: _private.topMargin + + Item + { + id: _content + anchors.fill: parent + anchors.margins: control.margins + anchors.leftMargin: control.leftMargin + anchors.rightMargin: control.rightMargin + anchors.topMargin: control.topMargin + anchors.bottomMargin: _private.bottomMargin + } + + Column + { + id: _footerContent + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + children: footer + } + } + + Timer + { + id: _autoHideHeaderTimer + interval: autoHideHeaderDelay + onTriggered: + { + if(control.autoHideHeader && !control.altHeader) + { + pullBackHeader() + } + + stop() + } + } + + Timer + { + id: _autoHideFooterTimer + interval: control.autoHideFooterDelay + onTriggered: + { + if(control.autoHideFooter) + { + pullBackFooter() + } + + stop() + } + } + + Item + { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: visible ? _headerContent.height + control.autoHideHeaderMargins : 0 + z: _content.z +1 + visible: control.autoHideHeader && !control.altHeader && !Kirigami.Settings.isMobile + + HoverHandler + { + target: parent + acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus + + onHoveredChanged: + { + if(!control.autoHideHeader || control.altHeader) + { + _autoHideHeaderTimer.stop() + return + } + + if(!hovered) + { + _autoHideHeaderTimer.start() + + }else + { + pullDownHeader() + _autoHideHeaderTimer.stop() + } + } + } + } + + Item + { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: visible ? _footerContent.height + control.autoHideFooterMargins : 0 + z: _footerContent.z - 1 + visible: control.autoHideFooter && !control.altHeader && !Kirigami.Settings.isMobile + + HoverHandler + { + target: parent + + acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus + + onHoveredChanged: + { + if(!control.autoHideFooter) + { + return + } + + if(!hovered) + { + _autoHideFooterTimer.start() + + }else + { + pullDownFooter() + _autoHideFooterTimer.stop() + } + } + } + } + + + + // Item + // { + // anchors.fill: parent + // anchors.topMargin: header.height + // anchors.bottomMargin: footer.height + // z: _content.z + 9999 + // + // TapHandler + // { + // target: parent + // enabled: control.autoHideHeader && !control.altHeader + // + // grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.CanTakeOverFromAnything + // + // onSingleTapped: + // { + // if(!control.autoHideHeader) + // { + // return + // } + // console.log("Pgae tapped") + // header.visible = !header.visible + // } + // } + // } + + + + Keys.onBackPressed: + { + control.goBackTriggered(); + } + + Shortcut + { + sequence: "Forward" + onActivated: control.goForwardTriggered(); + } + + Shortcut + { + sequence: StandardKey.Forward + onActivated: control.goForwardTriggered(); + } + + Shortcut + { + sequence: StandardKey.Back + onActivated: control.goBackTriggered(); + } + + function returnToBounds() + { + if(control.header) + { + pullDownHeader() + } + + if(control.footer) + { + pullDownFooter() + } + } + + function pullBackHeader() + { + _headerAnimation.enabled = true + header.height= 0 + } + + function pullDownHeader() + { + _headerAnimation.enabled = true + header.height = header.implicitHeight + } + + function pullBackFooter() + { + _footerAnimation.enabled = true + footer.height= 0 + } + + function pullDownFooter() + { + _footerAnimation.enabled = true + footer.height = footer.implicitHeight + } + + +} diff --git a/src/controls/SelectionBar.qml b/src/controls/SelectionBar.qml index 7fa2e6a..f9be841 100644 --- a/src/controls/SelectionBar.qml +++ b/src/controls/SelectionBar.qml @@ -1,23 +1,489 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.10 +import QtQuick.Controls 2.10 +import QtQuick.Layouts 1.3 +import org.kde.kirigami 2.7 as Kirigami +import org.kde.mauikit 1.0 as Maui +import QtGraphicalEffects 1.0 -import org.kde.mauikit 1.1 as MauiLab - -MauiLab.SelectionBar {} +Item +{ + id: control + + implicitHeight: barHeight + padding + implicitWidth: _layout.implicitWidth + Maui.Style.space.big + (height * 2) + + visible: control.count > 0 + focus: true + + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Complementary + + default property list actions + property list hiddenActions + property int padding : 0 + property int barHeight: Maui.Style.toolBarHeightAlt + property int display : ToolButton.IconOnly + property int maxListHeight : 400 + property int radius: Maui.Style.radiusV + /** + * if singleSelection is set to true then only a single item is selected + * at time, and replaced with a newe item appended + **/ + property bool singleSelection: false + + readonly property alias uris: _private._uris + readonly property alias items: _private._items + + readonly property alias selectionList : selectionList + readonly property alias count : selectionList.count + + property alias background : bg + + readonly property QtObject m_private : QtObject + { + id: _private + property var _uris : [] + property var _items : [] + } + + property Component listDelegate: Maui.ItemDelegate + { + id: delegate + height: Maui.Style.rowHeight * 1.5 + width: parent.width + + Kirigami.Theme.backgroundColor: "transparent" + Kirigami.Theme.textColor: control.Kirigami.Theme.textColor + + onClicked: control.itemClicked(index) + onPressAndHold: control.itemPressAndHold(index) + + Maui.ListItemTemplate + { + id: _template + anchors.fill: parent + iconVisible: false + labelsVisible: true + label1.text: model.uri + + checkable: true + checked: true + onToggled: control.removeAtIndex(index) + } + } + + signal iconClicked() + signal cleared() + signal exitClicked() + signal itemClicked(int index) + signal itemPressAndHold(int index) + + signal itemAdded(var item) + signal itemRemoved(var item) + + signal uriAdded(string uri) + signal uriRemoved(string uri) + + signal clicked(var mouse) + signal rightClicked(var mouse) + + signal urisDropped(var uris) + + + Item + { + id: _container + anchors.centerIn: parent + implicitHeight: control.barHeight + width: parent.width + + Rectangle + { + id: _listContainer + property bool showList : false + height: showList ? Math.min(Math.min(400, control.maxListHeight), selectionList.contentHeight) + control.barHeight + Maui.Style.space.big : 0 + width: parent.width + color: Qt.lighter(Kirigami.Theme.backgroundColor) + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) + radius: control.radius + focus: true + y: ((height) * -1) + parent.implicitHeight + x: parent.x + + opacity: showList ? 1 : .97 + + Behavior on height + { + NumberAnimation + { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + + Behavior on opacity + { + NumberAnimation + { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + + + Maui.ListBrowser + { + anchors.fill: parent + anchors.topMargin: Maui.Style.space.medium + anchors.bottomMargin: _container.height + id: selectionList + padding: 0 + visible: _listContainer.height > 10 + spacing: Maui.Style.space.small + model: ListModel{} + background: null + + delegate: control.listDelegate + } + } + + DropShadow + { + id: rectShadow + anchors.fill: _listContainer + cached: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 8.0 + samples: 16 + color: "#333" + smooth: true + source: _listContainer + } + + + Rectangle + { + id: bg + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + radius: control.radius + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) + + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.RightButton | Qt.LeftButton + + onClicked: + { + if(!Kirigami.Settings.isMobile && mouse.button === Qt.RightButton) + control.rightClicked(mouse) + else + control.clicked(mouse) + } + + onPressAndHold : + { + if(Kirigami.Settings.isMobile) + control.rightClicked(mouse) + } + } + } + + + + RowLayout + { + id: _rowLayout + anchors.fill: parent + clip: true + spacing: 0 + + Maui.Badge + { + Kirigami.Theme.colorSet: control.Kirigami.Theme.colorSet + Layout.fillHeight: true + Layout.preferredWidth: height + Layout.margins: Maui.Style.space.tiny + radius: Maui.Style.radiusV + onClicked: control.exitClicked() + Kirigami.Theme.backgroundColor: Qt.darker(bg.color) + border.color: "transparent" + + Maui.X + { + height: Maui.Style.iconSizes.medium - 10 + width: height + anchors.centerIn: parent + color: parent.hovered ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.textColor + } + } + + Maui.ToolBar + { + id: _layout + clip: true + position: ToolBar.Footer + + Layout.fillWidth: true + Layout.fillHeight: true + preferredHeight: height + background: Item{} + leftSretch: false + rightSretch: false + middleContent: Repeater + { + model: control.actions + + ToolButton + { + action: modelData + display: control.display + Kirigami.Theme.colorSet: control.Kirigami.Theme.colorSet + + ToolTip.delay: 1000 + ToolTip.timeout: 5000 + ToolTip.visible: hovered || pressed && action.text + ToolTip.text: action.text + } + } + + rightContent: Maui.ToolButtonMenu + { + visible: content.length > 0 + content: control.hiddenActions + } + } + + Maui.Badge + { + id: _counter + Layout.fillHeight: true + Layout.preferredWidth: height + Layout.margins: Maui.Style.space.tiny + text: selectionList.count + radius: Maui.Style.radiusV + + Kirigami.Theme.backgroundColor: _listContainer.showList ? + Kirigami.Theme.highlightColor : Qt.darker(bg.color) + border.color: "transparent" + + onClicked: + { + _listContainer.showList = !_listContainer.showList + } + + Component.onCompleted: + { + _counter.item.font.pointSize= Maui.Style.fontSizes.big + + } + + SequentialAnimation + { + id: anim + + PropertyAnimation + { + target: _counter + property: "radius" + easing.type: Easing.InOutQuad + from: target.height + to: Maui.Style.radiusV + duration: 200 + } + } + + Maui.Rectangle + { + opacity: 0.3 + anchors.fill: parent + anchors.margins: 4 + visible: _counter.hovered + color: "transparent" + borderColor: "white" + solidBorder: false + } + + MouseArea + { + id: _mouseArea + anchors.fill: parent + propagateComposedEvents: true + property int startX + property int startY + Drag.active: drag.active + Drag.hotSpot.x: 0 + Drag.hotSpot.y: 0 + Drag.dragType: Drag.Automatic + Drag.supportedActions: Qt.CopyAction + Drag.keys: ["text/plain","text/uri-list"] + + onPressed: + { + if( mouse.source !== Qt.MouseEventSynthesizedByQt) + { + drag.target = _counter + _counter.grabToImage(function(result) + { + _mouseArea.Drag.imageSource = result.url + }) + + _mouseArea.Drag.mimeData = { "text/uri-list": control.uris.join("\n")} + + startX = _counter.x + startY = _counter.y + + }else mouse.accepted = false + } + + onReleased : + { + _counter.x = startX + _counter.y = startY + } + } + } + + } + + Maui.Rectangle + { + opacity: 0.2 + anchors.fill: parent + anchors.margins: 4 + visible: _dropArea.containsDrag + color: "transparent" + borderColor: "white" + solidBorder: false + } + } + + DropArea + { + id: _dropArea + anchors.fill: parent + onDropped: + { + control.urisDropped(drop.urls) + } + } + + Keys.onEscapePressed: + { + control.exitClicked(); + } + + Keys.onBackPressed: + { + control.exitClicked(); + event.accepted = true + } + + function clear() + { + _private._uris = [] + _private._items = [] + _listContainer.showList = false + selectionList.model.clear() + control.cleared() + } + + function itemAt(index) + { + if(index < 0 || index > selectionList.count) + return + return selectionList.model.get(index) + } + + function removeAtIndex(index) + { + if(index < 0) + return + + const item = selectionList.model.get(index) + const uri = item.uri + + if(contains(uri)) + { + _private._uris.splice(index, 1) + _private._items.splice(index, 1) + selectionList.model.remove(index) + control.itemRemoved(item) + control.uriRemoved(uri) + } + } + + function removeAtUri(uri) + { + removeAtIndex(indexOf(uri)) + } + + function indexOf(uri) + { + return _private._uris.indexOf(uri) + } + + function append(uri, item) + { + const index = _private._uris.indexOf(uri) + if(index < 0) + { + if(control.singleSelection) + clear() + + _private._items.push(item) + _private._uris.push(uri) + + item.uri = uri + selectionList.model.append(item) + selectionList.listView.positionViewAtEnd() + selectionList.currentIndex = selectionList.count - 1 + + control.itemAdded(item) + control.uriAdded(uri) + + }else + { + selectionList.currentIndex = index + // notify(item.icon, qsTr("Item already selected!"), String("The item '%1' is already in the selection box").arg(item.label), null, 4000) + } + + animate() + } + + function animate() + { + anim.running = true + } + + function getSelectedUrisString() + { + return String(""+_private._uris.join(",")) + } + + function contains(uri) + { + return _private._uris.includes(uri) + } +} diff --git a/src/controls/TagsDialog.qml b/src/controls/TagsDialog.qml index 9017584..f3118b9 100644 --- a/src/controls/TagsDialog.qml +++ b/src/controls/TagsDialog.qml @@ -1,168 +1,165 @@ import QtQuick 2.0 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import TagsModel 1.0 import TagsList 1.0 Maui.Dialog { id: control property alias taglist :_tagsList property alias listView: _listView property alias composerList: tagListComposer.list - acceptText: "OK" - rejectText: "Cancel" - signal tagsReady(var tags) defaultButtons: true maxHeight: Maui.Style.unit * 500 page.margins: Maui.Style.space.medium acceptButton.text: i18n("Add") rejectButton.text: i18n("Cancel") onAccepted: setTags() onRejected: close() headBar.visible: true headBar.leftContent: ToolButton { icon.name: "view-sort" onClicked: sortMenu.popup() Menu { id: sortMenu MenuItem { text: i18n("Sort by name") checkable: true autoExclusive: true checked: _tagsList.sortBy === TagsList.TAG onTriggered: _tagsList.sortBy = TagsList.TAG } MenuItem { text: i18n("Sort by date") checkable: true autoExclusive: true checked: _tagsList.sortBy === TagsList.ADD_DATE onTriggered: _tagsList.sortBy = TagsList.ADD_DATE } } } headBar.middleContent: Maui.TextField { id: tagText Layout.fillWidth: true placeholderText: i18n("Add a new tag...") onAccepted: { const tags = tagText.text.split(",") for(var i in tags) { const myTag = tags[i].trim() _tagsList.insert(myTag) tagListComposer.list.append(myTag) } clear() } } headBar.rightContent: ToolButton { icon.name: "view-refresh" onClicked: taglist.refresh() } ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true Item { Layout.fillHeight: true Layout.fillWidth: true Maui.ListBrowser { id: _listView anchors.fill: parent spacing: Maui.Style.space.tiny TagsModel { id: _tagsModel list: _tagsList } TagsList { id: _tagsList } holder.emoji: "qrc:/assets/Electricity.png" holder.visible: _listView.count === 0 holder.isMask: false holder.title : i18n("No tags!") holder.body: i18n("Start by creating tags") holder.emojiSize: Maui.Style.iconSizes.huge model: _tagsModel delegate: Maui.ListDelegate { id: delegate label: model.tag iconName: model.icon iconSize: Maui.Style.iconSizes.small radius: Maui.Style.radiusV Connections { target: delegate onClicked: { _listView.currentIndex = index tagListComposer.list.append(_tagsList.get(_listView.currentIndex ).tag) } } } } } Maui.TagList { id: tagListComposer Layout.fillWidth: true Layout.leftMargin: Maui.Style.contentMargins Layout.rightMargin: Maui.Style.contentMargins height: Maui.Style.rowHeight width: parent.width onTagRemoved: list.remove(index) placeholderText: "" } } onClosed: { composerList.urls = [] } function setTags() { var tags = [] for(var i = 0; i < tagListComposer.count; i++) tags.push(tagListComposer.list.get(i).tag) control.tagsReady(tags) close() } } diff --git a/src/controls/labs/AlternateListItem.qml b/src/controls/labs/AlternateListItem.qml new file mode 100644 index 0000000..5ddbbdf --- /dev/null +++ b/src/controls/labs/AlternateListItem.qml @@ -0,0 +1,42 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import org.kde.kirigami 2.9 as Kirigami +import org.kde.mauikit 1.2 as Maui + +Rectangle +{ + id: control + + property bool alt : false + default property alias content : _content.data + + // color: alt ? Kirigami.Theme.backgroundColor : Qt.darker(Kirigami.Theme.backgroundColor, 1.2) + color: Kirigami.Theme.backgroundColor + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: alt ? Kirigami.Theme.View : Kirigami.Theme.Window + Kirigami.Separator + { + opacity: 0.5 + color: Qt.darker(parent.color, 2.5) + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + } + + Kirigami.Separator + { + opacity: 0.3 + color: Qt.lighter(parent.color, 2.5) + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: 1 + } + + Item + { + id: _content + anchors.fill: parent + } +} diff --git a/src/controls/labs/Page.qml b/src/controls/labs/Page.qml deleted file mode 100644 index f7c06d8..0000000 --- a/src/controls/labs/Page.qml +++ /dev/null @@ -1,761 +0,0 @@ -/* - * Copyright 2019 Camilo Higuita - * - * 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 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.13 -//import QtQml 2.14 -import QtQuick.Controls 2.13 -import QtQuick.Layouts 1.3 -import org.kde.mauikit 1.0 as Maui -import org.kde.kirigami 2.7 as Kirigami -import QtQuick.Layouts 1.3 -import QtGraphicalEffects 1.0 - -Pane -{ - id: control - focus: true - - padding: 0 - leftPadding: control.padding - rightPadding: control.padding - topPadding: control.padding - bottomPadding: control.padding - - default property alias content: _content.data - property alias headerBackground : _headerBackground - readonly property alias internalHeight : _content.height - property Flickable flickable : null - property int footerPositioning : ListView.InlineFooter - property int headerPositioning : Kirigami.Settings.isMobile && flickable ? ListView.PullBackHeader : ListView.InlineHeader - - property string title - - property int margins: 0 - property int leftMargin : margins - property int rightMargin: margins - property int topMargin: margins - property int bottomMargin: margins - - property bool altHeader : false - - property bool autoHideHeader : false - property bool autoHideFooter : false - - property int autoHideHeaderMargins : Maui.Style.toolBarHeight - property int autoHideFooterMargins : Maui.Style.toolBarHeight - - property int autoHideFooterDelay : 1000 - property int autoHideHeaderDelay : 1000 - - property bool floatingHeader : control.flickable && control.flickable.contentHeight > control.height && !altHeader ? !_private.flickableAtStart : false - - property bool floatingFooter: control.flickable - - QtObject - { - id: _private - property bool flickableAtStart : control.flickable ? true : true - - property int topMargin : !control.altHeader ? (control.floatingHeader ? 0 : _headerContent.height) : 0 - property int bottomMargin: control.floatingFooter && control.footerPositioning === ListView.InlineFooter ? control.bottomMargin : control.bottomMargin + _footerContent.height - - Behavior on topMargin - { - enabled: control.header.visible && control.headerPositioning === ListView.InlineHeader && control.floatingHeader - NumberAnimation - { - duration: Kirigami.Units.shortDuration - easing.type: Easing.InOutQuad - } - } - - } - - Binding - { - delayed: false - when: control.floatingFooter - target: control.flickable - property: "bottomMargin" - value: control.flickable && control.footer.visible && control.footerPositioning === ListView.InlineFooter ? _footerContent.height : 0 -// restoreMode: Binding.RestoreBindingOrValue - } - - Connections - { - target: control.flickable - enabled: control.flickable && control.flickable.contentHeight > _content.height - - onAtYBeginningChanged: - { - - if(control.headerPositioning !== ListView.InlineHeader || !control.header.visible || control.altHeader || control.flickable.contentHeight <= control.height) - { - return - } - - if(control.flickable.atYBeginning && !control.floatingHeader) - { - return - } - - if(!control.flickable.atYBeginning && control.floatingHeader) - { - return - } - - if(_private.flickableAtStart === control.flickable.atYBeginning) - { - return - } - - _private.flickableAtStart = flickable.atYBeginning - - console.log("AT START CHANGES", _private.flickableAtStart, control.flickable.atYBeginning, control.floatingHeader) - - } - } - - property bool showTitle : true - property alias headBar : _headBar - property alias footBar: _footBar - - Kirigami.Theme.colorSet: Kirigami.Theme.View - - signal goBackTriggered() - signal goForwardTriggered() - - background: Rectangle - { - color: Kirigami.Theme.backgroundColor - } - - onFlickableChanged: - { -// control.flickable.bottomMargin += control.floatingFooter && control.footer.visible ? _footerContent.height : 0 - returnToBounds() - } - - Connections - { - target: control.flickable ? control.flickable : null - enabled: control.flickable && ((control.header && control.headerPositioning === ListView.PullBackHeader) || (control.footer && control.footerPositioning === ListView.PullBackFooter)) - property int oldContentY - property bool updatingContentY: false - - onContentYChanged: - { - _headerAnimation.enabled = false - _footerAnimation.enabled = false - - if(!control.flickable.dragging && control.flickable.atYBeginning) - { - control.returnToBounds() - } - - if (updatingContentY || !control.flickable || !control.flickable.dragging) - { - oldContentY = control.flickable.contentY; - return; - //TODO: merge - //if moves but not dragging, just update oldContentY - } - - if(control.flickable.contentHeight < control.height) - { - return - } - - var oldFHeight - var oldHHeight - - if (control.footer && control.footerPositioning === ListView.PullBackFooter && control.footer.visible) - { - oldFHeight = control.footer.height - control.footer.height = Math.max(0, - Math.min(control.footer.implicitHeight, - control.footer.height + oldContentY - control.flickable.contentY)); - } - - if (control.header && control.headerPositioning === ListView.PullBackHeader && control.header.visible && !control.altHeader) - { - oldHHeight = control.header.height - control.header.height = Math.max(0, - Math.min(control.header.implicitHeight, - control.header.height + oldContentY - control.flickable.contentY)); - } - - //if the implicitHeight is changed, use that to simulate scroll - if (control.header && oldHHeight !== control.header.height && control.header.visible && !control.altHeader) - { - updatingContentY = true - control.flickable.contentY -= (oldHHeight - control.header.height) - updatingContentY = false - - } else { - oldContentY = control.flickable.contentY - } - } - - onMovementEnded: - { - if (control.header && control.header.visible && control.headerPositioning === ListView.PullBackHeader && !control.altHeader) - { - _headerAnimation.enabled = true - - if (control.header.height >= (control.header.implicitHeight/2) || control.flickable.atYBeginning ) - { - control.header.height = control.header.implicitHeight - - } else - { - control.header.height = 0 - } - } - - if (control.footer && control.footer.visible && control.footerPositioning === ListView.PullBackFooter) - { - _footerAnimation.enabled = true - - if (control.footer.height >= (control.footer.implicitHeight/2) || control.flickable.atYEnd) - { - if(control.flickable.atYEnd) - { - control.footer.height = control.footer.implicitHeight - - control.flickable.contentY = control.flickable.contentHeight - control.flickable.height - oldContentY = control.flickable.contentY - }else - { - control.footer.height = control.footer.implicitHeight - - } - - } else - { - control.footer.height = 0 - } - } - } - } - /* - Component.onCompleted: - { - if(control.header && control.header instanceof Maui.ToolBar) - { - control.header.visible = header.visibleCount > 0 - } - }*/ - - property Item header : Maui.ToolBar - { - id: _headBar - visible: visibleCount > 0 - width: visible ? parent.width : 0 - height: visible ? implicitHeight : 0 - - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Maui.Handy.isWindows ? Kirigami.Theme.View : Kirigami.Theme.Window - - /** to not break the visible binding just check the count state of the header and act upon it **/ -// readonly property bool hide : visibleCount === 0 -// onHideChanged: -// { -// if(!header.visible) -// { -// return -// } -// -// if(hide) -// { -// pullBackHeader() -// }else -// { -// pullDownHeader() -// } -// } - -// Label -// { -// visible: false -// color: "yellow" -// text: _headBar.visibleCount + " / " + _headBar.count + " - " + _headBar.height + " / " + header.height + " - " + _headBar.visible + " / " + header.visible -// } - - Behavior on height - { - id: _headerAnimation - enabled: false - NumberAnimation - { - duration: Kirigami.Units.shortDuration - easing.type: Easing.InOutQuad - } - } - - Behavior on opacity - { - NumberAnimation - { - duration: Kirigami.Units.shortDuration - easing.type: Easing.InOutQuad - } - } - - Component - { - id: _titleComponent - Label - { - text: control.title - elide : Text.ElideRight - font.bold : false - font.weight: Font.Bold - color : Kirigami.Theme.textColor - font.pointSize: Maui.Style.fontSizes.big - horizontalAlignment : Text.AlignHCenter - verticalAlignment : Text.AlignVCenter - } - } - - middleContent: Loader - { - visible: item - Layout.fillWidth: sourceComponent === _titleComponent - Layout.fillHeight: sourceComponent === _titleComponent - sourceComponent: control.title && control.showTitle ? _titleComponent : null - } - - background: Rectangle - { - id: _headerBackground - color: _headBar.Kirigami.Theme.backgroundColor - - Kirigami.Separator - { - id: _border - opacity: 0.6 - color: Qt.darker(parent.color, 2) - anchors.left: parent.left - anchors.right: parent.right - } - - Kirigami.Separator - { - id: _border2 - opacity: 0.4 - color: Qt.lighter(parent.color, 2.5) - anchors.left: parent.left - anchors.right: parent.right - anchors.bottomMargin: 1 - } - - FastBlur - { - anchors.fill: parent - visible: control.floatingHeader && !altHeader - opacity: 0.25 - - transparentBorder: false - source: ShaderEffectSource - { - samples : 0 - recursive: true - sourceItem: _content - sourceRect: Qt.rect(0, 0-control.topMargin, headBar.width, headBar.height) - } - radius: 64 - } - } - - } - -// Label -// { -// // visible: false -// z: 999999999999 -// color: "yellow" -// text: _footBar.visibleCount + " / " + _footBar.count + " - " + _footBar.height + " / " + footer.height + " - " + _footBar.visible + " / " + footer.visible -// } - - property Item footer : Maui.ToolBar - { - id: _footBar - visible: visibleCount > 0 - width: visible ? parent.width : 0 - height: visible ? implicitHeight : 0 - - position: ToolBar.Footer - - Behavior on height - { - id: _footerAnimation - enabled: false - NumberAnimation - { - duration: Kirigami.Units.shortDuration - easing.type: Easing.InOutQuad - } - } - - background: Rectangle - { - color: _footBar.Kirigami.Theme.backgroundColor - - Kirigami.Separator - { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - } - - FastBlur - { - anchors.fill: parent - visible: control.floatingFooter - opacity: 0.4 - transparentBorder: false - source: ShaderEffectSource - { - samples : 0 - recursive: true - sourceItem: _content - sourceRect: Qt.rect(0, control.height - (footBar.height), footBar.width, footBar.height) - } - radius: 64 - } - } - } - - states: [ State - { - when: !altHeader && header.visible - - AnchorChanges - { - target: _headerContent - anchors.top: parent.top - anchors.bottom: undefined - } - - AnchorChanges - { - target: _border - anchors.top: undefined - anchors.bottom: parent.bottom - } - - AnchorChanges - { - target: _border2 - anchors.top: undefined - anchors.bottom: parent.bottom - } - - PropertyChanges - { - target: _headBar - position: ToolBar.Header - } - }, - - State - { - when: altHeader && header.visible - - AnchorChanges - { - target: _headerContent - anchors.top: undefined - anchors.bottom: parent.bottom - } - - AnchorChanges - { - target: _border - anchors.top: parent.top - anchors.bottom: undefined - } - - AnchorChanges - { - target: _border2 - anchors.top: parent.top - anchors.bottom: undefined - } - - - PropertyChanges - { - target: header - height: header.implicitHeight - } - - PropertyChanges - { - target: _headBar - position: ToolBar.Footer - } - } ] - - - onAutoHideHeaderChanged: pullDownHeader() - onAutoHideFooterChanged: pullDownFooter() - onAltHeaderChanged: pullDownHeader() - - - Column - { - id: _headerContent - anchors.left: parent.left - anchors.right: parent.right - children: header - z: _content.z+1 - } - -// Label -// { -// anchors.centerIn: _headerContent -// text: header.height + "/" + _headerContent.height + " - " + _layout.anchors.topMargin -// color: "orange" -// z: _headerContent.z + 1 -// visible: header.visible -// } - - Item - { - id: _layout - anchors.fill: parent - - anchors.bottomMargin: control.altHeader ? _headerContent.height : 0 - anchors.topMargin: _private.topMargin - - Item - { - id: _content - anchors.fill: parent - anchors.margins: control.margins - anchors.leftMargin: control.leftMargin - anchors.rightMargin: control.rightMargin - anchors.topMargin: control.topMargin - anchors.bottomMargin: _private.bottomMargin - } - - Column - { - id: _footerContent - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - children: footer - } - } - - Timer - { - id: _autoHideHeaderTimer - interval: autoHideHeaderDelay - onTriggered: - { - if(control.autoHideHeader && !control.altHeader) - { - pullBackHeader() - } - - stop() - } - } - - Timer - { - id: _autoHideFooterTimer - interval: control.autoHideFooterDelay - onTriggered: - { - if(control.autoHideFooter) - { - pullBackFooter() - } - - stop() - } - } - - Item - { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: visible ? _headerContent.height + control.autoHideHeaderMargins : 0 - z: _content.z +1 - visible: control.autoHideHeader && !control.altHeader && !Kirigami.Settings.isMobile - - HoverHandler - { - target: parent - acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus - - onHoveredChanged: - { - if(!control.autoHideHeader || control.altHeader) - { - _autoHideHeaderTimer.stop() - return - } - - if(!hovered) - { - _autoHideHeaderTimer.start() - - }else - { - pullDownHeader() - _autoHideHeaderTimer.stop() - } - } - } - } - - Item - { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: visible ? _footerContent.height + control.autoHideFooterMargins : 0 - z: _footerContent.z - 1 - visible: control.autoHideFooter && !control.altHeader && !Kirigami.Settings.isMobile - - HoverHandler - { - target: parent - - acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus - - onHoveredChanged: - { - if(!control.autoHideFooter) - { - return - } - - if(!hovered) - { - _autoHideFooterTimer.start() - - }else - { - pullDownFooter() - _autoHideFooterTimer.stop() - } - } - } - } - - - - // Item - // { - // anchors.fill: parent - // anchors.topMargin: header.height - // anchors.bottomMargin: footer.height - // z: _content.z + 9999 - // - // TapHandler - // { - // target: parent - // enabled: control.autoHideHeader && !control.altHeader - // - // grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.CanTakeOverFromAnything - // - // onSingleTapped: - // { - // if(!control.autoHideHeader) - // { - // return - // } - // console.log("Pgae tapped") - // header.visible = !header.visible - // } - // } - // } - - - - Keys.onBackPressed: - { - control.goBackTriggered(); - } - - Shortcut - { - sequence: "Forward" - onActivated: control.goForwardTriggered(); - } - - Shortcut - { - sequence: StandardKey.Forward - onActivated: control.goForwardTriggered(); - } - - Shortcut - { - sequence: StandardKey.Back - onActivated: control.goBackTriggered(); - } - - function returnToBounds() - { - if(control.header) - { - pullDownHeader() - } - - if(control.footer) - { - pullDownFooter() - } - } - - function pullBackHeader() - { - _headerAnimation.enabled = true - header.height= 0 - } - - function pullDownHeader() - { - _headerAnimation.enabled = true - header.height = header.implicitHeight - } - - function pullBackFooter() - { - _footerAnimation.enabled = true - footer.height= 0 - } - - function pullDownFooter() - { - _footerAnimation.enabled = true - footer.height = footer.implicitHeight - } - - -} diff --git a/src/controls/labs/SettingsDialog.qml b/src/controls/labs/SettingsDialog.qml index 40d2af6..36fb061 100644 --- a/src/controls/labs/SettingsDialog.qml +++ b/src/controls/labs/SettingsDialog.qml @@ -1,57 +1,54 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami -import org.kde.mauikit 1.0 as Maui -import org.kde.mauikit 1.1 as MauiLab +import org.kde.mauikit 1.2 as Maui Maui.Dialog { id: control default property alias content : _layout.data maxHeight: Math.min(_scrollView.contentHeight + Maui.Style.space.big, 500) + headBar.height maxWidth: 350 defaultButtons: false page.title: i18n("Settings") // page.flickable: _flickable headBar.visible: true acceptButton.text: i18n("Apply") rejectButton.text: i18n("Cancel") ScrollView { id: _scrollView Layout.fillWidth: true Layout.fillHeight: true contentHeight: _layout.implicitHeight Flickable { id: _flickable ColumnLayout { id: _layout width: parent.width spacing: 0 - } - - } - + } + } } Component.onCompleted: { for(var i in control.content) { - if(control.content[i] instanceof MauiLab.SettingsSection) + if(control.content[i] instanceof Maui.SettingsSection) { control.content[i].index = i } } } } diff --git a/src/controls/labs/SettingsSection.qml b/src/controls/labs/SettingsSection.qml index 6a790db..3164835 100644 --- a/src/controls/labs/SettingsSection.qml +++ b/src/controls/labs/SettingsSection.qml @@ -1,75 +1,62 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami -import org.kde.mauikit 1.0 as Maui -import org.kde.mauikit 1.1 as MauiLab +import org.kde.mauikit 1.2 as Maui -Rectangle +Maui.AlternateListItem { id: control default property alias content : _mainData.data - + property int index : -1 property alias title : _titleLabel.text property alias description : _descLabel.text + alt: index % 2 === 0 Layout.fillWidth: true implicitHeight: _layout.implicitHeight + (Maui.Style.space.huge + _layout.spacing) - property int index : -1 - ColumnLayout { id: _layout anchors.fill: parent anchors.margins: Maui.Style.space.big spacing: Maui.Style.space.small Label { id: _titleLabel Layout.fillWidth: true font.pointSize: Maui.Style.fontSizes.big font.bold: true font.weight: Font.Bold visible: text.length } Label { id: _descLabel Layout.fillWidth: true font.pointSize: Maui.Style.fontSizes.small font.bold: false visible: text.length wrapMode: Text.WordWrap elide: Qt.ElideRight opacity: 0.7 } // Item // { // visible: _descLabel.visible // Layout.fillWidth: true // Layout.preferredHeight: visible ? Maui.Style.space.small : 0 // } Kirigami.FormLayout { id: _mainData Layout.fillWidth: true // Layout.margins: Maui.Style.space.medium } - } - - Kirigami.Separator - { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - } - - color: Kirigami.Theme.backgroundColor - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: index % 2 === 0 ? Kirigami.Theme.View : Kirigami.Theme.Window + } } diff --git a/src/controls/private/AboutDialog.qml b/src/controls/private/AboutDialog.qml index 1d63940..8126cb9 100644 --- a/src/controls/private/AboutDialog.qml +++ b/src/controls/private/AboutDialog.qml @@ -1,247 +1,191 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.10 import QtQuick.Controls 2.10 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.12 -import org.kde.kirigami 2.7 as Kirigami -import org.kde.mauikit 1.0 as Maui +import org.kde.kirigami 2.13 as Kirigami +import org.kde.mauikit 1.2 as Maui Maui.Dialog { id: control defaultButtons: false - widthHint: 0.9 - heightHint: 0.8 - - maxWidth: Maui.Style.unit * 400 - maxHeight: Maui.Style.unit * 250 - - page.padding: 0 - footBar.visible: true - footBar.middleContent: ToolButton - { - icon.name: "link" - visible: true - onClicked: Qt.openUrlExternally(Maui.App.webPage) - } - - footBar.rightContent: ToolButton - { - icon.name: "love" - onClicked: Qt.openUrlExternally(Maui.App.donationPage) - } - - footBar.leftContent: ToolButton - { - icon.name: "documentinfo" - onClicked: Qt.openUrlExternally(Maui.App.reportPage) - } - - RowLayout - { - id: layout - Layout.fillWidth: true - Layout.fillHeight: true - spacing: Maui.Style.space.medium - - Item + persistent: false + widthHint: 0.9 + heightHint: 0.8 + + maxWidth: 400 + maxHeight: 300 + + page.padding: 0 + footBar.visible: true + footBar.middleContent: Button { - visible: parent.width > control.maxWidth * 0.7 - Layout.fillHeight: true - Layout.margins: Maui.Style.space.medium - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: Maui.Style.iconSizes.huge + Maui.Style.space.big - - Image - { - id: _imgIcon - anchors.centerIn: parent - source: Maui.App.iconName - width: Math.min(Maui.Style.iconSizes.huge, parent.width) - height: width - sourceSize.width: width - sourceSize.height: height - asynchronous: true - fillMode: Image.PreserveAspectFit - } - - DropShadow - { - anchors.fill: _imgIcon - horizontalOffset: 0 - verticalOffset: 0 - radius: 8.0 - samples: 17 - color: "#80000000" - source: _imgIcon - } + icon.name: "link" + text: i18n("Site") + onClicked: Qt.openUrlExternally(Maui.App.webPage) } - + + footBar.rightContent: Button + { + icon.name: "love" + text: i18n("Donate") + onClicked: Qt.openUrlExternally(Maui.App.donationPage) + } + + footBar.leftContent: Button + { + icon.name: "documentinfo" + text: i18n("Report") + onClicked: Qt.openUrlExternally(Maui.App.reportPage) + } + Kirigami.ScrollablePage { - id: _descriptionItem Layout.fillWidth: true Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Kirigami.Theme.backgroundColor: "transparent" - padding: Maui.Style.space.medium + padding: 0 leftPadding: padding rightPadding: padding - topPadding: padding*3 + topPadding: padding bottomPadding: padding - + ColumnLayout - { - id: _columnInfo - width: parent.width - spacing: Maui.Style.space.medium - - Label - { - Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft - color: Kirigami.Theme.textColor - text: Maui.App.displayName - font.weight: Font.Bold - font.bold: true - font.pointSize: Maui.Style.fontSizes.enormous * 1.3 - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - - Label + { + Maui.AlternateListItem { - Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft - color: Qt.lighter(Kirigami.Theme.textColor, 1.2) - text: Maui.App.version - font.weight: Font.Light - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Label - { - id: body - Layout.fillWidth: true - text: Maui.App.description - color: Kirigami.Theme.textColor - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Label - { - color: Kirigami.Theme.textColor - Layout.fillWidth: true - text: i18n("By ") + Maui.App.org - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Kirigami.Separator - { - Layout.fillWidth: true - Layout.margins: Maui.Style.space.tiny - opacity: 0.4 - } + Layout.fillWidth: true + implicitHeight: _div1.height + Maui.Style.space.huge + alt: true + Kirigami.Theme.backgroundColor: palette.background + Kirigami.Theme.textColor: palette.foreground + Kirigami.ImageColors + { + id: palette + source: Maui.App.name + } + + Maui.ListItemTemplate + { + id: _div1 + width: parent.width + height: Math.max(150, label2.implicitHeight + label1.implicitHeight) + anchors.centerIn: parent + imageBorder: false + imageSource: Maui.App.iconName + imageWidth: Math.min(Maui.Style.iconSizes.huge, parent.width) + imageHeight: imageWidth + fillMode: Image.PreserveAspectFit + imageSizeHint: imageWidth + + spacing: Maui.Style.space.big + label1.text: Maui.App.displayName + label1.font.weight: Font.Bold + label1.font.bold: true + label1.font.pointSize: Maui.Style.fontSizes.enormous * 1.3 + + label2.text: Maui.App.version + "\n" + Maui.App.description + "\n" + Maui.App.org + label2.font.pointSize: Maui.Style.fontSizes.default + label2.elide: Text.ElideRight + label2.wrapMode: Text.WrapAtWordBoundaryOrAnywhere + } + } - Label + Maui.AlternateListItem { - visible: _creditsRepeater.count > 0 - color: Kirigami.Theme.textColor Layout.fillWidth: true - text: i18n("Credits") - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Repeater - { - id: _creditsRepeater - model: Maui.App.credits + Layout.preferredHeight: _credits.contentHeight + Maui.Style.space.huge + alt: false - Column + ListView { - Label + id: _credits + spacing: Maui.Style.space.big + model: Maui.App.credits + width: parent.width + height: contentHeight + anchors.centerIn: parent + delegate: Maui.ListItemTemplate { - color: Kirigami.Theme.textColor - Layout.fillWidth: true - text: modelData.name - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Label - { - color: Kirigami.Theme.textColor - Layout.fillWidth: true - text: modelData.email - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - - Label - { - color: Kirigami.Theme.textColor - Layout.fillWidth: true - text: modelData.year - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - } - } + width: parent.width + iconSource: "animal" + iconSizeHint: Maui.Style.iconSizes.medium + spacing: Maui.Style.space.medium + label1.text: modelData.name + label2.text: modelData.email + label3.text: modelData.year + } + } } - Kirigami.Separator - { - Layout.fillWidth: true - Layout.margins: Maui.Style.space.tiny - opacity: 0.4 - } + // Label + // { + // visible: _creditsRepeater.count > 0 + // color: Kirigami.Theme.textColor + // Layout.fillWidth: true + // text: i18n("Credits") + // font.pointSize: Maui.Style.fontSizes.default + // elide: Text.ElideRight + // wrapMode: Text.WrapAtWordBoundaryOrAnywhere + // } + // + // + // + // Kirigami.Separator + // { + // Layout.fillWidth: true + // Layout.margins: Maui.Style.space.tiny + // opacity: 0.4 + // } - Label + Maui.AlternateListItem { - color: Kirigami.Theme.textColor Layout.fillWidth: true + Layout.preferredHeight: _poweredBy.implicitHeight + Maui.Style.space.huge + alt: true - text: i18n("Powered by") + " MauiKit " + - Maui.App.mauikitVersion + " and Kirigami" - font.pointSize: Maui.Style.fontSizes.default - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - - onLinkActivated: Qt.openUrlExternally(link) + Maui.ListItemTemplate + { + id: _poweredBy + anchors.centerIn: parent + width: parent.width + iconSource: "code-context" + iconSizeHint: Maui.Style.iconSizes.medium + spacing: Maui.Style.space.medium + label1.text: "Powered by" + label2.text: "MauiKit " + + Maui.App.mauikitVersion + " and Kirigami" + Connections + { + target: _poweredBy.label2 + onLinkActivated: Qt.openUrlExternally(link) + } + } } } } - } + } diff --git a/src/controls/qmldir b/src/controls/qmldir index 176f426..cce8101 100644 --- a/src/controls/qmldir +++ b/src/controls/qmldir @@ -1,81 +1,84 @@ module org.kde.mauikit plugin MauiKit classname MauiKit -depends QtQuick.Controls 2.10 +depends QtQuick.Controls 2.13 depends QtQuick.Controls.Private 2.10 depends QtQuick.Controls 2.10 depends QtGraphicalEffects 1.0 designersupported typeinfo plugins.qmltypes singleton Style 1.0 Style.qml ApplicationWindow 1.0 ApplicationWindow.qml ToolBar 1.0 ToolBar.qml Page 1.0 Page.qml ShareDialog 1.0 ShareDialog.qml OpenWithDialog 1.0 OpenWithDialog.qml PieButton 1.0 PieButton.qml SideBar 1.0 SideBar.qml AbstractSideBar 1.0 AbstractSideBar.qml ListDelegate 1.0 ListDelegate.qml ItemDelegate 1.0 ItemDelegate.qml SwipeItemDelegate 1.0 SwipeItemDelegate.qml SwipeBrowserDelegate 1.0 SwipeBrowserDelegate.qml ListBrowserDelegate 1.0 ListBrowserDelegate.qml GridBrowserDelegate 1.0 GridBrowserDelegate.qml SelectionBar 1.0 SelectionBar.qml LabelDelegate 1.0 LabelDelegate.qml NewDialog 1.0 NewDialog.qml TagsBar 1.0 TagsBar.qml TagsDialog 1.0 TagsDialog.qml Taglist 1.0 private/TagList.qml GridBrowser 1.0 GridBrowser.qml ListBrowser 1.0 ListBrowser.qml FileBrowser 1.0 FileBrowser.qml FilePreviewer 1.0 FilePreviewer.qml FileDialog 1.0 FileDialog.qml PlacesListBrowser 1.0 PlacesListBrowser.qml PathBar 1.0 PathBar.qml Dialog 1.0 Dialog.qml Popup 1.0 Popup.qml TextField 1.0 TextField.qml Badge 1.0 Badge.qml GridView 1.0 GridView.qml Terminal 1.0 Terminal.qml SyncDialog 1.0 SyncDialog.qml SyncDialog 1.0 SyncDialogA.qml Editor 1.0 Editor.qml ColorsBar 1.0 ColorsBar.qml Holder 1.0 Holder.qml ImageViewer 1.0 ImageViewer.qml TabBar 1.0 TabBar.qml TabButton 1.0 TabButton.qml -ActionGroup 1.0 ActionGroup.qml ActionSideBar 1.0 ActionSideBar.qml ToolActions 1.0 ToolActions.qml DocumentPreview 1.0 DocumentPreview.qml ToolButtonMenu 1.0 ToolButtonMenu.qml ListItemTemplate 1.0 ListItemTemplate.qml GridItemTemplate 1.0 GridItemTemplate.qml FloatingButton 1.0 FloatingButton.qml -SelectionBar 1.1 labs/SelectionBar.qml -ShareDialog 1.1 labs/ShareDialog.qml -ActionToolBar 1.1 labs/ActionToolBar.qml -ToolButtonAction 1.1 labs/ToolButtonAction.qml -AppViews 1.1 labs/AppViews.qml -AppViewLoader 1.1 labs/AppViewLoader.qml -AltBrowser 1.1 labs/AltBrowser.qml -TabsBrowser 1.1 labs/TabsBrowser.qml -SettingsDialog 1.1 labs/SettingsDialog.qml -SettingsSection 1.1 labs/SettingsSection.qml - X 1.0 private/shapes/X.qml PlusSign 1.0 private/shapes/PlusSign.qml Arrow 1.0 private/shapes/Arrow.qml Triangle 1.0 private/shapes/Triangle.qml CheckMark 1.0 private/shapes/CheckMark.qml Rectangle 1.0 private/shapes/Rectangle.qml +AppViews 1.1 AppViews.qml +AppViewLoader 1.1 AppViewLoader.qml +AltBrowser 1.1 AltBrowser.qml +SelectionBar 1.1 SelectionBar.qml + +ShareDialog 1.1 labs/ShareDialog.qml +ActionToolBar 1.1 labs/ActionToolBar.qml +ToolButtonAction 1.1 labs/ToolButtonAction.qml + +TabsBrowser 1.1 labs/TabsBrowser.qml +SettingsDialog 1.1 labs/SettingsDialog.qml +SettingsSection 1.1 labs/SettingsSection.qml +Doodle 1.1 labs/Doodle.qml + +AlternateListItem 1.2 labs/AlternateListItem.qml diff --git a/src/mauikit.cpp b/src/mauikit.cpp index 0bb3d6f..aba33f4 100644 --- a/src/mauikit.cpp +++ b/src/mauikit.cpp @@ -1,267 +1,272 @@ /* * Copyright 2018 Camilo Higuita * * 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 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. */ #include "mauikit.h" #include #include "appview.h" #include "fmstatic.h" #include "handy.h" #include "mauiapp.h" #include "mauilist.h" #include "mauimodel.h" #include "pathlist.h" #ifdef COMPONENT_ACCOUNTS #include "mauiaccounts.h" #endif #ifdef COMPONENT_FM #include "fm.h" #include "fmlist.h" #include "placeslist.h" #endif #ifdef COMPONENT_TAGGING #include "tagslist.h" #include "tagsmodel.h" #endif #ifdef COMPONENT_STORE #include "storelist.h" #include "storemodel.h" #endif #ifdef COMPONENT_EDITOR #include "documenthandler.h" #endif #ifdef Q_OS_ANDROID #include "mauiandroid.h" #elif defined Q_OS_LINUX #include "mauikde.h" #endif #ifdef MAUIKIT_STYLE #include #include #endif QUrl MauiKit::componentUrl(const QString &fileName) const { #ifdef MAUI_APP return QUrl(QStringLiteral("qrc:/maui/kit/") + fileName); #else return QUrl(resolveFileUrl(fileName)); #endif } void MauiKit::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.mauikit")); qmlRegisterSingletonType(componentUrl(QStringLiteral("Style.qml")), uri, 1, 0, "Style"); qmlRegisterType(componentUrl(QStringLiteral("ToolBar.qml")), uri, 1, 0, "ToolBar"); qmlRegisterType(componentUrl(QStringLiteral("ApplicationWindow.qml")), uri, 1, 0, "ApplicationWindow"); qmlRegisterType(componentUrl(QStringLiteral("Page.qml")), uri, 1, 0, "Page"); qmlRegisterType(componentUrl(QStringLiteral("ShareDialog.qml")), uri, 1, 0, "ShareDialog"); qmlRegisterType(componentUrl(QStringLiteral("OpenWithDialog.qml")), uri, 1, 0, "OpenWithDialog"); qmlRegisterType(componentUrl(QStringLiteral("PieButton.qml")), uri, 1, 0, "PieButton"); qmlRegisterType(componentUrl(QStringLiteral("SideBar.qml")), uri, 1, 0, "SideBar"); qmlRegisterType(componentUrl(QStringLiteral("AbstractSideBar.qml")), uri, 1, 0, "AbstractSideBar"); qmlRegisterType(componentUrl(QStringLiteral("Holder.qml")), uri, 1, 0, "Holder"); qmlRegisterType(componentUrl(QStringLiteral("GlobalDrawer.qml")), uri, 1, 0, "GlobalDrawer"); qmlRegisterType(componentUrl(QStringLiteral("ListDelegate.qml")), uri, 1, 0, "ListDelegate"); qmlRegisterType(componentUrl(QStringLiteral("ListBrowserDelegate.qml")), uri, 1, 0, "ListBrowserDelegate"); qmlRegisterType(componentUrl(QStringLiteral("SwipeItemDelegate.qml")), uri, 1, 0, "SwipeItemDelegate"); qmlRegisterType(componentUrl(QStringLiteral("SwipeBrowserDelegate.qml")), uri, 1, 0, "SwipeBrowserDelegate"); qmlRegisterType(componentUrl(QStringLiteral("ItemDelegate.qml")), uri, 1, 0, "ItemDelegate"); qmlRegisterType(componentUrl(QStringLiteral("GridBrowserDelegate.qml")), uri, 1, 0, "GridBrowserDelegate"); qmlRegisterType(componentUrl(QStringLiteral("SelectionBar.qml")), uri, 1, 0, "SelectionBar"); qmlRegisterType(componentUrl(QStringLiteral("LabelDelegate.qml")), uri, 1, 0, "LabelDelegate"); qmlRegisterType(componentUrl(QStringLiteral("NewDialog.qml")), uri, 1, 0, "NewDialog"); qmlRegisterType(componentUrl(QStringLiteral("Dialog.qml")), uri, 1, 0, "Dialog"); qmlRegisterType(componentUrl(QStringLiteral("Popup.qml")), uri, 1, 0, "Popup"); qmlRegisterType(componentUrl(QStringLiteral("TextField.qml")), uri, 1, 0, "TextField"); qmlRegisterType(componentUrl(QStringLiteral("Badge.qml")), uri, 1, 0, "Badge"); qmlRegisterType(componentUrl(QStringLiteral("GridView.qml")), uri, 1, 0, "GridView"); qmlRegisterType(componentUrl(QStringLiteral("ColorsBar.qml")), uri, 1, 0, "ColorsBar"); qmlRegisterType(componentUrl(QStringLiteral("ImageViewer.qml")), uri, 1, 0, "ImageViewer"); qmlRegisterType(componentUrl(QStringLiteral("TabBar.qml")), uri, 1, 0, "TabBar"); qmlRegisterType(componentUrl(QStringLiteral("TabButton.qml")), uri, 1, 0, "TabButton"); qmlRegisterType(componentUrl(QStringLiteral("ActionSideBar.qml")), uri, 1, 0, "ActionSideBar"); qmlRegisterType(componentUrl(QStringLiteral("ToolActions.qml")), uri, 1, 0, "ToolActions"); qmlRegisterType(componentUrl(QStringLiteral("ToolButtonMenu.qml")), uri, 1, 0, "ToolButtonMenu"); qmlRegisterType(componentUrl(QStringLiteral("ListItemTemplate.qml")), uri, 1, 0, "ListItemTemplate"); qmlRegisterType(componentUrl(QStringLiteral("GridItemTemplate.qml")), uri, 1, 0, "GridItemTemplate"); qmlRegisterType(componentUrl(QStringLiteral("FloatingButton.qml")), uri, 1, 0, "FloatingButton"); qmlRegisterType(componentUrl(QStringLiteral("PathBar.qml")), uri, 1, 0, "PathBar"); qmlRegisterType(uri, 1, 0, "PathList"); /** Shapes **/ qmlRegisterType(componentUrl(QStringLiteral("private/shapes/X.qml")), uri, 1, 0, "X"); qmlRegisterType(componentUrl(QStringLiteral("private/shapes/PlusSign.qml")), uri, 1, 0, "PlusSign"); qmlRegisterType(componentUrl(QStringLiteral("private/shapes/Arrow.qml")), uri, 1, 0, "Arrow"); qmlRegisterType(componentUrl(QStringLiteral("private/shapes/Triangle.qml")), uri, 1, 0, "Triangle"); qmlRegisterType(componentUrl(QStringLiteral("private/shapes/CheckMark.qml")), uri, 1, 0, "CheckMark"); qmlRegisterType(componentUrl(QStringLiteral("private/shapes/Rectangle.qml")), uri, 1, 0, "Rectangle"); /** 1.1 **/ - qmlRegisterType(componentUrl(QStringLiteral("labs/SelectionBar.qml")), uri, 1, 1, "SelectionBar"); qmlRegisterType(componentUrl(QStringLiteral("labs/ShareDialog.qml")), uri, 1, 1, "ShareDialog"); qmlRegisterType(componentUrl(QStringLiteral("labs/ActionToolBar.qml")), uri, 1, 1, "ActionToolBar"); qmlRegisterType(componentUrl(QStringLiteral("labs/ToolButtonAction.qml")), uri, 1, 1, "ToolButtonAction"); - qmlRegisterType(componentUrl(QStringLiteral("labs/AppViews.qml")), uri, 1, 1, "AppViews"); - qmlRegisterType(componentUrl(QStringLiteral("labs/AppViewLoader.qml")), uri, 1, 1, "AppViewLoader"); - qmlRegisterType(componentUrl(QStringLiteral("labs/AltBrowser.qml")), uri, 1, 1, "AltBrowser"); + qmlRegisterType(componentUrl(QStringLiteral("AppViews.qml")), uri, 1, 1, "AppViews"); + qmlRegisterType(componentUrl(QStringLiteral("AppViewLoader.qml")), uri, 1, 1, "AppViewLoader"); + qmlRegisterType(componentUrl(QStringLiteral("AltBrowser.qml")), uri, 1, 1, "AltBrowser"); + qmlRegisterType(componentUrl(QStringLiteral("labs/TabsBrowser.qml")), uri, 1, 1, "TabsBrowser"); qmlRegisterType(componentUrl(QStringLiteral("labs/SettingsDialog.qml")), uri, 1, 1, "SettingsDialog"); qmlRegisterType(componentUrl(QStringLiteral("labs/SettingsSection.qml")), uri, 1, 1, "SettingsSection"); - qmlRegisterType(componentUrl(QStringLiteral("labs/Page.qml")), uri, 1, 1, "Page"); qmlRegisterType(componentUrl(QStringLiteral("labs/Doodle.qml")), uri, 1, 1, "Doodle"); - + + /** 1.2 **/ + qmlRegisterType(componentUrl(QStringLiteral("labs/AlternateListItem.qml")), uri, 1, 2, "AlternateListItem"); + + + /// NON UI CONTROLS qmlRegisterUncreatableType(uri, 1, 1, "AppView", "Cannot be created App"); /** Experimental **/ #ifdef Q_OS_WIN32 qmlRegisterType(componentUrl(QStringLiteral("labs/WindowControlsWindows.qml")), uri, 1, 1, "WindowControls"); #elif defined Q_OS_MAC qmlRegisterType(componentUrl(QStringLiteral("labs/WindowControlsMac.qml")), uri, 1, 1, "WindowControls"); #elif defined Q_OS_ANDROID qmlRegisterType(componentUrl(QStringLiteral("labs/WindowControlsWindows.qml")), uri, 1, 1, "WindowControls"); #elif defined Q_OS_LINUX && !defined Q_OS_ANDROID qmlRegisterType(componentUrl(QStringLiteral("labs/CSDControls.qml")), uri, 1, 1, "CSDControls"); qmlRegisterType(componentUrl(QStringLiteral("labs/WindowControlsLinux.qml")), uri, 1, 1, "WindowControls"); #endif /** STORE CONTROLS, MODELS AND INTERFACES **/ #ifdef COMPONENT_STORE qmlRegisterType("StoreList", 1, 0, "StoreList"); qmlRegisterType("StoreModel", 1, 0, "StoreModel"); qmlRegisterType(componentUrl(QStringLiteral("private/StoreDelegate.qml")), uri, 1, 0, "StoreDelegate"); qmlRegisterType(componentUrl(QStringLiteral("Store.qml")), uri, 1, 0, "Store"); #endif /** BROWSING CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("ListBrowser.qml")), uri, 1, 0, "ListBrowser"); qmlRegisterType(componentUrl(QStringLiteral("GridBrowser.qml")), uri, 1, 0, "GridBrowser"); /** FM CONTROLS, MODELS AND INTERFACES **/ #ifdef COMPONENT_FM qmlRegisterType(uri, 1, 0, "PlacesList"); qmlRegisterType(uri, 1, 0, "FMList"); qmlRegisterSingletonType(uri, 1, 0, "FM", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new FMStatic; }); qmlRegisterType(componentUrl(QStringLiteral("FileBrowser.qml")), uri, 1, 0, "FileBrowser"); qmlRegisterType(componentUrl(QStringLiteral("PlacesListBrowser.qml")), uri, 1, 0, "PlacesListBrowser"); qmlRegisterType(componentUrl(QStringLiteral("FilePreviewer.qml")), uri, 1, 0, "FilePreviewer"); qmlRegisterType(componentUrl(QStringLiteral("FileDialog.qml")), uri, 1, 0, "FileDialog"); #endif #ifdef COMPONENT_EDITOR /** EDITOR CONTROLS **/ qmlRegisterType(uri, 1, 0, "DocumentHandler"); qmlRegisterType(); qmlRegisterType(); qmlRegisterType(componentUrl(QStringLiteral("Editor.qml")), uri, 1, 0, "Editor"); qmlRegisterType(componentUrl(QStringLiteral("private/DocumentPreview.qml")), uri, 1, 0, "DocumentPreview"); #endif /** PLATFORMS SPECIFIC CONTROLS **/ #if defined Q_OS_LINUX || defined Q_OS_MACOS qmlRegisterType(componentUrl(QStringLiteral("Terminal.qml")), uri, 1, 0, "Terminal"); #endif #ifdef Q_OS_ANDROID qmlRegisterSingletonType(uri, 1, 0, "Android", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new MAUIAndroid; }); #elif defined Q_OS_LINUX qmlRegisterUncreatableType(uri, 1, 0, "KDE", "Cannot be created KDE"); #elif defined Q_OS_WIN32 // here window platform integration interfaces #endif /** DATA MODELING TEMPLATED INTERFACES **/ qmlRegisterType(); // ABSTRACT BASE LIST qmlRegisterType(uri, 1, 0, "BaseModel"); // BASE MODEL #ifdef COMPONENT_TAGGING /** TAGGING INTERFACES AND MODELS **/ qmlRegisterType("TagsList", 1, 0, "TagsList"); qmlRegisterType("TagsModel", 1, 0, "TagsModel"); qmlRegisterType(componentUrl(QStringLiteral("private/TagList.qml")), uri, 1, 0, "TagList"); qmlRegisterType(componentUrl(QStringLiteral("TagsBar.qml")), uri, 1, 0, "TagsBar"); qmlRegisterType(componentUrl(QStringLiteral("TagsDialog.qml")), uri, 1, 0, "TagsDialog"); #endif /** MAUI APPLICATION SPECIFIC PROPS **/ #ifdef COMPONENT_ACCOUNTS qmlRegisterType(); qmlRegisterType(componentUrl(QStringLiteral("SyncDialog.qml")), uri, 1, 0, "SyncDialog"); // to be rename to accountsDialog -#endif - qmlRegisterUncreatableType(uri, 1, 0, "App", "Cannot be created App"); - - /** HELPERS **/ - qmlRegisterSingletonType(uri, 1, 0, "Handy", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { - Q_UNUSED(engine) - Q_UNUSED(scriptEngine) - return new Handy; - }); - +#endif + + /** HELPERS **/ + qmlRegisterUncreatableType(uri, 1, 0, "App", "Cannot be created App"); + qmlRegisterSingletonType(uri, 1, 0, "Handy", + [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + return new Handy; + }); + /** MAUI PLUGIN SUPPORT **/ #ifdef SUPPORT_PLUGINS qmlRegisterType(componentUrl(QStringLiteral("AppViewsPlugin.qml")), uri, 1, 2, "AppViewsPlugin"); qmlRegisterType(componentUrl(QStringLiteral("PagePlugin.qml")), uri, 1, 2, "PagePlugin"); qmlRegisterType(componentUrl(QStringLiteral("PluginManager.qml")), uri, 1, 2, "PluginManager"); qmlRegisterType(componentUrl(QStringLiteral("PluginsInfo.qml")), uri, 1, 2, "PluginsInfo"); #endif this->initResources(); qmlProtectModule(uri, 1); } void MauiKit::initResources() { #ifdef MAUIKIT_STYLE Q_INIT_RESOURCE(mauikit); #ifdef ICONS_PNG Q_INIT_RESOURCE(icons_png); #else Q_INIT_RESOURCE(icons); #endif Q_INIT_RESOURCE(style); QIcon::setThemeSearchPaths({":/icons/luv-icon-theme"}); QIcon::setThemeName("Luv"); QQuickStyle::setStyle(":/style"); #endif } //#include "moc_mauikit.cpp" diff --git a/src/mauikit.qrc b/src/mauikit.qrc index b1ac8b6..0a4e5b3 100644 --- a/src/mauikit.qrc +++ b/src/mauikit.qrc @@ -1,100 +1,99 @@ controls/ToolBar.qml controls/AbstractSideBar.qml controls/SideBar.qml controls/ApplicationWindow.qml controls/Style.qml controls/ShareDialog.qml controls/labs/ShareDialog.qml controls/labs/ShareDialogLinux.qml controls/OpenWithDialog.qml controls/PieButton.qml controls/Page.qml controls/private/PathBarDelegate.qml controls/private/EdgeShadow.qml controls/private/BrowserMenu.qml controls/private/BrowserView.qml controls/private/BrowserSettings.qml controls/private/BrowserHolder.qml controls/private/FileMenu.qml controls/private/AudioPreview.qml controls/private/ImagePreview.qml controls/private/TextPreview.qml controls/private/VideoPreview.qml controls/private/DocumentPreview.qml controls/private/DefaultPreview.qml controls/private/AccountsHelper.qml controls/private/BasicToolButton.qml controls/Holder.qml controls/ListDelegate.qml controls/ItemDelegate.qml controls/SwipeItemDelegate.qml controls/SwipeBrowserDelegate.qml controls/GridBrowserDelegate.qml controls/ListBrowserDelegate.qml controls/GlobalDrawer.qml controls/SelectionBar.qml controls/LabelDelegate.qml controls/NewDialog.qml controls/TagsBar.qml controls/TagsDialog.qml controls/private/TagList.qml controls/private/TagDelegate.qml controls/ColorsBar.qml controls/FileBrowser.qml controls/FilePreviewer.qml controls/FileDialog.qml controls/ListBrowser.qml controls/PathBar.qml controls/GridBrowser.qml controls/Dialog.qml controls/private/AboutDialog.qml controls/Popup.qml controls/TextField.qml controls/Badge.qml controls/GridView.qml controls/SyncDialog.qml controls/Terminal.qml controls/Editor.qml controls/PlacesListBrowser.qml controls/Store.qml controls/ImageViewer.qml controls/TabBar.qml controls/TabButton.qml controls/private/ActionGroup.qml controls/ActionSideBar.qml controls/private/StoreDelegate.qml controls/ToolActions.qml controls/ToolButtonMenu.qml controls/ListItemTemplate.qml controls/FloatingButton.qml - controls/labs/SelectionBar.qml controls/GridItemTemplate.qml controls/private/shapes/Arrow.qml controls/private/shapes/X.qml controls/private/shapes/Triangle.qml controls/private/shapes/CheckMark.qml controls/private/shapes/PlusSign.qml controls/private/shapes/Rectangle.qml controls/labs/CSDControls.qml controls/labs/ActionToolBar.qml controls/labs/ToolButtonAction.qml - controls/labs/AppViews.qml - controls/labs/AppViewLoader.qml - controls/labs/AltBrowser.qml + controls/AppViews.qml + controls/AppViewLoader.qml + controls/AltBrowser.qml controls/labs/TabsBrowser.qml controls/labs/SettingsDialog.qml controls/labs/SettingsSection.qml - controls/labs/Page.qml controls/labs/Doodle.qml controls/labs/WindowControlsLinux.qml controls/labs/WindowControlsMac.qml controls/labs/WindowControlsWindows.qml + controls/labs/AlternateListItem.qml controls/plugin/AppViewsPlugin.qml controls/plugin/PagePlugin.qml controls/plugin/PluginManager.qml controls/plugin/PluginsInfo.qml