Add a playback toggle button
This commit is contained in:
parent
e23ed245db
commit
6e903f6f5c
36
fastiv.c
36
fastiv.c
|
@ -70,12 +70,11 @@ exit_fatal(const gchar *format, ...)
|
||||||
XX(S2, make_separator()) \
|
XX(S2, make_separator()) \
|
||||||
XX(SKIP_BACK, B("media-skip-backward-symbolic", "Rewind playback")) \
|
XX(SKIP_BACK, B("media-skip-backward-symbolic", "Rewind playback")) \
|
||||||
XX(SEEK_BACK, B("media-seek-backward-symbolic", "Previous frame")) \
|
XX(SEEK_BACK, B("media-seek-backward-symbolic", "Previous frame")) \
|
||||||
/* TODO(p): The opposite is "media-playback-play-symbolic". */ \
|
XX(PLAY_PAUSE, B("media-playback-start-symbolic", "Pause")) \
|
||||||
/* XX(PAUSE, B("media-playback-pause-symbolic", "Pause")) */ \
|
|
||||||
XX(SEEK_FORWARD, B("media-seek-forward-symbolic", "Next frame")) \
|
XX(SEEK_FORWARD, B("media-seek-forward-symbolic", "Next frame")) \
|
||||||
XX(S3, make_separator()) \
|
XX(S3, make_separator()) \
|
||||||
XX(PLUS, B("zoom-in-symbolic", "Zoom in")) \
|
XX(PLUS, B("zoom-in-symbolic", "Zoom in")) \
|
||||||
XX(SCALE, gtk_label_new("100%")) \
|
XX(SCALE, gtk_label_new("")) \
|
||||||
XX(MINUS, B("zoom-out-symbolic", "Zoom out")) \
|
XX(MINUS, B("zoom-out-symbolic", "Zoom out")) \
|
||||||
XX(ONE, B("zoom-original-symbolic", "Original size")) \
|
XX(ONE, B("zoom-original-symbolic", "Original size")) \
|
||||||
XX(FIT, T("zoom-fit-best-symbolic", "Scale to fit")) \
|
XX(FIT, T("zoom-fit-best-symbolic", "Scale to fit")) \
|
||||||
|
@ -457,8 +456,10 @@ on_window_state_event(G_GNUC_UNUSED GtkWidget *widget,
|
||||||
const char *name = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
const char *name = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||||
? "view-restore-symbolic"
|
? "view-restore-symbolic"
|
||||||
: "view-fullscreen-symbolic";
|
: "view-fullscreen-symbolic";
|
||||||
gtk_button_set_image(GTK_BUTTON(g.toolbar[TOOLBAR_FULLSCREEN]),
|
|
||||||
gtk_image_new_from_icon_name(name, GTK_ICON_SIZE_BUTTON));
|
GtkButton *button = GTK_BUTTON(g.toolbar[TOOLBAR_FULLSCREEN]);
|
||||||
|
GtkImage *image = GTK_IMAGE(gtk_button_get_image(button));
|
||||||
|
gtk_image_set_from_icon_name(image, name, GTK_ICON_SIZE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursor keys, e.g., simply cannot be bound through accelerators
|
// Cursor keys, e.g., simply cannot be bound through accelerators
|
||||||
|
@ -649,6 +650,21 @@ on_notify_view_scale(
|
||||||
// FIXME: The label doesn't immediately assume its new width.
|
// FIXME: The label doesn't immediately assume its new width.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_notify_view_playing(
|
||||||
|
GObject *object, GParamSpec *param_spec, G_GNUC_UNUSED gpointer user_data)
|
||||||
|
{
|
||||||
|
gboolean b = FALSE;
|
||||||
|
g_object_get(object, g_param_spec_get_name(param_spec), &b, NULL);
|
||||||
|
const char *name = b
|
||||||
|
? "media-playback-pause-symbolic"
|
||||||
|
: "media-playback-start-symbolic";
|
||||||
|
|
||||||
|
GtkButton *button = GTK_BUTTON(g.toolbar[TOOLBAR_PLAY_PAUSE]);
|
||||||
|
GtkImage *image = GTK_IMAGE(gtk_button_get_image(button));
|
||||||
|
gtk_image_set_from_icon_name(image, name, GTK_ICON_SIZE_BUTTON);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_view_boolean(
|
on_notify_view_boolean(
|
||||||
GObject *object, GParamSpec *param_spec, gpointer user_data)
|
GObject *object, GParamSpec *param_spec, gpointer user_data)
|
||||||
|
@ -728,6 +744,7 @@ make_view_toolbar(void)
|
||||||
toolbar_command(TOOLBAR_PAGE_LAST, FIV_VIEW_COMMAND_PAGE_LAST);
|
toolbar_command(TOOLBAR_PAGE_LAST, FIV_VIEW_COMMAND_PAGE_LAST);
|
||||||
toolbar_command(TOOLBAR_SKIP_BACK, FIV_VIEW_COMMAND_FRAME_FIRST);
|
toolbar_command(TOOLBAR_SKIP_BACK, FIV_VIEW_COMMAND_FRAME_FIRST);
|
||||||
toolbar_command(TOOLBAR_SEEK_BACK, FIV_VIEW_COMMAND_FRAME_PREVIOUS);
|
toolbar_command(TOOLBAR_SEEK_BACK, FIV_VIEW_COMMAND_FRAME_PREVIOUS);
|
||||||
|
toolbar_command(TOOLBAR_PLAY_PAUSE, FIV_VIEW_COMMAND_TOGGLE_PLAYBACK);
|
||||||
toolbar_command(TOOLBAR_SEEK_FORWARD, FIV_VIEW_COMMAND_FRAME_NEXT);
|
toolbar_command(TOOLBAR_SEEK_FORWARD, FIV_VIEW_COMMAND_FRAME_NEXT);
|
||||||
toolbar_command(TOOLBAR_PLUS, FIV_VIEW_COMMAND_ZOOM_IN);
|
toolbar_command(TOOLBAR_PLUS, FIV_VIEW_COMMAND_ZOOM_IN);
|
||||||
toolbar_command(TOOLBAR_MINUS, FIV_VIEW_COMMAND_ZOOM_OUT);
|
toolbar_command(TOOLBAR_MINUS, FIV_VIEW_COMMAND_ZOOM_OUT);
|
||||||
|
@ -741,10 +758,17 @@ make_view_toolbar(void)
|
||||||
toolbar_command(TOOLBAR_RIGHT, FIV_VIEW_COMMAND_ROTATE_RIGHT);
|
toolbar_command(TOOLBAR_RIGHT, FIV_VIEW_COMMAND_ROTATE_RIGHT);
|
||||||
toolbar_connect(TOOLBAR_FULLSCREEN, G_CALLBACK(toggle_fullscreen));
|
toolbar_connect(TOOLBAR_FULLSCREEN, G_CALLBACK(toggle_fullscreen));
|
||||||
|
|
||||||
|
g_signal_connect(g.view, "notify::scale",
|
||||||
|
G_CALLBACK(on_notify_view_scale), NULL);
|
||||||
|
g_signal_connect(g.view, "notify::playing",
|
||||||
|
G_CALLBACK(on_notify_view_playing), NULL);
|
||||||
g_signal_connect(g.view, "notify::scale-to-fit",
|
g_signal_connect(g.view, "notify::scale-to-fit",
|
||||||
G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_FIT]);
|
G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_FIT]);
|
||||||
g_signal_connect(g.view, "notify::filter",
|
g_signal_connect(g.view, "notify::filter",
|
||||||
G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_SMOOTH]);
|
G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_SMOOTH]);
|
||||||
|
|
||||||
|
g_object_notify(G_OBJECT(g.view), "scale");
|
||||||
|
g_object_notify(G_OBJECT(g.view), "playing");
|
||||||
g_object_notify(G_OBJECT(g.view), "scale-to-fit");
|
g_object_notify(G_OBJECT(g.view), "scale-to-fit");
|
||||||
g_object_notify(G_OBJECT(g.view), "filter");
|
g_object_notify(G_OBJECT(g.view), "filter");
|
||||||
return view_toolbar;
|
return view_toolbar;
|
||||||
|
@ -840,8 +864,6 @@ main(int argc, char *argv[])
|
||||||
G_CALLBACK(on_key_press_view), NULL);
|
G_CALLBACK(on_key_press_view), NULL);
|
||||||
g_signal_connect(g.view, "button-press-event",
|
g_signal_connect(g.view, "button-press-event",
|
||||||
G_CALLBACK(on_button_press_view), NULL);
|
G_CALLBACK(on_button_press_view), NULL);
|
||||||
g_signal_connect(g.view, "notify::scale",
|
|
||||||
G_CALLBACK(on_notify_view_scale), NULL);
|
|
||||||
gtk_container_add(GTK_CONTAINER(view_scroller), g.view);
|
gtk_container_add(GTK_CONTAINER(view_scroller), g.view);
|
||||||
|
|
||||||
// Maybe our custom widgets should derive colours from the theme instead.
|
// Maybe our custom widgets should derive colours from the theme instead.
|
||||||
|
|
15
fiv-view.c
15
fiv-view.c
|
@ -88,6 +88,7 @@ enum {
|
||||||
PROP_SCALE = 1,
|
PROP_SCALE = 1,
|
||||||
PROP_SCALE_TO_FIT,
|
PROP_SCALE_TO_FIT,
|
||||||
PROP_FILTER,
|
PROP_FILTER,
|
||||||
|
PROP_PLAYING,
|
||||||
N_PROPERTIES
|
N_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,6 +118,9 @@ fiv_view_get_property(
|
||||||
case PROP_FILTER:
|
case PROP_FILTER:
|
||||||
g_value_set_boolean(value, self->filter);
|
g_value_set_boolean(value, self->filter);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PLAYING:
|
||||||
|
g_value_set_boolean(value, !!self->frame_update_connection);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
}
|
}
|
||||||
|
@ -472,6 +476,7 @@ stop_animating(FivView *self)
|
||||||
self->frame_time = 0;
|
self->frame_time = 0;
|
||||||
self->frame_update_connection = 0;
|
self->frame_update_connection = 0;
|
||||||
self->remaining_loops = 0;
|
self->remaining_loops = 0;
|
||||||
|
g_object_notify_by_pspec(G_OBJECT(self), view_properties[PROP_PLAYING]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -546,6 +551,7 @@ start_animating(FivView *self)
|
||||||
(uintptr_t) cairo_surface_get_user_data(self->page, &fiv_io_key_loops);
|
(uintptr_t) cairo_surface_get_user_data(self->page, &fiv_io_key_loops);
|
||||||
|
|
||||||
gdk_frame_clock_begin_updating(clock);
|
gdk_frame_clock_begin_updating(clock);
|
||||||
|
g_object_notify_by_pspec(G_OBJECT(self), view_properties[PROP_PLAYING]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -790,6 +796,8 @@ fiv_view_key_press_event(GtkWidget *widget, GdkEventKey *event)
|
||||||
return command(self, FIV_VIEW_COMMAND_FRAME_PREVIOUS);
|
return command(self, FIV_VIEW_COMMAND_FRAME_PREVIOUS);
|
||||||
case GDK_KEY_braceright:
|
case GDK_KEY_braceright:
|
||||||
return command(self, FIV_VIEW_COMMAND_FRAME_NEXT);
|
return command(self, FIV_VIEW_COMMAND_FRAME_NEXT);
|
||||||
|
case GDK_KEY_space:
|
||||||
|
return command(self, FIV_VIEW_COMMAND_TOGGLE_PLAYBACK);
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -811,6 +819,9 @@ fiv_view_class_init(FivViewClass *klass)
|
||||||
view_properties[PROP_FILTER] = g_param_spec_boolean(
|
view_properties[PROP_FILTER] = g_param_spec_boolean(
|
||||||
"filter", "Use filtering", "Scale images smoothly",
|
"filter", "Use filtering", "Scale images smoothly",
|
||||||
TRUE, G_PARAM_READWRITE);
|
TRUE, G_PARAM_READWRITE);
|
||||||
|
view_properties[PROP_PLAYING] = g_param_spec_boolean(
|
||||||
|
"playing", "Playing animation", "An animation is running",
|
||||||
|
TRUE, G_PARAM_READWRITE);
|
||||||
g_object_class_install_properties(
|
g_object_class_install_properties(
|
||||||
object_class, N_PROPERTIES, view_properties);
|
object_class, N_PROPERTIES, view_properties);
|
||||||
|
|
||||||
|
@ -918,6 +929,10 @@ fiv_view_command(FivView *self, FivViewCommand command)
|
||||||
frame_step(self, -1);
|
frame_step(self, -1);
|
||||||
break; case FIV_VIEW_COMMAND_FRAME_NEXT:
|
break; case FIV_VIEW_COMMAND_FRAME_NEXT:
|
||||||
frame_step(self, +1);
|
frame_step(self, +1);
|
||||||
|
break; case FIV_VIEW_COMMAND_TOGGLE_PLAYBACK:
|
||||||
|
self->frame_update_connection
|
||||||
|
? stop_animating(self)
|
||||||
|
: start_animating(self);
|
||||||
|
|
||||||
break; case FIV_VIEW_COMMAND_TOGGLE_FILTER:
|
break; case FIV_VIEW_COMMAND_TOGGLE_FILTER:
|
||||||
self->filter = !self->filter;
|
self->filter = !self->filter;
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef enum _FivViewCommand {
|
||||||
FIV_VIEW_COMMAND_FRAME_PREVIOUS,
|
FIV_VIEW_COMMAND_FRAME_PREVIOUS,
|
||||||
FIV_VIEW_COMMAND_FRAME_NEXT,
|
FIV_VIEW_COMMAND_FRAME_NEXT,
|
||||||
// Going to the end frame makes no sense, wrap around if needed.
|
// Going to the end frame makes no sense, wrap around if needed.
|
||||||
|
FIV_VIEW_COMMAND_TOGGLE_PLAYBACK,
|
||||||
|
|
||||||
FIV_VIEW_COMMAND_TOGGLE_FILTER,
|
FIV_VIEW_COMMAND_TOGGLE_FILTER,
|
||||||
FIV_VIEW_COMMAND_PRINT,
|
FIV_VIEW_COMMAND_PRINT,
|
||||||
|
|
Loading…
Reference in New Issue