This gives the UI a chance to set the new path or new size. I also
updated Ocarina to show the library path size in its liststore row.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This also removed the other `typedef sid_t` left in the header file.
I'll re-add in functions and variables as I need them, and hopefully
keep things working more efficiently.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I was using the sid_t to lookups for tracks and library paths. I think
I can simplify things by storing pointers in the UI rather than using
id numbers. This will give me direct access to whatever it is I want to
manipulate.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I created a new "list_dir()" function to recursively list directory
contents. I plan on using this to find songs to add to the library, but
it could also be modified to read playlists and library paths in the
appdir.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Whenever a task is queued, I increment a counter. When it is run, I
increment a different counter. This allows me to track the idle queue
completion percentage. I also created a progress bar for Ocarina to
display in the toes of the footer.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This allows other tools to be written to modify the library of a
currently running program without having to create a library driver
instance.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The set_tab_packing() function is deprecated, so I might as well just
use the real way to do this...
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I'm going to need a polling loop for the progress bar. I might as well
only create one poll() function that is used to do everything...
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The UI calls the library::add_path() function to create a new
LibraryPath structure to be managed by the library.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I want to gradually re-add everything and clean it up as I go along. To
help with this, I comment out the old code so I can use it as a
reference while writing new code.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I'm going to use a ribbon-ish interface for the footer and work the
settings pages in with the now playing widgets to make things easier to
find. Right now, I created everything with placeholders.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I'm not using a notebook as the main widget anymore. I'm also setting
the content directly, rather than getting the widget from the body code
and setting it in the window code.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I need to do some hacky things if the maximization changes. First, I
need to track the old (w, h) values and restore them in the preferences
since the configure-event will resize the window before the maximize
signal is given. Next, I need to ignore the next configure event since
it'll overwrite the preferences with the size of the window when it was
maximized.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I do this from the window init function using default values, rather
than pass it as a parameter to the init function.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I combined the ocarina.h and gtk.h header files into one single file. I
also began writing new window managing code under a window namespace for
code separation.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Instead, I pass a string with the name of the application being run.
This will be used to have separate applications using libsaria.
This commit also comments out most of the libsaria and ocarina init
functions until I can revise and clean up everything.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I eventually plan on creating more cpp binaries that link with libsaria
for pipe actions and other things. It's helpful to only initialize the
parts of libsaria that I intend to use.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The UI shortcuts may remove songs from the queue with no way of
notifying the stack layer. The UI should call the stack_top_pop()
function to check if the top playlist is empty and ready for removal.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Now renderers don't need to track this on their own, and renderers will
update as tracks are added.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Not all renderers are created dynamically, so I made a way of telling
the playlist system if renderers should be deleted.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I only allow one queue instance right now, but this allows me to remove
the queue directory since it is no longer needed. I also removed the
QUEUE_REFRESH callback since all this is handled through the libsaria
playlist code. All that's left is reloading saved playlists on startup.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Right now it's just for a single queue, but I should be able to expand
this once I enable more stacking in the backend.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This patch does two things. First, I remove the Page class and let each
notebook page manage itself. Second, I created functions to add the
header and footer to a GtkWidget and then prepend the page in the
notebook (so it adds pages as if it was a stack).
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This replaces the "remove id" ability and replaces it with a "remove
index" ability. Removing an index will remove the correct song in the
case that the same song has been added multiple times. I also modified
the UI to remove rows at a specific index.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I can get everything I need using playlists and renderers, so I can
safely remove this bit of code (I never really liked it anyway...). I
have to keep around the queue::size() function for a little bit longer,
since choosing the next song still uses it.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I don't need these now that I have playlist renderers, so I might as
well rip out the code while I'm thinking about it.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Rather than exposing iterator functions, I now have a function to walk
the playlist and call the renderer insert() function for each track.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This class will be given a Playlist and will be in charge of calling
Playlist functions. I eventually plan on expanding this to allow the
playlist to call renderer functions instead of using my current callback
system.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
GTK was printing a warning whenever a non-escaped string was hovered
over. The tooltip was also empty.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This function returns a newly allocated string, so I can't set it
directly to a C++ string since this will leak memory. Instead, I need
to keep the char* pointer around to free it.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The UI now passes in a string to use as the filename. In addition, I
store the filename and remove it when the application is closed. If the
pipe already exists, then I return the path without creating a new one.
Pipes will only be removed by the application that creates them.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I save the song before refreshing the library so I can scroll back to
it. This way the user isn't interrupted too much...
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I want to store the currently selected row and go back there after a
refresh or a filter. This allows me to find the current songid and
scroll back to it later.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I eventually want to be able to choose what columns are shown, so I need
them added to the treeview but now shown.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The tooltip is the filepath of the selected track. This should help me
figure out what some non-tagged tracks are...
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I keep one array instead of two, and I store more information for each
array entry. I can then find the size of the array for the number of
columns, and I can add new columns without having to modify the allay,
treestore and liststore.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I eventually only want the library page to have this header, but setting
this up allows me to remove the "switched page" logic that may (or may
not) have been causing problems.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
After listening to a long queue, I noticed that there were problems
re-realizing widgets after moving the footer to a different page (the
header might have the same problem?). I decided to fix this issue by
creating a new footer instance for each notebook page.
If I do the same thing for the page header then I can get rid of the
"move this widget from page X to page Y" logic AND allow pages to use
their own custom header AND allow for separate library and queue
filters.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
If the text is "play", "pause", or "next" then I call the appropriate
libsaria function. I eventually plan on adding more commands so bash
can act as a generic remote control, but for now this is a good start!
To use: `echo play > ~/.config/saria[-debug]/saria.pipe` after creating
the fifo (see scripts/makepipe).
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
Gstreamer uses multiple threads, and doing gtk calls outside the main
thread can lead to X11 errors. I get around this by creating a new
signal to respond to by the main loop.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The new code is a bit simpler, and it correctly fills in the list of
library paths during startup (I still have no idea why this didn't
happen with the old code).
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
I use the gdk threading functions to change my gtk code. This should
create fewer UI inconsistencies whenever anything changes, and it should
also allow me to trigger TRACK_LOADED from a new gstreamer thread.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
It was only getting filtered when new songs were added to it and never
unfiltered. This was somewhat confusing for me, and not very useful
since the only visible songs were the last ones added. I fixed this by
creating an init option to enable filtering on songlists.
Unlike my old version, this menu item is a check box that shows the user
the current 'pause after' state. This should be more useful and less
frustrating / confusing now.
I had a test function, but it wasn't being called. I connected the
widget to the activate signal and improved the function to list the rows
that are currently selected.
relative paths can't be trusted once the program has been installed. To
get around this, I assume that the install directory has been configured
correctly and then point to images located in the subdirectory next to
the executable.
Random hasn't been implemented in libsaria yet, but I can still create
the button to test preferences. The random button should set itself to
the value store in the preferences file.
Button 1 seeks by 10 seconds either forward or backward, button 2 seeks
to an absolute position. I initally wanted to switch the behavior of
these two buttons, but for now I'll just have to get used to the GTK
defaults.
I switched over to using pango <span> tags to set font properties to
make the text larger. I decided that the title will be bigger than
artist and album, so I can't have one generic function for setting the
label properties. Instead, I divided it up into one function for each
label.
Namespaces make code easier to follow, and remove the need to mangle the
beginning of function names by using ocarina_*() or libsaria_*(). In
other words: "namespaces are one honking good idea. Let's have more of
them!"
The SourceModel declares an insert() function that is called when
filling the list. I have defined this function in a way that the list
will be filled in through repeated calls to insert()
I want controls to be on the same level as the artist / album / title
labels. This will be more compact, and it won't waste a lot of empty
space above the labels and next to the controls.
This is just an initial implementation, so it's not very good right now.
It does give all the information, though. That's a plus. I also set
the artist / album / playlist whenever a SONG_LOADED callback is given.
It really should go into the include directory. I don't want to use
relative paths to include header files in a subdirectory... I don't know
why I even did it in the first place!
I combined reference counting with the get_footer() function to make
using it easier (no manual reference counting). put_footer() will
deallocate the widget if the reference count is 0 (this is already done
by the g_object_unref() function) so it should work in a sane way.
Calling the remove() function will destroy the footer if it has no other
references. To prevent this, I need to call g_object_ref() add a
reference to the widget.
I register the idle task when there are events in the idle queue and I
remove the idle task once those events have been processed. This should
cut down on CPU usage when nothing is happening.
A text button will use a slightly larger image to make it easier to see.
This also gives me an opportunity to add some help text to describe what
the button does.
I think ocarina/ is a better name for this directory, and now that I've
named the executable "ocarina.bin" I can do this again. I also added
functions for creating a page footer with the basic controls.
I create a panel for each library path showing the full path and the
number of songs. I also have a dummy button for removing the path from
the library.
I use a gobject signal to force setting album art in the main loop.
In theory, this should cut down on the number of crashes I see when
album art is fetched.
This patch introduces a new function "all_attrs()" which will return a
dictionary containing all the attributes for the current song. To help
the gui, I pass this dictionary during an on_load() callback.
I should use get_attrs() and then use the first result in the list,
rather than using the cur_id variable. cur_id is not set in the case of
loading a file.
I was using a get_attrs() call for finding the current song id. This
information is available directly through libsaria.sources, though. I
think it will be easier to just use the cur_id variable.
Each source was doing the exact same thing for filtering now that I have
a generic is_visible() function. There is no need for each source to
implement this.
I make the list of songs visible, I also update the number of songs.
Finally, I respond to the library_updated() callback when songs are
added / removed from the library.
This reflects my recent libsaria change. I'm keeping around my old
library code for now. The new library will gradually be introduced
through several patches ending with the removal of the old library.
I now wrap the entire resize operation in a try / except block.
Hopefully this will help to catch some errors. I also cleaned up my
"return early" conditions.
I was starting Ocarina through "import ocarina" in the launcher. This
was apparently a bad idea, since the import lock will never be released.
This lock prevents other threads from importing modules, so when I tried
to use urllib2 to download album art the call blocked until after I
closed Ocarina.
I've been looking forward to this. The last several commits have
replaced the generic event system with a hardcoded callback system.
This should be more efficient, easier to understand, and easier to
follow. I feel it is a better solution.
I removed the old methods, so I need to use the new methods for ocarina
to start up. This patch switches everything over.
NOTE: As of this patch, ocarina should work again.
I use a generic "set attributes" function to set the default attributes,
rather than having this function essentially twice (once for normal
buttons and once for toggle buttons)