Changes
8 changed files (+116/-155)
-
-
@@ -48,5 +48,10 @@ <default>false</default><summary>Show seek by 10secs buttons</summary> <description>Show buttons that seek forward/backwards by 10 seconds.</description> </key> <key name="show-browse-item-separators" type="b"> <default>false</default> <summary>Show separators for browse items</summary> <description>Show separator between browse items.</description> </key> </schema> </schemalist>
-
-
-
@@ -20,18 +20,18 @@ <interface><template class="PlacGtkAdwaitaBrowseItemNavigation" parent="GtkBox"> <property name="orientation">horizontal</property> <property name="spacing">8</property> <property name="margin-top">8</property> <property name="margin-top">4</property> <binding name="margin-bottom"> <lookup name="margin-top" type="PlacGtkAdwaitaBrowseItemNavigation" /> </binding> <property name="margin-start">8</property> <property name="margin-start">12</property> <binding name="margin-end"> <lookup name="margin-start" type="PlacGtkAdwaitaBrowseItemNavigation" /> </binding> <child> <object class="PlacGtkAdwaitaArtwork" id="artwork"> <property name="visible">false</property> <property name="width">40</property> <property name="width">36</property> <binding name="height"> <lookup name="width">artwork</lookup> </binding>
-
@@ -68,24 +68,6 @@ <child><object class="GtkImage" id="icon"> <property name="accessible-role">presentation</property> <property name="icon-name">go-next-symbolic</property> </object> </child> <child> <object class="GtkMenuButton" id="action_menu"> <property name="visible">false</property> <property name="valign">center</property> <property name="icon-name">view-more-symbolic</property> <property name="popover"> <object class="GtkPopover" id="action_menu_popover"> <child> <object class="GtkListBox" id="action_menu_list"> <style> <class name="navigation-sidebar" /> </style> </object> </child> </object> </property> </object> </child> </template>
-
-
-
@@ -26,6 +26,7 @@ <object class="GtkOverlay"><child> <object class="GtkBox"> <property name="orientation">vertical</property> <property name="spacing">6</property> <child> <object class="GtkBox" id="metadata"> <property name="margin-top">20</property>
-
@@ -86,17 +87,8 @@ <child><object class="GtkScrolledWindow" id="scroller"> <property name="vexpand">true</property> <property name="child"> <object class="GtkListBox" id="items"> <object class="GtkListView" id="items"> <property name="valign">start</property> <property name="margin-top">6</property> <property name="margin-bottom">12</property> <property name="margin-start">12</property> <binding name="margin-end"> <lookup name="margin-start">metadata</lookup> </binding> <style> <class name="boxed-list" /> </style> </object> </property> </object>
-
-
-
@@ -67,8 +67,14 @@ settings.settings.bind(Settings.LABEL_PARSING_ENABLED, label_parsing_enabled, "active", DEFAULT);label_parsing_enabled.title = "Parse labels"; label_parsing_enabled.subtitle = "Enable parsing of \"[[id|text]]\" labels in browse section."; var show_browse_item_separators = new Adw.SwitchRow(); settings.settings.bind(Settings.SHOW_BROWSE_ITEM_SEPARATORS, show_browse_item_separators, "active", DEFAULT); show_browse_item_separators.title = "Show separators for browse items"; show_browse_item_separators.subtitle = "Show separator between browse items."; var browse = new Adw.PreferencesGroup(); browse.add(label_parsing_enabled); browse.add(show_browse_item_separators); browse.title = "Browse"; var show_seek_by_10secs = new Adw.SwitchRow();
-
-
-
@@ -23,6 +23,7 @@public class Settings { public const string LABEL_PARSING_ENABLED = "label-parsing-enabled"; public const string SHOW_SEEK_BY_10SECS = "show-seek-by-10secs"; public const string SHOW_BROWSE_ITEM_SEPARATORS = "show-browse-item-separators"; public GLib.Settings settings;
-
-
-
@@ -33,13 +33,15 @@ [GtkChild]private unowned Gtk.Button back; [GtkChild] private unowned Gtk.ListBox items; private unowned Gtk.ListView items; [GtkChild] private unowned Gtk.ScrolledWindow scroller; [GtkChild] private unowned Adw.ToastOverlay toasts; private GLib.ListStore items_store = new GLib.ListStore(typeof (BrowseItem.Item)); private Plac.AsyncConnection? conn = null;
-
@@ -64,7 +66,7 @@ }} } private Plac.Browse.Item? item = null; private BrowseItem.Item? item = null; private bool is_loading = false; private Settings settings = new Settings();
-
@@ -74,24 +76,29 @@ Object();} construct { items.row_activated.connect((row) => { var item_row = (BrowseItem.Row) row; item = item_row.item; items.single_click_activate = true; items.model = new Gtk.NoSelection(items_store); switch (item.hint) { case ACTION_LIST: var nav = (BrowseItem.Navigation) item_row.child; nav.open_actions(); break; default: load(); break; var factory = new Gtk.SignalListItemFactory(); factory.setup.connect(BrowseItem.setup_browse_item); factory.bind.connect(BrowseItem.bind_browse_item); items.factory = factory; items.activate.connect((position) => { var item = (BrowseItem.Item) items_store.get_item(position); if (item == null) { return; } this.item = item; load(false, false); }); back.clicked.connect(() => { pop(); }); settings.settings.bind(Settings.SHOW_BROWSE_ITEM_SEPARATORS, items, "show-separators", GET); } public void start(Plac.AsyncConnection? conn) {
-
@@ -123,6 +130,7 @@ if (conn == null || _hierarchy == null || is_loading) {return; } var item = this.item == null ? null : this.item.item; start_loading(); conn.browse.begin(_hierarchy, _zone, item, pop, (obj, res) => { var result = conn.browse.end(res);
-
@@ -166,54 +174,16 @@ } else {subtitle.visible = false; } items.remove_all(); items_store.remove_all(); if (scroll_to_top) { scroller.vadjustment.value = scroller.vadjustment.lower; } foreach (var item in action.items) { var row = new BrowseItem.Row(item, conn); var nav = (BrowseItem.Navigation) row.child; nav.action_selected.connect((selected_item) => { this.item = selected_item; load(false, false); }); nav.actions_open.connect(() => { load_actions(nav, item); }); nav.actions_close.connect(() => { this.pop(false); }); items.append(row); foreach (var new_item in action.items) { items_store.append(new BrowseItem.Item(new_item, conn)); } back.visible = action.level > 0; end_loading(); }); } private void load_actions(BrowseItem.Navigation target, Plac.Browse.Item item) { if (conn == null || _hierarchy == null || is_loading) { return; } conn.browse.begin(_hierarchy, _zone, item, false, (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(); target.set_action_items(action); }); } }
-
-
-
@@ -0,0 +1,74 @@// 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 { class Item : Object { public Plac.Browse.Item item { get; construct; } public Plac.AsyncConnection? conn { get; construct; } public Item(Plac.Browse.Item item, Plac.AsyncConnection? conn = null) { Object(item: item, conn: conn); } } // GListView requires a widget to calculate row sizes. private class RowContainer : Gtk.Box { private Gtk.Widget? child = null; private Item? _item = null; public Item? item { get { return _item; } construct set { _item = value; if (child != null) { this.remove(child); child = null; } if (value != null) { child = new Navigation(value.item, value.conn); this.append(child); } } } public RowContainer(Item? item = null) { Object(item: item); this.height_request = 48; } } void setup_browse_item(Gtk.ListItemFactory factory, Object object) { var list_item = (Gtk.ListItem) object; list_item.child = new RowContainer(); list_item.selectable = false; } void bind_browse_item(Gtk.ListItemFactory factory, Object object) { var list_item = (Gtk.ListItem) object; var item = (Item) list_item.item; var container = (RowContainer) list_item.child; container.item = item; } } }
-
-
-
@@ -18,10 +18,6 @@ namespace PlacGtkAdwaita {namespace BrowseItem { [GtkTemplate(ui = "/jp/pocka/plac/gtk-adwaita/ui/browse-item-navigation.ui")] class Navigation : Gtk.Box { public signal void action_selected(Plac.Browse.Item item); public signal void actions_open(); public signal void actions_close(); [GtkChild] private unowned Gtk.Label title;
-
@@ -33,17 +29,6 @@ private unowned Artwork artwork;[GtkChild] private unowned Gtk.Image icon; [GtkChild] private unowned Gtk.MenuButton action_menu; [GtkChild] private unowned Gtk.Popover action_menu_popover; [GtkChild] private unowned Gtk.ListBox action_menu_list; private bool is_popover_closed_by_submission = false; public Plac.Browse.Item item { get; construct; }
-
@@ -80,68 +65,14 @@ artwork.visible = true;} switch (item.hint) { case ACTION_LIST: case LIST: icon.icon_name = "go-next-symbolic"; break; case ACTION_LIST: icon.visible = false; action_menu.visible = true; break; default: icon.visible = false; break; } action_menu_list.row_activated.connect((row) => { is_popover_closed_by_submission = true; var action_row = (ActionRow) row; item = action_row.item; action_selected(item); }); action_menu_popover.show.connect(() => { is_popover_closed_by_submission = false; actions_open(); }); action_menu_popover.closed.connect(() => { if (!is_popover_closed_by_submission) { actions_close(); } }); } public void open_actions() { action_menu.popup(); } public void set_action_items(Plac.Browse.ListAction list) { action_menu_list.remove_all(); bool set_focus = false; foreach (var item in list.items) { var row = new ActionRow(item); action_menu_list.append(row); if (!set_focus) { row.grab_focus(); set_focus = true; } } } } class ActionRow : Gtk.ListBoxRow { private Gtk.Label label; public Plac.Browse.Item item { get; construct set; } public ActionRow(Plac.Browse.Item item) { Object(item: item); } construct { label = new Gtk.Label(item.title); this.child = label; this.activatable = true; } } }
-