Add GTK application implementation

This commit is contained in:
Olli 2026-02-26 10:41:33 +01:00
commit b7c0307f6b
29 changed files with 2564 additions and 266 deletions

32
data/data.go Normal file
View file

@ -0,0 +1,32 @@
package data
import (
_ "embed"
)
//go:embed ui/window.ui
var WindowXML string
//go:embed ui/shortcuts-dialog.ui
var ShortcutsDialogXML string
//go:embed ui/connection-panel.ui
var ConnectionPanelXML string
//go:embed ui/server-panel.ui
var ServerPanelXML string
//go:embed ui/cover-panel.ui
var CoverPanelXML string
//go:embed ui/playlist-panel.ui
var PlaylistPanelXML string
//go:embed ui/album-headerbar.ui
var AlbumHeaderbarXML string
//go:embed ui/library-panel.ui
var LibraryPanelXML string
//go:embed gtk.css
var MainCSS string

View file

@ -1,6 +1,5 @@
#content_stack {
box-shadow:inset 4px 4px 10px rgba(0,0,0,0.3);
background-image:url('noise-texture.png');
}
#port_spinner {
@ -30,10 +29,6 @@
font-weight:bold;
}
window.fullscreen #cover_box {
background: black;
}
#cover_info_revealer {
background-color:alpha(@theme_bg_color, 0.8);
box-shadow:0 0 10px @theme_bg_color;

View file

@ -1,7 +0,0 @@
application_id = 'xyz.suruatoel.mcg'
scalable_dir = join_paths('hicolor', 'scalable', 'apps')
install_data(
join_paths(scalable_dir, ('@0@.svg').format(application_id)),
install_dir: join_paths(get_option('datadir'), 'icons', scalable_dir)
)

View file

@ -2,7 +2,7 @@
<interface>
<requires lib="gtk+" version="4.8"/>
<requires lib="adw" version="1.2" />
<template class="McgAlbumHeaderbar" parent="AdwBin">
<object id="McgAlbumHeaderbar" class="AdwBin">
<child>
<object class="GtkHeaderBar">
<child type="title">
@ -25,9 +25,8 @@
</object>
</child>
<child>
<object class="GtkButton">
<object id="close_button" class="GtkButton">
<property name="receives-default">True</property>
<signal name="clicked" handler="on_close_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">go-previous-symbolic</property>
@ -37,5 +36,5 @@
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -9,79 +9,58 @@
<property name="step-increment">1</property>
<property name="page-increment">100</property>
</object>
<object class="GtkBox" id="toolbar">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
</object>
<template class="McgConnectionPanel" parent="AdwBin">
<object id="McgConnectionPanel" class="AdwBin">
<child>
<object class="AdwStatusPage">
<property name="title">Connect to MPD</property>
<child>
<object class="GtkBox">
<object class="GtkListBox">
<property name="hexpand">false</property>
<property name="halign">center</property>
<property name="selection-mode">none</property>
<style>
<class name="boxed-list"/>
</style>
<child>
<object class="GtkListBox" id="zeroconf_list">
<property name="hexpand">true</property>
<child type="placeholder">
<object class="AdwEntryRow" id="host_row">
<property name="title" translatable="yes">Host</property>
<property name="show-apply-button">true</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="header"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No service found</property>
<property name="label" translatable="yes">Port</property>
<property name="halign">start</property>
<property name="hexpand">false</property>
<style>
<class name="subtitle"/>
</style>
</object>
</child>
<child>
<object class="GtkSpinButton" id="port_spinner">
<property name="name">port_spinner</property>
<property name="value">6600</property>
<property name="adjustment">server-port-adjustment</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox">
<property name="hexpand">true</property>
<property name="selection-mode">none</property>
<style>
<class name="boxed-list"/>
</style>
<child>
<object class="AdwEntryRow" id="host_row">
<property name="title" translatable="yes">Host</property>
<property name="show-apply-button">true</property>
<signal name="apply" handler="on_host_entry_apply"/>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="header"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Port</property>
<property name="halign">start</property>
<property name="hexpand">false</property>
<style>
<class name="subtitle"/>
</style>
</object>
</child>
<child>
<object class="GtkSpinButton" id="port_spinner">
<property name="name">port_spinner</property>
<property name="value">6600</property>
<property name="adjustment">server-port-adjustment</property>
<signal name="value-changed" handler="on_port_spinner_value_changed"/>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPasswordEntryRow" id="password_row">
<property name="title" translatable="yes">Password</property>
<property name="show-apply-button">true</property>
</object>
</child>
<object class="AdwPasswordEntryRow" id="password_row">
<property name="title" translatable="yes">Password</property>
<property name="show-apply-button">true</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -19,7 +19,7 @@
</object>
</child>
</object>
<template class="McgCoverPanel" parent="GtkOverlay">
<object id="McgCoverPanel" class="GtkOverlay">
<child>
<object class="GtkStack" id="cover_stack">
<property name="visible-child">cover_default</property>
@ -157,5 +157,5 @@
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -26,13 +26,11 @@
<property name="round-digits">0</property>
<property name="digits">0</property>
<property name="has-origin">False</property>
<signal name="value-changed" handler="on_grid_scale_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton" id="library-toolbar-update">
<property name="label" translatable="yes">update library</property>
<signal name="clicked" handler="on_update_clicked" swapped="no"/>
</object>
</child>
<child>
@ -53,7 +51,6 @@
<property name="label" translatable="yes">sort by artist</property>
<property name="receives-default">False</property>
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
@ -61,14 +58,12 @@
<property name="label" translatable="yes">sort by title</property>
<property name="receives-default">False</property>
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="sort_year">
<property name="label" translatable="yes">sort by year</property>
<property name="receives-default">False</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
@ -76,7 +71,6 @@
<property name="label" translatable="yes">sort by modification</property>
<property name="receives-default">False</property>
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
@ -86,7 +80,6 @@
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<signal name="toggled" handler="on_sort_order_toggled" swapped="no"/>
</object>
</child>
</object>
@ -108,9 +101,6 @@
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
<!--
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-->
</object>
</child>
<child>
@ -119,7 +109,6 @@
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Select multiple albums</property>
<signal name="toggled" handler="on_select_toggled" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">object-select-symbolic</property>
@ -145,7 +134,7 @@
</child>
</object>
<template class="McgLibraryPanel" parent="AdwBin">
<object id="McgLibraryPanel" class="AdwBin">
<child>
<object class="GtkStack" id="library_stack">
<property name="transition-type">slide-left-right</property>
@ -158,7 +147,6 @@
<child>
<object class="GtkSearchEntry" id="filter_entry">
<property name="placeholder-text" translatable="yes">search library</property>
<signal name="search-changed" handler="on_filter_entry_changed" swapped="no"/>
</object>
</child>
</object>
@ -206,49 +194,9 @@
<object class="GtkGridView" id="library_grid">
<property name="orientation">vertical</property>
<property name="single_click_activate">true</property>
<signal name="activate" handler="on_library_grid_clicked"/>
<style>
<class name="no-bg"/>
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="activatable">true</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="vexpand">true</property>
<property name="hexpand">true</property>
<child>
<object class="GtkPicture">
<property name="content-fit">contain</property>
<property name="can-shrink">false</property>
<property name="vexpand">true</property>
<property name="hexpand">true</property>
<binding name="tooltip-markup">
<lookup name="tooltip" type="GridItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<binding name="paintable">
<lookup name="cover" type="GridItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
<style>
@ -264,17 +212,15 @@
<child>
<object class="GtkActionBar" id="actionbar">
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="selection_cancel_button">
<property name="label" translatable="yes">cancel</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="selection_queue_button">
<property name="label" translatable="yes">queue</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_add_clicked" swapped="no"/>
</object>
</child>
</object>
@ -321,17 +267,15 @@
<child>
<object class="GtkActionBar" id="actionbar_standalone">
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="standalone_play_button">
<property name="label" translatable="yes">play</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="standalone_queue_button">
<property name="label" translatable="yes">queue</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_queue_clicked" swapped="no"/>
</object>
</child>
</object>
@ -340,5 +284,5 @@
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -12,7 +12,6 @@
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Select multiple albums</property>
<signal name="toggled" handler="on_select_toggled" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">object-select-symbolic</property>
@ -26,7 +25,6 @@
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Clear the playlist</property>
<signal name="clicked" handler="on_clear_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
@ -37,7 +35,7 @@
</object>
</child>
</object>
<template class="McgPlaylistPanel" parent="AdwBin">
<object id="McgPlaylistPanel" class="AdwBin">
<child>
<object class="GtkStack" id="playlist_stack">
<property name="transition-type">slide-left-right</property>
@ -51,45 +49,9 @@
<object class="GtkGridView" id="playlist_grid">
<property name="orientation">vertical</property>
<property name="single-click-activate">true</property>
<signal name="activate" handler="on_playlist_grid_clicked"/>
<style>
<class name="no-bg"/>
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="activatable">true</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPicture">
<property name="content-fit">contain</property>
<property name="can-shrink">false</property>
<binding name="tooltip-markup">
<lookup name="tooltip" type="GridItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<binding name="paintable">
<lookup name="cover" type="GridItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
<style>
@ -103,17 +65,15 @@
<child>
<object class="GtkActionBar" id="actionbar">
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="selection_cancel_button">
<property name="label" translatable="yes">cancel</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="selection_remove_button">
<property name="label" translatable="yes">remove</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_remove_clicked" swapped="no"/>
</object>
</child>
</object>
@ -159,17 +119,15 @@
<child>
<object class="GtkActionBar" id="actionbar_standalone">
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="standalone_play_button">
<property name="label" translatable="yes">play</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="standalone_remove_button">
<property name="label" translatable="yes">remove</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_remove_clicked" swapped="no"/>
</object>
</child>
</object>
@ -178,5 +136,5 @@
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -13,7 +13,7 @@
</object>
</child>
</object>
<template class="McgServerPanel" parent="AdwBin">
<object id="McgServerPanel" class="AdwBin">
<child>
<object class="AdwFlap" id="server_flap">
<property name="flap-position">end</property>
@ -322,5 +322,5 @@
</property>
</object>
</child>
</template>
</object>
</interface>

View file

@ -2,7 +2,7 @@
<interface>
<requires lib="gtk+" version="4.8"/>
<requires lib="adw" version="1.2" />
<template class="McgShortcutsDialog" parent="GtkShortcutsWindow">
<object id="McgShortcutsDialog" class="GtkShortcutsWindow">
<property name="modal">1</property>
<child>
<object class="GtkShortcutsSection">
@ -103,5 +103,5 @@
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -2,7 +2,8 @@
<interface>
<requires lib="gtk+" version="4.8" />
<requires lib="adw" version="1.2" />
<template class="McgAppWindow" parent="AdwApplicationWindow">
<object id="McgAppWindow" class="AdwApplicationWindow">
<property name="title">CoverGrid</property>
<property name="content">
<object class="AdwToolbarView" id="toolbar_view">
<child type="top">
@ -17,13 +18,12 @@
</property>
<child>
<object class="GtkSwitch" id="headerbar_button_connect">
<signal name="state-set" handler="on_headerbar_connection_state_set" swapped="no"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="headerbar_button_playpause">
<property name="sensitive">false</property>
<property name="tooltip-text" translatable="yes">Switch between play and pause</property>
<signal name="toggled" handler="on_headerbar_playpause_toggled" swapped="no"/>
<child>
<object class="GtkImage">
<property name="can-focus">False</property>
@ -34,7 +34,7 @@
</child>
<child>
<object class="GtkVolumeButton" id="headerbar_button_volume">
<signal name="value-changed" handler="on_headerbar_volume_changed" swapped="no"/>
<property name="sensitive">false</property>
</object>
</child>
<child type="end">
@ -44,7 +44,7 @@
</object>
</child>
<property name="content">
<object class="GtkBox" id="content_box">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwToastOverlay" id="info_toast">
@ -55,7 +55,6 @@
<child>
<object class="AdwViewStack" id="panel_stack">
<property name="vexpand">true</property>
<signal name="notify::visible-child" handler="on_stack_switched" swapped="no"/>
</object>
</child>
</object>
@ -70,9 +69,13 @@
</binding>
</object>
</child>
<child>
<object class="GtkDrawingArea" id="resize_helper">
</object>
</child>
</object>
</property>
</object>
</property>
</template>
</object>
</interface>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/xyz/suruatoel/mcg">
<file>gtk.css</file>
<file>noise-texture.png</file>
<file>ui/window.ui</file>
<file>ui/shortcuts-dialog.ui</file>
<file>ui/connection-panel.ui</file>
<file>ui/album-headerbar.ui</file>
<file>ui/server-panel.ui</file>
<file>ui/cover-panel.ui</file>
<file>ui/playlist-panel.ui</file>
<file>ui/library-panel.ui</file>
</gresource>
</gresources>

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<enum id="xyz.suruatoel.mcg.SortOrder">
<value nick="artist" value="0" />
<value nick="title" value="1" />
<value nick="year" value="2" />
<value nick="modified" value="3" />
</enum>
<schema path="/xyz/suruatoel/mcg/" id="xyz.suruatoel.mcg" gettext-domain="mcg">
<key type="s" name="host">
<default>'localhost'</default>
<summary>MPD host</summary>
<description>MPD host to connect to</description>
</key>
<key type="i" name="port">
<default>6600</default>
<summary>MPD port</summary>
<description>MPD port to connect to</description>
</key>
<key type="b" name="connected">
<default>false</default>
<summary>Connection state</summary>
<description>State of last connection</description>
</key>
<key type="i" name="width">
<default>800</default>
<summary>Window width</summary>
<description>The window width in pixels.</description>
</key>
<key type="i" name="height">
<default>600</default>
<summary>Window height</summary>
<description>The window height in pixels.</description>
</key>
<key type="b" name="is-maximized">
<default>false</default>
<summary>Window maximized</summary>
<description>Whether or not the window is in maximized state.</description>
</key>
<key type="i" name="panel">
<range min="0" max="3"/>
<default>1</default>
<summary>Last selected panel</summary>
<description>The index of the last selected panel.</description>
</key>
<key type="i" name="item-size">
<range min="100" max="1000" />
<default>150</default>
<summary>Size of library items</summary>
<description>The size of items displayed in the library.</description>
</key>
<key enum="xyz.suruatoel.mcg.SortOrder" name="sort-order">
<default>'year'</default>
<summary>Sort criterium for library items</summary>
<description>The sort criterium of items displayed in the library.</description>
</key>
<key type="b" name="sort-type">
<default>true</default>
<summary>Sort type for library items</summary>
<description>The sort type of items displayed in the library.</description>
</key>
</schema>
</schemalist>

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Before After
Before After