From c25f04ad150f4526c3cbb505817737cfac932f2e Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Tue, 3 May 2022 07:43:57 +0200 Subject: [PATCH] Added about page, and better file operation. --- dub.json | 3 +- dub.selections.json | 1 + resources/todo-ui.glade | 1 + source/app.d | 73 ++++++++++++++++++++++++++++++++++------- source/model.d | 20 +++++------ 5 files changed, 76 insertions(+), 22 deletions(-) diff --git a/dub.json b/dub.json index 614ab67..6aa22ea 100644 --- a/dub.json +++ b/dub.json @@ -4,7 +4,8 @@ ], "copyright": "Copyright © 2022, Andrew Lalis", "dependencies": { - "gtk-d": "~>3.10.0" + "gtk-d": "~>3.10.0", + "dsh": "~>1.6.1" }, "stringImportPaths": [ "resources" diff --git a/dub.selections.json b/dub.selections.json index fd7260a..65cd0e3 100644 --- a/dub.selections.json +++ b/dub.selections.json @@ -1,6 +1,7 @@ { "fileVersion": 1, "versions": { + "dsh": "1.6.1", "gtk-d": "3.10.0" } } diff --git a/resources/todo-ui.glade b/resources/todo-ui.glade index 3dc8f12..656e54a 100644 --- a/resources/todo-ui.glade +++ b/resources/todo-ui.glade @@ -107,6 +107,7 @@ False True True + diff --git a/source/app.d b/source/app.d index a6baf3a..d5c9f75 100644 --- a/source/app.d +++ b/source/app.d @@ -2,6 +2,9 @@ import model; import std.stdio; import std.functional : toDelegate; +import dsh : getHomeDir; +import std.path; +import std.file; import gtk.MainWindow; import gtk.Main; @@ -63,6 +66,7 @@ void main(string[] args) { builder.addCallbackSymbol("onSaveAsMenuActivated", &onSaveAsMenuActivated); builder.addCallbackSymbol("onOpenMenuActivated", &onOpenMenuActivated); builder.addCallbackSymbol("onQuitMenuActivated", &onWindowDestroy); + builder.addCallbackSymbol("onAboutMenuActivated", &onAboutMenuActivated); builder.connectSignals(null); taskList = cast(ListBox) builder.getObject("taskList"); @@ -71,24 +75,53 @@ void main(string[] args) { taskEntry = cast(Entry) builder.getObject("addTaskEntry"); todoModel = new ToDoModel(); - todoModel.addListener(ModelUpdateListener.of(toDelegate(&itemsUpdated))); + string lastOpenPath = buildPath(getHomeDir(), ".config/todo-d/last-open.txt"); + if (exists(lastOpenPath)) { + import std.string : strip; + string lastOpenFile = readText(lastOpenPath).strip; + todoModel.openFromJson(lastOpenFile); + } window = cast(ApplicationWindow) builder.getObject("window"); + auto listener = new UIModelUpdateListener(window); + todoModel.addListener(listener); + + // Trigger UI updates once before rendering the window. + todoModel.notifyListeners(); + listener.fileUpdated(todoModel.getOpenFilename()); + window.showAll(); Main.run(); } -void itemsUpdated(ToDoItem[] items) { - taskList.removeAll(); - foreach (item; items) { - auto widget = new ToDoItemWidget(item, todoModel); - auto row = new ListBoxRow(); - row.setSelectable(true); - row.setActivatable(false); - row.add(widget); - taskList.add(row); +class UIModelUpdateListener : ModelUpdateListener { + private ApplicationWindow window; + + this(ApplicationWindow window) { + this.window = window; + } + + void itemsUpdated(ToDoItem[] items) { + taskList.removeAll(); + foreach (item; items) { + auto widget = new ToDoItemWidget(item, todoModel); + auto row = new ListBoxRow(); + row.setSelectable(true); + row.setActivatable(false); + row.add(widget); + taskList.add(row); + } + taskList.showAll(); + } + + void fileUpdated(string filename) { + if (filename is null) { + window.setTitle("todo-d"); + } else { + window.setTitle("todo-d - " ~ filename); + } + window.showAll(); } - taskList.showAll(); } bool taskListKeyPressed(GdkEventKey* event, Widget w) { @@ -146,6 +179,12 @@ extern (C) void onWindowDestroy() { Main.quit(); if (todoModel.getOpenFilename() !is null) { todoModel.saveToJson(todoModel.getOpenFilename()); + string configPath = buildPath(getHomeDir(), ".config/todo-d/"); + if (!exists(configPath)) { + mkdirRecurse(configPath); + } + string lastOpenFile = buildPath(configPath, "last-open.txt"); + std.file.write(lastOpenFile, todoModel.getOpenFilename()); } } @@ -191,3 +230,15 @@ extern (C) void onOpenMenuActivated() { } dialog.close(); } + +extern (C) void onAboutMenuActivated() { + import gtk.AboutDialog; + AboutDialog dialog = new AboutDialog(); + dialog.setProgramName("Todo-D"); + dialog.setLicenseType(GtkLicense.MIT_X11); + dialog.setAuthors(["Andrew Lalis"]); + dialog.setComments("A simple To-Do app written in D using GTK."); + dialog.setWebsite("https://github.com/andrewlalis/todo-d"); + dialog.run(); + dialog.destroy(); +} diff --git a/source/model.d b/source/model.d index d6b8534..2f87316 100644 --- a/source/model.d +++ b/source/model.d @@ -13,14 +13,7 @@ class ToDoItem { interface ModelUpdateListener { void itemsUpdated(ToDoItem[] items); - - static ModelUpdateListener of(void delegate(ToDoItem[]) dg) { - return new class ModelUpdateListener { - void itemsUpdated(ToDoItem[] items) { - dg(items); - } - }; - } + void fileUpdated(string filename); } class ToDoModel { @@ -108,7 +101,10 @@ class ToDoModel { ); items ~= item; } - openFilename = filename; + if (openFilename != filename) { + openFilename = filename; + foreach (l; listeners) l.fileUpdated(filename); + } sort!((a, b) => a.priority < b.priority)(items); normalizePrio(); notifyListeners(); @@ -128,12 +124,16 @@ class ToDoModel { } j["items"] = JSONValue(itemObjs); write(filename, toJSON(j, true)); - openFilename = filename; + if (openFilename != filename) { + openFilename = filename; + foreach (l; listeners) l.fileUpdated(filename); + } } void clear() { items = []; openFilename = null; + foreach (l; listeners) l.fileUpdated(openFilename); notifyListeners(); }