[goobox] moved the toolbar on top



commit 588f6c0c8a19c1cf73120868cb11d88e6788ef1a
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Fri Dec 28 18:04:28 2018 +0100

    moved the toolbar on top

 src/goo-application.c                           |  11 +-
 src/goo-player-bar.h                            |  61 -------
 src/{goo-player-bar.c => goo-player-progress.c} | 227 +++++++++---------------
 src/goo-player-progress.h                       |  63 +++++++
 src/goo-window.c                                | 155 +++++++++++++---
 src/goobox.gresource.xml                        |   1 -
 src/gtk-utils.c                                 |  29 +++
 src/gtk-utils.h                                 |   8 +
 src/meson.build                                 |   2 +-
 src/ui/app-menu.ui                              |  40 -----
 src/ui/gears-menu.ui                            |  29 ++-
 11 files changed, 346 insertions(+), 280 deletions(-)
---
diff --git a/src/goo-application.c b/src/goo-application.c
index 725a65c..15a1bc3 100644
--- a/src/goo-application.c
+++ b/src/goo-application.c
@@ -347,17 +347,18 @@ pref_playlist_shuffle_changed (GSettings  *settings,
 static void
 initialize_app_menu (GApplication *application)
 {
+       const _GtkAccelerator app_accelerators[] = {
+               { "app.help", "F1" },
+               { "app.quit", "<Control>q" }
+       };
        GooApplication *self = (GooApplication *) application;
-       GtkBuilder     *builder;
 
        g_action_map_add_action_entries (G_ACTION_MAP (application),
                                         goo_application_actions,
                                         G_N_ELEMENTS (goo_application_actions),
                                         application);
 
-       builder = _gtk_builder_new_from_resource ("app-menu.ui");
-       gtk_application_set_app_menu (GTK_APPLICATION (application),
-                                     G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
+       _gtk_application_add_accelerators (GTK_APPLICATION (application), app_accelerators, G_N_ELEMENTS 
(app_accelerators));
 
        g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (application), 
PREF_PLAYLIST_PLAYALL)),
                                   g_variant_new_boolean (g_settings_get_boolean (self->priv->settings, 
PREF_PLAYLIST_PLAYALL)));
@@ -378,8 +379,6 @@ initialize_app_menu (GApplication *application)
                          "changed::" PREF_PLAYLIST_REPEAT,
                          G_CALLBACK (pref_playlist_repeat_changed),
                          self);
-
-       g_object_unref (builder);
 }
 
 
diff --git a/src/goo-player-bar.c b/src/goo-player-progress.c
similarity index 60%
rename from src/goo-player-bar.c
rename to src/goo-player-progress.c
index 1ad0a32..0772123 100644
--- a/src/goo-player-bar.c
+++ b/src/goo-player-progress.c
@@ -3,7 +3,7 @@
 /*
  *  Goo
  *
- *  Copyright (C) 2012 Free Software Foundation, Inc.
+ *  Copyright (C) 2018 Free Software Foundation, Inc.
  *
  *  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
@@ -22,7 +22,7 @@
 #include <config.h>
 #include <string.h>
 #include <glib/gi18n.h>
-#include "goo-player-bar.h"
+#include "goo-player-progress.h"
 #include "goo-marshal.h"
 #include "glib-utils.h"
 #include "gtk-utils.h"
@@ -30,18 +30,18 @@
 
 #define SCALE_WIDTH 150
 #define TIME_LABEL_WIDTH_IN_CHARS 8
-#define PLAY_BUTTON_SIZE GTK_ICON_SIZE_SMALL_TOOLBAR
+#define PLAY_BUTTON_SIZE GTK_ICON_SIZE_SMALL_TOOLPROGRESS
 #define MIN_WIDTH 500
 #define UPDATE_TIMEOUT 50
 
 
-struct _GooPlayerBarPrivate {
+struct _GooPlayerProgressPrivate {
        GooPlayer *player;
        GtkWidget *current_time_label;
        GtkWidget *remaining_time_label;
        GtkWidget *time_scale;
        GtkWidget *time_box;
-       GtkWidget *play_button_image;
+       GtkWidget *title;
        gint64     track_length;
        gint64     current_time;
        gboolean   dragging;
@@ -51,21 +51,21 @@ struct _GooPlayerBarPrivate {
 };
 
 
-G_DEFINE_TYPE_WITH_CODE (GooPlayerBar, goo_player_bar, GTK_TYPE_BOX,
-                        G_ADD_PRIVATE (GooPlayerBar))
+G_DEFINE_TYPE_WITH_CODE (GooPlayerProgress, goo_player_progress, GTK_TYPE_BOX,
+                        G_ADD_PRIVATE (GooPlayerProgress))
 
 
 enum {
        SKIP_TO,
-        LAST_SIGNAL
+       LAST_SIGNAL
 };
-static guint goo_player_bar_signals[LAST_SIGNAL] = { 0 };
+static guint goo_player_progress_signals[LAST_SIGNAL] = { 0 };
 
 
 static void
-goo_player_bar_get_preferred_width (GtkWidget *widget,
-                                   int       *minimum_width,
-                                   int       *natural_width)
+goo_player_progress_get_preferred_width (GtkWidget *widget,
+                                        int       *minimum_width,
+                                        int       *natural_width)
 {
        *minimum_width = *natural_width = MIN_WIDTH;
 }
@@ -97,7 +97,7 @@ set_label (GtkWidget  *label,
 
 
 static void
-_goo_player_bar_update_current_time (GooPlayerBar *self)
+_goo_player_progress_update_current_time (GooPlayerProgress *self)
 {
        char *s;
 
@@ -116,16 +116,16 @@ _goo_player_bar_update_current_time (GooPlayerBar *self)
 
 static void
 time_scale_value_changed_cb (GtkRange     *range,
-                            GooPlayerBar *self)
+                            GooPlayerProgress *self)
 {
        self->priv->current_time = self->priv->track_length * gtk_range_get_value (range);
-       _goo_player_bar_update_current_time (self);
+       _goo_player_progress_update_current_time (self);
 
        if (! self->priv->dragging) {
                int seconds;
 
                seconds = (int) (gtk_range_get_value (range) * self->priv->track_length);
-               g_signal_emit (self, goo_player_bar_signals[SKIP_TO], 0, seconds);
+               g_signal_emit (self, goo_player_progress_signals[SKIP_TO], 0, seconds);
        }
 }
 
@@ -133,7 +133,7 @@ time_scale_value_changed_cb (GtkRange     *range,
 static gboolean
 update_time_label_cb (gpointer data)
 {
-       GooPlayerBar *self = data;
+       GooPlayerProgress *self = data;
 
        if (self->priv->update_id != 0) {
                g_source_remove (self->priv->update_id);
@@ -141,7 +141,7 @@ update_time_label_cb (gpointer data)
        }
 
        self->priv->current_time = self->priv->track_length * gtk_range_get_value (GTK_RANGE 
(self->priv->time_scale));
-       _goo_player_bar_update_current_time (self);
+       _goo_player_progress_update_current_time (self);
 
        self->priv->update_id = g_timeout_add (UPDATE_TIMEOUT,
                                               update_time_label_cb,
@@ -152,9 +152,9 @@ update_time_label_cb (gpointer data)
 
 
 static gboolean
-time_scale_button_press_cb (GtkRange         *range,
-                           GdkEventButton   *event,
-                           GooPlayerBar    *self)
+time_scale_button_press_cb (GtkRange          *range,
+                           GdkEventButton    *event,
+                           GooPlayerProgress *self)
 {
        self->priv->dragging = TRUE;
        if (self->priv->update_id == 0)
@@ -166,9 +166,9 @@ time_scale_button_press_cb (GtkRange         *range,
 
 
 static gboolean
-time_scale_button_release_cb (GtkRange         *range,
-                             GdkEventButton   *event,
-                             GooPlayerBar    *self)
+time_scale_button_release_cb (GtkRange          *range,
+                             GdkEventButton    *event,
+                             GooPlayerProgress *self)
 {
        if (self->priv->update_id != 0) {
                g_source_remove (self->priv->update_id);
@@ -183,9 +183,9 @@ time_scale_button_release_cb (GtkRange         *range,
 
 
 static void
-goo_player_bar_init (GooPlayerBar *self)
+goo_player_progress_init (GooPlayerProgress *self)
 {
-       self->priv = goo_player_bar_get_instance_private (self);
+       self->priv = goo_player_progress_get_instance_private (self);
        self->priv->dragging = FALSE;
        self->priv->track_length = 0;
        self->priv->current_time = 0;
@@ -197,32 +197,13 @@ goo_player_bar_init (GooPlayerBar *self)
 }
 
 
-static GtkWidget *
-_gtk_menu_button_new_from_icon_name (const char *icon_name)
-{
-       GtkWidget *button;
-       GtkWidget *image;
-
-       button = gtk_menu_button_new ();
-       image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       gtk_widget_show (image);
-       gtk_container_add (GTK_CONTAINER (button), image);
-
-       return button;
-}
-
-
 static void
-goo_player_bar_construct (GooPlayerBar *self,
-                         GActionMap    *action_map)
+goo_player_progress_construct (GooPlayerProgress *self)
 {
        GtkWidget *frame;
        GtkWidget *main_box;
-       GtkWidget *button_box;
-       GtkWidget *button;
 
        frame = gtk_event_box_new ();
-       gtk_style_context_add_class (gtk_widget_get_style_context (frame), GTK_STYLE_CLASS_BACKGROUND);
        gtk_widget_show (frame);
        gtk_box_pack_start (GTK_BOX (self), frame, TRUE, TRUE, 0);
 
@@ -233,28 +214,6 @@ goo_player_bar_construct (GooPlayerBar     *self,
        gtk_widget_show (main_box);
        gtk_container_add (GTK_CONTAINER (frame), main_box);
 
-       /* Play buttons */
-
-       self->priv->play_button_image = gtk_image_new_from_icon_name (GOO_ICON_NAME_PLAY, PLAY_BUTTON_SIZE);
-       button = gtk_button_new ();
-       gtk_container_add (GTK_CONTAINER (button), self->priv->play_button_image);
-       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.toggle-play");
-       gtk_box_pack_start (GTK_BOX (main_box), button, FALSE, FALSE, 0);
-
-       button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_style_context_add_class (gtk_widget_get_style_context (button_box), GTK_STYLE_CLASS_LINKED);
-       gtk_box_pack_start (GTK_BOX (main_box), button_box, FALSE, FALSE, 0);
-
-       button = gtk_button_new_from_icon_name (GOO_ICON_NAME_PREV, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.previous-track");
-       gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
-
-       button = gtk_button_new_from_icon_name (GOO_ICON_NAME_NEXT, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.next-track");
-       gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
-
-       /* Time */
-
        self->priv->time_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
        gtk_widget_set_no_show_all (self->priv->time_box, TRUE);
        gtk_box_pack_start (GTK_BOX (main_box), self->priv->time_box, TRUE, FALSE, 0);
@@ -279,26 +238,12 @@ goo_player_bar_construct (GooPlayerBar    *self,
        gtk_box_pack_start (GTK_BOX (self->priv->time_box), self->priv->time_scale, FALSE, FALSE, 0);
        gtk_box_pack_start (GTK_BOX (self->priv->time_box), self->priv->remaining_time_label, FALSE, FALSE, 
0);
 
-       /* Other actions */
-
-       button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_box_set_spacing (GTK_BOX (button_box), 6);
-       gtk_box_pack_end (GTK_BOX (main_box), button_box, FALSE, FALSE, 0);
-
-       button = gtk_button_new_from_icon_name (GOO_ICON_NAME_EXTRACT, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.extract");
-       gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
-
-       {
-               GtkBuilder *builder;
-
-               builder = _gtk_builder_new_from_resource ("gears-menu.ui");
-               button = _gtk_menu_button_new_from_icon_name ("emblem-system-symbolic");
-               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), G_MENU_MODEL 
(gtk_builder_get_object (builder, "gears-menu")));
-               gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
-
-               g_object_unref (builder);
-       }
+       self->priv->title = gtk_label_new ("");
+       gtk_label_set_line_wrap (GTK_LABEL (self->priv->title), FALSE);
+       gtk_label_set_single_line_mode (GTK_LABEL (self->priv->title), TRUE);
+       gtk_label_set_ellipsize (GTK_LABEL (self->priv->title), PANGO_ELLIPSIZE_END);
+       gtk_style_context_add_class (gtk_widget_get_style_context (self->priv->title), "title");
+       gtk_box_pack_start (GTK_BOX (main_box), self->priv->title, TRUE, FALSE, 0);
 
        /* signals */
 
@@ -318,14 +263,14 @@ goo_player_bar_construct (GooPlayerBar    *self,
 
 
 static void
-goo_player_bar_finalize (GObject *object)
+goo_player_progress_finalize (GObject *object)
 {
-        GooPlayerBar *self;
+       GooPlayerProgress *self;
 
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GOO_IS_PLAYER_BAR (object));
+       g_return_if_fail (object != NULL);
+       g_return_if_fail (GOO_IS_PLAYER_PROGRESS (object));
 
-       self = GOO_PLAYER_BAR (object);
+       self = GOO_PLAYER_PROGRESS (object);
 
        if (self->priv->update_progress_timeout != 0) {
                g_source_remove (self->priv->update_progress_timeout);
@@ -337,27 +282,27 @@ goo_player_bar_finalize (GObject *object)
                self->priv->update_id = 0;
        }
 
-       G_OBJECT_CLASS (goo_player_bar_parent_class)->finalize (object);
+       G_OBJECT_CLASS (goo_player_progress_parent_class)->finalize (object);
 }
 
 
 static void
-goo_player_bar_class_init (GooPlayerBarClass *class)
+goo_player_progress_class_init (GooPlayerProgressClass *class)
 {
-        GObjectClass   *gobject_class;
+       GObjectClass   *gobject_class;
        GtkWidgetClass *widget_class;
 
        gobject_class = G_OBJECT_CLASS (class);
-        gobject_class->finalize = goo_player_bar_finalize;
+       gobject_class->finalize = goo_player_progress_finalize;
 
        widget_class = GTK_WIDGET_CLASS (class);
-       widget_class->get_preferred_width = goo_player_bar_get_preferred_width;
+       widget_class->get_preferred_width = goo_player_progress_get_preferred_width;
 
-       goo_player_bar_signals[SKIP_TO] =
-                g_signal_new ("skip-to",
+       goo_player_progress_signals[SKIP_TO] =
+               g_signal_new ("skip-to",
                              G_TYPE_FROM_CLASS (class),
                              G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (GooPlayerBarClass, skip_to),
+                             G_STRUCT_OFFSET (GooPlayerProgressClass, skip_to),
                              NULL, NULL,
                              goo_marshal_VOID__INT,
                              G_TYPE_NONE,
@@ -367,14 +312,14 @@ goo_player_bar_class_init (GooPlayerBarClass *class)
 
 
 static void
-_goo_player_bar_set_time (GooPlayerBar *self,
-                         gint64        current_time)
+_goo_player_progress_set_time (GooPlayerProgress *self,
+                              gint64             current_time)
 {
        if (self->priv->dragging)
                return;
 
        self->priv->current_time = current_time;
-       _goo_player_bar_update_current_time (self);
+       _goo_player_progress_update_current_time (self);
 
        g_signal_handlers_block_by_data (self->priv->time_scale, self);
        gtk_range_set_value (GTK_RANGE (self->priv->time_scale), (double) current_time / 
self->priv->track_length);
@@ -385,21 +330,21 @@ _goo_player_bar_set_time (GooPlayerBar *self,
 static gboolean
 update_progress_cb (gpointer data)
 {
-       GooPlayerBar *self = data;
+       GooPlayerProgress *self = data;
 
        self->priv->update_progress_timeout = 0;
 
        if ((self->priv->fraction >= 0.0) && (self->priv->fraction <= 1.0))
-               _goo_player_bar_set_time (self, self->priv->fraction * self->priv->track_length);
+               _goo_player_progress_set_time (self, self->priv->fraction * self->priv->track_length);
 
        return FALSE;
 }
 
 
 static void
-player_progress_cb (GooPlayer     *player,
-                   double         fraction,
-                   GooPlayerBar *self)
+player_progress_cb (GooPlayer         *player,
+                   double             fraction,
+                   GooPlayerProgress *self)
 {
        self->priv->fraction = fraction;
        if (self->priv->update_progress_timeout == 0)
@@ -408,15 +353,15 @@ player_progress_cb (GooPlayer     *player,
 
 
 static void
-goo_player_bar_set_sensitive (GooPlayerBar *self,
-                             gboolean      value)
+goo_player_progress_set_sensitive (GooPlayerProgress *self,
+                                  gboolean           value)
 {
        /* FIXME */
 }
 
 
 static void
-goo_player_bar_update_state (GooPlayerBar *self)
+goo_player_progress_update_state (GooPlayerProgress *self)
 {
        GooPlayerState state;
 
@@ -429,39 +374,30 @@ goo_player_bar_update_state (GooPlayerBar *self)
            || (state == GOO_PLAYER_STATE_PAUSED))
        {
                gtk_widget_show (self->priv->time_box);
+               gtk_widget_hide (self->priv->title);
        }
        else {
                gtk_widget_hide (self->priv->time_box);
+               gtk_widget_show (self->priv->title);
        }
 }
 
 
 static void
 player_state_changed_cb (GooPlayer     *player,
-                        GooPlayerBar *self)
-{
-       goo_player_bar_update_state (self);
-       goo_player_bar_set_sensitive (self, (goo_player_get_state (player) != GOO_PLAYER_STATE_ERROR) && 
(goo_player_get_discid (player) != NULL));
-}
-
-
-static void
-_goo_player_bar_update_play_button_icon (GooPlayerBar *self,
-                                        gboolean      playing)
+                        GooPlayerProgress *self)
 {
-       gtk_image_set_from_icon_name (GTK_IMAGE (self->priv->play_button_image),
-                                     playing ? GOO_ICON_NAME_PAUSE : GOO_ICON_NAME_PLAY,
-                                     PLAY_BUTTON_SIZE);
+       goo_player_progress_update_state (self);
+       goo_player_progress_set_sensitive (self, (goo_player_get_state (player) != GOO_PLAYER_STATE_ERROR) && 
(goo_player_get_discid (player) != NULL));
 }
 
 
 static void
 player_start_cb (GooPlayer       *player,
                 GooPlayerAction  action,
-                GooPlayerBar    *self)
+                GooPlayerProgress    *self)
 {
-       _goo_player_bar_update_play_button_icon (self, action == GOO_PLAYER_ACTION_PLAY);
-       goo_player_bar_update_state (self);
+       goo_player_progress_update_state (self);
 }
 
 
@@ -469,32 +405,30 @@ static void
 player_done_cb (GooPlayer       *player,
                GooPlayerAction  action,
                GError          *error,
-               GooPlayerBar    *self)
+               GooPlayerProgress    *self)
 {
        AlbumInfo *album;
 
        switch (action) {
        case GOO_PLAYER_ACTION_LIST:
-               goo_player_bar_update_state (self);
-               _goo_player_bar_set_time (self, 0);
+               goo_player_progress_update_state (self);
+               _goo_player_progress_set_time (self, 0);
                break;
        case GOO_PLAYER_ACTION_METADATA:
-               goo_player_bar_update_state (self);
+               goo_player_progress_update_state (self);
                break;
        case GOO_PLAYER_ACTION_SEEK_SONG:
                album = goo_player_get_album (player);
                self->priv->track_length = album_info_get_track (album, goo_player_get_current_track 
(player))->length;
-               goo_player_bar_update_state (self);
-               _goo_player_bar_set_time (self, 0);
+               goo_player_progress_update_state (self);
+               _goo_player_progress_set_time (self, 0);
                break;
        case GOO_PLAYER_ACTION_PLAY:
        case GOO_PLAYER_ACTION_STOP:
        case GOO_PLAYER_ACTION_MEDIUM_REMOVED:
-               _goo_player_bar_update_play_button_icon (self, FALSE);
-               _goo_player_bar_set_time (self, 0);
+               _goo_player_progress_set_time (self, 0);
                break;
        case GOO_PLAYER_ACTION_PAUSE:
-               _goo_player_bar_update_play_button_icon (self, FALSE);
                break;
        default:
                break;
@@ -503,16 +437,15 @@ player_done_cb (GooPlayer       *player,
 
 
 GtkWidget *
-goo_player_bar_new (GooPlayer  *player,
-                   GActionMap  *action_map)
+goo_player_progress_new (GooPlayer     *player)
 {
-       GooPlayerBar *self;
+       GooPlayerProgress *self;
 
        g_return_val_if_fail (player != NULL, NULL);
 
-       self = GOO_PLAYER_BAR (g_object_new (GOO_TYPE_PLAYER_BAR, NULL));
+       self = GOO_PLAYER_PROGRESS (g_object_new (GOO_TYPE_PLAYER_PROGRESS, NULL));
        self->priv->player = g_object_ref (player);
-       goo_player_bar_construct (self, action_map);
+       goo_player_progress_construct (self);
 
        g_signal_connect (player,
                          "start",
@@ -535,8 +468,16 @@ goo_player_bar_new (GooPlayer      *player,
 }
 
 
+void
+goo_player_progress_set_title (GooPlayerProgress       *progress,
+                              const char               *title)
+{
+       gtk_label_set_text (GTK_LABEL (progress->priv->title), title);
+}
+
+
 double
-goo_player_bar_get_progress (GooPlayerBar *self)
+goo_player_progress_get_progress (GooPlayerProgress *self)
 {
        return self->priv->fraction;
 }
diff --git a/src/goo-player-progress.h b/src/goo-player-progress.h
new file mode 100644
index 0000000..eabd3e2
--- /dev/null
+++ b/src/goo-player-progress.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Goo
+ *
+ *  Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GOO_PLAYER_PROGRESS_H
+#define GOO_PLAYER_PROGRESS_H
+
+#include <gtk/gtk.h>
+#include "goo-player.h"
+
+#define GOO_TYPE_PLAYER_PROGRESS              (goo_player_progress_get_type ())
+#define GOO_PLAYER_PROGRESS(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_PLAYER_PROGRESS, 
GooPlayerProgress))
+#define GOO_PLAYER_PROGRESS_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_PLAYER_PROGRESS, 
GooPlayerProgressClass))
+#define GOO_IS_PLAYER_PROGRESS(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_PLAYER_PROGRESS))
+#define GOO_IS_PLAYER_PROGRESS_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_PLAYER_PROGRESS))
+#define GOO_PLAYER_PROGRESS_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GOO_TYPE_PLAYER_PROGRESS, 
GooPlayerProgressClass))
+
+typedef struct _GooPlayerProgress            GooPlayerProgress;
+typedef struct _GooPlayerProgressClass       GooPlayerProgressClass;
+typedef struct _GooPlayerProgressPrivate     GooPlayerProgressPrivate;
+
+struct _GooPlayerProgress
+{
+       GtkBox __parent;
+       GooPlayerProgressPrivate *priv;
+};
+
+struct _GooPlayerProgressClass
+{
+       GtkBoxClass __parent_class;
+
+       /*<signals>*/
+
+       void (*skip_to) (GooPlayerProgress      *info,
+                        int                     seconds);
+
+};
+
+GType          goo_player_progress_get_type    (void);
+GtkWidget *    goo_player_progress_new         (GooPlayer              *player);
+void           goo_player_progress_set_title   (GooPlayerProgress      *progress,
+                                                const char             *title);
+double         goo_player_progress_get_progress
+                                               (GooPlayerProgress      *progress);
+
+#endif /* GOO_PLAYER_PROGRESS_H */
diff --git a/src/goo-window.c b/src/goo-window.c
index 696a0fa..7fbde8b 100644
--- a/src/goo-window.c
+++ b/src/goo-window.c
@@ -30,8 +30,8 @@
 #include "dlg-cover-chooser.h"
 #include "goo-marshal.h"
 #include "goo-player.h"
-#include "goo-player-bar.h"
 #include "goo-player-info.h"
+#include "goo-player-progress.h"
 #include "goo-window.h"
 #include "goo-window-actions-entries.h"
 #include "gth-user-dir.h"
@@ -72,7 +72,8 @@ struct _GooWindowPrivate {
        GtkWidget         *message_label;
        GtkWidget         *message_bar_properties_button;
        GtkWidget         *info;
-       GtkWidget         *player_bar;
+       GtkWidget         *play_button;
+       GtkWidget         *progress;
 
        guint              first_time_event;
        guint              next_timeout_handle;
@@ -1317,7 +1318,7 @@ goo_window_set_current_track (GooWindow *window,
 static void
 window_update_title (GooWindow *window)
 {
-       gtk_window_set_title (GTK_WINDOW (window), _("CD Player"));
+       goo_player_progress_set_title (GOO_PLAYER_PROGRESS (window->priv->progress), _("CD Player"));
 
 #if 0
        GooPlayerState  state;
@@ -1341,7 +1342,7 @@ window_update_title (GooWindow *window)
                break;
        }
 
-       gtk_window_set_title (GTK_WINDOW (window), title->str);
+       goo_player_progress_set_title (GOO_PLAYER_PROGRESS (window->priv->progress), title->str);
 
        g_string_free (title, TRUE);
 #endif
@@ -1518,6 +1519,15 @@ goo_window_update_album (GooWindow *window)
 }
 
 
+static void
+window_update_play_button_state (GooWindow *window)
+{
+       gboolean playing = (goo_player_get_state (window->priv->player) == GOO_PLAYER_STATE_PLAYING);
+       gtk_button_set_image (GTK_BUTTON (window->priv->play_button),
+                             gtk_image_new_from_icon_name (playing ? GOO_ICON_NAME_PAUSE : 
GOO_ICON_NAME_PLAY, GTK_ICON_SIZE_MENU));
+}
+
+
 static void
 player_done_cb (GooPlayer       *player,
                GooPlayerAction  action,
@@ -1568,11 +1578,13 @@ player_done_cb (GooPlayer       *player,
                else if (action == GOO_PLAYER_ACTION_STOP)
                        set_current_track_icon (window, GOO_ICON_NAME_STOP);
                notify_current_state (window, action);
+               window_update_play_button_state (window);
                break;
 
        case GOO_PLAYER_ACTION_PAUSE:
                set_current_track_icon (window, GOO_ICON_NAME_PAUSE);
                notify_current_state (window, action);
+               window_update_play_button_state (window);
                break;
 
        case GOO_PLAYER_ACTION_STARTED_NEXT:
@@ -1593,6 +1605,7 @@ player_state_changed_cb (GooPlayer *player,
 {
        window_update_sensitivity (window);
        window_update_title (window);
+       window_update_play_button_state (window);
 }
 
 
@@ -1767,16 +1780,6 @@ update_ui_from_expander_state (GooWindow *window)
 }
 
 
-static void
-player_bar_skip_to_cb (GooPlayerBar *info,
-                      int           seconds,
-                      GooWindow    *window)
-{
-       debug (DEBUG_INFO, "[Window] skip to %d\n", seconds);
-       goo_player_skip_to (window->priv->player, (guint) seconds);
-}
-
-
 static void
 player_info_cover_clicked_cb (GooPlayerInfo *info,
                              GooWindow     *window)
@@ -1915,6 +1918,30 @@ window_size_allocate_cb (GtkWidget    *widget,
 }
 
 
+static void
+_gtk_menu_button_set_style_for_header_bar (GtkWidget *button)
+{
+       GtkStyleContext *context;
+
+       gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
+       context = gtk_widget_get_style_context (button);
+       gtk_style_context_add_class (context, "image-button");
+       gtk_style_context_remove_class (context, "text-button");
+}
+
+
+static GtkWidget *
+_gtk_image_button_new_for_header_bar (const char *icon_name)
+       {
+       GtkWidget *button;
+
+       button = gtk_button_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
+       _gtk_menu_button_set_style_for_header_bar (button);
+
+       return button;
+}
+
+
 static void
 goo_window_init (GooWindow *window)
 {
@@ -1929,12 +1956,11 @@ goo_window_init (GooWindow *window)
 
        gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accel_group);
 
-       gtk_window_set_title (GTK_WINDOW (window), _("CD Player"));
 
        g_action_map_add_action_entries (G_ACTION_MAP (window),
                                         goo_window_actions,
                                         G_N_ELEMENTS (goo_window_actions),
-                                                window);
+                                        window);
        goo_window_add_accelerators (window,
                                     goo_window_accelerators,
                                     G_N_ELEMENTS (goo_window_accelerators));
@@ -2068,6 +2094,16 @@ message_bar_response_cb (GtkInfoBar *info_bar,
 }
 
 
+static void
+progress_skip_to_cb (GooPlayerProgress *progress,
+                    int                seconds,
+                    GooWindow         *window)
+{
+       debug (DEBUG_INFO, "[Window] skip to %d\n", seconds);
+       goo_player_skip_to (window->priv->player, (guint) seconds);
+}
+
+
 static void
 goo_window_construct (GooWindow    *window,
                      BraseroDrive *drive)
@@ -2077,6 +2113,7 @@ goo_window_construct (GooWindow    *window,
        GtkWidget        *vbox;
        GtkWidget        *hbox;
        GtkTreeSelection *selection;
+       GtkWidget        *headerbar;
 
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), 
"goobox-main-window");
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), 
GTK_STYLE_CLASS_VIEW);
@@ -2234,14 +2271,6 @@ goo_window_construct (GooWindow    *window,
 
        gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
 
-       window->priv->player_bar = goo_player_bar_new (window->priv->player, G_ACTION_MAP (window));
-       g_signal_connect (window->priv->player_bar,
-                         "skip-to",
-                         G_CALLBACK (player_bar_skip_to_cb),
-                         window);
-       gtk_widget_show (window->priv->player_bar);
-       gtk_box_pack_start (GTK_BOX (vbox), window->priv->player_bar, FALSE, FALSE, 0);
-
        /**/
 
        gtk_widget_show_all (vbox);
@@ -2257,6 +2286,84 @@ goo_window_construct (GooWindow    *window,
                                     g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_WIDTH),
                                     g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_HEIGHT));
 
+       headerbar = gtk_header_bar_new ();
+       gtk_widget_show (headerbar);
+       gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE);
+
+       /* play buttons */
+
+       {
+               GtkWidget *button;
+               GtkWidget *button_box;
+
+               window->priv->play_button = button = _gtk_image_button_new_for_header_bar 
(GOO_ICON_NAME_PLAY);
+               gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.toggle-play");
+               gtk_widget_show_all (button);
+               gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button);
+
+               button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+               gtk_style_context_add_class (gtk_widget_get_style_context (button_box), 
GTK_STYLE_CLASS_LINKED);
+               gtk_widget_show (button_box);
+               gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button_box);
+
+               button = _gtk_image_button_new_for_header_bar (GOO_ICON_NAME_PREV);
+               gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.previous-track");
+               gtk_widget_show_all (button);
+               gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
+
+               button = _gtk_image_button_new_for_header_bar (GOO_ICON_NAME_NEXT);
+               gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.next-track");
+               gtk_widget_show_all (button);
+               gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
+       }
+
+       /* gears menu button */
+
+       {
+               GtkBuilder *builder;
+               GMenuModel *menu;
+               GtkWidget  *button;
+
+               builder = _gtk_builder_new_from_resource ("gears-menu.ui");
+               menu = G_MENU_MODEL (gtk_builder_get_object (builder, "gears-menu"));
+               button = gtk_menu_button_new ();
+               _gtk_menu_button_set_style_for_header_bar (button);
+               gtk_menu_button_set_direction (GTK_MENU_BUTTON (button), GTK_ARROW_NONE);
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
+               gtk_widget_show_all (button);
+               gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button);
+
+               _gtk_window_add_accelerators_from_menu ((GTK_WINDOW (window)), menu);
+
+               g_object_unref (builder);
+       }
+
+       /* extract button */
+
+       {
+               GtkWidget *button;
+
+               button = _gtk_image_button_new_for_header_bar (GOO_ICON_NAME_EXTRACT);
+               gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.extract");
+               gtk_widget_show_all (button);
+               gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button);
+       }
+
+       /* custom title */
+
+       window->priv->progress = goo_player_progress_new (window->priv->player);
+       gtk_widget_show (window->priv->progress);
+       gtk_header_bar_set_custom_title (GTK_HEADER_BAR (headerbar), window->priv->progress);
+
+       g_signal_connect (window->priv->progress,
+                         "skip-to",
+                         G_CALLBACK (progress_skip_to_cb),
+                         window);
+
+       gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
+
+       goo_player_progress_set_title (GOO_PLAYER_PROGRESS (window->priv->progress), _("CD Player"));
+
        /* Add notification callbacks. */
 
        g_signal_connect (window->priv->settings_playlist,
diff --git a/src/goobox.gresource.xml b/src/goobox.gresource.xml
index 5ff3077..2efa2fa 100644
--- a/src/goobox.gresource.xml
+++ b/src/goobox.gresource.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/Goobox">
-    <file compressed="true">ui/app-menu.ui</file>
     <file compressed="true">ui/cover-chooser.ui</file>
     <file compressed="true">ui/extract.ui</file>
     <file compressed="true">ui/format-options.ui</file>
diff --git a/src/gtk-utils.c b/src/gtk-utils.c
index c39dd59..cb2d8aa 100644
--- a/src/gtk-utils.c
+++ b/src/gtk-utils.c
@@ -1007,6 +1007,35 @@ _gtk_application_get_current_window (GtkApplication *application)
 }
 
 
+void
+_gtk_application_add_accelerator_for_action (GtkApplication   *app,
+                                            const char       *action_name,
+                                            const char       *accel)
+{
+       const char *accels[2];
+
+       accels[0] = accel;
+       accels[1] = NULL;
+       gtk_application_set_accels_for_action (app, action_name, accels);
+}
+
+
+void
+_gtk_application_add_accelerators (GtkApplication        *app,
+                                  const _GtkAccelerator *accelerators,
+                                  int                    n_accelerators)
+{
+       int i;
+
+       for (i = 0; i < n_accelerators; i++) {
+               const _GtkAccelerator *acc = accelerators + i;
+               _gtk_application_add_accelerator_for_action (GTK_APPLICATION (app),
+                                                            acc->action_name,
+                                                            acc->accelerator);
+       }
+}
+
+
 gboolean
 _gtk_window_get_monitor_info (GtkWindow            *window,
                              GdkRectangle  *geometry,
diff --git a/src/gtk-utils.h b/src/gtk-utils.h
index f47c95b..97909cc 100644
--- a/src/gtk-utils.h
+++ b/src/gtk-utils.h
@@ -149,6 +149,14 @@ void               _g_action_map_change_action_state       (GActionMap             
*action_map,
                                                         const char             *action_name,
                                                         gboolean                value);
 GtkWidget *    _gtk_application_get_current_window     (GtkApplication         *application);
+void           _gtk_application_add_accelerator_for_action
+                                                       (GtkApplication         *app,
+                                                        const char             *action_name,
+                                                        const char             *accel);
+void           _gtk_application_add_accelerators       (GtkApplication         *app,
+                                                        const _GtkAccelerator  *accelerators,
+                                                        int                     n_accelerators);
+
 gboolean       _gtk_window_get_monitor_info            (GtkWindow              *window,
                                                         GdkRectangle           *geometry,
                                                         int                    *number,
diff --git a/src/meson.build b/src/meson.build
index e5d999f..dc5d5ba 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -52,8 +52,8 @@ source_files = files(
   'goo-application-actions-callbacks.c',
   'goo-error.c',
   'goo-player.c',
-  'goo-player-bar.c',
   'goo-player-info.c',
+  'goo-player-progress.c',
   'goo-window.c',
   'goo-window-actions-callbacks.c',
   'gth-user-dir.c',
diff --git a/src/ui/gears-menu.ui b/src/ui/gears-menu.ui
index 0463a4b..4b2568a 100644
--- a/src/ui/gears-menu.ui
+++ b/src/ui/gears-menu.ui
@@ -1,6 +1,5 @@
 <?xml version="1.0"?>
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
   <menu id="gears-menu">
     <section>
       <item>
@@ -22,9 +21,31 @@
     </section>
     <section>
       <item>
-        <attribute name="label" translatable="yes">_Close</attribute>
-        <attribute name="action">win.close</attribute>
-        <attribute name="accel"><![CDATA[<Control>w]]></attribute>
+        <attribute name="action">app.play-all</attribute>
+        <attribute name="label" translatable="yes">Play _All</attribute>
+      </item>
+      <item>
+        <attribute name="action">app.repeat</attribute>
+        <attribute name="label" translatable="yes">_Repeat</attribute>
+      </item>
+      <item>
+        <attribute name="action">app.shuffle</attribute>
+        <attribute name="label" translatable="yes">S_huffle</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="action">app.preferences</attribute>
+        <attribute name="label" translatable="yes">_Preferences</attribute>
+      </item>
+      <item>
+        <attribute name="action">app.help</attribute>
+        <attribute name="label" translatable="yes">_Help</attribute>
+        <attribute name="accel">F1</attribute>
+      </item>
+      <item>
+        <attribute name="action">app.about</attribute>
+        <attribute name="label" translatable="yes">_About</attribute>
       </item>
     </section>
   </menu>


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