Add tags settings in UI

This commit is contained in:
Vyn 2024-04-22 14:34:24 +02:00
parent 01037b1717
commit e5328c15d4
10 changed files with 233 additions and 22 deletions

View file

@ -51,6 +51,7 @@ qt_add_qml_module(mirai
src/qml/TaskItem.qml src/qml/TaskItem.qml
src/qml/forms/TaskForm.qml src/qml/forms/TaskForm.qml
src/qml/forms/FilesForm.qml src/qml/forms/FilesForm.qml
src/qml/forms/TagsConfigForm.qml
src/qml/components/TabSelector.qml src/qml/components/TabSelector.qml
src/qml/components/Tag.qml src/qml/components/Tag.qml
src/qml/components/Calendar.qml src/qml/components/Calendar.qml
@ -61,10 +62,12 @@ qt_add_qml_module(mirai
SOURCES SOURCES
src/Backend.h src/Backend.cpp src/Backend.h src/Backend.cpp
src/TaskItem.h src/TaskItem.cpp src/TaskItem.h src/TaskItem.cpp
src/Tag.h src/Tag.cpp
src/TasksFile.h src/TasksFile.cpp src/TasksFile.h src/TasksFile.cpp
RESOURCES RESOURCES
src/images/calendar.png src/images/calendar.png
src/images/add.png src/images/add.png
src/images/settings.png
) )
target_link_libraries(mirai PRIVATE Qt6::Quick) target_link_libraries(mirai PRIVATE Qt6::Quick)

View file

@ -197,7 +197,10 @@ void Backend::rebuildQMLTasksList()
QMLTags.clear(); QMLTags.clear();
for (auto &tag : mirai.getTags()) { for (auto &tag : mirai.getTags()) {
QMLTags.push_back(QString::fromStdString(tag)); QMLTags.push_back({
.name = QString::fromStdString(tag),
.color = getTagColor(QString::fromStdString(tag)),
});
} }
QMLActiveTagsFilter.clear(); QMLActiveTagsFilter.clear();
@ -248,3 +251,45 @@ QString Backend::getTagColor(QString tag)
} }
return tagsConfig[tag]; return tagsConfig[tag];
} }
void Backend::saveTagsColor(QVariant modifiedTags)
{
auto aa = modifiedTags.toList();
for (auto bb : aa) {
auto cc = bb.toMap();
std::cout << cc["name"].toString().toStdString() << ": "
<< cc["color"].toString().toStdString() << std::endl;
tagsConfig[cc["name"].toString()] = cc["color"].toString();
}
rebuildQMLTasksList();
emit tagsChanged();
emit tasksChanged();
saveConfig();
}
void Backend::saveConfig()
{
QJsonObject rootJson;
QJsonArray filesJson;
for (auto &file : mirai.getFiles()) {
filesJson.append(QString::fromStdString(file->getPath()));
}
rootJson["files"] = filesJson;
QJsonObject tagsJson;
for (auto &tag : tagsConfig.keys()) {
QJsonObject tagConfig;
tagConfig["color"] = getTagColor(tag);
tagsJson[tag] = tagConfig;
}
rootJson["tags"] = tagsJson;
QFile configFile(QDir::homePath() + "/.config/mirai/config.json");
if (!configFile.open(QIODevice::WriteOnly)) {
qWarning() << "Cannot save config";
return;
}
configFile.write(QJsonDocument(rootJson).toJson());
configFile.close();
}

View file

@ -10,6 +10,7 @@
#include "QtCore/qcontainerfwd.h" #include "QtCore/qcontainerfwd.h"
#include "QtCore/qtmetamacros.h" #include "QtCore/qtmetamacros.h"
#include "QtCore/qvariant.h" #include "QtCore/qvariant.h"
#include "Tag.h"
#include "TasksFile.h" #include "TasksFile.h"
#include "core/Mirai.h" #include "core/Mirai.h"
#include "core/TasksView.h" #include "core/TasksView.h"
@ -33,7 +34,7 @@ class Backend : public QObject
QML_ELEMENT QML_ELEMENT
Q_PROPERTY(QVariant tasks READ getTasks NOTIFY tasksChanged) Q_PROPERTY(QVariant tasks READ getTasks NOTIFY tasksChanged)
Q_PROPERTY(QVariant files READ getFiles NOTIFY filesChanged) Q_PROPERTY(QVariant files READ getFiles NOTIFY filesChanged)
Q_PROPERTY(QVariant tags READ getTags NOTIFY tasksChanged) Q_PROPERTY(QVariant tags READ getTags NOTIFY tagsChanged)
Q_PROPERTY(QVariant activeTagsFilter READ getActiveTagsFilter NOTIFY tasksChanged) Q_PROPERTY(QVariant activeTagsFilter READ getActiveTagsFilter NOTIFY tasksChanged)
Q_PROPERTY(QVariant activeFilesFilter READ getActiveFilesFilter NOTIFY tasksChanged) Q_PROPERTY(QVariant activeFilesFilter READ getActiveFilesFilter NOTIFY tasksChanged)
Q_PROPERTY(bool shouldHideCompletedTasks READ shouldHideCompletedTasks WRITE hideCompletedTasks Q_PROPERTY(bool shouldHideCompletedTasks READ shouldHideCompletedTasks WRITE hideCompletedTasks
@ -54,6 +55,7 @@ class Backend : public QObject
Q_INVOKABLE void removeTodo(int todoIndex); Q_INVOKABLE void removeTodo(int todoIndex);
Q_INVOKABLE void hideCompletedTasks(bool shouldHide); Q_INVOKABLE void hideCompletedTasks(bool shouldHide);
Q_INVOKABLE QString getTagColor(QString tag); Q_INVOKABLE QString getTagColor(QString tag);
Q_INVOKABLE void saveTagsColor(QVariant tags);
private: private:
void rebuildQMLTasksList(); void rebuildQMLTasksList();
@ -64,13 +66,14 @@ class Backend : public QObject
QVariant getActiveTagsFilter(); QVariant getActiveTagsFilter();
QVariant getActiveFilesFilter(); QVariant getActiveFilesFilter();
bool shouldHideCompletedTasks(); bool shouldHideCompletedTasks();
void saveConfig();
mirai::Mirai mirai; mirai::Mirai mirai;
mirai::TasksView view; mirai::TasksView view;
QList<QMLTaskItem> QMLTasks; QList<QMLTaskItem> QMLTasks;
QList<QMLTasksFile> QMLTasksFiles; QList<QMLTasksFile> QMLTasksFiles;
QList<QString> QMLTags; QList<QMLTag> QMLTags;
QList<QString> QMLActiveTagsFilter; QList<QString> QMLActiveTagsFilter;
QList<QString> QMLActiveFilesFilter; QList<QString> QMLActiveFilesFilter;
QMap<QString, QString> tagsConfig; QMap<QString, QString> tagsConfig;
@ -80,6 +83,7 @@ class Backend : public QObject
signals: signals:
void tasksChanged(); void tasksChanged();
void tagsChanged();
void filesChanged(); void filesChanged();
}; };

17
src/Tag.cpp Normal file
View file

@ -0,0 +1,17 @@
/*
* Mirai. Copyright (C) 2024 Vyn
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
*/
#include "Tag.h"
QString QMLTag::getName()
{
return name;
}
QString QMLTag::getColor()
{
return color;
}

29
src/Tag.h Normal file
View file

@ -0,0 +1,29 @@
/*
* Mirai. Copyright (C) 2024 Vyn
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
*/
#ifndef QML_TAG_H
#define QML_TAG_H
#include <QtCore/QString>
#include <QtQml/qqmlregistration.h>
#include <qobjectdefs.h>
struct QMLTag {
Q_GADGET
Q_PROPERTY(QString name READ getName)
Q_PROPERTY(QString color READ getColor)
QML_VALUE_TYPE(tag)
public:
QString getName();
QString getColor();
QString name;
QString color;
};
#endif

BIN
src/images/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -11,5 +11,12 @@ import Mirai
Button { Button {
icon.color: MiraiColorPalette.buttonIcon icon.color: MiraiColorPalette.buttonIcon
background: Rectangle { color: "transparent" } background: Rectangle {
color: "transparent"
HoverHandler {
id: mouse
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
cursorShape: Qt.PointingHandCursor
}
}
} }

View file

@ -7,6 +7,7 @@
import QtQuick import QtQuick
import QtQuick.Window import QtQuick.Window
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls
import Mirai import Mirai
ColumnLayout { ColumnLayout {
@ -50,10 +51,21 @@ ColumnLayout {
Item { Layout.preferredHeight: 16 } Item { Layout.preferredHeight: 16 }
RowLayout {
AppText { AppText {
text: "Tags" text: "Tags"
font.pixelSize: 32 font.pixelSize: 32
} }
Item { Layout.fillWidth: true }
AppIcon {
icon.source: "qrc:/qt/qml/Mirai/src/images/settings.png"
icon.color: colorPalette.selected.textPlaceholder
onClicked: {
tagsForm.reset();
tagsFormPopup.open();
}
}
}
Item { Layout.preferredHeight: 16 } Item { Layout.preferredHeight: 16 }
@ -62,25 +74,26 @@ ColumnLayout {
Rectangle { Rectangle {
Layout.preferredHeight: childrenRect.height Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true Layout.fillWidth: true
color: backend.activeTagsFilter.includes(modelData) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent" color: backend.activeTagsFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
radius: 4 radius: 4
QtObject { QtObject {
id: internal id: internal
property string configTagColor: backend.getTagColor(modelData)
} }
AppText { AppText {
text: modelData.name
text: modelData color: {
color: internal.configTagColor != "" ? internal.configTagColor : MiraiColorPalette.text console.log("ttagg", modelData.name, modelData.color)
return modelData.color
}
padding: 4 padding: 4
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
if (backend.activeTagsFilter.includes(modelData)) { if (backend.activeTagsFilter.includes(modelData.name)) {
backend.removeTagFilter(modelData) backend.removeTagFilter(modelData.name)
} else { } else {
backend.addTagFilter(modelData) backend.addTagFilter(modelData.name)
} }
} }
HoverHandler { HoverHandler {
@ -104,10 +117,27 @@ ColumnLayout {
} }
} }
/*AppButton { Popup {
text: `Settings` parent: Overlay.overlay
onClicked: { id: tagsFormPopup
root.openSettings() width: parent.width * 0.75
implicitHeight: tagsForm.height + padding * 2
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height * 0.4) / 2)
padding: 8
background: Rectangle {
border.color: colorPalette.selected.modalBorder
border.width: 2
color: colorPalette.selected.pane
radius: 4
}
TagsConfigForm {
id: tagsForm
width: parent.width
onConfirmed: (tags) => {
tagsFormPopup.close()
backend.saveTagsColor(tags)
}
}
} }
}*/
} }

View file

@ -20,11 +20,10 @@ Rectangle {
QtObject { QtObject {
id: internal id: internal
property string configTagColor: backend.getTagColor(control.text)
} }
AppText { AppText {
color: internal.configTagColor != "" ? internal.configTagColor : control.textColor color: backend.getTagColor(control.text)
padding: 2 padding: 2
leftPadding: 6 leftPadding: 6
rightPadding: 6 rightPadding: 6

View file

@ -0,0 +1,77 @@
/*
* Mirai. Copyright (C) 2024 Vyn
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
*/
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import Mirai
ColumnLayout {
id: form
spacing: 6
signal confirmed(tags: var)
function reset() {
internal.tags = Qt.binding(function () { return [] })
internal.tags = Qt.binding(function () { return backend.tags.map(tag => {
return {name: tag.name, color: tag.color}
})})
}
QtObject {
id: internal
property var tags: []
}
Repeater {
id: tagsList
model: internal.tags
RowLayout {
Rectangle {
id: newTagColor
color: colorDialog.selectedColor
Layout.fillHeight: true
Layout.preferredWidth: 32
MouseArea {
anchors.fill: parent
onClicked: {
colorDialog.open()
}
HoverHandler {
id: mouse
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
cursorShape: Qt.PointingHandCursor
}
}
}
ColorDialog {
id: colorDialog
selectedColor: modelData.color
onAccepted: {
colorDialog.selectedColor = selectedColor
internal.tags[index].color = selectedColor
}
}
AppText {
text: modelData.name
color: colorDialog.selectedColor
}
}
}
AppButton {
text: "Save"
onClicked: {
form.confirmed(internal.tags)
}
}
}