diff --git a/src/audrey.gresource.xml b/src/audrey.gresource.xml index de54e33..9fd414e 100644 --- a/src/audrey.gresource.xml +++ b/src/audrey.gresource.xml @@ -4,6 +4,7 @@ style.css gtk/help-overlay.ui ui/play_queue.ui + ui/play_queue_song.ui ui/setup.ui ui/window.ui diff --git a/src/ui/meson.build b/src/ui/meson.build index b168e86..a0ba2ba 100644 --- a/src/ui/meson.build +++ b/src/ui/meson.build @@ -1,7 +1,7 @@ blueprints = custom_target( 'blueprints', - input: files('play_queue.blp', 'setup.blp', 'window.blp'), - output: ['play_queue.ui', 'setup.ui', 'window.ui'], + input: files('play_queue.blp', 'play_queue_song.blp', 'setup.blp', 'window.blp'), + output: ['play_queue.ui', 'play_queue_song.ui', 'setup.ui', 'window.ui'], command: [ find_program('blueprint-compiler'), 'batch-compile', diff --git a/src/ui/play_queue.blp b/src/ui/play_queue.blp index b19271e..862453d 100644 --- a/src/ui/play_queue.blp +++ b/src/ui/play_queue.blp @@ -15,48 +15,13 @@ template $UiPlayQueue: Adw.NavigationPage { } ScrolledWindow { - ColumnView view { - styles [ "data-table" ] - + ListView view { model: bind template.selection; - //ColumnViewColumn { - // factory: SignalListItemFactory { - // setup => $on_delete_cell_setup (); - // }; - //} - - ColumnViewColumn { - title: _("Title"); - expand: true; - - factory: BuilderListItemFactory { - template ColumnViewCell { - child: Label { - halign: start; - label: bind template.item as <$SubsonicSong>.title; - tooltip-text: bind template.item as <$SubsonicSong>.title; - ellipsize: end; - }; - } - }; - } - - ColumnViewColumn { - title: _("Artist"); - fixed-width: 200; - - factory: BuilderListItemFactory { - template ColumnViewCell { - child: Label { - halign: start; - label: bind template.item as <$SubsonicSong>.artist; - tooltip-text: bind template.item as <$SubsonicSong>.artist; - ellipsize: end; - }; - } - }; - } + factory: SignalListItemFactory { + setup => $on_song_list_setup (); + bind => $on_song_list_bind (); + }; } } } diff --git a/src/ui/play_queue.vala b/src/ui/play_queue.vala index a9a64b3..9e06c2c 100644 --- a/src/ui/play_queue.vala +++ b/src/ui/play_queue.vala @@ -1,3 +1,17 @@ +[GtkTemplate (ui = "/eu/callcc/audrey/ui/play_queue_song.ui")] +class Ui.PlayQueueSong : Gtk.ListBoxRow { + public uint position { get; set; } + public Subsonic.Song song { get; set; } + + [GtkCallback] private string format_duration (int duration) { + return "%02d:%02d".printf(duration/60, duration%60); + } + + [GtkCallback] private string star_button_icon_name (DateTime? starred) { + return starred == null ? "non-starred" : "starred"; + } +} + [GtkTemplate (ui = "/eu/callcc/audrey/ui/play_queue.ui")] public class Ui.PlayQueue : Adw.NavigationPage { public PlayQueueSelection selection { get; default = new PlayQueueSelection (); } @@ -24,6 +38,19 @@ public class Ui.PlayQueue : Adw.NavigationPage { private void on_store_items_changed (GLib.ListModel store, uint position, uint removed, uint added) { this.can_clear_all = store.get_n_items () > 0; } + + [GtkCallback] private void on_song_list_setup (Gtk.SignalListItemFactory factory, Object object) { + var item = object as Gtk.ListItem; + item.child = new PlayQueueSong (); + } + + [GtkCallback] private void on_song_list_bind (Gtk.SignalListItemFactory factory, Object object) { + var item = object as Gtk.ListItem; + var child = item.child as PlayQueueSong; + + child.position = item.position+1; + child.song = item.item as Subsonic.Song; + } } // this is a custom SelectionModel that lets us only signal the diff --git a/src/ui/play_queue_song.blp b/src/ui/play_queue_song.blp new file mode 100644 index 0000000..9a78050 --- /dev/null +++ b/src/ui/play_queue_song.blp @@ -0,0 +1,121 @@ +using Gtk 4.0; + +template $UiPlayQueueSong: ListBoxRow { + selectable: false; + + Box { + focusable: false; + spacing: 6; + + Image { + visible: false; + icon-name: "list-drag-handle"; + styles [ "drag-handle" ] + } + + Box { + width-request: 48; + focusable: false; + homogeneous: true; + + Image { + focusable: false; + icon-size: normal; + //icon-name: "media-playback-start"; + } + + Label { + focusable: false; + halign: end; + justify: right; + styles [ "dim-label", "numeric" ] + + label: bind template.position; + } + } + + Box title_box { + focusable: false; + hexpand: true; + + Label { + focusable: false; + xalign: 0; + halign: start; + hexpand: true; + ellipsize: end; + max-width-chars: 90; + justify: fill; + margin-start: 9; + + label: bind template.song as <$SubsonicSong>.title; + } + } + + Box artist_box { + //visible: false; + focusable: false; + hexpand: true; + + Label { + focusable: false; + xalign: 0; + halign: start; + hexpand: true; + ellipsize: end; + max-width-chars: 90; + justify: fill; + margin-start: 9; + + label: bind template.song as <$SubsonicSong>.artist; + } + } + + Box album_duration_box { + focusable: false; + hexpand: true; + spacing: 6; + + Label { + //visible: false; + focusable: false; + xalign: 0; + halign: start; + hexpand: true; + ellipsize: end; + max-width-chars: 90; + justify: fill; + + label: bind template.song as <$SubsonicSong>.album; + } + + Label { + focusable: false; + halign: end; + hexpand: true; + single-line-mode: true; + styles [ "numeric" ] + + label: bind $format_duration (template.song as <$SubsonicSong>.duration) as ; + } + } + + Button { + focusable: true; + icon-name: bind $star_button_icon_name (template.song as <$SubsonicSong>.starred) as ; + styles [ "flat" ] + } + + MenuButton { + //visible: false; + focusable: true; + icon-name: "view-more"; + styles [ "flat" ] + } + } +} + +SizeGroup { + mode: horizontal; + widgets [title_box, artist_box, album_duration_box] +}