Added resources!

This commit is contained in:
Andrew Lalis 2022-04-29 08:46:52 +02:00
parent 710379c19f
commit 93f6fd7d18
6 changed files with 128 additions and 55 deletions

2
.gitignore vendored
View File

@ -13,3 +13,5 @@ todo-d-test-*
*.o *.o
*.obj *.obj
*.lst *.lst
*.glade~
*.gresource

View File

@ -6,6 +6,12 @@
"dependencies": { "dependencies": {
"gtk-d": "~>3.10.0" "gtk-d": "~>3.10.0"
}, },
"stringImportPaths": [
"resources"
],
"preBuildCommands": [
"glib-compile-resources --sourcedir=resources --target=resources/resources.gresource resources/gresource.xml"
],
"description": "A simple to-do list, implemented as a desktop application in D.", "description": "A simple to-do list, implemented as a desktop application in D.",
"license": "MIT", "license": "MIT",
"name": "todo-d" "name": "todo-d"

View File

@ -35,6 +35,8 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="onNewMenuActivated" swapped="no"/>
<accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
@ -44,24 +46,28 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="onOpenMenuActivated" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkImageMenuItem"> <object class="GtkImageMenuItem" id="saveMenuItem">
<property name="label">gtk-save</property> <property name="label">gtk-save</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="onSaveMenuActivated" swapped="no"/>
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkImageMenuItem"> <object class="GtkImageMenuItem" id="saveAsMenuItem">
<property name="label">gtk-save-as</property> <property name="label">gtk-save-as</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="onSaveAsMenuActivated" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
@ -84,56 +90,6 @@
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem">
<property name="label">gtk-cut</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem">
<property name="label">gtk-copy</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem">
<property name="label">gtk-paste</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem">
<property name="label">gtk-delete</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
@ -145,7 +101,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkImageMenuItem"> <object class="GtkImageMenuItem" id="aboutMenuItem">
<property name="label">gtk-about</property> <property name="label">gtk-about</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
@ -213,6 +169,7 @@
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="always_show_image">True</property> <property name="always_show_image">True</property>
<signal name="clicked" handler="onAddTask" swapped="no"/> <signal name="clicked" handler="onAddTask" swapped="no"/>
<accelerator key="Return" signal="clicked"/>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>

View File

@ -14,6 +14,8 @@ import gtk.Label;
import gtk.CheckButton; import gtk.CheckButton;
import gtk.ToggleButton; import gtk.ToggleButton;
import gtk.Button; import gtk.Button;
import gio.Resource;
import glib.Bytes;
class ToDoItemWidget : Box { class ToDoItemWidget : Box {
this(ToDoItem item, ToDoModel todoModel) { this(ToDoItem item, ToDoModel todoModel) {
@ -54,15 +56,26 @@ class ToDoItemWidget : Box {
Entry taskEntry; Entry taskEntry;
ListBox taskList; ListBox taskList;
ApplicationWindow window;
ToDoModel todoModel; ToDoModel todoModel;
void main(string[] args) { void main(string[] args) {
Main.init(args); Main.init(args);
Builder builder = new Builder("todo-ui.glade");
auto bytes = new Bytes(cast(ubyte[]) import("resources.gresource"));
Resource.register(new Resource(bytes));
Builder builder = new Builder();
builder.addFromResource("/ui/todo-ui.glade");
builder.addCallbackSymbol("onAddTask", &addTask); builder.addCallbackSymbol("onAddTask", &addTask);
builder.addCallbackSymbol("onWindowDestroy", &onWindowDestroy); builder.addCallbackSymbol("onWindowDestroy", &onWindowDestroy);
builder.addCallbackSymbol("onNewMenuActivated", &onNewMenuActivated);
builder.addCallbackSymbol("onSaveMenuActivated", &onSaveMenuActivated);
builder.addCallbackSymbol("onSaveAsMenuActivated", &onSaveAsMenuActivated);
builder.addCallbackSymbol("onOpenMenuActivated", &onOpenMenuActivated);
builder.addCallbackSymbol("onQuitMenuActivated", &onWindowDestroy); builder.addCallbackSymbol("onQuitMenuActivated", &onWindowDestroy);
builder.connectSignals(null); builder.connectSignals(null);
@ -73,7 +86,7 @@ void main(string[] args) {
import std.functional : toDelegate; import std.functional : toDelegate;
todoModel.addListener(ModelUpdateListener.of(toDelegate(&itemsUpdated))); todoModel.addListener(ModelUpdateListener.of(toDelegate(&itemsUpdated)));
ApplicationWindow window = cast(ApplicationWindow) builder.getObject("window"); window = cast(ApplicationWindow) builder.getObject("window");
window.showAll(); window.showAll();
Main.run(); Main.run();
} }
@ -96,4 +109,50 @@ extern (C) void addTask() {
extern (C) void onWindowDestroy() { extern (C) void onWindowDestroy() {
Main.quit(); Main.quit();
if (todoModel.getOpenFilename() !is null) {
todoModel.saveToJson(todoModel.getOpenFilename());
}
}
extern (C) void onNewMenuActivated() {
todoModel.clear();
}
extern (C) void onSaveMenuActivated() {
if (todoModel.getOpenFilename() is null) {
onSaveAsMenuActivated();
} else {
todoModel.saveToJson(todoModel.getOpenFilename());
}
}
extern (C) void onSaveAsMenuActivated() {
import gtk.FileChooserDialog;
auto dialog = new FileChooserDialog(
"Save As",
window,
FileChooserAction.SAVE
);
if (todoModel.getOpenFilename() !is null) {
dialog.setFilename(todoModel.getOpenFilename());
}
int result = dialog.run();
if (result == -5) {
todoModel.saveToJson(dialog.getFilename());
}
dialog.close();
}
extern (C) void onOpenMenuActivated() {
import gtk.FileChooserDialog;
auto dialog = new FileChooserDialog(
"Open",
window,
FileChooserAction.OPEN
);
int result = dialog.run();
if (result == -5) {
todoModel.openFromJson(dialog.getFilename());
}
dialog.close();
} }

View File

@ -26,11 +26,16 @@ interface ModelUpdateListener {
class ToDoModel { class ToDoModel {
private ToDoItem[] items; private ToDoItem[] items;
private ModelUpdateListener[] listeners; private ModelUpdateListener[] listeners;
private string openFilename = null;
void addListener(ModelUpdateListener listener) { void addListener(ModelUpdateListener listener) {
listeners ~= listener; listeners ~= listener;
} }
string getOpenFilename() {
return openFilename;
}
void addItem(string text) { void addItem(string text) {
addItem(new ToDoItem(text, 1_000_000, false)); addItem(new ToDoItem(text, 1_000_000, false));
} }
@ -79,6 +84,50 @@ class ToDoModel {
notifyListeners(); notifyListeners();
} }
void openFromJson(string filename) {
import std.json;
import std.file;
import std.algorithm;
JSONValue j = parseJSON(readText(filename));
JSONValue[] itemsArray = j["items"].array();
items = [];
foreach (JSONValue itemObj; itemsArray) {
ToDoItem item = new ToDoItem(
itemObj["text"].str,
itemObj["priority"].get!int,
itemObj["checked"].boolean
);
items ~= item;
}
openFilename = filename;
sort!((a, b) => a.priority < b.priority)(items);
normalizePrio();
notifyListeners();
}
void saveToJson(string filename) {
import std.json;
import std.file;
JSONValue j = JSONValue();
JSONValue[] itemObjs;
foreach (item; items) {
JSONValue itemObj = JSONValue();
itemObj["text"] = JSONValue(item.text);
itemObj["priority"] = JSONValue(item.priority);
itemObj["checked"] = JSONValue(item.checked);
itemObjs ~= itemObj;
}
j["items"] = JSONValue(itemObjs);
write(filename, toJSON(j, true));
openFilename = filename;
}
void clear() {
items = [];
openFilename = null;
notifyListeners();
}
private void normalizePrio() { private void normalizePrio() {
int prio = 1; int prio = 1;
foreach (item; items) { foreach (item; items) {