diff --git a/data/meson.build b/data/meson.build index 80189c5..c66579e 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,3 +1,7 @@ install_data( - meson.project_name() + '.gschema.xml' + meson.project_name() + '.gschema.xml', + + install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') ) + +subdir('ui') diff --git a/data/reclaim.gresource.xml b/data/reclaim.gresource.xml index 8eb5345..c41dd07 100644 --- a/data/reclaim.gresource.xml +++ b/data/reclaim.gresource.xml @@ -1,6 +1,12 @@ - + application.css + + ui/MainWindow.ui + ui/MainAccountListView.ui + ui/MainAccountListRow.ui + ui/ContentView.ui + diff --git a/data/ui/#Reclaim.ui# b/data/ui/#Reclaim.ui# new file mode 100644 index 0000000..67bb3c9 --- /dev/null +++ b/data/ui/#Reclaim.ui# @@ -0,0 +1,64 @@ + + + + + + False + + + True + True + True + + + True + False + + + True + True + + + True + False + label + + + + + + + False + True + + + + + True + False + crossfade + + + + + + + + + + + + + + + + + + True + True + + + + + + diff --git a/data/ui/#TransactionsView.ui# b/data/ui/#TransactionsView.ui# new file mode 100644 index 0000000..cc92a8a --- /dev/null +++ b/data/ui/#TransactionsView.ui# @@ -0,0 +1,12 @@ + + + + + + + False + + + + + diff --git a/data/ui/AccountTransactions.ui b/data/ui/AccountTransactions.ui new file mode 100644 index 0000000..1307a97 --- /dev/null +++ b/data/ui/AccountTransactions.ui @@ -0,0 +1,21 @@ + + + + diff --git a/data/ui/ContentView.ui b/data/ui/ContentView.ui new file mode 100644 index 0000000..6c2fdcf --- /dev/null +++ b/data/ui/ContentView.ui @@ -0,0 +1,25 @@ + + + + diff --git a/data/ui/MainAccountListRow.ui b/data/ui/MainAccountListRow.ui new file mode 100644 index 0000000..8d165cb --- /dev/null +++ b/data/ui/MainAccountListRow.ui @@ -0,0 +1,26 @@ + + + + diff --git a/data/ui/MainAccountListView.ui b/data/ui/MainAccountListView.ui new file mode 100644 index 0000000..d1d437f --- /dev/null +++ b/data/ui/MainAccountListView.ui @@ -0,0 +1,32 @@ + + + + diff --git a/data/ui/MainWindow.ui b/data/ui/MainWindow.ui new file mode 100644 index 0000000..513e714 --- /dev/null +++ b/data/ui/MainWindow.ui @@ -0,0 +1,174 @@ + + + + + + diff --git a/data/ui/MainWindow.ui~ b/data/ui/MainWindow.ui~ new file mode 100644 index 0000000..6b8e689 --- /dev/null +++ b/data/ui/MainWindow.ui~ @@ -0,0 +1,5 @@ + + + + + diff --git a/data/ui/Reclaim.ui~ b/data/ui/Reclaim.ui~ new file mode 100644 index 0000000..12b9344 --- /dev/null +++ b/data/ui/Reclaim.ui~ @@ -0,0 +1,57 @@ + + + + + + + False + Reclaim + + + 50 + True + True + start + start + False + True + True + + + True + False + start + + + True + True + + + True + False + label + + + + + + + False + True + + + + + True + False + gtk-about + + + True + True + + + + + + diff --git a/data/ui/TransactionsView.ui~ b/data/ui/TransactionsView.ui~ new file mode 100644 index 0000000..d4a5d6c --- /dev/null +++ b/data/ui/TransactionsView.ui~ @@ -0,0 +1,25 @@ + + + + + diff --git a/data/ui/meson.build b/data/ui/meson.build new file mode 100644 index 0000000..919e716 --- /dev/null +++ b/data/ui/meson.build @@ -0,0 +1,7 @@ +gnome = import ('gnome') + +reclaim_resources = gnome.compile_resources( + 'reclaim-resources', + 'reclaim.gresource.xml', + c_name: 'reclaim' +) diff --git a/meson.build b/meson.build index 60a91d2..c83f785 100644 --- a/meson.build +++ b/meson.build @@ -24,24 +24,12 @@ asresources = gnome.compile_resources( c_name: 'as' ) -conf_data = configuration_data() -conf_data.set_quoted('PROJECT_NAME', meson.project_name()) -conf_data.set_quoted('VERSION', meson.project_version()) -conf_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) -conf_data.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir'))) -config_header = configure_file( - input : 'config.vala.in', - output : 'config.vala', - configuration : conf_data -) - dependencies = [ dependency('gee-0.8'), dependency('glib-2.0'), dependency('gobject-2.0'), - dependency('gtk+-3.0'), - dependency('granite', version: '>=6.1.0'), - dependency('libhandy-1', version: '>=1.4.0'), + dependency('gtk4', version: '>=4.4.1'), + dependency('libadwaita-1', version: '>=1.0.1'), dependency('sqlite3'), meson.get_compiler('vala').find_library('posix'), @@ -49,4 +37,5 @@ dependencies = [ ] subdir('src') +subdir('data') subdir('po') diff --git a/src/Application.vala b/src/Application.vala index e7c7a4b..c7f7f0b 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -1,11 +1,16 @@ -public class Reclaim.Application : Gtk.Application { - public static GLib.Settings settings; +public class Reclaim.Application : Adw.Application { + public static int main (string[] args) { + var app = new Reclaim.Application (); - private MainWindow? main_window = null; + return app.run (args); + } + + public Application () { + Object ( + application_id: Config.APP_ID, + flags: ApplicationFlags.HANDLES_COMMAND_LINE + ); - construct { - flags |= ApplicationFlags.HANDLES_COMMAND_LINE; - application_id = "org.bonerbonerboner.reclaim"; Intl.setlocale (LocaleCategory.ALL, ""); Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); @@ -13,18 +18,28 @@ public class Reclaim.Application : Gtk.Application { Intl.textdomain (Config.GETTEXT_PACKAGE); } - static construct { -// settings = new GLib.Settings ("org.bonerbonerboner.reclaim"); + protected override void activate () { + active_window?.present (); } - public override void activate () { - if (main_window == null) { - main_window = new MainWindow (this); + protected override void startup () { + resource_base_path = "/boneboneboner/reclaim"; - main_window.show_all (); - } + base.startup (); + +// typeof (AccountListView).ensure (); + + // var account_repository = new AccountRespository (); + // var account_view_model = new AccountViewModel (account_repository); + // + typeof (ContentView).ensure (); + + new MainWindow (this); + } + + protected override void shutdown () { + base.shutdown (); - main_window.present (); } public override int command_line (ApplicationCommandLine command_line) { @@ -32,10 +47,4 @@ public class Reclaim.Application : Gtk.Application { return 0; } - - public static int main (string[] args) { - var app = new Reclaim.Application (); - - return app.run (args); - } } diff --git a/config.vala.in b/src/Config.vala.in similarity index 58% rename from config.vala.in rename to src/Config.vala.in index d6e9925..94442f6 100644 --- a/config.vala.in +++ b/src/Config.vala.in @@ -1,6 +1,9 @@ +[CCode (cprefix="", lower_case_cprefix = "", cheader_filename = "config.h")] namespace Config { + public const string APP_ID = @APP_ID@; public const string PROJECT_NAME = @PROJECT_NAME@; public const string VERSION = @VERSION@; public const string GETTEXT_PACKAGE = @GETTEXT_PACKAGE@; public const string LOCALEDIR = @LOCALEDIR@; + public const string DATADIR = @DATADIR@; } diff --git a/src/core/Account.vala b/src/core/Account.vala new file mode 100644 index 0000000..8b79439 --- /dev/null +++ b/src/core/Account.vala @@ -0,0 +1,6 @@ +namespace Reclaim { + public class Account : Object { + public int id { get; set; } + public string name { get; set; } + } +} diff --git a/src/meson.build b/src/meson.build index be1a75d..5e97256 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,9 +1,37 @@ source_files = files( 'Application.vala', - 'ui/TransactionsView.vala', + + 'utils/ObservableList.vala', + + 'repositories/AccountRepository.vala', + + 'core/Account.vala', + + 'repositories/AccountRepository.vala', + + 'ui/View.vala', + + 'ui/ContentView.vala', + 'ui/AccountViewModel.vala', + 'ui/MainAccountListView.vala', 'ui/MainWindow.vala' ) +conf_data = configuration_data() +conf_data.set_quoted('G_LOG_DOMAIN', 'Reclaim') +conf_data.set_quoted('APP_ID', 'com.bonerbonerboner.Reclaim') +conf_data.set_quoted('PROJECT_NAME', meson.project_name()) +conf_data.set_quoted('VERSION', meson.project_version()) +conf_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) +conf_data.set_quoted('DATADIR', join_paths(get_option('prefix'), get_option('datadir'))) +conf_data.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir'))) +config_header = configure_file( + input : 'Config.vala.in', + output : 'Config.vala', + configuration : conf_data +) + + executable( meson.project_name(), source_files, diff --git a/src/repositories/AccountRepository.vala b/src/repositories/AccountRepository.vala new file mode 100644 index 0000000..81d754b --- /dev/null +++ b/src/repositories/AccountRepository.vala @@ -0,0 +1,4 @@ +namespace Reclaim { + public class AccountRepository : Object { + } +} diff --git a/src/ui/AccountTransactions.vala b/src/ui/AccountTransactions.vala new file mode 100644 index 0000000..c8c2547 --- /dev/null +++ b/src/ui/AccountTransactions.vala @@ -0,0 +1,5 @@ +namespace Reclaim { + [GtkTempalte (ui = "/reclaim/AccountTransactions.ui")] + public class AccountTransactions : GtkBox { + } +} diff --git a/src/ui/AccountViewModel.vala b/src/ui/AccountViewModel.vala new file mode 100644 index 0000000..b11aa22 --- /dev/null +++ b/src/ui/AccountViewModel.vala @@ -0,0 +1,10 @@ +namespace Reclaim { + public class AccountViewModel : Object { + public ObservableList accounts { get; default = new ObservableList (); } + public AccountRepository? repository { get; construct; } + + public AccountViewModel (AccountRepository repository) { + Object(repository: repository); + } + } +} diff --git a/src/ui/ContentView.vala b/src/ui/ContentView.vala new file mode 100644 index 0000000..2253e41 --- /dev/null +++ b/src/ui/ContentView.vala @@ -0,0 +1,5 @@ +namespace Reclaim { + [GtkTemplate (ui = "/reclaim/ContentView.ui")] + public class ContentView : View { + } +} diff --git a/src/ui/MainAccountListView.vala b/src/ui/MainAccountListView.vala new file mode 100644 index 0000000..09031b1 --- /dev/null +++ b/src/ui/MainAccountListView.vala @@ -0,0 +1,5 @@ +namespace Reclaim { + [GtkTemplate (ui = "/reclaim/MainAccountListView.ui")] + public class MainAccountListView : View { + } +} diff --git a/src/ui/MainWindow.vala b/src/ui/MainWindow.vala index 7233fec..4ee9589 100644 --- a/src/ui/MainWindow.vala +++ b/src/ui/MainWindow.vala @@ -1,41 +1,14 @@ namespace Reclaim { - public class MainWindow : Hdy.ApplicationWindow { + [GtkTemplate (ui = "/reclaim/MainWindow.ui")] + public class MainWindow : Adw.ApplicationWindow { public Reclaim.Application app { get; construct; } - public Reclaim.TransactionView transaction_view { get; construct; } + public MainWindow? main_window { get; set; } + public Adw.Leaflet? leaflet { get; set; } public MainWindow (Reclaim.Application app) { - Object ( - app: app - ); - } - - static construct { - Hdy.init (); - } - - construct { - set_application (app); - - // temp code for now - var store = new Gtk.TreeStore (2, typeof(string), typeof(string)); - - var transaction_view = new Reclaim.TransactionView(); - transaction_view.set_model(store); - add(transaction_view); - - set_visual (Gdk.Screen.get_default ().get_rgba_visual ()); - - setup_ui (); - show_all (); - } - - private void setup_ui () { - var provider = new Gtk.CssProvider (); - - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), - provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + 1 + GLib.Object ( + application: app, + title: "Reclaim" ); } } diff --git a/src/ui/TransactionsView.vala b/src/ui/TransactionsView.vala deleted file mode 100644 index 47ace92..0000000 --- a/src/ui/TransactionsView.vala +++ /dev/null @@ -1,33 +0,0 @@ -using Gtk; - -namespace Reclaim { - public class TransactionView : TreeView { - - public TreeViewColumn date_column { get; construct; } - public TreeViewColumn payee_column { get; construct; } - - construct { - date_column = new TreeViewColumn (); - payee_column = new TreeViewColumn (); - - setup_ui (); - } - - private void setup_ui () { - date_column.title = _("Date"); - var date_cell = new CellRendererText (); - date_column.add_attribute (date_cell, "text", 0); - date_column.set_resizable (true); - date_column.pack_start (date_cell, true); - - payee_column.title = _("Payee"); - payee_column.set_resizable (true); - var payee_cell = new CellRendererText (); - payee_column.add_attribute (payee_cell, "text", 1); - payee_column.pack_start (payee_cell, true); - - append_column (date_column); - append_column (payee_column); - } - } -} diff --git a/src/ui/View.vala b/src/ui/View.vala new file mode 100644 index 0000000..9b200e6 --- /dev/null +++ b/src/ui/View.vala @@ -0,0 +1,35 @@ +using Gtk; +using Adw; + +namespace Reclaim { + public abstract class View : Widget, Buildable { + Bin? child_bin = new Bin () { vexpand = true }; + + public Widget? child { + get { return child_bin.child; } + set { child_bin.child = value; } + } + + construct { + layout_manager = new BoxLayout (VERTICAL); + + child_bin?.set_parent (this); + } + + protected override void dispose () { + child_bin?.unparent (); + child_bin = null; + + base.dispose (); + } + + void add_child (Builder builder, Object child, string? type) { + if (child is Widget) { + this.child = (Widget) child; + return; + } + + base.add_child (builder, child, type); + } + } +} diff --git a/src/utils/ObservableList.vala b/src/utils/ObservableList.vala new file mode 100644 index 0000000..694d26a --- /dev/null +++ b/src/utils/ObservableList.vala @@ -0,0 +1,56 @@ +namespace Reclaim { + public class ObservableList : Object, ListModel { + List data = new List (); + + public void add (T item) { + var position = data.length (); + + data.append (item); + + items_changed (position, 0, 1); + } + + public void add_all (List items) { + var position = data.length (); + + foreach (var item in items) + data.append (item); + + items_changed (position, 0, items.length ()); + } + + public void remove_all () { + var current_size = data.length (); + data = new List (); + items_changed (0, current_size, 0); + } + + public new T @get (uint index) { + return data.nth_data (index); + } + + public bool remove (T item) { + var position = data.index (item); + + if (position == -1) + return false; + + data.remove (item); + items_changed (position, 1, 0); + + return true; + } + + Object? get_item (uint position) { + return this[position] as Object; + } + + Type get_item_type () { + return typeof (T); + } + + uint get_n_items () { + return data.length (); + } + } +}