This function is now unused, since we're using bisection insertion
instead. We switch remaining callers over to using node.append_child()
while we're at it.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is slower, but puts things in their right place. Implementing a
bisect search should help speed this up.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Let's just set the visible state directly. Additionally, I add a test
for setting visibility back to false when showing a different playlist
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lets us clean up add() so we only need to loop over the list once
and we can remove the buggy built-in iterator code.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
- Create a test_album variable instead of making each test build the
same path
- Create a single self.plist for test playlists
- Create a helper function for adding tracks
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
- curds.playlist.current() for the currently selected playlist
- curds.playlist.lookup() for lookups
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
- Make a shortcut to the Starred playlist for the UI
- Always sort playlists, rather than sorting as soon as they become
visible
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We need to re-add this playlist to the node after doing a reset since it
is a default playlist.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lets us delay sorting playlists until the first time they are shown
to make adding tracks faster. Additionally, we don't need to send
add-track notifications for playlists that aren't visible.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is cleaner than calling the sort function several times, or
overriding the sort_order array after construction.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
And disable sorting on the Previous playlist, since doing so would
basically be changing history.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This way, we control it all from one place instead of needing to derive
a new playlist to set these values. Additionally, the UI can use these
values to enable or disable the corresponding buttons
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We need to be able to see what's going on in order to fix the code, so
let's not fail silently and pretend that nothing went wrong.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Making it easy to look up a PlaylistNode by the python object id means
we can use the object id in the GtkTreeIter rather than storing the
entire path
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I noticed that the toplevel playlist siblings were always set to None,
so make sure we're properly setting these so they can be used.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'm going to take a different approach with setting the row heights
directly, so start by removing the newline here.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'm transitioning this class to be a PlaylistNode, and nodes can easily
access their parent through a .parent pointer
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Nothing else inherits from this class anymore, so let's merge it into
one to make it easier to deal with going forward.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This will eventually replace the GenreManager instance, and makes use of
the new playlist node code
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We'll use this do display the node in the UI. I add a newline so we
don't have to implement some kind of spacer class.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
My intention is to try to match the GtkTreeModel interface in terms of
functionality. This way, each node can act as its own iterator.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This helps reduce code duplication, since we can just call a single
function to handle sending the changed() signal.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I guess this could be lifted later if anybody asks for it, but I don't
think this really makes sense as a playlist source.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The collection playlist always has loop=True, so we'll never pop it from
the stack under normal conditions. Let's clear the list when selecting
this playlist so we don't keep a list of unreachable playlists.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'm going to keep a list of playlists that have been selected so we can
switch playlists automatically when one ends.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'm planning to use this for the automatic pausing code to tell the user
how much longer until we pause.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
If everything goes well and the test passes, then this line will never
be reached. Let's move it so it doesn't skew the code coverage report.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Otherwise we could end up sending notifications that don't make any
sense after their corresponding test ends.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The UI might take a while to process queued notifications, so to keep
from overwhelming the UI we want to only queue notification that haven't
been added already.
I also add in a lock around the notification queue since the main thread
processes notifications added by other threads.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lets the UI know that it has something to process when it gets the
chance. Additionally, I change the return value of run_queued() to
return false when there are no tasks remaining on the queue.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Rather than doing this as part of the playlist constructor. This ensures
that the UI is notified AFTER the playlist has been appended to the
PlaylistManager to prevent race conditions.
Additionally, I send the sorted index of the playlist and an indicator
if this is the first playlist added as part of the notification to help
make the UI's job easier.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The playlist manager doesn't need all the information about what changed
in the playlist, since it's mostly just updating the track count. Let's
just send the playlist so it won't get queued multiple times.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This isn't intended to hold playlists. Instead, it represents extra
spacing between playlists for the UI.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This makes the user's intentions a little more explicit, and saves us a
couple of lines of code.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This replaces the PlaylistAllocator, and provides a true base class that
can be used by each type of playlist manager.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lines up with how we handle the Library and Genre managers, and it
seems best to keep things consistent. For now, I keep string-indexing
implemented but I plan to switch over to numeric indexing soon.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We can figure this out a little easier on the backend side, so let's
handle this there rather than on the UI side
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This should make the UI side easier, since we can check against the
playlist type when searching for the playlist.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We have a find_playlist() function, so let's stick with a more generic
notification name so we don't have to repeat a lot of code.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Reset is used to make testing a little easier, since we won't have to
manually set set everything up again during each setUp function.
Stop is used to stop the library thread before shutdown.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Keeping this as a class that can never be instantiated seems like
overkill when we could just use plain functions.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This eases up some of the work on the UI side, since we don't need to
spend time trying to figure out where the track is in the playlist.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Gtk really doesn't like updates coming from outside of the main thread,
so let's add a way to register callbacks that can be queued up and run
later.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This playlist is designed to hold all the tracks that have been selected
for playback, and iterate through them backwards if needed.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We still fix the value, but if we ever add extra handling in the base
class then we'll be able to catch it.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Users might have images or ripping logs mixed in with their tracks, so
let's make sure we don't crash if we try to scan one of these.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I switch around the sidebar icons again, and also make the header bar
icons larger to make them easier to press with touchscreens
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Library paths are directories on disk, so it makes sense to use the
folder-music icon to represent them.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'll eventually make this more complex when I add in more playlists, but
for now it just calls next on the Collection playlist
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>