Draft: Big overhaul of the settings

This commit is contained in:
Carl Schwan
2021-06-04 23:46:31 +02:00
parent d9eaa95b9d
commit 23bd73c499
11 changed files with 467 additions and 69 deletions

View File

@@ -68,8 +68,7 @@ if(ANDROID)
)
else()
find_package(Qt5 ${QT_MIN_VERSION} COMPONENTS Widgets)
find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS REQUIRED KIO)
find_package(KF5QQC2DesktopStyle ${KF5_MIN_VERSION} REQUIRED)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle ConfigWidgets KIO)
set_package_properties(KF5QQC2DesktopStyle PROPERTIES
TYPE RUNTIME
)

View File

@@ -8,80 +8,302 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
import NeoChat.Settings 1.0
Kirigami.ScrollablePage {
title: i18n("Settings")
bottomPadding: 0
leftPadding: 0
rightPadding: 0
topPadding: 0
Kirigami.FormLayout {
QQC2.CheckBox {
Kirigami.FormData.label: i18n("General settings:")
text: i18n("Close to system tray")
checked: Config.systemTray
visible: Controller.supportSystemTray
onToggled: {
Config.systemTray = checked
Config.save()
onBackRequested: {
if (pageSettingStack.depth > 1 && !pageSettingStack.wideMode && pageSettingStack.currentIndex !== 0) {
event.accepted = true;
pageSettingStack.pop();
}
}
Kirigami.PageRow {
id: pageSettingStack
anchors.fill: parent
columnView.columnWidth: Kirigami.Units.gridUnit * 12
initialPage: Kirigami.ScrollablePage {
bottomPadding: 0
leftPadding: 0
rightPadding: 0
topPadding: 0
Kirigami.Theme.colorSet: Kirigami.Theme.View
ListView {
Component.onCompleted: actions[0].trigger();
property list<Kirigami.Action> actions: [
Kirigami.Action {
text: i18n("General")
icon.name: "org.kde.neochat"
onTriggered: pageSettingStack.push(generalSettings)
},
Kirigami.Action {
text: i18n("Appearance")
icon.name: "preferences-desktop-theme-global"
onTriggered: pageSettingStack.push(appearanceSettings)
}
]
model: actions
delegate: Kirigami.BasicListItem {
action: modelData
}
}
}
QQC2.CheckBox {
// TODO: When there are enough notification and timeline event
// settings, make 2 separate groups with FormData labels.
Kirigami.FormData.label: i18n("Notifications and events:")
text: i18n("Show notifications")
checked: Config.showNotifications
onToggled: {
Config.showNotifications = checked
Config.save()
}
Component {
id: generalSettings
Kirigami.ScrollablePage {
Kirigami.FormLayout {
QQC2.CheckBox {
Kirigami.FormData.label: i18n("General settings:")
text: i18n("Close to system tray")
checked: Config.systemTray
visible: Controller.supportSystemTray
onToggled: {
Config.systemTray = checked
Config.save()
}
}
QQC2.CheckBox {
// TODO: When there are enough notification and timeline event
// settings, make 2 separate groups with FormData labels.
Kirigami.FormData.label: i18n("Notifications and events:")
text: i18n("Show notifications")
checked: Config.showNotifications
onToggled: {
Config.showNotifications = checked
Config.save()
}
}
QQC2.CheckBox {
text: i18n("Show leave and join events")
checked: Config.showLeaveJoinEvent
onToggled: {
Config.showLeaveJoinEvent = checked
Config.save()
}
}
QQC2.RadioButton {
Kirigami.FormData.label: i18n("Rooms and private chats:")
text: i18n("Separated")
checked: !Config.mergeRoomList
onToggled: {
Config.mergeRoomList = false
Config.save()
}
}
QQC2.RadioButton {
text: i18n("Intermixed")
checked: Config.mergeRoomList
onToggled: {
Config.mergeRoomList = true
Config.save()
}
}
QQC2.CheckBox {
text: i18n("Use s/text/replacement syntax to edit your last message")
checked: Config.allowQuickEdit
onToggled: {
Config.allowQuickEdit = checked
Config.save()
}
}
}
}
QQC2.CheckBox {
text: i18n("Show leave and join events")
checked: Config.showLeaveJoinEvent
onToggled: {
Config.showLeaveJoinEvent = checked
Config.save()
}
}
QQC2.RadioButton {
Kirigami.FormData.label: i18n("Rooms and private chats:")
text: i18n("Separated")
checked: !Config.mergeRoomList
onToggled: {
Config.mergeRoomList = false
Config.save()
}
}
QQC2.RadioButton {
text: i18n("Intermixed")
checked: Config.mergeRoomList
onToggled: {
Config.mergeRoomList = true
Config.save()
}
}
QQC2.CheckBox {
Kirigami.FormData.label: i18n("Timeline:")
text: i18n("Show User Avatar")
checked: Config.showAvatarInTimeline
onToggled: {
Config.showAvatarInTimeline = checked
Config.save()
}
}
QQC2.CheckBox {
text: i18n("Show Fancy Effects")
checked: Config.showFancyEffects
onToggled: {
Config.showFancyEffects = checked
Config.save()
}
}
QQC2.CheckBox {
text: i18n("Use s/text/replacement syntax to edit your last message")
checked: Config.allowQuickEdit
onToggled: {
Config.allowQuickEdit = checked
Config.save()
}
Component {
id: appearanceSettings
Kirigami.ScrollablePage {
ColumnLayout {
RowLayout {
Layout.alignment: Qt.AlignCenter
spacing: Kirigami.Units.gridUnit * 2
ThemeRadioButton {
innerObject: [
RowLayout {
Layout.fillWidth: true
Kirigami.Avatar {
color: "blue"
Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
}
QQC2.Control {
Layout.fillWidth: true
contentItem: ColumnLayout {
QQC2.Label {
Layout.fillWidth: true
font.weight: Font.Bold
font.pixelSize: 7
text: "Paul Müller"
color: "blue"
wrapMode: Text.Wrap
}
QQC2.Label {
Layout.fillWidth: true
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt."
wrapMode: Text.Wrap
font.pixelSize: 7
}
}
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: Kirigami.Units.devicePixelRatio
}
}
},
RowLayout {
Layout.fillWidth: true
Kirigami.Avatar {
color: "red"
Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
}
QQC2.Control {
Layout.fillWidth: true
contentItem: ColumnLayout {
QQC2.Label {
Layout.fillWidth: true
font.weight: Font.Bold
font.pixelSize: 7
text: "Jean Paul"
color: "red"
wrapMode: Text.Wrap
}
QQC2.Label {
Layout.fillWidth: true
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta , quis sem suscipit tincidunt."
wrapMode: Text.Wrap
font.pixelSize: 7
}
}
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: Kirigami.Units.devicePixelRatio
}
}
}
]
text: i18n("Bubbles")
checked: !Config.compactLayout
QQC2.ButtonGroup.group: themeGroup
onToggled: {
Config.compactLayout = !checked;
Config.save();
}
}
ThemeRadioButton {
innerObject: [
RowLayout {
Layout.fillWidth: true
Kirigami.Avatar {
color: "blue"
Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
}
ColumnLayout {
Layout.fillWidth: true
QQC2.Label {
Layout.fillWidth: true
font.weight: Font.Bold
font.pixelSize: 7
text: "Paul Müller"
color: "blue"
wrapMode: Text.Wrap
}
QQC2.Label {
Layout.fillWidth: true
text: "Lorem ipsum dolor sit amet, consectetur elit. Vivamus facilisis porta mauris, finibus sem suscipit tincidunt."
wrapMode: Text.Wrap
font.pixelSize: 7
}
}
},
RowLayout {
Layout.fillWidth: true
Kirigami.Avatar {
color: "red"
Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
}
ColumnLayout {
Layout.fillWidth: true
QQC2.Label {
Layout.fillWidth: true
font.weight: Font.Bold
font.pixelSize: 7
text: "Jean Paul"
color: "red"
wrapMode: Text.Wrap
}
QQC2.Label {
Layout.fillWidth: true
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt."
wrapMode: Text.Wrap
font.pixelSize: 7
}
}
}
]
text: i18n("Compact")
checked: Config.compactLayout
QQC2.ButtonGroup.group: themeGroup
onToggled: {
Config.compactLayout = checked;
Config.save();
}
}
}
Kirigami.FormLayout {
QQC2.CheckBox {
text: i18n("Show User Avatar")
checked: Config.showAvatarInTimeline
onToggled: {
Config.showAvatarInTimeline = checked;
Config.save();
}
}
QQC2.CheckBox {
text: i18n("Show Fancy Effects")
checked: Config.showFancyEffects
onToggled: {
Config.showFancyEffects = checked;
Config.save();
}
}
Loader {
visible: item !== null
Kirigami.FormData.label: item ? i18n("Theme:") : ""
Kirigami.FormData.buddyFor: item ? item.slider : null
source: "qrc:/imports/NeoChat/Settings/ColorScheme.qml"
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
import NeoChat.Settings 1.0
QQC2.ComboBox {
textRole: "display"
model: ColorSchemer.model
Component.onCompleted: currentIndex = ColorSchemer.indexForScheme(Config.colorScheme);
onActivated: {
ColorSchemer.apply(currentIndex);
Config.colorScheme = ColorSchemer.nameForIndex(currentIndex);
Config.save();
}
}

View File

@@ -0,0 +1,65 @@
// Copyright 2021 Marco Martin <mart@kde.org>
// Copyright 2018 Furkan Tokac <furkantokac34@gmail.com>
// Copyright 2019 Nate Graham <nate@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
QQC2.RadioButton {
id: delegate
implicitWidth: contentItem.implicitWidth
implicitHeight: contentItem.implicitHeight
property alias innerObject: contentLayout.children
contentItem: ColumnLayout {
Kirigami.ShadowedRectangle {
implicitWidth: implicitHeight * 1.6
implicitHeight: Kirigami.Units.gridUnit * 6
radius: Kirigami.Units.smallSpacing
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View
shadow.xOffset: 0
shadow.yOffset: 2
shadow.size: 10
shadow.color: Qt.rgba(0, 0, 0, 0.3)
color: {
if (delegate.checked) {
return Kirigami.Theme.highlightColor;
} else if (delegate.hovered) {
// Match appearance of hovered list items
return Qt.rgba(Kirigami.Theme.highlightColor.r,
Kirigami.Theme.highlightColor.g,
Kirigami.Theme.highlightColor.b,
0.5);
} else {
return Kirigami.Theme.backgroundColor;
}
}
ColumnLayout {
id: contentLayout
anchors.fill: parent
anchors.margins: Kirigami.Units.smallSpacing
clip: true
}
}
QQC2.Label {
id: label
Layout.fillWidth: true
text: delegate.text
horizontalAlignment: Text.AlignHCenter
}
}
indicator: Item {}
background: Item {}
}

View File

@@ -0,0 +1,2 @@
module NeoChat.Settings
ThemeRadioButton 1.0 ThemeRadioButton.qml

View File

@@ -65,5 +65,8 @@
<file>qtquickcontrols2.conf</file>
<file>imports/NeoChat/Component/glowdot.png</file>
<file>imports/NeoChat/Component/confetti.png</file>
<file>imports/NeoChat/Settings/ThemeRadioButton.qml</file>
<file>imports/NeoChat/Settings/ColorScheme.qml</file>
<file>imports/NeoChat/Settings/qmldir</file>
</qresource>
</RCC>

View File

@@ -43,7 +43,9 @@ ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID)
target_sources(neochat PRIVATE trayicon.cpp)
target_sources(neochat PRIVATE trayicon.cpp colorschemer.cpp)
target_link_libraries(neochat PRIVATE KF5::ConfigWidgets)
target_compile_definitions(neochat PRIVATE -DHAVE_COLORSCHEME)
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})

39
src/colorschemer.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include <KColorSchemeManager>
#include <QAbstractItemModel>
#include "colorschemer.h"
ColorSchemer::ColorSchemer(QObject* parent)
: QObject(parent)
, c(new KColorSchemeManager(this))
{
}
ColorSchemer::~ColorSchemer()
{
}
QAbstractItemModel *ColorSchemer::model() const
{
return c->model();
}
void ColorSchemer::apply(int idx)
{
c->activateScheme(c->model()->index(idx, 0));
}
void ColorSchemer::apply(const QString &name)
{
c->activateScheme(c->indexForScheme(name));
}
int ColorSchemer::indexForScheme(const QString &name) const
{
return c->indexForScheme(name).row();
}
QString ColorSchemer::nameForIndex(int index) const
{
return c->model()->data(c->model()->index(index, 0), Qt::DisplayRole).toString();
}

26
src/colorschemer.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include <QObject>
#include <QIdentityProxyModel>
class QAbstractItemModel;
class KColorSchemeManager;
class ColorSchemer : public QObject
{
Q_OBJECT
Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT)
public:
ColorSchemer(QObject* parent = nullptr);
~ColorSchemer();
QAbstractItemModel* model() const;
Q_INVOKABLE void apply(int idx);
Q_INVOKABLE void apply(const QString &name);
Q_INVOKABLE int indexForScheme(const QString &name) const;
Q_INVOKABLE QString nameForIndex(int index) const;
private:
KColorSchemeManager* c;
};

View File

@@ -57,6 +57,9 @@
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
#include "webshortcutmodel.h"
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
using namespace Quotient;
@@ -137,6 +140,14 @@ int main(int argc, char *argv[])
Login *login = new Login();
ChatBoxHelper chatBoxHelper;
#ifdef HAVE_COLORSCHEME
ColorSchemer colorScheme;
qmlRegisterSingletonInstance<ColorSchemer>("org.kde.neochat", 1, 0, "ColorSchemer", &colorScheme);
if (!config->colorScheme().isEmpty()) {
colorScheme.apply(config->colorScheme());
}
#endif
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Controller", &Controller::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Clipboard", &clipboard);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Config", config);

View File

@@ -14,6 +14,9 @@
<entry name="ActiveConnection" type="String">
<label>Latest active connection</label>
</entry>
<entry name="ColorScheme" type="String">
<label>Color scheme</label>
</entry>
<entry name="ShowNotifications" type="bool">
<label>Show notifications</label>
<default>true</default>
@@ -36,6 +39,10 @@
<label>Show avatar in the timeline</label>
<default>true</default>
</entry>
<entry name="CompactLayout" type="bool">
<label>Use a compact layout</label>
<default>false</default>
</entry>
<entry name="ShowRename" type="bool">
<label>Show rename events in the timeline</label>
<default>true</default>