mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-03 01:33:19 +00:00
Add basic responsive layout for Phone
This commit is contained in:
parent
1416b5db58
commit
375a1bfb2d
7 changed files with 360 additions and 293 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ todo.md
|
||||||
.clangd
|
.clangd
|
||||||
.cache
|
.cache
|
||||||
.nvimrc
|
.nvimrc
|
||||||
|
CMakeLists.txt.user
|
||||||
|
|
|
@ -39,6 +39,7 @@ qt_add_qml_module(mirai
|
||||||
#RESOURCE_PREFIX /qt/qml
|
#RESOURCE_PREFIX /qt/qml
|
||||||
QML_FILES
|
QML_FILES
|
||||||
src/qml/Main.qml
|
src/qml/Main.qml
|
||||||
|
src/qml/MainPanel.qml
|
||||||
src/qml/SideMenu.qml
|
src/qml/SideMenu.qml
|
||||||
src/qml/DatePicker.qml
|
src/qml/DatePicker.qml
|
||||||
src/qml/DateField.qml
|
src/qml/DateField.qml
|
||||||
|
|
|
@ -19,19 +19,19 @@ namespace cpputils::debug
|
||||||
class Timer
|
class Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Timer() : startTime(std::chrono::high_resolution_clock::now())
|
Timer() : startTime(std::chrono::steady_clock::now())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void start()
|
void start()
|
||||||
{
|
{
|
||||||
startTime = std::chrono::high_resolution_clock::now();
|
startTime = std::chrono::steady_clock::now();
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
const auto now = std::chrono::high_resolution_clock::now();
|
const auto now = std::chrono::steady_clock::now();
|
||||||
duration += std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
|
duration += std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class Timer
|
||||||
{
|
{
|
||||||
long durationToShow = duration;
|
long durationToShow = duration;
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
const auto now = std::chrono::high_resolution_clock::now();
|
const auto now = std::chrono::steady_clock::now();
|
||||||
durationToShow +=
|
durationToShow +=
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
|
std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class Timer
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::time_point<std::chrono::system_clock> startTime;
|
std::chrono::time_point<std::chrono::steady_clock, std::chrono::nanoseconds> startTime;
|
||||||
|
|
||||||
// Timer are always running when created. You can use .reset() after creation.
|
// Timer are always running when created. You can use .reset() after creation.
|
||||||
bool isRunning = true;
|
bool isRunning = true;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "core/TodoMd.h"
|
#include "core/TodoMd.h"
|
||||||
#include "cpp-utils/debug.h"
|
#include "cpp-utils/debug.h"
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <qjsonarray.h>
|
#include <qjsonarray.h>
|
||||||
|
@ -28,41 +29,42 @@ Backend::Backend() : todoView(&mirai)
|
||||||
QFile loadFile(QDir::homePath() + "/.config/mirai/config.json");
|
QFile loadFile(QDir::homePath() + "/.config/mirai/config.json");
|
||||||
readConfigDuration.printTimeElapsed("Read config duration");
|
readConfigDuration.printTimeElapsed("Read config duration");
|
||||||
|
|
||||||
if (!loadFile.open(QIODevice::ReadOnly)) {
|
if (loadFile.open(QIODevice::ReadOnly)) {
|
||||||
qWarning() << "Couldn't find existing config file";
|
QByteArray loadData = loadFile.readAll();
|
||||||
exit(1);
|
QJsonDocument json = QJsonDocument::fromJson(loadData);
|
||||||
}
|
loadFile.close();
|
||||||
|
if (!json.isObject()) {
|
||||||
QByteArray loadData = loadFile.readAll();
|
qWarning() << "config.json is not a valid config file";
|
||||||
QJsonDocument json = QJsonDocument::fromJson(loadData);
|
exit(1);
|
||||||
loadFile.close();
|
|
||||||
if (!json.isObject()) {
|
|
||||||
qWarning() << "config.json is not a valid config file";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
QJsonObject jsonRootObject = json.object();
|
|
||||||
|
|
||||||
auto jsonFilesPath = json["files"];
|
|
||||||
if (!jsonFilesPath.isArray()) {
|
|
||||||
qWarning() << "config.json should contains a 'files' string array";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
for (const QJsonValueRef &filePath : jsonFilesPath.toArray()) {
|
|
||||||
cpputils::debug::Timer loadingFileDuration;
|
|
||||||
mirai.loadFile(filePath.toString().toStdString());
|
|
||||||
loadingFileDuration.printTimeElapsed(
|
|
||||||
"Loading file duration of " + filePath.toString().toStdString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto jsonTagsConfig = json["tags"];
|
|
||||||
if (jsonTagsConfig.isObject()) {
|
|
||||||
for (auto &jsonTagConfigKey : jsonTagsConfig.toObject().keys()) {
|
|
||||||
tagsConfig[jsonTagConfigKey] =
|
|
||||||
jsonTagsConfig.toObject()[jsonTagConfigKey].toObject()["color"].toString();
|
|
||||||
}
|
}
|
||||||
|
QJsonObject jsonRootObject = json.object();
|
||||||
|
|
||||||
|
auto jsonFilesPath = json["files"];
|
||||||
|
if (!jsonFilesPath.isArray()) {
|
||||||
|
qWarning() << "config.json should contains a 'files' string array";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (const QJsonValueRef &filePath : jsonFilesPath.toArray()) {
|
||||||
|
cpputils::debug::Timer loadingFileDuration;
|
||||||
|
mirai.loadFile(filePath.toString().toStdString());
|
||||||
|
loadingFileDuration.printTimeElapsed(
|
||||||
|
"Loading file duration of " + filePath.toString().toStdString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto jsonTagsConfig = json["tags"];
|
||||||
|
if (jsonTagsConfig.isObject()) {
|
||||||
|
for (auto &jsonTagConfigKey : jsonTagsConfig.toObject().keys()) {
|
||||||
|
tagsConfig[jsonTagConfigKey] =
|
||||||
|
jsonTagsConfig.toObject()[jsonTagConfigKey].toObject()["color"].toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "Couldn't find existing config file";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cpputils::debug::Timer updatingViewDuration;
|
cpputils::debug::Timer updatingViewDuration;
|
||||||
todoView.update();
|
todoView.update();
|
||||||
updatingViewDuration.printTimeElapsed("Updating view duration");
|
updatingViewDuration.printTimeElapsed("Updating view duration");
|
||||||
|
|
168
src/qml/Main.qml
168
src/qml/Main.qml
|
@ -51,123 +51,65 @@ Window {
|
||||||
taskFormPopup.open()
|
taskFormPopup.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: sideMenuComponent
|
||||||
|
SideMenu {
|
||||||
|
id: sideMenu
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: mainPanelComponent
|
||||||
|
MainPanel {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: desktopLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Rectangle {
|
Loader {
|
||||||
color: MiraiColorPalette.pane
|
sourceComponent: sideMenuComponent
|
||||||
Layout.preferredWidth: childrenRect.width + 20
|
Layout.preferredWidth: item.width
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
sourceComponent: mainPanelComponent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
SideMenu {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: colorPalette.selected.background
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: 10
|
|
||||||
spacing: 16
|
|
||||||
|
|
||||||
TabSelector {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
|
|
||||||
tabs: [
|
|
||||||
{
|
|
||||||
label: "Todo",
|
|
||||||
onClick: () => {
|
|
||||||
backend.hideCompletedTasks(true) // Little workaround for now.
|
|
||||||
root.selectedView = "list"
|
|
||||||
},
|
|
||||||
selected: root.selectedView === "list"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Calendar",
|
|
||||||
onClick: () => {
|
|
||||||
backend.hideCompletedTasks(false) // Little workaround for now.
|
|
||||||
root.selectedView = "calendar"
|
|
||||||
},
|
|
||||||
selected: root.selectedView === "calendar"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AppButton {
|
|
||||||
icon.source: "qrc:/qt/qml/Mirai/src/images/add.png"
|
|
||||||
icon.color: colorPalette.selected.palette.green
|
|
||||||
text: "Add task"
|
|
||||||
onClicked: {
|
|
||||||
root.newTask()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: listViewComponent
|
|
||||||
ListView {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: calendarViewComponent
|
|
||||||
CalendarView {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: gettingStartedComponent
|
|
||||||
AppText {
|
|
||||||
text: "You currently have no files loaded, you can add them by clicking on the cog icon on the left pane"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
sourceComponent: backend.tasks.length === 0 ? gettingStartedComponent
|
|
||||||
: selectedView === "list" ? listViewComponent
|
|
||||||
: selectedView === "calendar" ? calendarViewComponent
|
|
||||||
: undefined
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: taskFormPopup
|
|
||||||
width: parent.width * 0.75
|
|
||||||
implicitHeight: taskForm.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
|
|
||||||
}
|
|
||||||
TaskForm {
|
|
||||||
id: taskForm
|
|
||||||
width: parent.width
|
|
||||||
onConfirmed: {
|
|
||||||
taskFormPopup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SwipeView {
|
||||||
|
id: phoneLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
sourceComponent: sideMenuComponent
|
||||||
|
Layout.preferredWidth: item.width
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
sourceComponent: mainPanelComponent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFittingLayout() {
|
||||||
|
if (width > height) {
|
||||||
|
desktopLayout.visible = true
|
||||||
|
phoneLayout.visible = false
|
||||||
|
} else {
|
||||||
|
desktopLayout.visible = false
|
||||||
|
phoneLayout.visible = true
|
||||||
|
phoneLayout.setCurrentIndex(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onWidthChanged: setFittingLayout()
|
||||||
|
Component.onCompleted: setFittingLayout()
|
||||||
}
|
}
|
||||||
|
|
112
src/qml/MainPanel.qml
Normal file
112
src/qml/MainPanel.qml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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 Mirai
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: colorPalette.selected.background
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
TabSelector {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: childrenRect.height
|
||||||
|
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
label: "Todo",
|
||||||
|
onClick: () => {
|
||||||
|
backend.hideCompletedTasks(true) // Little workaround for now.
|
||||||
|
root.selectedView = "list"
|
||||||
|
},
|
||||||
|
selected: root.selectedView === "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Calendar",
|
||||||
|
onClick: () => {
|
||||||
|
backend.hideCompletedTasks(false) // Little workaround for now.
|
||||||
|
root.selectedView = "calendar"
|
||||||
|
},
|
||||||
|
selected: root.selectedView === "calendar"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AppButton {
|
||||||
|
icon.source: "qrc:/qt/qml/Mirai/src/images/add.png"
|
||||||
|
icon.color: colorPalette.selected.palette.green
|
||||||
|
text: "Add task"
|
||||||
|
onClicked: {
|
||||||
|
root.newTask()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: listViewComponent
|
||||||
|
ListView {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: calendarViewComponent
|
||||||
|
CalendarView {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gettingStartedComponent
|
||||||
|
AppText {
|
||||||
|
text: "You currently have no files loaded, you can add them by clicking on the cog icon on the left pane"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
sourceComponent: backend.tasks.length === 0 ? gettingStartedComponent
|
||||||
|
: selectedView === "list" ? listViewComponent
|
||||||
|
: selectedView === "calendar" ? calendarViewComponent
|
||||||
|
: undefined
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: taskFormPopup
|
||||||
|
width: parent.width * 0.75
|
||||||
|
implicitHeight: taskForm.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
|
||||||
|
}
|
||||||
|
TaskForm {
|
||||||
|
id: taskForm
|
||||||
|
width: parent.width
|
||||||
|
onConfirmed: {
|
||||||
|
taskFormPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,169 +10,178 @@ import QtQuick.Layouts
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Mirai
|
import Mirai
|
||||||
|
|
||||||
ColumnLayout {
|
Rectangle {
|
||||||
|
|
||||||
RowLayout {
|
color: MiraiColorPalette.pane
|
||||||
AppText {
|
implicitWidth: childrenRect.width + 20
|
||||||
text: "Files"
|
|
||||||
font.pixelSize: 32
|
|
||||||
}
|
|
||||||
|
|
||||||
Item { Layout.fillWidth: true }
|
ColumnLayout {
|
||||||
AppIcon {
|
anchors.top: parent.top
|
||||||
icon.source: "qrc:/qt/qml/Mirai/src/images/settings.png"
|
anchors.bottom: parent.bottom
|
||||||
icon.color: colorPalette.selected.textPlaceholder
|
anchors.left: parent.left
|
||||||
onClicked: {
|
anchors.margins: 10
|
||||||
filesForm.reset();
|
RowLayout {
|
||||||
filesFormPopup.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item { Layout.preferredHeight: 16 }
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: backend.files
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: backend.activeFilesFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
|
||||||
radius: 4
|
|
||||||
AppText {
|
AppText {
|
||||||
text: modelData.name
|
text: "Files"
|
||||||
padding: 4
|
font.pixelSize: 32
|
||||||
}
|
}
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
Item { Layout.fillWidth: true }
|
||||||
|
AppIcon {
|
||||||
|
icon.source: "qrc:/qt/qml/Mirai/src/images/settings.png"
|
||||||
|
icon.color: colorPalette.selected.textPlaceholder
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (backend.activeFilesFilter.includes(modelData.name)) {
|
filesForm.reset();
|
||||||
backend.removeFileFilter(modelData.name)
|
filesFormPopup.open();
|
||||||
} else {
|
}
|
||||||
backend.addFileFilter(modelData.name)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.preferredHeight: 16 }
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: backend.files
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: childrenRect.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: backend.activeFilesFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
||||||
|
radius: 4
|
||||||
|
AppText {
|
||||||
|
text: modelData.name
|
||||||
|
padding: 4
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (backend.activeFilesFilter.includes(modelData.name)) {
|
||||||
|
backend.removeFileFilter(modelData.name)
|
||||||
|
} else {
|
||||||
|
backend.addFileFilter(modelData.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HoverHandler {
|
||||||
|
id: mouse
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HoverHandler {
|
|
||||||
id: mouse
|
|
||||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item { Layout.preferredHeight: 16 }
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
AppText {
|
|
||||||
text: "Tags"
|
|
||||||
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 }
|
||||||
|
|
||||||
Repeater {
|
RowLayout {
|
||||||
model: backend.tags
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: backend.activeTagsFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
|
||||||
radius: 4
|
|
||||||
QtObject {
|
|
||||||
id: internal
|
|
||||||
}
|
|
||||||
AppText {
|
AppText {
|
||||||
text: modelData.name
|
text: "Tags"
|
||||||
color: {
|
font.pixelSize: 32
|
||||||
return modelData.color
|
|
||||||
}
|
|
||||||
padding: 4
|
|
||||||
}
|
}
|
||||||
MouseArea {
|
Item { Layout.fillWidth: true }
|
||||||
anchors.fill: parent
|
AppIcon {
|
||||||
|
icon.source: "qrc:/qt/qml/Mirai/src/images/settings.png"
|
||||||
|
icon.color: colorPalette.selected.textPlaceholder
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (backend.activeTagsFilter.includes(modelData.name)) {
|
tagsForm.reset();
|
||||||
backend.removeTagFilter(modelData.name)
|
tagsFormPopup.open();
|
||||||
} else {
|
}
|
||||||
backend.addTagFilter(modelData.name)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.preferredHeight: 16 }
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: backend.tags
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: childrenRect.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: backend.activeTagsFilter.includes(modelData.name) ? MiraiColorPalette.filterSelected : mouse.hovered ? MiraiColorPalette.filterHovered : "transparent"
|
||||||
|
radius: 4
|
||||||
|
QtObject {
|
||||||
|
id: internal
|
||||||
|
}
|
||||||
|
AppText {
|
||||||
|
text: modelData.name
|
||||||
|
color: {
|
||||||
|
return modelData.color
|
||||||
|
}
|
||||||
|
padding: 4
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (backend.activeTagsFilter.includes(modelData.name)) {
|
||||||
|
backend.removeTagFilter(modelData.name)
|
||||||
|
} else {
|
||||||
|
backend.addTagFilter(modelData.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HoverHandler {
|
||||||
|
id: mouse
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HoverHandler {
|
|
||||||
id: mouse
|
}
|
||||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
}
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
AppButton {
|
||||||
|
text: `Hide completed tasks: ${backend.shouldHideCompletedTasks ? "ON" : "OFF"}`
|
||||||
|
onClicked: {
|
||||||
|
backend.hideCompletedTasks(!backend.shouldHideCompletedTasks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
parent: Overlay.overlay
|
||||||
|
id: filesFormPopup
|
||||||
|
width: parent.width * 0.75
|
||||||
|
implicitHeight: filesForm.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
|
||||||
|
}
|
||||||
|
FilesForm {
|
||||||
|
id: filesForm
|
||||||
|
width: parent.width
|
||||||
|
onConfirmed: (filesPath) => {
|
||||||
|
filesFormPopup.close()
|
||||||
|
console.log(filesPath)
|
||||||
|
backend.saveFilesPath(filesPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Popup {
|
||||||
Layout.fillHeight: true
|
parent: Overlay.overlay
|
||||||
}
|
id: tagsFormPopup
|
||||||
|
width: parent.width * 0.75
|
||||||
AppButton {
|
implicitHeight: tagsForm.height + padding * 2
|
||||||
text: `Hide completed tasks: ${backend.shouldHideCompletedTasks ? "ON" : "OFF"}`
|
x: Math.round((parent.width - width) / 2)
|
||||||
onClicked: {
|
y: Math.round((parent.height * 0.4) / 2)
|
||||||
backend.hideCompletedTasks(!backend.shouldHideCompletedTasks)
|
padding: 8
|
||||||
}
|
background: Rectangle {
|
||||||
}
|
border.color: colorPalette.selected.modalBorder
|
||||||
|
border.width: 2
|
||||||
Popup {
|
color: colorPalette.selected.pane
|
||||||
parent: Overlay.overlay
|
radius: 4
|
||||||
id: filesFormPopup
|
|
||||||
width: parent.width * 0.75
|
|
||||||
implicitHeight: filesForm.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
|
|
||||||
}
|
|
||||||
FilesForm {
|
|
||||||
id: filesForm
|
|
||||||
width: parent.width
|
|
||||||
onConfirmed: (filesPath) => {
|
|
||||||
filesFormPopup.close()
|
|
||||||
console.log(filesPath)
|
|
||||||
backend.saveFilesPath(filesPath)
|
|
||||||
}
|
}
|
||||||
}
|
TagsConfigForm {
|
||||||
}
|
id: tagsForm
|
||||||
|
width: parent.width
|
||||||
Popup {
|
onConfirmed: (tags) => {
|
||||||
parent: Overlay.overlay
|
tagsFormPopup.close()
|
||||||
id: tagsFormPopup
|
backend.saveTagsColor(tags)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue