Working dark mode && more drawer specific changes.

This commit is contained in:
Black Hat
2018-11-17 20:52:17 +08:00
parent 08ce01473a
commit a7f62c13b0
18 changed files with 829 additions and 452 deletions

View File

@@ -1,6 +1,7 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.2
import Spectral.Setting 0.1
import Spectral.Font 0.1
@@ -10,7 +11,7 @@ Text {
id: materialLabel
color: MSettings.darkTheme ? "white" : "dark"
color: Material.foreground
font.pointSize: 16
font.family: MaterialFont.name
horizontalAlignment: Text.AlignHCenter

View File

@@ -1,25 +0,0 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.2
import "qrc:/js/util.js" as Util
ItemDelegate {
property var page
property bool selected: stackView.currentItem === page
property color highlightColor: Material.accent
Rectangle {
width: selected ? 4 : 0
height: parent.height
color: highlightColor
Behavior on width {
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
}
}
onClicked: Util.pushToStack(stackView, page)
}

View File

@@ -41,6 +41,7 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Window 2.1
import Spectral.Setting 0.1
Item {
id: root
@@ -64,7 +65,7 @@ Item {
property Component handleDelegate: Rectangle {
width: 1
height: 1
color: "#E1E1E1"
color: MSettings.darkTheme ? "#424242" : "#E1E1E1"
}
/*!

View File

@@ -74,24 +74,6 @@ RowLayout {
spacing: 0
// TimelineLabel {
// Layout.fillWidth: true
// id: authorLabel
// visible: messageRow.avatarVisible
// text: author.displayName
// Material.foreground: Material.accent
// coloredBackground: highlighted
// font.bold: true
// MouseArea {
// anchors.fill: parent
// cursorShape: Qt.PointingHandCursor
// onClicked: roomPanelInput.insert(author.displayName)
// }
// }
TextEdit {
Layout.fillWidth: true
@@ -134,54 +116,6 @@ RowLayout {
active: eventType === "image" || eventType === "file" || eventType === "audio"
}
// Row {
// Layout.alignment: Qt.AlignRight
// spacing: 4
// TimelineLabel {
// visible: userMarker.length > 5
// text: userMarker.length - 5 + "+"
// coloredBackground: highlighted
// Material.foreground: "grey"
// font.pointSize: 8
// }
// Repeater {
// model: userMarker.length > 5 ? userMarker.slice(0, 5) : userMarker
// ImageItem {
// width: parent.height
// height: parent.height
// hint: modelData.displayName
// source: modelData.paintable
// MouseArea {
// anchors.fill: parent
// cursorShape: Qt.PointingHandCursor
// onClicked: {
// readMarkerDialog.listModel = userMarker
// readMarkerDialog.open()
// }
// }
// }
// }
// TimelineLabel {
// id: timeLabel
// visible: Math.abs(time - aboveTime) > 600000 || index == 0
// text: Qt.formatTime(time, "hh:mm")
// coloredBackground: highlighted
// Material.foreground: "grey"
// font.pointSize: 8
// }
// }
}
Component {

View File

@@ -3,7 +3,6 @@ import QtQuick.Controls 2.2
Label {
text: section + " • " + Qt.formatTime(time, "hh:mm")
color: "#1D333E"
font.pointSize: 9.75
font.weight: Font.Medium
font.capitalization: Font.AllUppercase

View File

@@ -0,0 +1,29 @@
import QtQuick 2.9
import QtGraphicalEffects 1.0
Item {
id: item
property alias source: mask.source
Rectangle {
id: circleMask
width: parent.width
height: parent.height
smooth: true
visible: false
radius: Math.max(width/2, height/2)
}
OpacityMask {
id: mask
width: parent.width
height: parent.height
maskSource: circleMask
}
}

View File

@@ -0,0 +1,239 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
import Spectral.Component 2.0
import Spectral.Setting 0.1
AutoMouseArea {
id: ripple
property color color: MSettings.darkTheme ? Qt.rgba(255, 255, 255, 0.16) : Qt.rgba(0, 0, 0, 0.08)
property bool circular: false
property bool centered: false
property bool focused
property color focusColor: "transparent"
property int focusWidth: width - 32
property Item control
clip: true
Connections {
target: control
onPressedChanged: {
if (!control.pressed)
__private.removeLastCircle()
}
}
onPressed: {
__private.createTapCircle(mouse.x, mouse.y)
if (control)
mouse.accepted = false
}
onReleased: __private.removeLastCircle()
onCanceled: __private.removeLastCircle()
QtObject {
id: __private
property int startRadius: circular ? width/10 : width/6
property int endRadius
property bool showFocus: true
property Item lastCircle
function createTapCircle(x, y) {
endRadius = centered ? width/2 : radius(x, y) + 5
showFocus = false
lastCircle = tapCircle.createObject(ripple, {
"circleX": centered ? width/2 : x,
"circleY": centered ? height/2 : y
})
}
function removeLastCircle() {
if (lastCircle)
lastCircle.removeCircle()
}
function radius(x, y) {
var dist1 = Math.max(dist(x, y, 0, 0), dist(x, y, width, height))
var dist2 = Math.max(dist(x, y, width, 0), dist(x, y, 0, height))
return Math.max(dist1, dist2)
}
function dist(x1, y1, x2, y2) {
var distX = x2 - x1
var distY = y2 - y1
return Math.sqrt(distX * distX + distY * distY)
}
}
Rectangle {
id: focusBackground
objectName: "focusBackground"
width: parent.width
height: parent.height
color: Qt.rgba(0,0,0,0.2)
opacity: __private.showFocus && focused ? 1 : 0
Behavior on opacity {
NumberAnimation { duration: 500; easing.type: Easing.InOutQuad }
}
}
Rectangle {
id: focusCircle
objectName: "focusRipple"
property bool focusedState
x: (parent.width - width)/2
y: (parent.height - height)/2
width: focused
? focusedState ? focusWidth
: Math.min(parent.width - 8, focusWidth + 12)
: parent.width/5
height: width
radius: width/2
opacity: __private.showFocus && focused ? 1 : 0
color: focusColor.a === 0 ? Qt.rgba(1,1,1,0.4) : focusColor
Behavior on opacity {
NumberAnimation { duration: 500; easing.type: Easing.InOutQuad }
}
Behavior on width {
NumberAnimation { duration: focusTimer.interval; }
}
Timer {
id: focusTimer
running: focused
repeat: true
interval: 800
onTriggered: focusCircle.focusedState = !focusCircle.focusedState
}
}
Component {
id: tapCircle
Item {
id: circleItem
objectName: "tapRipple"
property bool done
property real circleX
property real circleY
property bool closed
width: parent.width
height: parent.height
function removeCircle() {
done = true
if (fillSizeAnimation.running) {
fillOpacityAnimation.stop()
closeAnimation.start()
circleItem.destroy(500);
} else {
__private.showFocus = true
fadeAnimation.start();
circleItem.destroy(300);
}
}
Item {
id: circleParent
width: parent.width
height: parent.height
visible: !circular
Rectangle {
id: circleRectangle
x: circleItem.circleX - radius
y: circleItem.circleY - radius
width: radius * 2
height: radius * 2
opacity: 0
color: ripple.color
NumberAnimation {
id: fillSizeAnimation
running: true
target: circleRectangle; property: "radius"; duration: 500;
from: __private.startRadius; to: __private.endRadius;
easing.type: Easing.InOutQuad
onStopped: {
if (done)
__private.showFocus = true
}
}
NumberAnimation {
id: fillOpacityAnimation
running: true
target: circleRectangle; property: "opacity"; duration: 300;
from: 0; to: 1; easing.type: Easing.InOutQuad
}
NumberAnimation {
id: fadeAnimation
target: circleRectangle; property: "opacity"; duration: 300;
from: 1; to: 0; easing.type: Easing.InOutQuad
}
SequentialAnimation {
id: closeAnimation
NumberAnimation {
target: circleRectangle; property: "opacity"; duration: 250;
to: 1; easing.type: Easing.InOutQuad
}
NumberAnimation {
target: circleRectangle; property: "opacity"; duration: 250;
from: 1; to: 0; easing.type: Easing.InOutQuad
}
}
}
}
CircleMask {
anchors.fill: parent
source: circleParent
visible: circular
}
}
}
}

View File

@@ -1,2 +1,3 @@
module Spectral.Effect
ElevationEffect 2.0 ElevationEffect.qml
RippleEffect 2.0 RippleEffect.qml

View File

@@ -1,27 +0,0 @@
import QtQuick 2.9
LoginForm {
loginButton.onClicked: doLogin()
Shortcut {
sequence: "Return"
onActivated: doLogin()
}
function doLogin() {
if (!(serverField.text.startsWith("http") && serverField.text.includes("://"))) {
loginButtonTooltip.text = "Server address should start with http(s)://"
loginButtonTooltip.open()
return
}
loginButton.text = "Logging in..."
loginButton.enabled = false
controller.loginWithCredentials(serverField.text, usernameField.text, passwordField.text)
controller.connectionAdded.connect(function(conn) {
stackView.pop()
accountListView.currentConnection = conn
})
}
}

View File

@@ -1,143 +0,0 @@
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import Spectral.Component 2.0
import Spectral.Setting 0.1
Page {
property var controller
property alias loginButton: loginButton
property alias serverField: serverField
property alias usernameField: usernameField
property alias passwordField: passwordField
property alias loginButtonTooltip: loginButtonTooltip
Row {
anchors.fill: parent
Rectangle {
width: parent.width / 2
height: parent.height
color: Material.accent
Column {
x: 32
anchors.verticalCenter: parent.verticalCenter
Label {
text: "Matrix Login."
font.pointSize: 28
font.bold: true
font.capitalization: Font.AllUppercase
color: "white"
}
Label {
text: "A new method of messaging."
font.pointSize: 12
font.capitalization: Font.AllUppercase
color: "white"
}
}
}
Pane {
width: parent.width / 2
height: parent.height
padding: 64
ColumnLayout {
width: parent.width
id: mainCol
AutoTextField {
Layout.fillWidth: true
id: serverField
leftPadding: 16
topPadding: 0
bottomPadding: 0
text: "https://matrix.org"
placeholderText: "Server"
background: Rectangle {
implicitHeight: 48
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
border.color: parent.activeFocus ? Material.accent : "transparent"
border.width: 2
}
}
AutoTextField {
Layout.fillWidth: true
id: usernameField
leftPadding: 16
topPadding: 0
bottomPadding: 0
placeholderText: "Username"
background: Rectangle {
implicitHeight: 48
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
border.color: parent.activeFocus ? Material.accent : "transparent"
border.width: 2
}
}
AutoTextField {
Layout.fillWidth: true
id: passwordField
leftPadding: 16
topPadding: 0
bottomPadding: 0
placeholderText: "Password"
echoMode: TextInput.Password
background: Rectangle {
implicitHeight: 48
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
border.color: parent.activeFocus ? Material.accent : "transparent"
border.width: 2
}
}
Button {
Layout.fillWidth: true
id: loginButton
text: "LOGIN"
highlighted: true
ToolTip {
id: loginButtonTooltip
}
}
}
}
}
}
/*##^## Designer {
D{i:0;autoSize:true;height:480;width:640}
}
##^##*/

View File

@@ -6,7 +6,7 @@ import QtQuick.Controls.Material 2.2
import Spectral 0.1
import Spectral.Effect 2.0
Rectangle {
Control {
property alias paintable: headerImage.source
property alias topic: headerTopicLabel.text
property bool atTop: false
@@ -14,64 +14,65 @@ Rectangle {
id: header
color: atTop ? "transparent" : "white"
background: Rectangle {
color: Material.background
layer.enabled: !atTop
layer.effect: ElevationEffect {
elevation: 4
opacity: atTop ? 0 : 1
layer.enabled: true
layer.effect: ElevationEffect {
elevation: 2
}
}
ItemDelegate {
RowLayout {
anchors.fill: parent
anchors.margins: 12
id: roomHeader
spacing: 12
onClicked: header.clicked()
ImageItem {
Layout.preferredWidth: height
Layout.fillHeight: true
RowLayout {
anchors.fill: parent
anchors.margins: 12
id: headerImage
spacing: 12
source: currentRoom.paintable
hint: currentRoom ? currentRoom.displayName : "No name"
}
ImageItem {
Layout.preferredWidth: height
Layout.fillHeight: true
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
id: headerImage
visible: parent.width > 64
source: currentRoom.paintable
hint: currentRoom ? currentRoom.displayName : "No name"
}
ColumnLayout {
Label {
Layout.fillWidth: true
Layout.fillHeight: true
visible: parent.width > 64
text: currentRoom ? currentRoom.displayName : ""
font.pointSize: 12
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: currentRoom ? currentRoom.displayName : ""
color: "#1D333E"
font.pointSize: 12
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
id: headerTopicLabel
Label {
Layout.fillWidth: true
Layout.fillHeight: true
id: headerTopicLabel
color: "#5B7480"
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
color: "#5B7480"
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
}
RippleEffect {
anchors.fill: parent
onClicked: header.clicked()
}
}

View File

@@ -1,96 +0,0 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.2
import Spectral 0.1
import Spectral.Setting 0.1
import Spectral.Component 2.0
Item {
AutoMouseArea {
anchors.fill: parent
onSecondaryClicked: {
roomContextMenu.model = model
roomContextMenu.popup()
}
onPrimaryClicked: {
if (category === RoomType.Invited) {
inviteDialog.currentRoom = currentRoom
inviteDialog.open()
} else {
leaveRoom(enteredRoom)
enterRoom(currentRoom)
enteredRoom = currentRoom
}
}
}
Rectangle {
anchors.fill: parent
visible: highlightCount > 0 || currentRoom === enteredRoom
color: Material.accent
opacity: 0.1
}
Rectangle {
width: unreadCount > 0 ? 4 : 0
height: parent.height
color: Material.accent
Behavior on width {
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
}
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
spacing: 12
ImageItem {
id: imageItem
Layout.preferredWidth: height
Layout.fillHeight: true
source: paintable
hint: name || "No Name"
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
visible: parent.width > 64
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name || "No Name"
color: "#1D333E"
font.pointSize: 12
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: (lastEvent == "" ? topic : lastEvent).replace(/(\r\n\t|\n|\r\t)/gm,"")
color: "#5B7480"
font.pointSize: 9.75
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
}
}

View File

@@ -17,7 +17,7 @@ Rectangle {
property var controller: null
readonly property var user: controller.connection ? controller.connection.localUser : null
readonly property int filter: 0
property int filter: 0
property var enteredRoom: null
property alias errorControl: errorControl
@@ -140,7 +140,7 @@ Rectangle {
background: Rectangle { color: Material.primary }
ItemDelegate {
RippleEffect {
anchors.fill: parent
}
}
@@ -172,11 +172,19 @@ Rectangle {
}
}
ItemDelegate {
Layout.fillWidth: true
text: "Add Account"
onClicked: loginDialog.open()
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 1
color: "#e7ebeb"
color: MSettings.darkTheme ? "#424242" : "#e7ebeb"
}
ItemDelegate {
@@ -187,6 +195,14 @@ Rectangle {
onClicked: stackView.push(settingsPage)
}
ItemDelegate {
Layout.fillWidth: true
text: "Logout"
onClicked: controller.logout(controller.connection)
}
ItemDelegate {
Layout.fillWidth: true
@@ -249,14 +265,18 @@ Rectangle {
spacing: 0
Control {
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 64
visible: stackView.depth > 1
contentItem: RowLayout {
color: Material.primary
RowLayout {
anchors.fill: parent
anchors.margins: 4
ToolButton {
Layout.preferredWidth: height
Layout.fillHeight: true
@@ -277,10 +297,6 @@ Rectangle {
elide: Label.ElideRight
}
}
background: Rectangle {
color: Material.primary
}
}
StackView {
@@ -289,6 +305,8 @@ Rectangle {
id: stackView
clip: true
initialItem: mainPage
}
}
@@ -299,8 +317,6 @@ Rectangle {
spacing: 0
Control {
readonly property bool isSearching: searchField.text
Layout.fillWidth: true
Layout.preferredHeight: 64
@@ -316,22 +332,66 @@ Rectangle {
Layout.preferredWidth: height
Layout.fillHeight: true
contentItem: MaterialIcon {
icon: roomListHeader.isSearching ? "\ue5cd" : "\ue8b6"
color: roomListHeader.isSearching ? "#1D333E" : "7F7F7F"
}
visible: !searchField.active
onClicked: {
if (searchField.focus) {
searchField.clear()
searchField.focus = false
} else {
searchField.focus = true
contentItem: MaterialIcon {
icon: {
switch (filter) {
case 0: return "\ue8b6"
case 1: return "\ue7f5"
case 2: return "\ue7ff"
case 3: return "\ue7fc"
}
}
}
Menu {
id: filterMenu
MenuItem {
text: "All"
onClicked: filter = 0
}
MenuSeparator {}
MenuItem {
text: "New"
onClicked: filter = 1
}
MenuItem {
text: "People"
onClicked: filter = 2
}
MenuItem {
text: "Group"
onClicked: filter = 3
}
}
onClicked: filterMenu.popup()
}
ItemDelegate {
Layout.preferredWidth: height
Layout.fillHeight: true
visible: searchField.active
contentItem: MaterialIcon { icon: "\ue5cd" }
onClicked: searchField.clear()
}
AutoTextField {
readonly property bool active: text
Layout.fillWidth: true
Layout.fillHeight: true
@@ -349,7 +409,7 @@ Rectangle {
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
visible: !roomListHeader.isSearching
visible: !searchField.active
source: root.user ? root.user.paintable : null
hint: root.user ? root.user.displayName : "?"
@@ -360,6 +420,17 @@ Rectangle {
}
}
}
background: Rectangle {
color: Material.background
opacity: listView.atYBeginning ? 0 : 1
layer.enabled: true
layer.effect: ElevationEffect {
elevation: 2
}
}
}
Control {
@@ -423,9 +494,93 @@ Rectangle {
ScrollBar.vertical: ScrollBar {}
delegate: RoomListDelegate {
width: parent.width
delegate: Item {
width: listView.width
height: 64
Rectangle {
anchors.fill: parent
visible: highlightCount > 0 || currentRoom === enteredRoom
color: Material.accent
opacity: 0.1
}
Rectangle {
width: unreadCount > 0 ? 4 : 0
height: parent.height
color: Material.accent
Behavior on width {
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
}
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
spacing: 12
ImageItem {
id: imageItem
Layout.preferredWidth: height
Layout.fillHeight: true
source: paintable
hint: name || "No Name"
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
visible: parent.width > 64
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name || "No Name"
font.pointSize: 12
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: (lastEvent == "" ? topic : lastEvent).replace(/(\r\n\t|\n|\r\t)/gm,"")
color: "#5B7480"
font.pointSize: 9.75
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
}
RippleEffect {
anchors.fill: parent
onSecondaryClicked: {
roomContextMenu.model = model
roomContextMenu.popup()
}
onPrimaryClicked: {
if (category === RoomType.Invited) {
inviteDialog.currentRoom = currentRoom
inviteDialog.open()
} else {
leaveRoom(enteredRoom)
enterRoom(currentRoom)
enteredRoom = currentRoom
}
}
}
}
section.property: "display"

View File

@@ -54,7 +54,7 @@ Item {
visible: currentRoom
source: "qrc:/assets/img/roompanel.svg"
source: MSettings.darkTheme ? "qrc:/assets/img/roompanel-dark.svg" : "qrc:/assets/img/roompanel.svg"
fillMode: Image.PreserveAspectCrop
}