Added about page, and better file operation.
This commit is contained in:
parent
aded0b6400
commit
c25f04ad15
3
dub.json
3
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"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"fileVersion": 1,
|
||||
"versions": {
|
||||
"dsh": "1.6.1",
|
||||
"gtk-d": "3.10.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="onAboutMenuActivated" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
55
source/app.d
55
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,14 +75,33 @@ 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) {
|
||||
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);
|
||||
|
@ -89,6 +112,16 @@ void itemsUpdated(ToDoItem[] items) {
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
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));
|
||||
if (openFilename != filename) {
|
||||
openFilename = filename;
|
||||
foreach (l; listeners) l.fileUpdated(filename);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
items = [];
|
||||
openFilename = null;
|
||||
foreach (l; listeners) l.fileUpdated(openFilename);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue