Game Details View
Relevant source files
The following files were used as context for generating this wiki page:The Game Details View is a core feature of the SOFL application, providing users with a comprehensive interface to both view and manage individual game properties. It serves a dual purpose: a read-only display page integrated into the main application window for quick inspection of a selected game, and a separate, modal dialog for adding new games or editing the details of existing ones.
This system is central to the user's ability to organize their library, customize game metadata, change game types (e.g., from a regular game to an Online-Fix game), and manage executables and cover art. The implementation is split between the main SOFLWindow, which handles the display-only view, and the DetailsDialog class, which manages the form for data entry and modification.
Architecture Overview
The Game Details functionality is primarily implemented through two distinct but related GTK components:
SOFLWindowDetails Page (Adw.NavigationPage): A non-modal, read-only view that displays the selected game's information within the main window'sAdw.NavigationView. It is designed for quick viewing and accessing primary actions like "Play" or "Hide".DetailsDialog(Adw.Dialog): A modal dialog used for creating a new game or editing an existing one. It contains an editable form with fields for the game's name, developer, executable, and type.
These components interact with the Game widget and its underlying GameData object, which holds the state and properties of a game.
The following diagram illustrates the class relationships within the Game Details system.
This diagram shows that SOFLWindow can present a DetailsDialog and displays a Game. The DetailsDialog edits a Game object, which in turn contains a GameData object (or a subclass like OnlineFixGameData) holding the actual data.
Sources: sofl/window.py, sofl/details_dialog.py, sofl/game.py, sofl/game_data.py, sofl/onlinefix_game.py
Display Mode: The Details Page
The read-only details page is part of the main SOFLWindow and is displayed when a user selects a game from the library. Its purpose is to provide a visually rich summary and quick access to common actions.
Sources: sofl/window.py:200-264
UI Components
The details page is composed of several widgets defined in sofl/window.py.
Widget (SOFLWindow) | Type | Description |
|---|---|---|
details_page | Adw.NavigationPage | The main container for the details view. |
details_view_cover | Gtk.Picture | Displays the primary cover art for the game. |
details_view_blurred_cover | Gtk.Picture | Shows a blurred version of the cover as a background. |
details_view_title | Gtk.Label | Displays the game's name. |
details_view_developer | Gtk.Label | Shows the game's developer, if available. |
details_view_play_button | Gtk.Button | The primary action button to launch the game. |
details_view_added | Gtk.ShortcutLabel | Displays the date the game was added. |
details_view_last_played | Gtk.Label | Displays the date the game was last played. |
details_view_hide_button | Gtk.Button | Toggles the hidden status of the game. |
status_bar / status_separator | Gtk.Box / Gtk.Separator | These UI elements are hidden when the details page is visible. |
Sources: sofl/window.py:47-80, sofl/window.py:301-306
Data Flow for Display
When a user clicks a game, the show_details_page method in SOFLWindow is called. This method populates the UI components with data from the passed Game object.
The sequence diagram below shows the process of displaying game details.
Sources: sofl/window.py:200-264, sofl/game.py:101-104
Add/Edit Mode: The Details Dialog
The DetailsDialog is a modal window for creating new games or modifying existing ones. It is instantiated in two modes:
- Add Mode: When called with no
Gameobject (DetailsDialog()). The title is set to "Add New Game". - Edit Mode: When called with an existing
Gameobject (DetailsDialog(game)). The title is "Game Details" and the form is pre-filled.
Sources: sofl/details_dialog.py:79-105
UI Components
The dialog form is built from Adw.EntryRow and other widgets to capture game information.
Widget (DetailsDialog) | Type | Description |
|---|---|---|
name | Adw.EntryRow | Text input for the game's title. |
developer | Adw.EntryRow | Text input for the game's developer. |
executable | Adw.EntryRow | Text input for the game's executable path or command. |
game_type | Adw.ComboRow | A dropdown to select the game type: "Online-Fix Game" (index 0) or "Regular Game" (index 1). |
cover | Gtk.Picture | Displays the game's cover art. |
cover_button_edit | Gtk.Button | Opens a file dialog to choose a new cover image. |
cover_button_delete | Gtk.Button | Removes the current cover art. |
file_chooser_button | Gtk.Button | Opens a file dialog to select an executable. |
apply_button | Gtk.Button | The main action button, labeled "Add" or "Apply" depending on the mode. |
Sources: sofl/details_dialog.py:42-57
Game Type Management
A key feature of the DetailsDialog is the ability to change a game's type. The game_type combo box allows a user to classify a game as either "Online-Fix" or "Regular". This selection directly influences the source property of the game.
- Online-Fix Game (index 0): Sets the game's source to
online-fix. - Regular Game (index 1): Sets the game's source to
imported.
When the "Apply" button is clicked, the apply_preferences method checks if the game type has been changed. If so, it updates the game's source attribute and moves its reference within the main data store (shared.store.source_games) from the old source group to the new one. This ensures the game appears in the correct category in the main window's sidebar.
Sources: sofl/details_dialog.py:96-101, sofl/details_dialog.py:270-297
Data Persistence Flow
The apply_preferences method is the core of the dialog's functionality. It handles validation, ID generation (for new games), data updates, and saving.
This flowchart shows the logic inside apply_preferences.
Sources: sofl/details_dialog.py:214-348
Data Model
The data for each game is encapsulated in a GameData object or one of its subclasses, like OnlineFixGameData. The Game class is a GTK widget that holds a reference to a GameData object and presents it in the UI.
Sources: sofl/game.py:34-35, sofl/game_data.py
GameData Properties
The GameData class defines the fundamental attributes of a game.
| Property | Type | Description |
|---|---|---|
game_id | str | A unique identifier for the game (e.g., steam_12345, online-fix_1). |
name | str | The display name of the game. |
executable | str | The command or path to the game's executable. |
source | str | The origin of the game (e.g., steam, lutris, online-fix, imported). |
base_source | str | The primary part of the source, used for grouping (e.g., steam from steam_12345). |
developer | Optional[str] | The name of the game's developer. |
hidden | bool | If True, the game is hidden from the main library view. |
last_played | int | A Unix timestamp of when the game was last launched. |
added | int | A Unix timestamp of when the game was added to the library. |
Sources: sofl/game_data.py:29-41
OnlineFixGameData Specialization
The OnlineFixGameData class inherits from GameData and overrides certain methods to provide specialized behavior for Online-Fix games. This demonstrates how the details view can handle different game types polymorphically.
get_play_button_label(): Returns "Play with Online-Fix" to indicate the special launch method.launch(): Implements the specific logic for launching a game using a selected Proton version and the Steam API, which is different from a regular game launch.
This specialization is what allows the "Play" button in the SOFLWindow details page to perform a different action depending on the game's type, without the SOFLWindow needing to know the specific launch details.
Sources: sofl/onlinefix_game.py:21-24, sofl/onlinefix_game.py:48-53
Summary
The Game Details View is a flexible and essential part of SOFL, implemented through the SOFLWindow's details page for viewing and the DetailsDialog for editing. It allows users to manage all aspects of a game's metadata, from its name and cover art to its fundamental type and launch behavior. The architecture effectively separates display logic from data management, using the GameData class as a central model and allowing for specialized game types like OnlineFixGameData to integrate seamlessly.