Changes
13 changed files (+458/-14)
-
-
@@ -18,6 +18,9 @@ SPDX-License-Identifier: Apache-2.0--> <gresources> <gresource prefix="/jp/pocka/plac/gtk-adwaita"> <file preprocess="xml-stripblanks">ui/browse.ui</file> <file preprocess="xml-stripblanks">ui/browse-item-navigation.ui</file> <file preprocess="xml-stripblanks">ui/browse-item-row.ui</file> <file preprocess="xml-stripblanks">ui/main-window.ui</file> <file preprocess="xml-stripblanks">ui/playback-toolbar.ui</file> <file preprocess="xml-stripblanks">ui/server-list.ui</file>
-
@@ -25,6 +28,8 @@ <file preprocess="xml-stripblanks">ui/generic-error-dialog.ui</file><file preprocess="xml-stripblanks">ui/server-connecting.ui</file> <file preprocess="xml-stripblanks">ui/server-list-unexpected-error-dialog.ui</file> <file preprocess="xml-stripblanks">ui/server-list-network-error-dialog.ui</file> <file preprocess="xml-stripblanks">icons/scalable/actions/go-next-symbolic.svg</file> <file preprocess="xml-stripblanks">icons/scalable/actions/go-previous-symbolic.svg</file> <file preprocess="xml-stripblanks">icons/scalable/actions/item-missing-symbolic.svg</file> <file preprocess="xml-stripblanks">icons/scalable/actions/library-music-symbolic.svg</file> <file preprocess="xml-stripblanks">icons/scalable/actions/pause-large-symbolic.svg</file>
-
-
-
@@ -0,0 +1,8 @@<?xml version="1.0" encoding="UTF-8"?> <!-- SPDX-FileCopyrightText: Gnome Developers SPDX-License-Identifier: CC0-1.0 --> <svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg"> <path d="m 4 2 c 0 -0.265625 0.105469 -0.519531 0.292969 -0.707031 c 0.390625 -0.390625 1.023437 -0.390625 1.414062 0 l 6 6 c 0.1875 0.1875 0.292969 0.441406 0.292969 0.707031 s -0.105469 0.519531 -0.292969 0.707031 l -6 6 c -0.390625 0.390625 -1.023437 0.390625 -1.414062 0 c -0.1875 -0.1875 -0.292969 -0.441406 -0.292969 -0.707031 s 0.105469 -0.519531 0.292969 -0.707031 l 5.292969 -5.292969 l -5.292969 -5.292969 c -0.1875 -0.1875 -0.292969 -0.441406 -0.292969 -0.707031 z m 0 0" fill="#2e3436"/> </svg>
-
-
-
@@ -0,0 +1,8 @@<?xml version="1.0" encoding="UTF-8"?> <!-- SPDX-FileCopyrightText: Gnome Developers SPDX-License-Identifier: CC0-1.0 --> <svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg"> <path d="m 12 2 c 0 -0.265625 -0.105469 -0.519531 -0.292969 -0.707031 c -0.390625 -0.390625 -1.023437 -0.390625 -1.414062 0 l -6 6 c -0.1875 0.1875 -0.292969 0.441406 -0.292969 0.707031 s 0.105469 0.519531 0.292969 0.707031 l 6 6 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 c 0.1875 -0.1875 0.292969 -0.441406 0.292969 -0.707031 s -0.105469 -0.519531 -0.292969 -0.707031 l -5.292969 -5.292969 l 5.292969 -5.292969 c 0.1875 -0.1875 0.292969 -0.441406 0.292969 -0.707031 z m 0 0" fill="#2e3436"/> </svg>
-
-
-
@@ -0,0 +1,63 @@<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2025 Shota FUJI Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. SPDX-License-Identifier: Apache-2.0 --> <interface> <template class="PlacGtkAdwaitaBrowseItemNavigation" parent="GtkBox"> <property name="orientation">horizontal</property> <property name="spacing">4</property> <property name="margin-top">8</property> <binding name="margin-bottom"> <lookup name="margin-top" type="PlacGtkAdwaitaBrowseItemNavigation" /> </binding> <property name="margin-start">8</property> <binding name="margin-end"> <lookup name="margin-start" type="PlacGtkAdwaitaBrowseItemNavigation" /> </binding> <child> <object class="GtkBox"> <property name="orientation">vertical</property> <property name="spacing">2</property> <property name="hexpand">true</property> <child> <object class="GtkLabel" id="title"> <property name="ellipsize">end</property> <property name="xalign">0</property> <style> <class name="heading" /> </style> </object> </child> <child> <object class="GtkLabel" id="subtitle"> <property name="visible">false</property> <property name="ellipsize">end</property> <property name="xalign">0</property> <style> <class name="body" /> </style> </object> </child> </object> </child> <child> <object class="GtkImage"> <property name="icon-name">go-next-symbolic</property> </object> </child> </template> </interface>
-
-
-
@@ -0,0 +1,28 @@<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2025 Shota FUJI Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. SPDX-License-Identifier: Apache-2.0 --> <interface> <template class="PlacGtkAdwaitaBrowseItemRow" parent="GtkListBoxRow"> <property name="selectable">false</property> <property name="margin-top">12</property> <property name="margin-start">12</property> <binding name="margin-end"> <lookup name="margin-start" type="PlacGtkAdwaitaBrowseItemRow" /> </binding> </template> </interface>
-
-
-
@@ -0,0 +1,117 @@<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2025 Shota FUJI Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. SPDX-License-Identifier: Apache-2.0 --> <interface> <template class="PlacGtkAdwaitaBrowse" parent="GtkBox"> <property name="orientation">vertical</property> <style> <class name="view" /> </style> <child> <object class="GtkOverlay"> <child> <object class="GtkBox"> <property name="orientation">vertical</property> <child> <object class="GtkBox" id="metadata"> <property name="margin-top">20</property> <property name="margin-bottom">10</property> <property name="margin-start">12</property> <binding name="margin-end"> <lookup name="margin-start">metadata</lookup> </binding> <property name="orientation">vertical</property> <child> <object class="GtkBox"> <property name="orientation">horizontal</property> <property name="spacing">4</property> <child> <object class="GtkButton" id="back"> <property name="visible">false</property> <property name="icon-name">go-previous-symbolic</property> <style> <class name="flat" /> </style> </object> </child> <child> <object class="GtkLabel" id="title"> <property name="margin-start">4</property> <property name="xalign">0</property> <style> <class name="title-1" /> </style> </object> </child> </object> </child> <child> <object class="GtkLabel" id="subtitle"> <property name="visible">false</property> <property name="xalign">0</property> <style> <class name="title-2" /> </style> </object> </child> </object> </child> <child> <object class="GtkScrolledWindow"> <property name="vexpand">true</property> <property name="child"> <object class="GtkListBox" id="items"> <property name="margin-bottom">12</property> </object> </property> </object> </child> </object> </child> <child type="overlay"> <object class="GtkBox" id="loading"> <property name="visible">false</property> <property name="halign">end</property> <property name="valign">start</property> <property name="orientation">horizontal</property> <property name="spacing">4</property> <property name="margin-top">2</property> <property name="margin-end">2</property> <style> <class name="osd" /> </style> <child> <object class="AdwSpinner"> <property name="margin-start">4</property> </object> </child> <child> <object class="GtkLabel"> <property name="label">Loading...</property> <property name="margin-top">4</property> <property name="margin-bottom">4</property> <property name="margin-end">4</property> </object> </child> </object> </child> </object> </child> </template> </interface>
-
-
-
@@ -48,7 +48,7 @@ <child><object class="GtkStackPage"> <property name="name">main</property> <property name="child"> <object class="GtkLabel" id="test_label" /> <object class="PlacGtkAdwaitaBrowse" id="browse" /> </property> </object> </child>
-
-
-
@@ -22,6 +22,7 @@ <property name="orientation">vertical</property><property name="halign">center</property> <property name="valign">end</property> <property name="spacing">2</property> <property name="margin-top">8</property> <property name="margin-bottom">4</property> <child> <object class="GtkBox">
-
-
-
@@ -0,0 +1,110 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 namespace PlacGtkAdwaita { [GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/browse.ui")] class Browse : Gtk.Box { [GtkChild] private unowned Gtk.Label title; [GtkChild] private unowned Gtk.Label subtitle; [GtkChild] private unowned Gtk.Box loading; [GtkChild] private unowned Gtk.Button back; [GtkChild] private unowned Gtk.ListBox items; private Plac.AsyncConnection? conn = null; private Plac.Transport.Zone? _zone = null; public Plac.Transport.Zone? zone { get { return _zone; } set { _zone = value; load(); } } public Plac.Browse.Hierarchy hierarchy = BROWSE; private Plac.Browse.Item? item = null; public Browse() { Object(); } construct { items.row_activated.connect((row) => { var item_row = (BrowseItem.Row) row; item = item_row.item; load(); }); back.clicked.connect(() => { item = null; load(true); }); } public void start(Plac.AsyncConnection? conn) { this.conn = conn; this.load(); } private void load(bool pop = false) { if (conn == null) { return; } loading.visible = true; conn.browse.begin(hierarchy, _zone, item, pop, (obj, res) => { var result = conn.browse.end(res); if (result.code != OK) { GLib.log("Plac", LEVEL_WARNING, "Browse request failed: %s", result.code.to_string()); loading.visible = false; return; } if (result.action != LIST) { GLib.log("Plac", LEVEL_WARNING, "Unexpected result action: %s", result.action.to_string()); loading.visible = false; return; } var action = result.get_list_action(); title.label = action.title; if (action.subtitle != null) { subtitle.label = action.subtitle; } items.remove_all(); foreach (var item in action.items) { items.append(new BrowseItem.Row(item)); } back.visible = action.level > 0; loading.visible = false; }); } } }
-
-
-
@@ -0,0 +1,42 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 namespace PlacGtkAdwaita { namespace BrowseItem { [GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/browse-item-navigation.ui")] class Navigation : Gtk.Box { [GtkChild] private unowned Gtk.Label title; [GtkChild] private unowned Gtk.Label subtitle; public Plac.Browse.Item item { get; construct; } public Navigation(Plac.Browse.Item item) { Object(item: item); } construct { title.label = item.title; if (item.subtitle != null) { subtitle.label = item.subtitle; subtitle.visible = true; } } } } }
-
-
-
@@ -0,0 +1,37 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 namespace PlacGtkAdwaita { namespace BrowseItem { [GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/browse-item-row.ui")] class Row : Gtk.ListBoxRow { public Plac.Browse.Item item { get; construct; } public Row(Plac.Browse.Item item) { Object(item: item); } construct { this.activatable = item.item_key != null; if (this.activatable) { this.add_css_class("card"); } this.child = new Navigation(item); } } } }
-
-
-
@@ -17,6 +17,8 @@namespace PlacGtkAdwaita { [GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/playback-toolbar.ui")] class PlaybackToolbar : Gtk.Box { public signal void zone_selected(Plac.Transport.Zone? zone); [GtkChild] private unowned Gtk.Button play;
-
@@ -48,13 +50,33 @@ private Gee.HashMap<string, ZoneSelectorRow>zone_rows = new Gee.HashMap<string, ZoneSelectorRow>();private string? zone_id = null; private Plac.Transport.Zone? zone { get { var row = zone_rows[zone_id]; if (row == null) { return null; } return row.zone; } set { if (value == null) { zone_id = null; } else { zone_id = value.id; } zone_selected(value); } } public PlaybackToolbar() { Object(); } construct { zone_list.row_activated.connect((row) => { zone_id = ((ZoneSelectorRow) row).zone.id; this.zone = ((ZoneSelectorRow) row).zone; zone_list_popover.popdown(); this.render(); });
-
@@ -122,7 +144,7 @@ zone_rows[zone.id] = row;zone_list.append(row); if (zone_id == null) { zone_id = zone.id; this.zone = zone; } } }
-
@@ -139,7 +161,7 @@ zone_rows[zone.id] = row;zone_list.append(row); if (zone_id == null) { zone_id = zone.id; this.zone = zone; } } }
-
@@ -156,10 +178,10 @@ }// Selected zone has been removed. if (zone_id != null && !zone_rows.has_key(zone_id)) { zone_id = null; this.zone = null; foreach (var entry in zone_rows) { zone_id = entry.value.zone.id; this.zone = entry.value.zone; break; } }
-
@@ -169,14 +191,12 @@ });} private void render() { var row = zone_rows[zone_id]; if (row == null) { var zone = this.zone; if (zone == null) { play.visible = true; pause.visible = false; return; } var zone = row.zone; play.sensitive = (zone.allowed_action & Plac.Transport.ACTION_PLAY) != 0; pause.sensitive = (zone.allowed_action & Plac.Transport.ACTION_PAUSE) != 0;
-
-
-
@@ -23,9 +23,6 @@[GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/main-window.ui")] class MainWindow : Adw.ApplicationWindow { [GtkChild] private unowned Gtk.Label test_label; [GtkChild] private unowned Gtk.Stack root_stack; [GtkChild]
-
@@ -33,6 +30,9 @@ private unowned PlaybackToolbar playback_toolbar;[GtkChild] private unowned Adw.Banner error_banner; [GtkChild] private unowned Browse browse; private Settings settings = new Settings();
-
@@ -63,6 +63,10 @@ construct {error_banner.button_clicked.connect(() => { try_listen(); }); playback_toolbar.zone_selected.connect((zone) => { browse.zone = zone; }); } public void start() {
-
@@ -95,7 +99,6 @@ }private void listen_events() { this.title = "Plac - %s".printf(server.name); test_label.label = server.name; conn.connection_started.connect(() => { root_stack.visible_child_name = "loading";
-
@@ -108,6 +111,8 @@ playback_toolbar.visible = true;settings.connected_server_id = server_id; settings.connected_server_token = event.token; browse.start(conn); }); conn.connection_error.connect((event) => {
-