diff --git a/src/artist_list.blp b/src/artist_list.blp
new file mode 100644
index 0000000..64f808b
--- /dev/null
+++ b/src/artist_list.blp
@@ -0,0 +1,32 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $WaveletArtistList: Adw.NavigationPage {
+ title: _("Artists");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {}
+
+ Stack stack {
+ StackPage {
+ name: "loading";
+
+ child: Adw.Spinner {};
+ }
+
+ StackPage {
+ name: "ready";
+
+ child: ScrolledWindow {
+ ListView list_view {
+ factory: BuilderListItemFactory {
+ resource: "/eu/callcc/Wavelet/artist_list_artist.ui";
+ };
+ }
+ };
+ }
+ }
+ }
+}
+
diff --git a/src/artist_list.ui b/src/artist_list.ui
deleted file mode 100644
index 3dc832c..0000000
--- a/src/artist_list.ui
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
- Artists
-
-
-
-
-
diff --git a/src/artist_list_artist.blp b/src/artist_list_artist.blp
new file mode 100644
index 0000000..2404518
--- /dev/null
+++ b/src/artist_list_artist.blp
@@ -0,0 +1,9 @@
+using Gtk 4.0;
+
+template ListItem {
+ child: Label {
+ halign: start;
+ label: bind template.item as <$WaveletArtist>.name;
+ };
+}
+
diff --git a/src/artist_list_artist.ui b/src/artist_list_artist.ui
deleted file mode 100644
index 449f4bc..0000000
--- a/src/artist_list_artist.ui
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
- start
-
-
- GtkListItem
-
-
-
-
-
-
diff --git a/src/meson.build b/src/meson.build
index f0cc18b..7927bab 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -18,9 +18,40 @@ wavelet_deps = [
dependency('sqlite3'),
]
+blueprints = custom_target('blueprints',
+ input: files(
+ 'artist_list.blp',
+ 'artist_list_artist.blp',
+ 'play_queue.blp',
+ 'play_queue_song.blp',
+ 'setup.blp',
+ 'song_list.blp',
+ 'song_list_song.blp',
+ 'window.blp',
+ ),
+ output: [
+ 'artist_list.ui',
+ 'artist_list_artist.ui',
+ 'play_queue.ui',
+ 'play_queue_song.ui',
+ 'setup.ui',
+ 'song_list.ui',
+ 'song_list_song.ui',
+ 'window.ui',
+ ],
+ command: [
+ find_program('blueprint-compiler'),
+ 'batch-compile',
+ '@OUTDIR@',
+ '@CURRENT_SOURCE_DIR@',
+ '@INPUT@',
+ ],
+)
+
wavelet_sources += gnome.compile_resources('wavelet-resources',
'wavelet.gresource.xml',
- c_name: 'wavelet'
+ c_name: 'wavelet',
+ dependencies: blueprints,
)
executable('wavelet', wavelet_sources,
diff --git a/src/play_queue.blp b/src/play_queue.blp
new file mode 100644
index 0000000..3e3cb83
--- /dev/null
+++ b/src/play_queue.blp
@@ -0,0 +1,24 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $WaveletPlayQueue: Adw.NavigationPage {
+ title: _("Play queue");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {}
+
+ ScrolledWindow {
+ ListView list_view {
+ styles [
+ "view",
+ ]
+
+ factory: BuilderListItemFactory {
+ resource: "/eu/callcc/Wavelet/play_queue_song.ui";
+ };
+ }
+ }
+ }
+}
+
diff --git a/src/play_queue.ui b/src/play_queue.ui
deleted file mode 100644
index 4218c20..0000000
--- a/src/play_queue.ui
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
- Play queue
-
-
-
-
-
-
-
-
-
-
-
-
- /eu/callcc/Wavelet/play_queue_song.ui
-
-
-
-
-
-
-
-
-
-
diff --git a/src/play_queue_song.blp b/src/play_queue_song.blp
new file mode 100644
index 0000000..f8c28ee
--- /dev/null
+++ b/src/play_queue_song.blp
@@ -0,0 +1,9 @@
+using Gtk 4.0;
+
+template ListItem {
+ child: Label {
+ halign: start;
+ label: bind template.item as <$WaveletSong>.name;
+ };
+}
+
diff --git a/src/play_queue_song.ui b/src/play_queue_song.ui
deleted file mode 100644
index 2d7d76a..0000000
--- a/src/play_queue_song.ui
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
- start
-
-
- GtkListItem
-
-
-
-
-
-
diff --git a/src/setup.blp b/src/setup.blp
new file mode 100644
index 0000000..f1d8e6d
--- /dev/null
+++ b/src/setup.blp
@@ -0,0 +1,45 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $WaveletSetup: Adw.NavigationPage {
+ title: _("Setup");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {}
+
+ Adw.Clamp {
+ child: Adw.PreferencesGroup {
+ title: "Authentication";
+
+ Adw.EntryRow server_url {
+ title: "Server URL";
+ input-purpose: url;
+ }
+
+ Adw.EntryRow username {
+ title: "Username";
+ }
+
+ Adw.PasswordEntryRow password {
+ title: "Password";
+ }
+
+ Adw.ActionRow status {
+ title: "Status";
+ subtitle: "Not connected";
+
+ styles [
+ "property",
+ ]
+ }
+
+ Adw.ButtonRow validate {
+ title: "Connect and save";
+ sensitive: false;
+ }
+ };
+ }
+ }
+}
+
diff --git a/src/setup.ui b/src/setup.ui
deleted file mode 100644
index 895a897..0000000
--- a/src/setup.ui
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
- Setup
-
-
-
-
-
-
-
-
-
- Authentication
-
-
- Server URL
- url
-
-
-
-
- Username
-
-
-
-
- Password
-
-
-
-
- Status
- Not connected
-
-
-
-
-
- Connect and save
- False
-
-
-
-
-
-
-
-
-
-
diff --git a/src/song_list.blp b/src/song_list.blp
new file mode 100644
index 0000000..ad903de
--- /dev/null
+++ b/src/song_list.blp
@@ -0,0 +1,56 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $WaveletSongList: Adw.NavigationPage {
+ title: _("Songs");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {}
+
+ Stack stack {
+ StackPage {
+ name: "loading";
+
+ child: Adw.Spinner {};
+ }
+
+ StackPage {
+ name: "ready";
+
+ child: ScrolledWindow {
+ ColumnView column_view {
+ ColumnViewColumn title_column {
+ title: "Title";
+ resizable: true;
+
+ factory: SignalListItemFactory {};
+ }
+
+ ColumnViewColumn album_column {
+ title: "Album";
+ resizable: true;
+
+ factory: SignalListItemFactory {};
+ }
+
+ ColumnViewColumn artist_column {
+ title: "Artist";
+ resizable: true;
+
+ factory: SignalListItemFactory {};
+ }
+
+ ColumnViewColumn track_column {
+ title: "#";
+ resizable: true;
+
+ factory: SignalListItemFactory {};
+ }
+ }
+ };
+ }
+ }
+ }
+}
+
diff --git a/src/song_list.ui b/src/song_list.ui
deleted file mode 100644
index 54df915..0000000
--- a/src/song_list.ui
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
- Songs
-
-
-
-
-
-
-
-
-
- loading
-
-
-
-
-
-
-
- ready
-
-
-
-
-
-
- Title
- True
-
-
-
-
-
-
-
- Album
- True
-
-
-
-
-
-
-
- Artist
- True
-
-
-
-
-
-
-
- #
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/song_list_song.blp b/src/song_list_song.blp
new file mode 100644
index 0000000..3b518d6
--- /dev/null
+++ b/src/song_list_song.blp
@@ -0,0 +1,9 @@
+using Gtk 4.0;
+
+template ListItem {
+ child: Label {
+ halign: start;
+ label: bind template.item as <$WaveletSong>.title;
+ };
+}
+
diff --git a/src/song_list_song.ui b/src/song_list_song.ui
deleted file mode 100644
index 661053b..0000000
--- a/src/song_list_song.ui
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
- start
-
-
- GtkListItem
-
-
-
-
-
-
diff --git a/src/window.blp b/src/window.blp
new file mode 100644
index 0000000..a17b0e3
--- /dev/null
+++ b/src/window.blp
@@ -0,0 +1,200 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $WaveletWindow: Adw.ApplicationWindow {
+ title: _("Wavelet");
+ default-width: 800;
+ default-height: 600;
+
+ content: Box {
+ orientation: vertical;
+
+ Adw.OverlaySplitView {
+ vexpand: true;
+
+ [sidebar]
+ Adw.NavigationPage {
+ width-request: 100;
+ title: _("Wavelet");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {}
+
+ content: Box {
+ orientation: vertical;
+
+ ListBox sidebar {
+ styles [
+ "navigation-sidebar",
+ ]
+
+ ListBoxRow sidebar_setup {
+ Label {
+ xalign: 0;
+ label: "Setup";
+ }
+ }
+
+ ListBoxRow sidebar_play_queue {
+ Label {
+ xalign: 0;
+ label: "Play queue";
+ }
+ }
+ }
+
+ Separator {}
+
+ ListBox {
+ selection-mode: none;
+
+ styles [
+ "navigation-sidebar",
+ ]
+
+ Adw.ButtonRow {
+ title: "Shuffle all tracks";
+ start-icon-name: "media-playlist-shuffle";
+ }
+ }
+ };
+ }
+ }
+
+ [content]
+ Stack stack {
+ StackPage {
+ name: "setup";
+ title: "Setup";
+
+ child: $WaveletSetup setup {};
+ }
+
+ StackPage {
+ name: "artist_list";
+ title: "Artists";
+
+ child: $WaveletArtistList artist_list {};
+ }
+
+ StackPage {
+ name: "song_list";
+ title: "Songs";
+
+ child: $WaveletSongList song_list {};
+ }
+
+ StackPage {
+ name: "play_queue";
+ title: "Play queue";
+
+ child: $WaveletPlayQueue play_queue {};
+ }
+ }
+ }
+
+ [bottom]
+ Box {
+ orientation: horizontal;
+
+ styles [
+ "toolbar",
+ ]
+
+ Image {
+ height-request: 100;
+ width-request: 100;
+ }
+
+ Box {
+ orientation: vertical;
+ valign: center;
+
+ Label {
+ halign: start;
+ label: "Title";
+ }
+
+ Label {
+ halign: start;
+ label: "Artist - Album - Year";
+ }
+
+ Box {
+ halign: start;
+ orientation: horizontal;
+
+ Label {
+ label: "00:00";
+ }
+
+ Scale {
+ orientation: horizontal;
+ width-request: 200;
+
+ adjustment: Adjustment {
+ lower: 0;
+ upper: 100;
+ value: 0;
+ };
+ }
+
+ Label {
+ label: "99:99";
+ }
+ }
+ }
+
+ Separator {
+ styles [
+ "spacer",
+ ]
+
+ hexpand: true;
+ }
+
+ Button {
+ icon-name: "media-skip-backward";
+ valign: center;
+ }
+
+ Button {
+ icon-name: "media-playback-start";
+ valign: center;
+ }
+
+ Button {
+ icon-name: "media-skip-forward";
+ valign: center;
+ }
+
+ Button {
+ icon-name: "non-starred";
+ valign: center;
+ }
+
+ Button {
+ icon-name: "audio-volume-high";
+ valign: center;
+ }
+
+ Scale {
+ orientation: horizontal;
+ width-request: 130;
+
+ adjustment: Adjustment {
+ lower: 0;
+ upper: 100;
+ value: 100;
+ };
+ }
+
+ Button {
+ icon-name: "media-playlist-consecutive";
+ valign: center;
+ }
+ }
+ };
+}
+
diff --git a/src/window.ui b/src/window.ui
deleted file mode 100644
index 6f29edf..0000000
--- a/src/window.ui
+++ /dev/null
@@ -1,241 +0,0 @@
-
-
-
-
-
- Wavelet
-
- 800
- 600
-
-
- vertical
-
-
- true
-
-
- 100
- Wavelet
-
-
-
-
-
-
-
- vertical
-
-
-
-
-
-
-
-
-
- none
-
-
-
- Shuffle all tracks
- media-playlist-shuffle
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setup
- Setup
-
-
-
-
-
-
-
- artist_list
- Artists
-
-
-
-
-
-
-
- song_list
- Songs
-
-
-
-
-
-
-
- play_queue
- Play queue
-
-
-
-
-
-
-
-
-
-
-
- 0
-
-
-
- 100
- 100
-
-
-
-
- 1
- 3
-
-
- 1
- Title
-
-
-
-
- 1
- Artist - Album - Year
-
-
-
-
- 1
- 0
-
-
- 00:00
-
-
-
-
- 0
- 200
-
-
- 0
- 100
- 0
-
-
-
-
-
-
- 99:99
-
-
-
-
-
-
-
-
-
- true
-
-
-
-
- media-skip-backward
- 3
-
-
-
-
- media-playback-start
- 3
-
-
-
-
- media-skip-forward
- 3
-
-
-
-
- non-starred
- 3
-
-
-
-
- audio-volume-high
- 3
-
-
-
-
- 0
- 130
-
-
- 0
- 100
- 100
-
-
-
-
-
-
- media-playlist-consecutive
- 3
-
-
-
-
-
-
-
-