2021-02-09 17:37:26 +02:00
/* koto-playerbar.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 .
*/
2021-03-23 19:50:09 +02:00
# include <gstreamer-1.0/gst/gst.h>
2021-02-24 20:17:18 +02:00
# include <gtk-4.0/gtk/gtk.h>
2021-03-25 17:29:45 +02:00
# include "db/cartographer.h"
2021-04-06 10:41:15 +03:00
# include "playlist/current.h"
# include "playlist/playlist.h"
2021-03-23 19:50:09 +02:00
# include "playback/engine.h"
2021-02-12 12:56:41 +02:00
# include "koto-button.h"
2021-02-09 17:37:26 +02:00
# include "koto-config.h"
# include "koto-playerbar.h"
2021-04-06 10:41:15 +03:00
extern KotoCurrentPlaylist * current_playlist ;
2021-03-25 17:29:45 +02:00
extern KotoCartographer * koto_maps ;
2021-03-23 19:50:09 +02:00
extern KotoPlaybackEngine * playback_engine ;
2021-02-09 17:37:26 +02:00
struct _KotoPlayerBar {
2021-02-24 20:17:18 +02:00
GObject parent_instance ;
GtkWidget * main ;
2021-03-23 19:50:09 +02:00
GtkWidget * controls ;
2021-02-09 17:37:26 +02:00
/* Sections */
GtkWidget * playback_section ;
GtkWidget * primary_controls_section ;
GtkWidget * secondary_controls_section ;
/* Primary Buttons */
2021-02-12 12:56:41 +02:00
KotoButton * back_button ;
KotoButton * play_pause_button ;
KotoButton * forward_button ;
KotoButton * repeat_button ;
KotoButton * shuffle_button ;
KotoButton * playlist_button ;
KotoButton * eq_button ;
2021-02-09 17:37:26 +02:00
GtkWidget * volume_button ;
2021-03-23 19:50:09 +02:00
GtkWidget * progress_bar ;
2021-02-09 17:37:26 +02:00
/* Selected Playback Section */
GtkWidget * playback_details_section ;
GtkWidget * artwork ;
GtkWidget * playback_title ;
GtkWidget * playback_album ;
GtkWidget * playback_artist ;
2021-03-25 17:29:45 +02:00
gint64 last_recorded_duration ;
gboolean is_progressbar_seeking ;
2021-02-09 17:37:26 +02:00
} ;
struct _KotoPlayerBarClass {
2021-02-24 20:17:18 +02:00
GObjectClass parent_class ;
2021-02-09 17:37:26 +02:00
} ;
2021-02-24 20:17:18 +02:00
G_DEFINE_TYPE ( KotoPlayerBar , koto_playerbar , G_TYPE_OBJECT ) ;
2021-02-09 17:37:26 +02:00
static void koto_playerbar_constructed ( GObject * obj ) ;
static void koto_playerbar_class_init ( KotoPlayerBarClass * c ) {
GObjectClass * gobject_class ;
gobject_class = G_OBJECT_CLASS ( c ) ;
gobject_class - > constructed = koto_playerbar_constructed ;
}
static void koto_playerbar_constructed ( GObject * obj ) {
KotoPlayerBar * self = KOTO_PLAYERBAR ( obj ) ;
2021-03-23 19:50:09 +02:00
self - > main = gtk_box_new ( GTK_ORIENTATION_VERTICAL , 0 ) ;
self - > progress_bar = gtk_scale_new_with_range ( GTK_ORIENTATION_HORIZONTAL , 0 , 120 , 1 ) ; // Default to 120 as random max
gtk_scale_set_draw_value ( GTK_SCALE ( self - > progress_bar ) , FALSE ) ;
gtk_scale_set_digits ( GTK_SCALE ( self - > progress_bar ) , 0 ) ;
gtk_range_set_increments ( GTK_RANGE ( self - > progress_bar ) , 1 , 1 ) ;
2021-03-25 17:29:45 +02:00
gtk_range_set_round_digits ( GTK_RANGE ( self - > progress_bar ) , 1 ) ;
2021-04-06 10:41:15 +03:00
GtkEventController * scroll_controller = gtk_event_controller_scroll_new ( GTK_EVENT_CONTROLLER_SCROLL_HORIZONTAL ) ;
g_signal_connect ( scroll_controller , " scroll-begin " , G_CALLBACK ( koto_playerbar_handle_progressbar_scroll_begin ) , self ) ;
gtk_widget_add_controller ( GTK_WIDGET ( self - > progress_bar ) , scroll_controller ) ;
2021-03-25 17:29:45 +02:00
GtkGesture * press_controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureLongPress
2021-04-06 10:41:15 +03:00
gtk_gesture_single_set_button ( GTK_GESTURE_SINGLE ( press_controller ) , 1 ) ; // Set to left click
g_signal_connect ( GTK_GESTURE ( press_controller ) , " begin " , G_CALLBACK ( koto_playerbar_handle_progressbar_gesture_begin ) , self ) ;
g_signal_connect ( GTK_GESTURE ( press_controller ) , " end " , G_CALLBACK ( koto_playerbar_handle_progressbar_gesture_end ) , self ) ;
2021-03-25 17:29:45 +02:00
g_signal_connect ( press_controller , " pressed " , G_CALLBACK ( koto_playerbar_handle_progressbar_pressed ) , self ) ;
2021-04-06 10:41:15 +03:00
//g_signal_connect(press_controller, "unpaired-release", G_CALLBACK(koto_playerbar_handle_progressbar_unpaired_release), self);
2021-03-25 17:29:45 +02:00
gtk_widget_add_controller ( GTK_WIDGET ( self - > progress_bar ) , GTK_EVENT_CONTROLLER ( press_controller ) ) ;
g_signal_connect ( GTK_RANGE ( self - > progress_bar ) , " value-changed " , G_CALLBACK ( koto_playerbar_handle_progressbar_value_changed ) , self ) ;
2021-03-23 19:50:09 +02:00
self - > controls = gtk_center_box_new ( ) ;
gtk_center_box_set_baseline_position ( GTK_CENTER_BOX ( self - > controls ) , GTK_BASELINE_POSITION_CENTER ) ;
2021-02-24 20:17:18 +02:00
gtk_widget_add_css_class ( self - > main , " player-bar " ) ;
2021-02-09 17:37:26 +02:00
self - > playback_section = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL , 0 ) ;
self - > primary_controls_section = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL , 0 ) ;
self - > secondary_controls_section = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL , 0 ) ;
2021-03-23 19:50:09 +02:00
gtk_center_box_set_start_widget ( GTK_CENTER_BOX ( self - > controls ) , GTK_WIDGET ( self - > primary_controls_section ) ) ;
gtk_center_box_set_center_widget ( GTK_CENTER_BOX ( self - > controls ) , GTK_WIDGET ( self - > playback_section ) ) ;
gtk_center_box_set_end_widget ( GTK_CENTER_BOX ( self - > controls ) , GTK_WIDGET ( self - > secondary_controls_section ) ) ;
2021-02-09 17:37:26 +02:00
koto_playerbar_create_playback_details ( self ) ;
koto_playerbar_create_primary_controls ( self ) ;
koto_playerbar_create_secondary_controls ( self ) ;
2021-03-23 19:50:09 +02:00
gtk_box_prepend ( GTK_BOX ( self - > main ) , self - > progress_bar ) ;
gtk_box_append ( GTK_BOX ( self - > main ) , self - > controls ) ;
2021-02-24 20:17:18 +02:00
gtk_widget_set_hexpand ( GTK_WIDGET ( self - > main ) , TRUE ) ;
2021-03-23 19:50:09 +02:00
// Set up the bindings
2021-03-25 17:29:45 +02:00
g_signal_connect ( playback_engine , " is-playing " , G_CALLBACK ( koto_playerbar_handle_is_playing ) , self ) ;
g_signal_connect ( playback_engine , " is-paused " , G_CALLBACK ( koto_playerbar_handle_is_paused ) , self ) ;
g_signal_connect ( playback_engine , " tick-duration " , G_CALLBACK ( koto_playerbar_handle_tick_duration ) , self ) ;
g_signal_connect ( playback_engine , " tick-track " , G_CALLBACK ( koto_playerbar_handle_tick_track ) , self ) ;
g_signal_connect ( playback_engine , " track-changed " , G_CALLBACK ( koto_playerbar_update_track_info ) , self ) ;
2021-02-09 17:37:26 +02:00
}
static void koto_playerbar_init ( KotoPlayerBar * self ) {
2021-03-25 17:29:45 +02:00
self - > last_recorded_duration = 0 ;
self - > is_progressbar_seeking = FALSE ;
2021-02-09 17:37:26 +02:00
}
KotoPlayerBar * koto_playerbar_new ( void ) {
2021-02-24 20:17:18 +02:00
return g_object_new ( KOTO_TYPE_PLAYERBAR , NULL ) ;
2021-02-09 17:37:26 +02:00
}
void koto_playerbar_create_playback_details ( KotoPlayerBar * bar ) {
bar - > playback_details_section = gtk_box_new ( GTK_ORIENTATION_VERTICAL , 0 ) ;
2021-02-24 20:17:18 +02:00
GtkIconTheme * default_icon_theme = gtk_icon_theme_get_for_display ( gdk_display_get_default ( ) ) ; // Get the icon theme for this display
2021-02-09 17:37:26 +02:00
if ( default_icon_theme ! = NULL ) {
2021-02-27 17:26:24 +02:00
gint scale_factor = gtk_widget_get_scale_factor ( GTK_WIDGET ( bar - > main ) ) ;
2021-02-24 20:17:18 +02:00
GtkIconPaintable * audio_paintable = gtk_icon_theme_lookup_icon ( default_icon_theme , " audio-x-generic-symbolic " , NULL , 96 , scale_factor , GTK_TEXT_DIR_NONE , GTK_ICON_LOOKUP_PRELOAD ) ;
if ( GTK_IS_ICON_PAINTABLE ( audio_paintable ) ) {
if ( GTK_IS_IMAGE ( bar - > artwork ) ) {
gtk_image_set_from_paintable ( GTK_IMAGE ( bar - > artwork ) , GDK_PAINTABLE ( audio_paintable ) ) ;
} else { // Not an image
bar - > artwork = gtk_image_new_from_paintable ( GDK_PAINTABLE ( audio_paintable ) ) ;
gtk_widget_set_size_request ( bar - > artwork , 96 , 96 ) ;
gtk_box_append ( GTK_BOX ( bar - > playback_section ) , bar - > artwork ) ;
}
2021-02-09 17:37:26 +02:00
}
}
2021-02-12 12:56:41 +02:00
bar - > playback_title = gtk_label_new ( " Title " ) ;
bar - > playback_album = gtk_label_new ( " Album " ) ;
bar - > playback_artist = gtk_label_new ( " Artist " ) ;
2021-02-09 17:37:26 +02:00
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > playback_details_section ) , GTK_WIDGET ( bar - > playback_title ) ) ;
gtk_box_append ( GTK_BOX ( bar - > playback_details_section ) , GTK_WIDGET ( bar - > playback_album ) ) ;
gtk_box_append ( GTK_BOX ( bar - > playback_details_section ) , GTK_WIDGET ( bar - > playback_artist ) ) ;
2021-02-09 17:37:26 +02:00
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > playback_section ) , GTK_WIDGET ( bar - > playback_details_section ) ) ;
2021-02-09 17:37:26 +02:00
}
void koto_playerbar_create_primary_controls ( KotoPlayerBar * bar ) {
2021-02-25 18:15:36 +02:00
bar - > back_button = koto_button_new_with_icon ( " " , " media-skip-backward-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
2021-03-10 13:44:08 +02:00
bar - > play_pause_button = koto_button_new_with_icon ( " " , " media-playback-start-symbolic " , " media-playback-pause-symbolic " , KOTO_BUTTON_PIXBUF_SIZE_LARGE ) ; // TODO: Have this take in a state and switch to a different icon if necessary
2021-02-25 18:15:36 +02:00
bar - > forward_button = koto_button_new_with_icon ( " " , " media-skip-forward-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
2021-02-09 17:37:26 +02:00
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > back_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > primary_controls_section ) , GTK_WIDGET ( bar - > back_button ) ) ;
2021-04-06 10:41:15 +03:00
GtkGesture * back_controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureClick
g_signal_connect ( back_controller , " pressed " , G_CALLBACK ( koto_playerbar_go_backwards ) , NULL ) ;
gtk_widget_add_controller ( GTK_WIDGET ( bar - > back_button ) , GTK_EVENT_CONTROLLER ( back_controller ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > play_pause_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > primary_controls_section ) , GTK_WIDGET ( bar - > play_pause_button ) ) ;
2021-02-09 17:37:26 +02:00
2021-04-06 10:41:15 +03:00
GtkGesture * controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureClick
g_signal_connect ( controller , " pressed " , G_CALLBACK ( koto_playerbar_toggle_play_pause ) , NULL ) ;
gtk_widget_add_controller ( GTK_WIDGET ( bar - > play_pause_button ) , GTK_EVENT_CONTROLLER ( controller ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-03-23 19:50:09 +02:00
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > forward_button ) ) {
gtk_box_append ( GTK_BOX ( bar - > primary_controls_section ) , GTK_WIDGET ( bar - > forward_button ) ) ;
2021-03-23 19:50:09 +02:00
2021-04-06 10:41:15 +03:00
GtkGesture * forwards_controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureClick
g_signal_connect ( forwards_controller , " pressed " , G_CALLBACK ( koto_playerbar_go_forwards ) , NULL ) ;
gtk_widget_add_controller ( GTK_WIDGET ( bar - > forward_button ) , GTK_EVENT_CONTROLLER ( forwards_controller ) ) ;
}
2021-02-09 17:37:26 +02:00
}
void koto_playerbar_create_secondary_controls ( KotoPlayerBar * bar ) {
2021-02-25 18:15:36 +02:00
bar - > repeat_button = koto_button_new_with_icon ( " " , " media-playlist-repeat-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
bar - > shuffle_button = koto_button_new_with_icon ( " " , " media-playlist-shuffle-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
bar - > playlist_button = koto_button_new_with_icon ( " " , " playlist-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
bar - > eq_button = koto_button_new_with_icon ( " " , " multimedia-equalizer-symbolic " , NULL , KOTO_BUTTON_PIXBUF_SIZE_NORMAL ) ;
2021-02-09 17:37:26 +02:00
2021-04-06 10:41:15 +03:00
bar - > volume_button = gtk_volume_button_new ( ) ; // Have this take in a state and switch to a different icon if necessary
2021-03-25 17:29:45 +02:00
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > repeat_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > secondary_controls_section ) , GTK_WIDGET ( bar - > repeat_button ) ) ;
2021-04-06 10:41:15 +03:00
GtkGesture * controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureClick
g_signal_connect ( controller , " pressed " , G_CALLBACK ( koto_playerbar_toggle_track_repeat ) , bar ) ;
gtk_widget_add_controller ( GTK_WIDGET ( bar - > repeat_button ) , GTK_EVENT_CONTROLLER ( controller ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > shuffle_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > secondary_controls_section ) , GTK_WIDGET ( bar - > shuffle_button ) ) ;
2021-04-06 10:41:15 +03:00
GtkGesture * controller = gtk_gesture_click_new ( ) ; // Create a new GtkGestureClick
g_signal_connect ( controller , " pressed " , G_CALLBACK ( koto_playerbar_toggle_playlist_shuffle ) , bar ) ;
gtk_widget_add_controller ( GTK_WIDGET ( bar - > shuffle_button ) , GTK_EVENT_CONTROLLER ( controller ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > playlist_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > secondary_controls_section ) , GTK_WIDGET ( bar - > playlist_button ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-04-06 10:41:15 +03:00
if ( KOTO_IS_BUTTON ( bar - > eq_button ) ) {
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > secondary_controls_section ) , GTK_WIDGET ( bar - > eq_button ) ) ;
2021-02-09 17:37:26 +02:00
}
2021-04-06 10:41:15 +03:00
if ( GTK_IS_VOLUME_BUTTON ( bar - > volume_button ) ) {
GtkAdjustment * granular_volume_change = gtk_adjustment_new ( 0.5 , 0 , 1.0 , 0.02 , 0.02 , 0.02 ) ;
g_object_set ( bar - > volume_button , " use-symbolic " , TRUE , NULL ) ;
gtk_range_set_round_digits ( GTK_RANGE ( bar - > volume_button ) , FALSE ) ;
gtk_scale_button_set_adjustment ( GTK_SCALE_BUTTON ( bar - > volume_button ) , granular_volume_change ) ; // Set our adjustment
2021-02-24 20:17:18 +02:00
gtk_box_append ( GTK_BOX ( bar - > secondary_controls_section ) , bar - > volume_button ) ;
2021-04-06 10:41:15 +03:00
g_signal_connect ( GTK_SCALE_BUTTON ( bar - > volume_button ) , " value-changed " , G_CALLBACK ( koto_playerbar_handle_volume_button_change ) , bar ) ;
2021-02-09 17:37:26 +02:00
}
}
2021-02-24 20:17:18 +02:00
2021-03-23 19:50:09 +02:00
void koto_playerbar_go_backwards ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ; ( void ) data ;
koto_playback_engine_backwards ( playback_engine ) ;
}
void koto_playerbar_go_forwards ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ; ( void ) data ;
koto_playback_engine_forwards ( playback_engine ) ;
}
2021-03-25 17:29:45 +02:00
void koto_playerbar_handle_is_playing ( KotoPlaybackEngine * engine , gpointer user_data ) {
2021-03-23 19:50:09 +02:00
if ( ! KOTO_IS_PLAYBACK_ENGINE ( engine ) ) {
return ;
}
KotoPlayerBar * bar = user_data ;
2021-03-25 17:29:45 +02:00
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
koto_button_show_image ( bar - > play_pause_button , TRUE ) ; // Set to TRUE to show pause as the next action
2021-03-23 19:50:09 +02:00
}
2021-03-25 17:29:45 +02:00
void koto_playerbar_handle_is_paused ( KotoPlaybackEngine * engine , gpointer user_data ) {
2021-03-23 19:50:09 +02:00
if ( ! KOTO_IS_PLAYBACK_ENGINE ( engine ) ) {
return ;
}
KotoPlayerBar * bar = user_data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
2021-03-25 17:29:45 +02:00
koto_button_show_image ( bar - > play_pause_button , FALSE ) ; // Set to FALSE to show play as the next action
}
2021-04-06 10:41:15 +03:00
void koto_playerbar_handle_progressbar_scroll_begin ( GtkEventControllerScroll * controller , gpointer data ) {
( void ) controller ;
g_message ( " scroll-begin " ) ;
}
void koto_playerbar_handle_progressbar_gesture_begin ( GtkGesture * gesture , GdkEventSequence * seq , gpointer data ) {
( void ) gesture ; ( void ) seq ;
2021-03-25 17:29:45 +02:00
KotoPlayerBar * bar = data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
2021-04-06 10:41:15 +03:00
g_message ( " Begin " ) ;
2021-03-25 17:29:45 +02:00
bar - > is_progressbar_seeking = TRUE ;
}
2021-04-06 10:41:15 +03:00
void koto_playerbar_handle_progressbar_gesture_end ( GtkGesture * gesture , GdkEventSequence * seq , gpointer data ) {
( void ) gesture ; ( void ) seq ;
2021-03-25 17:29:45 +02:00
KotoPlayerBar * bar = data ;
2021-04-06 10:41:15 +03:00
g_message ( " Ended " ) ;
2021-03-25 17:29:45 +02:00
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
bar - > is_progressbar_seeking = FALSE ;
}
2021-04-06 10:41:15 +03:00
void koto_playerbar_handle_progressbar_pressed ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ;
KotoPlayerBar * bar = data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
g_message ( " Pressed " ) ;
bar - > is_progressbar_seeking = TRUE ;
}
2021-03-25 17:29:45 +02:00
void koto_playerbar_handle_progressbar_value_changed ( GtkRange * progress_bar , gpointer data ) {
KotoPlayerBar * bar = data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
if ( ! bar - > is_progressbar_seeking ) {
return ;
}
2021-03-23 19:50:09 +02:00
2021-03-25 17:29:45 +02:00
int desired_position = ( int ) gtk_range_get_value ( progress_bar ) ;
2021-04-06 10:41:15 +03:00
g_message ( " value changed " ) ;
2021-03-25 17:29:45 +02:00
koto_playback_engine_set_position ( playback_engine , desired_position ) ; // Update our position
}
void koto_playerbar_handle_tick_duration ( KotoPlaybackEngine * engine , gpointer user_data ) {
if ( ! KOTO_IS_PLAYBACK_ENGINE ( engine ) ) {
return ;
}
KotoPlayerBar * bar = user_data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
2021-03-23 19:50:09 +02:00
}
2021-03-25 17:29:45 +02:00
koto_playerbar_set_progressbar_duration ( bar , koto_playback_engine_get_duration ( engine ) ) ;
2021-03-23 19:50:09 +02:00
}
2021-03-25 17:29:45 +02:00
void koto_playerbar_handle_tick_track ( KotoPlaybackEngine * engine , gpointer user_data ) {
2021-03-23 19:50:09 +02:00
if ( ! KOTO_IS_PLAYBACK_ENGINE ( engine ) ) {
return ;
}
KotoPlayerBar * bar = user_data ;
2021-03-25 17:29:45 +02:00
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
if ( ! bar - > is_progressbar_seeking ) {
koto_playerbar_set_progressbar_value ( bar , koto_playback_engine_get_progress ( engine ) ) ;
}
}
void koto_playerbar_handle_volume_button_change ( GtkScaleButton * button , double value , gpointer user_data ) {
( void ) button ; ( void ) user_data ;
koto_playback_engine_set_volume ( playback_engine , value ) ;
2021-03-23 19:50:09 +02:00
}
void koto_playerbar_reset_progressbar ( KotoPlayerBar * bar ) {
gtk_range_set_range ( GTK_RANGE ( bar - > progress_bar ) , 0 , 0 ) ; // Reset range
gtk_range_set_value ( GTK_RANGE ( bar - > progress_bar ) , 0 ) ; // Set value to 0
}
void koto_playerbar_set_progressbar_duration ( KotoPlayerBar * bar , gint64 duration ) {
2021-03-25 17:29:45 +02:00
if ( duration < = 0 ) {
2021-03-23 19:50:09 +02:00
return ;
}
2021-03-25 17:29:45 +02:00
if ( duration ! = bar - > last_recorded_duration ) { // Duration is different than what we recorded
bar - > last_recorded_duration = duration ;
gtk_range_set_range ( GTK_RANGE ( bar - > progress_bar ) , 0 , bar - > last_recorded_duration ) ;
}
2021-03-23 19:50:09 +02:00
}
void koto_playerbar_set_progressbar_value ( KotoPlayerBar * bar , gint64 progress ) {
gtk_range_set_value ( GTK_RANGE ( bar - > progress_bar ) , progress ) ;
}
void koto_playerbar_toggle_play_pause ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ; ( void ) data ;
koto_playback_engine_toggle ( playback_engine ) ;
}
2021-04-06 10:41:15 +03:00
void koto_playerbar_toggle_playlist_shuffle ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ;
KotoPlayerBar * bar = data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
KotoPlaylist * playlist = koto_current_playlist_get_playlist ( current_playlist ) ;
if ( ! KOTO_IS_PLAYLIST ( playlist ) ) { // Don't have a playlist currently
gtk_widget_remove_css_class ( GTK_WIDGET ( bar - > shuffle_button ) , " active " ) ; // Remove active state
return ;
}
gboolean currently_shuffling = FALSE ;
g_object_get ( playlist , " is-shuffle-enabled " , & currently_shuffling , NULL ) ; // Get the current is-shuffle-enabled
( currently_shuffling ) ? gtk_widget_remove_css_class ( GTK_WIDGET ( bar - > shuffle_button ) , " active " ) : gtk_widget_add_css_class ( GTK_WIDGET ( bar - > shuffle_button ) , " active " ) ;
g_object_set ( playlist , " is-shuffle-enabled " , ! currently_shuffling , NULL ) ; // Provide inverse value
}
void koto_playerbar_toggle_track_repeat ( GtkGestureClick * gesture , int n_press , double x , double y , gpointer data ) {
( void ) gesture ; ( void ) n_press ; ( void ) x ; ( void ) y ;
KotoPlayerBar * bar = data ;
if ( koto_playback_engine_get_track_repeat ( playback_engine ) ) { // Toggled on at the moment
gtk_widget_remove_css_class ( GTK_WIDGET ( bar - > repeat_button ) , " active " ) ; // Remove active CSS class
} else {
gtk_widget_add_css_class ( GTK_WIDGET ( bar - > repeat_button ) , " active " ) ; // Add active CSS class
}
koto_playback_engine_toggle_track_repeat ( playback_engine ) ; // Toggle the state
}
2021-03-25 17:29:45 +02:00
void koto_playerbar_update_track_info ( KotoPlaybackEngine * engine , gpointer user_data ) {
if ( ! KOTO_IS_PLAYBACK_ENGINE ( engine ) ) {
return ;
}
KotoPlayerBar * bar = user_data ;
if ( ! KOTO_IS_PLAYERBAR ( bar ) ) {
return ;
}
KotoIndexedTrack * current_track = koto_playback_engine_get_current_track ( playback_engine ) ; // Get the current track from the playback engine
if ( ! KOTO_IS_INDEXED_TRACK ( current_track ) ) {
return ;
}
gchar * track_name = NULL ;
gchar * artist_uuid = NULL ;
gchar * album_uuid = NULL ;
g_object_get ( current_track , " parsed-name " , & track_name , " artist-uuid " , & artist_uuid , " album-uuid " , & album_uuid , NULL ) ;
KotoIndexedArtist * artist = koto_cartographer_get_artist_by_uuid ( koto_maps , artist_uuid ) ;
KotoIndexedAlbum * album = koto_cartographer_get_album_by_uuid ( koto_maps , album_uuid ) ;
g_free ( artist_uuid ) ;
g_free ( album_uuid ) ;
if ( ( track_name ! = NULL ) & & ( strcmp ( track_name , " " ) ! = 0 ) ) { // Have a track name
gtk_label_set_text ( GTK_LABEL ( bar - > playback_title ) , track_name ) ; // Set the label
}
if ( KOTO_IS_INDEXED_ARTIST ( artist ) ) {
gchar * artist_name = NULL ;
g_object_get ( artist , " name " , & artist_name , NULL ) ;
if ( ( artist_name ! = NULL ) & & ( strcmp ( artist_name , " " ) ! = 0 ) ) { // Have an artist name
gtk_label_set_text ( GTK_LABEL ( bar - > playback_artist ) , artist_name ) ;
gtk_widget_show ( bar - > playback_artist ) ;
} else { // Don't have an artist name somehow
gtk_widget_hide ( bar - > playback_artist ) ;
}
}
if ( KOTO_IS_INDEXED_ALBUM ( album ) ) {
gchar * album_name = NULL ;
gchar * art_path = NULL ;
g_object_get ( album , " name " , & album_name , " art-path " , & art_path , NULL ) ; // Get album name and art path
if ( ( album_name ! = NULL ) & & ( strcmp ( album_name , " " ) ! = 0 ) ) { // Have an album name
gtk_label_set_text ( GTK_LABEL ( bar - > playback_album ) , album_name ) ;
gtk_widget_show ( bar - > playback_album ) ;
} else {
gtk_widget_hide ( bar - > playback_album ) ;
}
if ( ( art_path ! = NULL ) & & g_path_is_absolute ( art_path ) ) { // Have an album artist path
gtk_image_set_from_file ( GTK_IMAGE ( bar - > artwork ) , art_path ) ; // Update the art
} else {
gtk_image_set_from_icon_name ( GTK_IMAGE ( bar - > artwork ) , " audio-x-generic-symbolic " ) ; // Use generic instead
}
}
}
2021-02-24 20:17:18 +02:00
GtkWidget * koto_playerbar_get_main ( KotoPlayerBar * bar ) {
return bar - > main ;
}