sources: Add initial UI
This commit is contained in:
committed by
Laura Kramolis
parent
7bc9d6aee9
commit
c5cfa476ff
@@ -54,6 +54,8 @@ class _SourceModule(Protocol):
|
||||
class Source(GObject.Object, Gio.ListModel): # pyright: ignore[reportIncompatibleMethodOverride]
|
||||
"""A source of games to import."""
|
||||
|
||||
__gtype_name__ = __qualname__
|
||||
|
||||
id = GObject.Property(type=str)
|
||||
name = GObject.Property(type=str)
|
||||
icon_name = GObject.Property(type=str)
|
||||
|
||||
@@ -7,6 +7,7 @@ python.install_sources(
|
||||
'game_details.py',
|
||||
'game_item.py',
|
||||
'games.py',
|
||||
'sources.py',
|
||||
'window.py',
|
||||
),
|
||||
subdir: 'cartridges' / 'ui',
|
||||
|
||||
44
cartridges/ui/sources.py
Normal file
44
cartridges/ui/sources.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Jamie Gravendeel
|
||||
|
||||
from gi.repository import Adw, Gio, GObject, Gtk
|
||||
|
||||
from cartridges import sources
|
||||
from cartridges.sources import Source
|
||||
from cartridges.ui import games
|
||||
|
||||
|
||||
class SourceSidebarItem(Adw.SidebarItem): # pyright: ignore[reportAttributeAccessIssue]
|
||||
"""A sidebar item representing a source."""
|
||||
|
||||
model = GObject.Property(type=Gio.ListModel)
|
||||
|
||||
@GObject.Property(type=Source)
|
||||
def source(self) -> Source:
|
||||
"""The source that `self` represents."""
|
||||
return self._source
|
||||
|
||||
@source.setter
|
||||
def source(self, source: Source):
|
||||
self._source = source
|
||||
flags = GObject.BindingFlags.SYNC_CREATE
|
||||
source.bind_property("name", self, "title", flags)
|
||||
source.bind_property("icon-name", self, "icon-name", flags)
|
||||
|
||||
self.model = Gtk.FilterListModel(
|
||||
model=source,
|
||||
filter=games.filter_,
|
||||
watch_items=True, # pyright: ignore[reportCallIssue]
|
||||
)
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/7959
|
||||
self.model.connect(
|
||||
"items-changed",
|
||||
lambda *_: self.set_property("visible", self.model.props.n_items),
|
||||
)
|
||||
self.props.visible = self.model.props.n_items
|
||||
|
||||
|
||||
model = Gtk.SortListModel.new(
|
||||
sources.model,
|
||||
Gtk.StringSorter.new(Gtk.PropertyExpression.new(Source, None, "name")),
|
||||
)
|
||||
@@ -94,6 +94,10 @@ template $Window: Adw.ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Adw.SidebarSection sources {
|
||||
title: _("Sources");
|
||||
}
|
||||
|
||||
Adw.SidebarSection collections {
|
||||
title: _("Collections");
|
||||
|
||||
|
||||
@@ -13,14 +13,15 @@ from gi.repository import Adw, Gio, GLib, GObject, Gtk
|
||||
from cartridges import STATE_SETTINGS
|
||||
from cartridges.collections import Collection
|
||||
from cartridges.config import PREFIX, PROFILE
|
||||
from cartridges.sources import imported
|
||||
from cartridges.ui import collections, games
|
||||
from cartridges.sources import Source, imported
|
||||
from cartridges.ui import collections, games, sources
|
||||
|
||||
from .collection_details import CollectionDetails
|
||||
from .collections import CollectionFilter, CollectionSidebarItem
|
||||
from .game_details import GameDetails
|
||||
from .game_item import GameItem # noqa: F401
|
||||
from .games import GameSorter
|
||||
from .sources import SourceSidebarItem
|
||||
|
||||
if sys.platform.startswith("linux"):
|
||||
from cartridges import gamepads
|
||||
@@ -45,6 +46,7 @@ class Window(Adw.ApplicationWindow):
|
||||
|
||||
split_view: Adw.OverlaySplitView = Gtk.Template.Child()
|
||||
sidebar: Adw.Sidebar = Gtk.Template.Child() # pyright: ignore[reportAttributeAccessIssue]
|
||||
sources: Adw.SidebarSection = Gtk.Template.Child() # pyright: ignore[reportAttributeAccessIssue]
|
||||
collections: Adw.SidebarSection = Gtk.Template.Child() # pyright: ignore[reportAttributeAccessIssue]
|
||||
new_collection_item: Adw.SidebarItem = Gtk.Template.Child() # pyright: ignore[reportAttributeAccessIssue]
|
||||
collection_menu: Gio.Menu = Gtk.Template.Child()
|
||||
@@ -108,6 +110,7 @@ class Window(Adw.ApplicationWindow):
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/7901
|
||||
self.search_entry.set_key_capture_widget(self)
|
||||
self.sources.bind_model(sources.model, self._create_source_item)
|
||||
self.collections.bind_model(
|
||||
collections.model,
|
||||
lambda collection: CollectionSidebarItem(collection=collection),
|
||||
@@ -162,6 +165,18 @@ class Window(Adw.ApplicationWindow):
|
||||
|
||||
self.toast_overlay.add_toast(toast)
|
||||
|
||||
def _create_source_item(self, source: Source) -> SourceSidebarItem:
|
||||
item = SourceSidebarItem(source=source)
|
||||
item.connect(
|
||||
"notify::visible",
|
||||
lambda item, _: self._source_empty() if not item.props.visible else None,
|
||||
)
|
||||
return item
|
||||
|
||||
def _source_empty(self):
|
||||
self.model = games.model
|
||||
self.sidebar.props.selected = 0
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def _show_sidebar_title(self, _obj, layout: str) -> bool:
|
||||
right_window_controls = layout.replace("appmenu", "").startswith(":")
|
||||
@@ -175,10 +190,15 @@ class Window(Adw.ApplicationWindow):
|
||||
case self.new_collection_item:
|
||||
self._add_collection()
|
||||
sidebar.props.selected = self._selected_sidebar_item
|
||||
case SourceSidebarItem():
|
||||
self.collection = None
|
||||
self.model = item.model
|
||||
case CollectionSidebarItem():
|
||||
self.collection = item.collection
|
||||
self.model = games.model
|
||||
case _:
|
||||
self.collection = None
|
||||
self.model = games.model
|
||||
|
||||
if item is not self.new_collection_item:
|
||||
self._selected_sidebar_item = index
|
||||
|
||||
1
data/icons/heroic-symbolic.svg
Normal file
1
data/icons/heroic-symbolic.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path fill="#000" fill-rule="evenodd" d="m7.872 16-3.817-3.083L2 2.79 7.872 0l5.871 2.789-2.055 10.128zm0-4.257-.294-.293-.88-7.927 1.1-1.908 1.174 1.908-.807 7.927zm-.294.367-.147.367-1.761.294-.294-.66.294-.662 1.761.294zm-.073.734-.22 1.541.587.294.587-.294-.22-1.541-.367-.22zm.807-.367-.147-.367.147-.367 1.761-.293.294.66-.294.66z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
@@ -4,6 +4,10 @@
|
||||
<file>apply-symbolic.svg</file>
|
||||
<file>cancel-symbolic.svg</file>
|
||||
<file>filter-symbolic.svg</file>
|
||||
<!-- Sources -->
|
||||
<file>heroic-symbolic.svg</file>
|
||||
<file>imported-symbolic.svg</file>
|
||||
<file>steam-symbolic.svg</file>
|
||||
<!-- Categories -->
|
||||
<file>collection-symbolic.svg</file>
|
||||
<file>ball-symbolic.svg</file>
|
||||
|
||||
1
data/icons/imported-symbolic.svg
Normal file
1
data/icons/imported-symbolic.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="#222" d="M7 1v6H1v2h6v6h2V9h6V7H9V1zm0 0"/></svg>
|
||||
|
After Width: | Height: | Size: 144 B |
1
data/icons/steam-symbolic.svg
Normal file
1
data/icons/steam-symbolic.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><g clip-path="url(#a)"><path fill="#000" fill-rule="evenodd" d="M9.352 5.1a1.509 1.509 0 1 0 2.51 1.675A1.509 1.509 0 0 0 9.352 5.1m2.923-.277a2.009 2.009 0 1 1-3.34 2.231 2.009 2.009 0 0 1 3.34-2.23ZM5.01 12.131l-.983-.407a1.7 1.7 0 0 0 3.108-.103 1.696 1.696 0 0 0-1.213-2.29 1.7 1.7 0 0 0-.966.07l1.015.421a1.249 1.249 0 0 1-.96 2.307zM2.546 2.121A8 8 0 0 1 7.966 0l.003.013a7.99 7.99 0 0 1 7.159 4.432 7.996 7.996 0 0 1-4.277 11.018 7.99 7.99 0 0 1-8.274-1.558A8 8 0 0 1 .279 10.18l3.064 1.267A2.264 2.264 0 0 0 7.823 11v-.107l2.718-1.938h.063A3.016 3.016 0 1 0 7.589 5.94v.031l-1.906 2.76h-.126c-.454 0-.898.138-1.273.395L0 7.354A8 8 0 0 1 2.546 2.12Z" clip-rule="evenodd"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 842 B |
@@ -17,6 +17,7 @@ cartridges/ui/game_details.py
|
||||
cartridges/ui/game_item.py
|
||||
cartridges/ui/games.py
|
||||
cartridges/ui/shortcuts-dialog.blp
|
||||
cartridges/ui/sources.py
|
||||
cartridges/ui/window.blp
|
||||
cartridges/ui/window.py
|
||||
data/page.kramo.Cartridges.desktop.in
|
||||
|
||||
Reference in New Issue
Block a user