/* * Copyright (C) 2023, KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, 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 General Public License * along with this program. If not, see . * */ import QtQml 2.12 import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.5 import AppControls2 1.0 as AppControls2 import org.ukui.menu.core 1.0 import org.ukui.menu.utils 1.0 import org.ukui.menu.extension 1.0 Item { ColumnLayout { id: sidebarLayout anchors.fill: parent anchors.topMargin: 12 spacing: 0 property bool liteMode: isLiteMode onLiteModeChanged: { updateSidebarLayout(extensionInfoList.currentItem.extensionOptions) } function updateSidebarLayout(options) { sidebarBottomBar.visible = !options.includes(MenuExtension.HideBottomBar); fullScreenbutton.visible = !isLiteMode && !options.includes(MenuExtension.HideFullScreenButton); } Item { id: sidebarTopBar Layout.fillWidth: true Layout.preferredHeight: 40 Layout.rightMargin: 12 Layout.leftMargin: 12 RowLayout { anchors.fill: parent spacing: 4 ListView { id: extensionInfoList Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: 4 Layout.rightMargin: 4 clip: true spacing: 24 interactive: false orientation: ListView.Horizontal model: extensionManager.extensionModel() delegate: extensionInfoDelegate function send(data) { if (currentItem !== null) { model.send(currentIndex, data); } } onCurrentIndexChanged: { if (currentItem !== null) { currentItem.select(); } } } Loader { id: extensionMenuLoader visible: sourceComponent !== undefined Layout.preferredWidth: 34 Layout.preferredHeight: 34 Layout.alignment: Qt.AlignVCenter } AppControls2.StyleBackground { id: fullScreenbutton Layout.preferredWidth: 34 Layout.preferredHeight: 34 Layout.alignment: Qt.AlignVCenter radius: 4 useStyleTransparent: false alpha: buttonMouseArea.containsPress ? 0.65 : buttonMouseArea.containsMouse ? 0.40 : 0.00 borderColor: Palette.Highlight border.width: buttonMouseArea.activeFocus ? 2 : 0 ThemeIcon { anchors.centerIn: parent width: 16; height: 16 source: "image://appicon/view-fullscreen-symbolic" MouseArea { id: buttonMouseArea hoverEnabled: true anchors.fill: parent ToolTip.delay: 500 ToolTip.text: qsTr("Expand") ToolTip.visible: containsMouse onClicked: mainWindow.isFullScreen = true activeFocusOnTab: true Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { mainWindow.isFullScreen = true; } } } } } } } Item { Layout.fillWidth: true Layout.fillHeight: true Loader { id: extensionLoader anchors.fill: parent clip: true onLoaded: { item.send.connect(extensionInfoList.send); sidebarLayout.updateSidebarLayout(extensionInfoList.currentItem.extensionOptions); updateMenu(); item.extensionMenuChanged.connect(updateMenu); } Keys.onTabPressed: { extensionInfoList.focus = true } function updateMenu() { if (item === null) { return; } if (item.extensionMenu !== null) { extensionMenuLoader.sourceComponent = item.extensionMenu; } else { extensionMenuLoader.sourceComponent = undefined; } } } } Item { id: sidebarBottomBar Layout.fillWidth: true Layout.preferredHeight: 32 Layout.topMargin: 5 Layout.bottomMargin: 8 Layout.leftMargin: 12 Layout.rightMargin: 12 RowLayout { anchors.fill: parent layoutDirection: Qt.RightToLeft spacing: 5 AppControls2.StyleBackground { Layout.preferredWidth: 32 Layout.preferredHeight: 32 Layout.alignment: Qt.AlignVCenter paletteRole: Palette.Base useStyleTransparent: false alpha: powerButtonArea.containsPress ? 0.85 : powerButtonArea.containsMouse ? 0.65 : 0 radius: height / 2 borderColor: Palette.Highlight border.width: powerButtonArea.activeFocus ? 2 : 0 PowerButton { id: powerButtonBase } Image { anchors.centerIn: parent width: 24 height: 24 source: powerButtonBase.icon } MouseArea { id: powerButtonArea anchors.fill: parent hoverEnabled: true ToolTip.delay: 500 ToolTip.visible: containsMouse ToolTip.text: powerButtonBase.toolTip acceptedButtons: Qt.LeftButton | Qt.RightButton property int spacingFromMenu: 4 activeFocusOnTab: true Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { powerButtonBase.clicked(true, 0, 0, mainWindow.isFullScreen); } } onClicked: { var buttonPosition = powerButtonArea.mapToGlobal(width, height); powerButtonBase.clicked(mouse.button === Qt.LeftButton, buttonPosition.x + sidebarBottomBar.Layout.rightMargin + 4, buttonPosition.y + sidebarBottomBar.Layout.bottomMargin, mainWindow.isFullScreen); } } } } } } Component { id: extensionInfoDelegate AppControls2.StyleBackground { useStyleTransparent: false paletteRole: Palette.Highlight alpha: 0 radius: 4 borderColor: Palette.Highlight border.width: activeFocus ? 2 : 0 property var extensionData: model.data property var extensionOptions: model.options width: styleText.width height: ListView.view ? ListView.view.height : 0 activeFocusOnTab: true KeyNavigation.down: extensionLoader Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { ListView.view.currentIndex = model.index; EventTrack.sendClickEvent("switch_plugin", "Sidebar", {"plugin": model.name}); } } onExtensionDataChanged: { if (extensionLoader.source === model.url) { extensionLoader.item.extensionData = extensionData; } } function select() { if (extensionLoader.source !== model.url) { extensionLoader.setSource(model.url, {extensionData: extensionData}); } } AppControls2.StyleText { height: parent.height id: styleText verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter font.bold: parent.ListView.isCurrentItem paletteRole: parent.ListView.isCurrentItem ? Palette.Highlight: Palette.Text text: model.name } MouseArea { anchors.fill: parent onClicked: { normalUI.focusToFalse(); parent.ListView.view.currentIndex = model.index; EventTrack.sendClickEvent("switch_plugin", "Sidebar", {"plugin": model.name}); } } } } Component.onCompleted: { if (extensionInfoList.count > 0) { extensionInfoList.currentIndex = 0; } } }