From 8f95c4f698b2f2fcfc8d81c371f0ad8d6ca8bd0b Mon Sep 17 00:00:00 2001 From: reionwong Date: Wed, 3 Nov 2021 01:00:51 +0800 Subject: [PATCH] Add Tab-related controls --- src/controls/TabBar.qml | 83 ++++++++++++++++++++++++++++++++ src/controls/TabButton.qml | 81 +++++++++++++++++++++++++++++++ src/controls/TabCloseButton.qml | 68 ++++++++++++++++++++++++++ src/controls/TabView.qml | 84 +++++++++++++++++++++++++++++++++ src/controls/qmldir | 5 ++ src/fishui.cpp | 4 ++ src/fishui.qrc | 6 +++ src/images/dark/add.svg | 66 ++++++++++++++++++++++++++ src/images/light/add.svg | 66 ++++++++++++++++++++++++++ 9 files changed, 463 insertions(+) create mode 100644 src/controls/TabBar.qml create mode 100644 src/controls/TabButton.qml create mode 100644 src/controls/TabCloseButton.qml create mode 100644 src/controls/TabView.qml create mode 100644 src/images/dark/add.svg create mode 100644 src/images/light/add.svg diff --git a/src/controls/TabBar.qml b/src/controls/TabBar.qml new file mode 100644 index 0000000..9b4e3bd --- /dev/null +++ b/src/controls/TabBar.qml @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * 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 + * 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 QtQuick 2.15 +import QtQml 2.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import FishUI 1.0 as FishUI + +TabBar { + id: control + + implicitWidth: _content.width + + default property alias content : _content.data + property bool newTabVisibile: true + + signal newTabClicked() + + background: Rectangle { + color: "transparent" + } + + contentItem: Item { + RowLayout { + anchors.fill: parent + spacing: FishUI.Units.smallSpacing + + ScrollView { + id: _scrollView + + Layout.fillWidth: true + Layout.fillHeight: true + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + ScrollBar.vertical.policy: ScrollBar.AlwaysOff + + clip: true + + Flickable { + id: _flickable + + Row { + id: _content + width: _scrollView.width + height: _scrollView.height + } + } + } + + Loader { + active: control.newTabVisibile + visible: active + asynchronous: true + + Layout.fillHeight: true + Layout.preferredWidth: visible ? height : 0 + + sourceComponent: FishUI.RoundImageButton { + source: "qrc:/images/" + (FishUI.Theme.darkMode ? "dark/" : "light/") + "add.svg" + onClicked: control.newTabClicked() + } + } + } + } +} diff --git a/src/controls/TabButton.qml b/src/controls/TabButton.qml new file mode 100644 index 0000000..7a60c56 --- /dev/null +++ b/src/controls/TabButton.qml @@ -0,0 +1,81 @@ +import QtQuick 2.15 +import QtQml 2.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import FishUI 1.0 as FishUI + +Item { + id: control + + property bool checked: false + property bool hovered: _mouseArea.containsMouse + property alias font: _label.font + property string text: "" + + signal clicked() + signal closeClicked() + + MouseArea { + id: _mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: control.clicked() + } + + Rectangle { + id: hoveredRect + anchors.fill: parent + anchors.leftMargin: FishUI.Units.smallSpacing / 2 + anchors.rightMargin: FishUI.Units.smallSpacing / 2 + anchors.topMargin: FishUI.Units.smallSpacing / 2 + color: _mouseArea.containsMouse ? FishUI.Theme.textColor : FishUI.Theme.secondBackgroundColor + opacity: _mouseArea.containsMouse ? _mouseArea.pressed ? 0.1 : 0.05 : 0.9 + border.width: 0 + radius: FishUI.Theme.smallRadius + } + + Rectangle { + id: checkedRect + anchors.leftMargin: FishUI.Units.smallSpacing / 2 + anchors.rightMargin: FishUI.Units.smallSpacing / 2 + anchors.topMargin: FishUI.Units.smallSpacing / 2 + anchors.fill: parent + color: FishUI.Theme.highlightColor + opacity: _mouseArea.pressed ? 0.9 : 1 + border.width: 0 + visible: checked + radius: FishUI.Theme.smallRadius + } + + RowLayout { + anchors.fill: parent + anchors.leftMargin: FishUI.Units.smallSpacing / 2 + anchors.rightMargin: FishUI.Units.smallSpacing / 2 + anchors.topMargin: FishUI.Units.smallSpacing / 2 + spacing: 0 + + Label { + id: _label + text: control.text + leftPadding: FishUI.Units.smallSpacing / 2 + Layout.fillWidth: true + Layout.fillHeight: true + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + color: control.checked ? FishUI.Theme.highlightedTextColor + : FishUI.Theme.textColor + elide: Text.ElideMiddle + wrapMode: Text.NoWrap + } + + FishUI.TabCloseButton { + enabled: control.checked + Layout.preferredHeight: 24 + Layout.preferredWidth: 24 + size: 24 + source: !enabled ? "" : "qrc:/images/" + (FishUI.Theme.darkMode || control.checked ? "dark/" : "light/") + "close.svg" + onClicked: control.closeClicked() + } + } +} diff --git a/src/controls/TabCloseButton.qml b/src/controls/TabCloseButton.qml new file mode 100644 index 0000000..fa1674a --- /dev/null +++ b/src/controls/TabCloseButton.qml @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * 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 + * 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 QtQuick 2.12 +import QtQuick.Window 2.3 +import QtQuick.Controls 2.4 +import FishUI 1.0 as FishUI + +Item { + id: control + + property var size: 32 + property var iconMargins: 0 + height: size + width: size + + property alias background: _background + property color backgroundColor: "transparent" + property color hoveredColor: "#FF5C6D" + property color pressedColor: "#CC4A57" + property alias source: _image.source + property alias image: _image + signal clicked() + + Rectangle { + id: _background + anchors.fill: parent + anchors.margins: size * 0.1 + radius: control.height / 2 + opacity: 0.9 + color: mouseArea.pressed ? pressedColor : mouseArea.containsMouse ? control.hoveredColor : control.backgroundColor + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + + onClicked: control.clicked() + } + + Image { + id: _image + objectName: "image" + anchors.fill: parent + anchors.margins: control.iconMargins + fillMode: Image.PreserveAspectFit + sourceSize: Qt.size(width, height) + cache: true + asynchronous: false + } +} diff --git a/src/controls/TabView.qml b/src/controls/TabView.qml new file mode 100644 index 0000000..d4694bc --- /dev/null +++ b/src/controls/TabView.qml @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * 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 + * 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 QtQuick 2.15 +import QtQml 2.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import FishUI 1.0 as FishUI + +Container { + id: control + + spacing: 0 + + contentItem: ColumnLayout { + spacing: 0 + + ListView { + id: _view + Layout.fillWidth: true + Layout.fillHeight: true + interactive: false + orientation: ListView.Horizontal + snapMode: ListView.SnapOneItem + currentIndex: control.currentIndex + + model: control.contentModel + + boundsBehavior: Flickable.StopAtBounds + boundsMovement :Flickable.StopAtBounds + + spacing: 0 + + preferredHighlightBegin: 0 + preferredHighlightEnd: width + + highlightRangeMode: ListView.StrictlyEnforceRange + highlightMoveDuration: 0 + highlightFollowsCurrentItem: true + highlightResizeDuration: 0 + highlightMoveVelocity: -1 + highlightResizeVelocity: -1 + + maximumFlickVelocity: 4 * width + + cacheBuffer: _view.count * width + keyNavigationEnabled : false + keyNavigationWraps : false + } + } + + function closeTab(index) { + control.removeItem(control.takeItem(index)) + control.currentItemChanged() + control.currentItem.forceActiveFocus() + } + + function addTab(component, properties) { + const object = component.createObject(control.contentModel, properties) + + control.addItem(object) + control.currentIndex = Math.max(control.count - 1, 0) + object.forceActiveFocus() + + return object + } +} diff --git a/src/controls/qmldir b/src/controls/qmldir index 5329761..2626ec6 100644 --- a/src/controls/qmldir +++ b/src/controls/qmldir @@ -22,4 +22,9 @@ PopupTips 1.0 PopupTips.qml RoundedRect 1.0 RoundedRect.qml Window 1.0 Window.qml RoundImageButton 1.0 RoundImageButton.qml +TabBar 1.0 TabBar.qml +TabButton 1.0 TabButton.qml +TabCloseButton 1.0 TabCloseButton.qml +TabView 1.0 TabView.qml + Toast 1.0 Toast.qml diff --git a/src/fishui.cpp b/src/fishui.cpp index ed7d6d4..2e2a289 100644 --- a/src/fishui.cpp +++ b/src/fishui.cpp @@ -69,6 +69,10 @@ void FishUI::registerTypes(const char *uri) qmlRegisterType(componentUrl(QStringLiteral("Icon.qml")), uri, 1, 0, "Icon"); qmlRegisterType(componentUrl(QStringLiteral("PopupTips.qml")), uri, 1, 0, "PopupTips"); qmlRegisterType(componentUrl(QStringLiteral("RoundedRect.qml")), uri, 1, 0, "RoundedRect"); + qmlRegisterType(componentUrl(QStringLiteral("TabBar.qml")), uri, 1, 0, "TabBar"); + qmlRegisterType(componentUrl(QStringLiteral("TabButton.qml")), uri, 1, 0, "TabButton"); + qmlRegisterType(componentUrl(QStringLiteral("TabCloseButton.qml")), uri, 1, 0, "TabCloseButton"); + qmlRegisterType(componentUrl(QStringLiteral("TabView.qml")), uri, 1, 0, "TabView"); qmlRegisterType(componentUrl(QStringLiteral("Toast.qml")), uri, 1, 0, "Toast"); qmlRegisterType(componentUrl(QStringLiteral("Window.qml")), uri, 1, 0, "Window"); qmlRegisterType(componentUrl(QStringLiteral("RoundImageButton.qml")), uri, 1, 0, "RoundImageButton"); diff --git a/src/fishui.qrc b/src/fishui.qrc index b07aaa5..7bde2f5 100644 --- a/src/fishui.qrc +++ b/src/fishui.qrc @@ -10,12 +10,18 @@ controls/Units.qml controls/Window.qml controls/RoundImageButton.qml + controls/TabBar.qml + controls/TabButton.qml + controls/TabCloseButton.qml + controls/TabView.qml controls/DesktopMenu.qml images/refresh.svg images/dark/close.svg images/dark/maximize.svg images/dark/minimize.svg images/dark/restore.svg + images/light/add.svg + images/dark/add.svg images/light/close.svg images/light/maximize.svg images/light/minimize.svg diff --git a/src/images/dark/add.svg b/src/images/dark/add.svg new file mode 100644 index 0000000..3bcd12d --- /dev/null +++ b/src/images/dark/add.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/images/light/add.svg b/src/images/light/add.svg new file mode 100644 index 0000000..def3824 --- /dev/null +++ b/src/images/light/add.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + +