koto/src/components/cover-art-button.c

269 lines
7.1 KiB
C
Raw Normal View History

Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
/* cover-art-button.c
*
* Copyright 2021 Joshua Strobl
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glib-2.0/glib.h>
#include <gtk-4.0/gtk/gtk.h>
#include "../koto-utils.h"
Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
#include "button.h"
#include "cover-art-button.h"
struct _KotoCoverArtButton {
GObject parent_instance;
GtkWidget * art;
GtkWidget * main;
GtkWidget * revealer;
KotoButton * play_button;
Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
gchar * art_path;
guint height;
guint width;
};
G_DEFINE_TYPE(KotoCoverArtButton, koto_cover_art_button, G_TYPE_OBJECT);
enum {
PROP_0,
PROP_DESIRED_HEIGHT,
PROP_DESIRED_WIDTH,
PROP_ART_PATH,
N_PROPERTIES
};
static GParamSpec * props[N_PROPERTIES] = {
NULL,
};
static void koto_cover_art_button_get_property(
GObject * obj,
guint prop_id,
GValue * val,
GParamSpec * spec
);
static void koto_cover_art_button_set_property(
GObject * obj,
guint prop_id,
const GValue * val,
GParamSpec * spec
);
static void koto_cover_art_button_class_init(KotoCoverArtButtonClass * c) {
GObjectClass * gobject_class;
gobject_class = G_OBJECT_CLASS(c);
gobject_class->get_property = koto_cover_art_button_get_property;
gobject_class->set_property = koto_cover_art_button_set_property;
props[PROP_DESIRED_HEIGHT] = g_param_spec_uint(
"desired-height",
"Desired height",
"Desired height",
0,
G_MAXUINT,
0,
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_WRITABLE
);
props[PROP_DESIRED_WIDTH] = g_param_spec_uint(
"desired-width",
"Desired width",
"Desired width",
0,
G_MAXUINT,
0,
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_WRITABLE
);
props[PROP_ART_PATH] = g_param_spec_string(
"art-path",
"Path to art",
"Path to art",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_WRITABLE
);
g_object_class_install_properties(gobject_class, N_PROPERTIES, props);
}
static void koto_cover_art_button_init(KotoCoverArtButton * self) {
self->main = gtk_overlay_new(); // Create our overlay container
gtk_widget_add_css_class(self->main, "cover-art-button");
self->revealer = gtk_revealer_new(); // Create a new revealer
gtk_revealer_set_transition_type(GTK_REVEALER(self->revealer), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE);
gtk_revealer_set_transition_duration(GTK_REVEALER(self->revealer), 400);
GtkWidget * controls = gtk_center_box_new(); // Create a center box for the controls
self->play_button = koto_button_new_with_icon("", "media-playback-start-symbolic", NULL, KOTO_BUTTON_PIXBUF_SIZE_NORMAL);
gtk_center_box_set_center_widget(GTK_CENTER_BOX(controls), GTK_WIDGET(self->play_button));
gtk_revealer_set_child(GTK_REVEALER(self->revealer), controls);
koto_cover_art_button_hide_overlay_controls(NULL, self); // Hide by default
gtk_overlay_add_overlay(GTK_OVERLAY(self->main), self->revealer); // Add our revealer as the overlay
GtkEventController * motion_controller = gtk_event_controller_motion_new(); // Create our new motion event controller to track mouse leave and enter
g_signal_connect(motion_controller, "enter", G_CALLBACK(koto_cover_art_button_show_overlay_controls), self);
g_signal_connect(motion_controller, "leave", G_CALLBACK(koto_cover_art_button_hide_overlay_controls), self);
gtk_widget_add_controller(self->main, motion_controller);
Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
self->art_path = NULL;
}
static void koto_cover_art_button_get_property(
GObject * obj,
guint prop_id,
GValue * val,
GParamSpec * spec
) {
(void) val;
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec);
break;
}
}
static void koto_cover_art_button_set_property(
GObject * obj,
guint prop_id,
const GValue * val,
GParamSpec * spec
) {
KotoCoverArtButton * self = KOTO_COVER_ART_BUTTON(obj);
switch (prop_id) {
case PROP_ART_PATH:
koto_cover_art_button_set_art_path(self, (gchar*) g_value_get_string(val)); // Get the value and call our set_art_path with it
break;
case PROP_DESIRED_HEIGHT:
koto_cover_art_button_set_dimensions(self, g_value_get_uint(val), 0);
break;
case PROP_DESIRED_WIDTH:
koto_cover_art_button_set_dimensions(self, 0, g_value_get_uint(val));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec);
break;
}
}
void koto_cover_art_button_hide_overlay_controls(
GtkEventControllerFocus * controller,
gpointer data
) {
(void) controller;
KotoCoverArtButton * self = data;
gtk_revealer_set_reveal_child(GTK_REVEALER(self->revealer), FALSE);
}
KotoButton * koto_cover_art_button_get_button(KotoCoverArtButton * self) {
if (!KOTO_IS_COVER_ART_BUTTON(self)) {
return NULL;
}
return self->play_button;
}
GtkWidget * koto_cover_art_button_get_main(KotoCoverArtButton * self) {
if (!KOTO_IS_COVER_ART_BUTTON(self)) {
return NULL;
}
return self->main;
}
void koto_cover_art_button_set_art_path(
KotoCoverArtButton * self,
gchar * art_path
) {
if (!KOTO_IS_COVER_ART_BUTTON(self)) {
return;
}
Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
gboolean defined_artwork = koto_utils_string_is_valid(art_path);
if (GTK_IS_IMAGE(self->art)) { // Already have an image
if (!defined_artwork) { // No art path or empty string
gtk_image_set_from_icon_name(GTK_IMAGE(self->art), "audio-x-generic-symbolic");
} else { // Have an art path
Implement initial audiobook UX (some of which is a bit of a WIP). - Renamed various components and moved them to src/components. - Renamed KOTO_PREFERRED_MODEL* to KOTO_PREFERRED_PLAYLIST* - Renamed koto string utility functions to always be prefixed with koto_utils_string_ for consistency. - Added configuration options for show / hiding various album information, as well as preferred sort type. - Changed db schema to reflect various metadata changes (sorry). - Implemented genre, narrator, year aggregation from KotoTrack to KotoAlbum for use in KotoAlbumInfo and audiobooks. - Rearchitected our playlist functionality for KotoAlbums to always have an inner KotoPlaylist that is used. - Added various getters / setters for new koto_album functionality. - Implement aggregation of KotoAlbum pointer aggregation in the KotoArtist as a GQueue and GListStore instead of GList so we can get all the albums associated with an artist and use the GListStore for the audiobook view. - Implement some initial album sorting in Artists (more work to do on this front). - Many improvements to file indexing logic for CD and position detection, various new koto_track_helpers. - Add new logic for knowing when to hide playlists given we generate them for each Album now. - Fix missing updates of KotoPlaylist in KotoNav. - Added playback position to KotoPlayerbar, renamed bar refs to self. - New Playlist state saving. - Updated track ticking logic for track in KotoPlaybackEngine. - Fixed playback position detection in our KotoPlaybackEngine by swapping from GST_FORMAT_DEFAULT to GST_FORMAT_TIME. - Changed our get_progress to divide by GST_SECOND. - Fixed missing type checks in various KotoPlaybackEngine functions. Fixes #13. Fixes #14. Fixes #15.
2021-08-10 19:18:46 +03:00
if (g_strcmp0(self->art_path, art_path) != 0) {
self->art_path = g_strdup(art_path); // Set our art path
gtk_image_set_from_file(GTK_IMAGE(self->art), self->art_path); // Set from the file
}
}
} else { // If we don't have an image
self->art = koto_utils_create_image_from_filepath(defined_artwork ? g_strdup(art_path) : NULL, "audio-x-generic-symbolic", self->width, self->height);
gtk_overlay_set_child(GTK_OVERLAY(self->main), self->art); // Set the child
}
}
void koto_cover_art_button_set_dimensions(
KotoCoverArtButton * self,
guint height,
guint width
) {
if (!KOTO_IS_COVER_ART_BUTTON(self)) {
return;
}
if (height != 0) {
self->height = height;
}
if (width != 0) {
self->width = width;
}
if ((self->height != 0) && (self->width != 0)) { // Both height and width set
gtk_widget_set_size_request(self->main, self->width, self->height); // Update our widget
if (GTK_IS_IMAGE(self->art)) { // Art is defined
gtk_widget_set_size_request(self->art, self->width, self->height); // Update our image as well
}
}
}
void koto_cover_art_button_show_overlay_controls(
GtkEventControllerFocus * controller,
gpointer data
) {
(void) controller;
KotoCoverArtButton * self = data;
gtk_revealer_set_reveal_child(GTK_REVEALER(self->revealer), TRUE);
}
KotoCoverArtButton * koto_cover_art_button_new(
guint height,
guint width,
gchar * art_path
) {
return g_object_new(
KOTO_TYPE_COVER_ART_BUTTON,
"desired-height",
height,
"desired-width",
width,
"art-path",
art_path,
NULL
);
}