[totem] variable-rate: Add menu items to change playback rate



commit 38683c69970bdeb2475be7afb083663346e271e3
Author: Bastien Nocera <hadess hadess net>
Date:   Fri Mar 11 16:38:04 2016 +0100

    variable-rate: Add menu items to change playback rate
    
    With the default values from:
    https://bugzilla.gnome.org/show_bug.cgi?id=417141#c65
    
    If you think that the values aren't the right ones, write a new plugin.
    If you think it looks bad with the separator there, see
    https://bugzilla.gnome.org/show_bug.cgi?id=767108
    
    https://bugzilla.gnome.org/show_bug.cgi?id=417141

 configure.ac                                       |    3 +-
 data/totem.ui                                      |    3 +
 src/plugins/variable-rate/Makefile.am              |   14 +
 .../variable-rate/totem-variable-rate-plugin.c     |  254 ++++++++++++++++++++
 src/plugins/variable-rate/variable-rate.plugin.in  |    9 +
 5 files changed, 282 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7c9d860..2159547 100644
--- a/configure.ac
+++ b/configure.ac
@@ -80,7 +80,7 @@ AC_SUBST(TOTEM_API_VERSION)
 AC_DEFINE_UNQUOTED(TOTEM_API_VERSION, ["$TOTEM_API_VERSION"], [Define to the Totem plugin API version])
 
 # The full list of plugins
-allowed_plugins="apple-trailers autoload-subtitles brasero-disc-recorder dbusservice im-status gromit lirc 
media-player-keys ontop opensubtitles properties pythonconsole recent rotation save-file samplepython 
sample-vala screensaver screenshot skipto zeitgeist-dp vimeo"
+allowed_plugins="apple-trailers autoload-subtitles brasero-disc-recorder dbusservice im-status gromit lirc 
media-player-keys ontop opensubtitles properties pythonconsole recent rotation save-file samplepython 
sample-vala screensaver screenshot skipto zeitgeist-dp variable-rate vimeo"
 
 PLUGINDIR='${libdir}/totem/plugins'
 AC_SUBST(PLUGINDIR)
@@ -565,6 +565,7 @@ src/plugins/pythonconsole/Makefile
 src/plugins/pythonconsole/org.gnome.totem.plugins.pythonconsole.gschema.xml
 src/plugins/brasero-disc-recorder/Makefile
 src/plugins/zeitgeist-dp/Makefile
+src/plugins/variable-rate/Makefile
 src/plugins/vimeo/Makefile
 src/backend/Makefile
 data/Makefile
diff --git a/data/totem.ui b/data/totem.ui
index 1c2afe4..24042f4 100644
--- a/data/totem.ui
+++ b/data/totem.ui
@@ -163,6 +163,9 @@
        <section>
                <section id="skipto-placeholder"/>
        </section>
+       <section id="variable-rate-placeholder">
+               <attribute name="label" translatable="yes">Speed</attribute>
+       </section>
 </menu>
 
 <object class="GtkAdjustment" id="tmw_seek_adjustment">
diff --git a/src/plugins/variable-rate/Makefile.am b/src/plugins/variable-rate/Makefile.am
new file mode 100644
index 0000000..03d76c8
--- /dev/null
+++ b/src/plugins/variable-rate/Makefile.am
@@ -0,0 +1,14 @@
+include $(top_srcdir)/src/plugins/Makefile.plugins
+
+plugindir = $(PLUGINDIR)/variable-rate
+plugin_LTLIBRARIES = libvariable-rate.la
+
+plugin_in_files = variable-rate.plugin.in
+
+libvariable_rate_la_SOURCES =          \
+       totem-variable-rate-plugin.c
+libvariable_rate_la_LDFLAGS = $(plugin_ldflags)
+libvariable_rate_la_CFLAGS = $(plugin_cflags)
+libvariable_rate_la_LIBADD = $(plugin_libadd)
+
+-include $(top_srcdir)/git.mk
diff --git a/src/plugins/variable-rate/totem-variable-rate-plugin.c 
b/src/plugins/variable-rate/totem-variable-rate-plugin.c
new file mode 100644
index 0000000..b00cceb
--- /dev/null
+++ b/src/plugins/variable-rate/totem-variable-rate-plugin.c
@@ -0,0 +1,254 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Bastien Nocera <hadess hadess net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add excemption clause.
+ * See license_change file for details.
+ *
+ * Author: Bastien Nocera <hadess hadess net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <libpeas/peas-activatable.h>
+
+#include "totem-plugin.h"
+#include "totem.h"
+
+#define TOTEM_TYPE_VARIABLE_RATE_PLUGIN                (totem_variable_rate_plugin_get_type ())
+#define TOTEM_VARIABLE_RATE_PLUGIN(o)                  (G_TYPE_CHECK_INSTANCE_CAST ((o), 
TOTEM_TYPE_VARIABLE_RATE_PLUGIN, TotemVariableRatePlugin))
+#define TOTEM_VARIABLE_RATE_PLUGIN_CLASS(k)            (G_TYPE_CHECK_CLASS_CAST((k), 
TOTEM_TYPE_VARIABLE_RATE_PLUGIN, TotemVariableRatePluginClass))
+#define TOTEM_IS_VARIABLE_RATE_PLUGIN(o)               (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
TOTEM_TYPE_VARIABLE_RATE_PLUGIN))
+#define TOTEM_IS_VARIABLE_RATE_PLUGIN_CLASS(k)         (G_TYPE_CHECK_CLASS_TYPE ((k), 
TOTEM_TYPE_VARIABLE_RATE_PLUGIN))
+#define TOTEM_VARIABLE_RATE_PLUGIN_GET_CLASS(o)        (G_TYPE_INSTANCE_GET_CLASS ((o), 
TOTEM_TYPE_VARIABLE_RATE_PLUGIN, TotemVariableRatePluginClass))
+
+typedef struct {
+       TotemObject       *totem;
+       guint              handler_id_key_press;
+       GSimpleAction     *action;
+       GMenuItem         *submenu_item;
+} TotemVariableRatePluginPrivate;
+
+#define NUM_RATES 6
+#define NORMAL_RATE_IDX 1
+
+static struct {
+       float rate;
+       const char *label;
+       const char *id;
+} rates[NUM_RATES] = {
+       { 0.75,  NC_("playback rate", "× 0.75"), "0_75" },
+       { 1.0,   NC_("playback rate", "Normal"), "normal" },
+       { 1.1,   NC_("playback rate", "× 1.1"),  "1_1" },
+       { 1.25,  NC_("playback rate", "× 1.25"), "1_25" },
+       { 1.5,   NC_("playback rate", "× 1.5"),  "1_5" },
+       { 1.75,  NC_("playback rate", "× 1.75"), "1_75" }
+};
+
+TOTEM_PLUGIN_REGISTER(TOTEM_TYPE_VARIABLE_RATE_PLUGIN, TotemVariableRatePlugin, totem_variable_rate_plugin)
+
+static char *
+get_submenu_label_for_index (guint i)
+{
+       return g_strdup_printf (_("Speed: %s"),
+                               g_dpgettext2 (NULL, "playback rate", rates[i].label));
+}
+
+static void
+variable_rate_action_callback (GSimpleAction           *action,
+                              GVariant                *parameter,
+                              TotemVariableRatePlugin *plugin)
+{
+       TotemVariableRatePlugin *pi = TOTEM_VARIABLE_RATE_PLUGIN (plugin);
+       TotemVariableRatePluginPrivate *priv = pi->priv;
+       const char *rate_id;
+       char *label;
+       guint i;
+
+       rate_id = g_variant_get_string (parameter, NULL);
+       for (i = 0; i < NUM_RATES; i++)
+               if (g_strcmp0 (rate_id, rates[i].id) == 0)
+                       break;
+
+       g_assert (i < NUM_RATES);
+
+       if (!totem_object_set_rate (priv->totem, rates[i].rate)) {
+               g_warning ("Failed to set rate to %f, resetting", rates[i].rate);
+               i = NORMAL_RATE_IDX;
+
+               if (!totem_object_set_rate (priv->totem, rates[i].rate))
+                       g_warning ("And failed to reset rate as well...");
+       } else {
+               g_debug ("Managed to set rate to %f", rates[i].rate);
+       }
+
+       g_simple_action_set_state (action, parameter);
+
+       label = get_submenu_label_for_index (i);
+       /* FIXME how do we change the section label?
+        * https://bugzilla.gnome.org/show_bug.cgi?id=667779 */
+       g_free (label);
+}
+
+static void
+reset_rate (TotemVariableRatePlugin *pi)
+{
+       TotemVariableRatePluginPrivate *priv = pi->priv;
+       GVariant *state;
+
+       g_debug ("Reset rate to 1.0");
+
+       state = g_variant_new_string (rates[NORMAL_RATE_IDX].id);
+       g_action_change_state (G_ACTION (priv->action), state);
+}
+
+static void
+change_rate (TotemVariableRatePlugin *pi,
+            gboolean                 increase)
+{
+       TotemVariableRatePluginPrivate *priv = pi->priv;
+       GVariant *state;
+       const char *rate_id;
+       int target, i;
+
+       state = g_action_get_state (G_ACTION (priv->action));
+       rate_id = g_variant_get_string (state, NULL);
+       g_assert (rate_id);
+
+       for (i = 0; i < NUM_RATES; i++)
+               if (g_strcmp0 (rate_id, rates[i].id) == 0)
+                       break;
+
+       g_variant_unref (state);
+
+       if (increase)
+               target = i + 1;
+       else
+               target = i - 1;
+
+       if (target >= NUM_RATES)
+               target = 0;
+       else if (target < 0)
+               target = NUM_RATES - 1;
+
+       g_message ("Switching from rate %s to rate %s",
+                rates[i].label, rates[target].label);
+
+       state = g_variant_new_string (rates[target].id);
+       g_action_change_state (G_ACTION (priv->action), state);
+}
+
+static gboolean
+on_window_key_press_event (GtkWidget *window, GdkEventKey *event, TotemVariableRatePlugin *plugin)
+{
+       TotemVariableRatePlugin *pi = TOTEM_VARIABLE_RATE_PLUGIN (plugin);
+
+       if (event->state == 0 ||
+           event->state & (GDK_CONTROL_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK)) {
+               return FALSE;
+       }
+
+       switch (event->keyval) {
+               case GDK_KEY_bracketleft:
+                       change_rate (pi, FALSE);
+                       break;
+               case GDK_KEY_bracketright:
+                       change_rate (pi, TRUE);
+                       break;
+               case GDK_KEY_BackSpace:
+                       reset_rate (pi);
+                       break;
+               default:
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void
+impl_activate (PeasActivatable *plugin)
+{
+       GtkWindow *window;
+       TotemVariableRatePlugin *pi = TOTEM_VARIABLE_RATE_PLUGIN (plugin);
+       TotemVariableRatePluginPrivate *priv = pi->priv;
+       GMenuItem *item;
+       GMenu *menu;
+       guint i;
+
+       priv->totem = g_object_get_data (G_OBJECT (plugin), "object");
+
+       /* Key press handler */
+       window = totem_object_get_main_window (priv->totem);
+       priv->handler_id_key_press = g_signal_connect (G_OBJECT(window),
+                               "key-press-event",
+                               G_CALLBACK (on_window_key_press_event),
+                               pi);
+       g_object_unref (window);
+
+       /* Create the variable rate action */
+       priv->action = g_simple_action_new_stateful ("variable-rate",
+                                                    G_VARIANT_TYPE_STRING,
+                                                    g_variant_new_string (rates[NORMAL_RATE_IDX].id));
+       g_signal_connect (G_OBJECT (priv->action), "change-state",
+                         G_CALLBACK (variable_rate_action_callback), plugin);
+       g_action_map_add_action (G_ACTION_MAP (priv->totem), G_ACTION (priv->action));
+
+       /* Create the submenu */
+       menu = totem_object_get_menu_section (priv->totem, "variable-rate-placeholder");
+       for (i = 0; i < NUM_RATES; i++) {
+               char *target;
+
+               target = g_strdup_printf ("app.variable-rate::%s", rates[i].id);
+               item = g_menu_item_new (g_dpgettext2 (NULL, "playback rate", rates[i].label), target);
+               g_free (target);
+               g_menu_append_item (G_MENU (menu), item);
+       }
+}
+
+static void
+impl_deactivate (PeasActivatable *plugin)
+{
+       GtkWindow *window;
+       TotemObject *totem;
+       TotemVariableRatePluginPrivate *priv = TOTEM_VARIABLE_RATE_PLUGIN (plugin)->priv;
+
+       totem = g_object_get_data (G_OBJECT (plugin), "object");
+
+       if (priv->handler_id_key_press != 0) {
+               window = totem_object_get_main_window (totem);
+               g_signal_handler_disconnect (G_OBJECT(window),
+                                            priv->handler_id_key_press);
+               priv->handler_id_key_press = 0;
+               g_object_unref (window);
+       }
+
+       /* Remove the menu */
+       totem_object_empty_menu_section (priv->totem, "variable-rate-placeholder");
+
+       /* Reset the rate */
+       if (!totem_object_set_rate (priv->totem, 1.0))
+               g_warning ("Failed to reset the playback rate to 1.0");
+}
diff --git a/src/plugins/variable-rate/variable-rate.plugin.in 
b/src/plugins/variable-rate/variable-rate.plugin.in
new file mode 100644
index 0000000..1353e8d
--- /dev/null
+++ b/src/plugins/variable-rate/variable-rate.plugin.in
@@ -0,0 +1,9 @@
+[Plugin]
+Module=variable-rate
+IAge=1
+Builtin=true
+_Name=Variable Rate
+_Description=Provides the variable rate menu item
+Authors=Bastien Nocera
+Copyright=Copyright © 2016 Bastien Nocera
+Website=http://www.gnome.org/projects/totem/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]