Allowing us to show and hide the sidebar by clicking the button in the
header. I also save the current state of the sidebar, although the
Adw.OverlaySplitView might override this when the window is shown.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The following shortcuts are implemented:
- Escape to unselect any selected tracks
- Delete to remove selected tracks from the current playlist
- <Control>/ to focus the "filter tracks" entry
- <Control>l to cycle the loop state of the current playlist
- <Control>s to toggle the shuffle state of the current playlist
- <Control>Up to move the selected track up one position
- <Control>Down to move the selected track down one position
I also change the volume up and down shortcuts to use the <Shift>
modifier. This matches how other Header shortcuts are triggered, and
frees up the non-shifted versions to use here.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The following shortcuts are implemented:
- <Control>? (<Shift><Control>/) to focus the "filter playlists" entry
- <Control><Alt>g to go to the current playlist
- <Shift><Control>p to open the Playlists section
- <Shift><Control>a to open the Artists section
- <Shift><Control>g to open the Genres section
- <Shift><Control>d to open the Decades section
- <Shift><Control>l to open the Libraries section
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I add accelerators for play, pause, next track, previous track, setting
autopause, adding the current track to the favorites playlist, and
scrolling to the current track in the tracklist.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I create can-activate-* properties to indicate if a specific accelerator
can be activated. At the same time, I introduce functions intended to be
called by accelerators to activate each of our widgets.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I add accelerators for opening files, changing the volume, toggling
background mode, and running the settings editor.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And wire up the bg-enabled and bg-volume properties from the header to
the playbin properties with the same name.
Implements: #50 ("Background Music Mode")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
For now it only has the Gtk.CenterBox child with an entry.Filter widget,
but this will be expanded on in future patches. I also take the chance
to bind the factory:visible-playlist property to the playlist displayed
in the tracklist.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And connect to the Player EOS and about-to-finish signals so we can
select the next track when the current one finishes (or slightly before
for gapless playback).
Implements: #7 (Add MPRIS2 Support)
Implements: #48 (Implement Intelligent ReplayGain)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The playlist factory has properties for the currently selected,
currently active, and previous playlists. It will eventually create
Gio.ListModel instances representing the tracks in each of these playlists,
in sorted order.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I attach these to the Now Playing card so the "add to favorites" button
can be correctly marked as sensitive and enabled when a Track is
selected for playback.
Additionally, I look for a notification from the Track table to say it
has been loaded. This lets me set the Player to load up the current_track
if one is set.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
It only contains a FilterEntry for filtering future playlists. The
application will save its size when resized.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This Thread uses the audio.tagger.tag_file() function to find the tags
for a specific file without hanging the UI. There may be cases where we
have an Artist MBID but not the matching Artist name. When this happens,
I do my best to first check the database and then query the musicbrainz
server.
I take some care to only connect to the database once, and to close the
connection when the thread exits.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And wire it up to the Player through the Application.
Implements: #45 (Create a new NowPlaying widget)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And wire up signals between the Now Playing card and the player.
Implements: #45 (Create a new NowPlaying widget)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And bind the Player tag properties to the Now Playing card.
Implements: #45 (Create a new NowPlaying widget)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And wire it up to the Header and Mpris.Player so we can apply volume &
replaygain changes as they happen.
Implements: #42 ("Remove global audio.Player instance")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The header currently contains just the title & subtitle information, but
will be expanded to add volume controls in the next patch.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Bind the width and height properties to the settings so they are
restored on startup and bind the fullscreen property to mpris.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This creates a new class to dynamically create GObject Properties, save
them to the database, and make it easy to bind application properties to
specific settings properties.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This inherits from the base Connection manager and adds in reading our
sql script to set up the database. It will also eventually hold pointers
to table objects that we can access directly.
Finally, I add a db property to the Application instance. The db is
connected during the ::startup signal handler, and disconnected during
the ::shutdown signal handler.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We can put all our icons into a single resource bundle that gets loaded
and only exists for our app.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'm going to put all of the main source code into a single subdirectory
under emmental/ and separate out tests into a separate tests/ directory.
Additionally, I have switched over to pytest for running tests to give
me better output (with color!)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>