Add Tab-related controls

pull/19/head
reionwong 5 years ago
parent 46adf20371
commit 8f95c4f698

@ -0,0 +1,83 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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()
}
}
}
}
}

@ -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()
}
}
}

@ -0,0 +1,68 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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
}
}

@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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
}
}

@ -22,4 +22,9 @@ PopupTips 1.0 PopupTips.qml
RoundedRect 1.0 RoundedRect.qml RoundedRect 1.0 RoundedRect.qml
Window 1.0 Window.qml Window 1.0 Window.qml
RoundImageButton 1.0 RoundImageButton.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 Toast 1.0 Toast.qml

@ -69,6 +69,10 @@ void FishUI::registerTypes(const char *uri)
qmlRegisterType(componentUrl(QStringLiteral("Icon.qml")), uri, 1, 0, "Icon"); qmlRegisterType(componentUrl(QStringLiteral("Icon.qml")), uri, 1, 0, "Icon");
qmlRegisterType(componentUrl(QStringLiteral("PopupTips.qml")), uri, 1, 0, "PopupTips"); qmlRegisterType(componentUrl(QStringLiteral("PopupTips.qml")), uri, 1, 0, "PopupTips");
qmlRegisterType(componentUrl(QStringLiteral("RoundedRect.qml")), uri, 1, 0, "RoundedRect"); 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("Toast.qml")), uri, 1, 0, "Toast");
qmlRegisterType(componentUrl(QStringLiteral("Window.qml")), uri, 1, 0, "Window"); qmlRegisterType(componentUrl(QStringLiteral("Window.qml")), uri, 1, 0, "Window");
qmlRegisterType(componentUrl(QStringLiteral("RoundImageButton.qml")), uri, 1, 0, "RoundImageButton"); qmlRegisterType(componentUrl(QStringLiteral("RoundImageButton.qml")), uri, 1, 0, "RoundImageButton");

@ -10,12 +10,18 @@
<file alias="Units.qml">controls/Units.qml</file> <file alias="Units.qml">controls/Units.qml</file>
<file alias="Window.qml">controls/Window.qml</file> <file alias="Window.qml">controls/Window.qml</file>
<file alias="RoundImageButton.qml">controls/RoundImageButton.qml</file> <file alias="RoundImageButton.qml">controls/RoundImageButton.qml</file>
<file alias="TabBar.qml">controls/TabBar.qml</file>
<file alias="TabButton.qml">controls/TabButton.qml</file>
<file alias="TabCloseButton.qml">controls/TabCloseButton.qml</file>
<file alias="TabView.qml">controls/TabView.qml</file>
<file alias="DesktopMenu.qml">controls/DesktopMenu.qml</file> <file alias="DesktopMenu.qml">controls/DesktopMenu.qml</file>
<file>images/refresh.svg</file> <file>images/refresh.svg</file>
<file>images/dark/close.svg</file> <file>images/dark/close.svg</file>
<file>images/dark/maximize.svg</file> <file>images/dark/maximize.svg</file>
<file>images/dark/minimize.svg</file> <file>images/dark/minimize.svg</file>
<file>images/dark/restore.svg</file> <file>images/dark/restore.svg</file>
<file>images/light/add.svg</file>
<file>images/dark/add.svg</file>
<file>images/light/close.svg</file> <file>images/light/close.svg</file>
<file>images/light/maximize.svg</file> <file>images/light/maximize.svg</file>
<file>images/light/minimize.svg</file> <file>images/light/minimize.svg</file>

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
enable-background="new"
version="1.1"
id="svg6"
sodipodi:docname="add.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1652"
inkscape:window-height="997"
id="namedview8"
showgrid="false"
inkscape:zoom="45.9375"
inkscape:cx="8"
inkscape:cy="8"
inkscape:window-x="290"
inkscape:window-y="564"
inkscape:window-maximized="0"
inkscape:current-layer="svg6"
inkscape:document-rotation="0" />
<rect
style="opacity:0.95;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.597918;stroke-miterlimit:4;stroke-dasharray:none"
id="rect832"
width="8.2469997"
height="0.5"
x="3.8765001"
y="7.75" />
<rect
style="opacity:0.95;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.597918;stroke-miterlimit:4;stroke-dasharray:none"
id="rect832-3"
width="8.2469997"
height="0.5"
x="3.8765001"
y="-8.25"
transform="rotate(90)" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
enable-background="new"
version="1.1"
id="svg6"
sodipodi:docname="add.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2160"
inkscape:window-height="1304"
id="namedview8"
showgrid="false"
inkscape:zoom="45.9375"
inkscape:cx="8"
inkscape:cy="8"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6"
inkscape:document-rotation="0" />
<rect
style="opacity:0.95;fill:#363636;fill-opacity:1;stroke:none;stroke-width:0.597918;stroke-miterlimit:4;stroke-dasharray:none"
id="rect832"
width="8.2469997"
height="0.5"
x="3.8765001"
y="7.75" />
<rect
style="opacity:0.95;fill:#363636;fill-opacity:1;stroke:none;stroke-width:0.597918;stroke-miterlimit:4;stroke-dasharray:none"
id="rect832-3"
width="8.2469997"
height="0.5"
x="3.8765001"
y="-8.25"
transform="rotate(90)" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Loading…
Cancel
Save