Skip to content

Commit

Permalink
Implement playback speed and jump forwards / backwards functionality.
Browse files Browse the repository at this point in the history
Ref #14.

Additionally fixed some bugs around the KotoButton showing the badge text label when it shouldn't, styling related to margins, and various legacy null and string valid checks.
  • Loading branch information
JoshStrobl committed Aug 17, 2021
1 parent 22d5bcc commit 62f2883
Show file tree
Hide file tree
Showing 17 changed files with 387 additions and 24 deletions.
9 changes: 9 additions & 0 deletions data/vectors/multimedia-backwards-jump.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions data/vectors/multimedia-forwards-jump.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 75 additions & 11 deletions src/components/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum {
PROP_IMAGE_FILE_PATH,
PROP_ICON_NAME,
PROP_ALT_ICON_NAME,
PROP_RESOURCE_PATH,
N_BTN_PROPERTIES
};

Expand All @@ -86,6 +87,7 @@ struct _KotoButton {
gchar * badge_text;
gchar * icon_name;
gchar * alt_icon_name;
gchar * resource_path;
gchar * text;

KotoButtonImagePosition image_position;
Expand Down Expand Up @@ -181,6 +183,14 @@ static void koto_button_class_init(KotoButtonClass * c) {
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
);

btn_props[PROP_RESOURCE_PATH] = g_param_spec_string(
"resource-path",
"Resource Path to an Icon",
"Resource Path to an Icon",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
);

g_object_class_install_properties(gobject_class, N_BTN_PROPERTIES, btn_props);
}

Expand All @@ -191,6 +201,8 @@ static void koto_button_init(KotoButton * self) {
self->left_click_gesture = gtk_gesture_click_new(); // Set up our left click gesture
self->right_click_gesture = gtk_gesture_click_new(); // Set up our right click gesture

self->resource_path = NULL;

gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(self->left_click_gesture), (int) KOTO_BUTTON_CLICK_TYPE_PRIMARY); // Only allow left clicks on left click gesture
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(self->right_click_gesture), (int) KOTO_BUTTON_CLICK_TYPE_SECONDARY); // Only allow right clicks on right click gesture

Expand Down Expand Up @@ -242,6 +254,9 @@ static void koto_button_get_property(
case PROP_ALT_ICON_NAME:
g_value_set_string(val, self->alt_icon_name);
break;
case PROP_RESOURCE_PATH:
g_value_set_string(val, self->resource_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec);
break;
Expand All @@ -261,7 +276,7 @@ static void koto_button_set_property(
koto_button_set_pixbuf_size(self, g_value_get_uint(val));
break;
case PROP_TEXT:
if (val != NULL) {
if (koto_utils_string_is_valid(g_value_get_string(val))) {
koto_button_set_text(self, (gchar*) g_value_get_string(val));
}

Expand All @@ -287,6 +302,9 @@ static void koto_button_set_property(
koto_button_show_image(self, TRUE);
}
break;
case PROP_RESOURCE_PATH:
koto_button_set_resource_path(self, g_strdup(g_value_get_string(val)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec);
break;
Expand Down Expand Up @@ -424,26 +442,29 @@ void koto_button_set_badge_text(
return;
}

if ((text == NULL) || (strcmp(text, "") == 0)) { // If the text is empty
self->badge_text = g_strdup("");
} else {
if (koto_utils_string_is_valid(self->badge_text)) { // Have existing text
g_free(self->badge_text);
self->badge_text = g_strdup(text);
}

if (!koto_utils_string_is_valid(text)) { // If the text is empty
self->badge_text = NULL;

if (GTK_IS_LABEL(self->badge_label)) { // If badge label already exists
gtk_widget_hide(self->badge_label); // Hide the label
}

return;
}

self->badge_text = g_strdup(text);

if (GTK_IS_LABEL(self->badge_label)) { // If badge label already exists
gtk_label_set_text(GTK_LABEL(self->badge_label), self->badge_text);
} else {
self->badge_label = gtk_label_new(self->badge_text); // Create our label
gtk_box_append(GTK_BOX(self), self->badge_label);
}

if (strcmp(self->badge_text, "") != 0) { // Empty badge
gtk_widget_hide(self->badge_label); // Hide our badge
} else { // Have some text
gtk_widget_show(self->badge_label); // Show our badge
}

g_object_notify_by_pspec(G_OBJECT(self), btn_props[PROP_BADGE_TEXT]);
}

Expand Down Expand Up @@ -561,6 +582,34 @@ void koto_button_set_pixbuf_size(
g_object_notify_by_pspec(G_OBJECT(self), btn_props[PROP_PIX_SIZE]);
}

void koto_button_set_resource_path(
KotoButton * self,
gchar * resource_path
) {
if (!KOTO_IS_BUTTON(self)) {
return;
}

if (!koto_utils_string_is_valid(resource_path)) { // Not a valid string
return;
}

if (koto_utils_string_is_valid(self->resource_path)) { // Have a resource path already
g_free(self->resource_path); // Free it
}

self->resource_path = g_strdup(resource_path);

if (GTK_IS_IMAGE(self->button_pic)) { // Already have a button image
gtk_image_set_from_resource(GTK_IMAGE(self->button_pic), self->resource_path);
} else {
self->button_pic = gtk_image_new_from_resource(self->resource_path); // Create a new image from the resource
gtk_image_set_pixel_size(GTK_IMAGE(self->button_pic), self->pix_size);
gtk_image_set_icon_size(GTK_IMAGE(self->button_pic), GTK_ICON_SIZE_INHERIT); // Inherit height of parent widget
gtk_box_prepend(GTK_BOX(self), self->button_pic); // Prepend to the box
}
}

void koto_button_set_text(
KotoButton * self,
gchar * text
Expand Down Expand Up @@ -590,6 +639,7 @@ void koto_button_set_text(
} else { // If we do not have a button label
if (koto_utils_string_is_valid(self->text)) { // If we have text
self->button_label = gtk_label_new(self->text); // Create our label
gtk_widget_add_css_class(self->button_label, "button-label");
gtk_widget_set_hexpand(self->button_label, TRUE);
gtk_label_set_xalign(GTK_LABEL(self->button_label), 0);

Expand Down Expand Up @@ -752,3 +802,17 @@ KotoButton * koto_button_new_with_file(
NULL
);
}

KotoButton * koto_button_new_with_resource (
gchar * resource_path,
KotoButtonPixbufSize size
) {
return g_object_new(
KOTO_TYPE_BUTTON,
"resource-path",
resource_path,
"pixbuf-size",
koto_get_pixbuf_size(size),
NULL
);
}
10 changes: 10 additions & 0 deletions src/components/button.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ KotoButton * koto_button_new_with_file(
KotoButtonPixbufSize size
);

KotoButton * koto_button_new_with_resource(
gchar * resource_path,
KotoButtonPixbufSize size
);

void koto_button_add_click_handler(
KotoButton * self,
KotoButtonClickType button,
Expand Down Expand Up @@ -127,6 +132,11 @@ void koto_button_set_image_position(
KotoButtonImagePosition pos
);

void koto_button_set_resource_path(
KotoButton * self,
gchar * resource_path
);

void koto_button_set_pixbuf(
KotoButton * self,
GdkPixbuf * pix
Expand Down
46 changes: 46 additions & 0 deletions src/config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ enum {
PROP_PLAYBACK_CONTINUE_ON_PLAYLIST,
PROP_PLAYBACK_LAST_USED_VOLUME,
PROP_PLAYBACK_MAINTAIN_SHUFFLE,
PROP_PLAYBACK_JUMP_BACKWARDS_INCREMENT,
PROP_PLAYBACK_JUMP_FORWARDS_INCREMENT,
PROP_PREFERRED_ALBUM_SORT_TYPE,
PROP_UI_ALBUM_INFO_SHOW_DESCRIPTION,
PROP_UI_ALBUM_INFO_SHOW_GENRES,
Expand Down Expand Up @@ -73,6 +75,8 @@ struct _KotoConfig {
gboolean playback_continue_on_playlist;
gdouble playback_last_used_volume;
gboolean playback_maintain_shuffle;
guint playback_jump_backwards_increment;
guint playback_jump_forwards_increment;

/* Misc Prefs */

Expand Down Expand Up @@ -146,6 +150,26 @@ static void koto_config_class_init(KotoConfigClass * c) {
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
);

config_props[PROP_PLAYBACK_JUMP_BACKWARDS_INCREMENT] = g_param_spec_uint(
"playback-jump-backwards-increment",
"Jump Backwards Increment",
"Jump Backwards Increment",
5, // 5s
90, // 1min30s
10, // 10s
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
);

config_props[PROP_PLAYBACK_JUMP_FORWARDS_INCREMENT] = g_param_spec_uint(
"playback-jump-forwards-increment",
"Jump Forwards Increment",
"Jump Forwards Increment",
5, // 5s
90, // 1min30s
30, // 30s
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
);

config_props[PROP_PREFERRED_ALBUM_SORT_TYPE] = g_param_spec_string(
"artist-preferred-album-sort-type",
"Preferred album sort type (chronological or alphabetical-only)",
Expand Down Expand Up @@ -235,6 +259,12 @@ static void koto_config_get_property(
case PROP_PLAYBACK_MAINTAIN_SHUFFLE:
g_value_set_boolean(val, self->playback_maintain_shuffle);
break;
case PROP_PLAYBACK_JUMP_BACKWARDS_INCREMENT:
g_value_set_uint(val, self->playback_jump_backwards_increment);
break;
case PROP_PLAYBACK_JUMP_FORWARDS_INCREMENT:
g_value_set_uint(val, self->playback_jump_forwards_increment);
break;
case PROP_UI_ALBUM_INFO_SHOW_DESCRIPTION:
g_value_set_boolean(val, self->ui_album_info_show_description);
break;
Expand Down Expand Up @@ -277,6 +307,12 @@ static void koto_config_set_property(
case PROP_PLAYBACK_MAINTAIN_SHUFFLE:
self->playback_maintain_shuffle = g_value_get_boolean(val);
break;
case PROP_PLAYBACK_JUMP_BACKWARDS_INCREMENT:
self->playback_jump_backwards_increment = g_value_get_uint(val);
break;
case PROP_PLAYBACK_JUMP_FORWARDS_INCREMENT:
self->playback_jump_forwards_increment = g_value_get_uint(val);
break;
case PROP_PREFERRED_ALBUM_SORT_TYPE:
self->preferred_album_sort_type = g_strcmp0(g_value_get_string(val), "alphabetical") ? KOTO_PREFERRED_ALBUM_ALWAYS_ALPHABETICAL : KOTO_PREFERRED_ALBUM_SORT_TYPE_DEFAULT;
break;
Expand Down Expand Up @@ -434,13 +470,23 @@ void koto_config_load(

if (playback_section) { // Have playback section
toml_datum_t continue_on_playlist = toml_bool_in(playback_section, "continue-on-playlist");
toml_datum_t jump_backwards_increment = toml_int_in(playback_section, "jump-backwards-increment");
toml_datum_t jump_forwards_increment = toml_int_in(playback_section, "jump-forwards-increment");
toml_datum_t last_used_volume = toml_double_in(playback_section, "last-used-volume");
toml_datum_t maintain_shuffle = toml_bool_in(playback_section, "maintain-shuffle");

if (continue_on_playlist.ok && (self->playback_continue_on_playlist != continue_on_playlist.u.b)) { // If we have a continue-on-playlist set and they are different
g_object_set(self, "playback-continue-on-playlist", continue_on_playlist.u.b, NULL);
}

if (jump_backwards_increment.ok && (self->playback_jump_backwards_increment != jump_backwards_increment.u.i)) { // If we have a jump-backwards-increment set and it is different
g_object_set(self, "playback-jump-backwards-increment", (guint) jump_backwards_increment.u.i, NULL);
}

if (jump_forwards_increment.ok && (self->playback_jump_forwards_increment != jump_forwards_increment.u.i)) { // If we have a jump-backwards-increment set and it is different
g_object_set(self, "playback-jump-forwards-increment", (guint) jump_forwards_increment.u.i, NULL);
}

if (last_used_volume.ok && (self->playback_last_used_volume != last_used_volume.u.d)) { // If we have last-used-volume set and they are different
g_object_set(self, "playback-last-used-volume", last_used_volume.u.d, NULL);
}
Expand Down
Loading

0 comments on commit 62f2883

Please sign in to comment.