Commit 14848d8a authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

media player: hide the mediabar after a timeout

parent b66427a3
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Mon Nov 4 23:47:57 2013 -->
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkAdjustment" id="position_adjustment">
......@@ -6,13 +7,14 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="volume_adjustment">
<property name="upper">50</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="mediabar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="spacing">34</property>
<child>
<object class="GtkBox" id="box2">
......@@ -20,20 +22,19 @@
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="play_slower_button">
<object class="GtkButton" id="play_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Slower</property>
<property name="use_action_appearance">False</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image1">
<object class="GtkImage" id="play_button_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-seek-backward-symbolic</property>
<property name="icon-size">2</property>
<property name="icon_name">media-playback-start-symbolic</property>
<property name="icon_size">2</property>
</object>
</child>
</object>
......@@ -44,20 +45,19 @@
</packing>
</child>
<child>
<object class="GtkButton" id="play_button">
<object class="GtkButton" id="play_slower_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="use_action_appearance">False</property>
<property name="tooltip_text" translatable="yes">Slower</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="play_button_image">
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-start-symbolic</property>
<property name="icon-size">3</property>
<property name="icon_name">media-seek-backward-symbolic</property>
<property name="icon_size">1</property>
</object>
</child>
</object>
......@@ -74,14 +74,13 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Faster</property>
<property name="use_action_appearance">False</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-seek-forward-symbolic</property>
<property name="icon-size">2</property>
<property name="icon_size">1</property>
</object>
</child>
</object>
......@@ -121,6 +120,7 @@
</child>
<child>
<object class="GtkScale" id="position_scale">
<property name="width_request">180</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">position_adjustment</property>
......@@ -201,19 +201,34 @@
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkToggleButton" id="volume_togglebutton">
<property name="use_action_appearance">False</property>
<object class="GtkVolumeButton" id="volumebutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Toggle volume</property>
<property name="use_action_appearance">False</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="volume_togglebutton_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">audio-volume-high-symbolic</property>
<property name="focus_on_click">False</property>
<property name="orientation">vertical</property>
<property name="size">menu</property>
<property name="adjustment">volume_adjustment</property>
<property name="icons">audio-volume-muted
audio-volume-high
audio-volume-low
audio-volume-medium</property>
<property name="use_symbolic">True</property>
<child internal-child="plus_button">
<object class="GtkButton" id="volumebutton-plus_button1">
<property name="label" translatable="yes">+</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
</child>
<child internal-child="minus_button">
<object class="GtkButton" id="volumebutton-minus_button1">
<property name="label" translatable="yes">-</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
</child>
</object>
......@@ -223,22 +238,6 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScale" id="volume_scale">
<property name="width_request">180</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Change volume level</property>
<property name="adjustment">volume_adjustment</property>
<property name="round_digits">1</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
......@@ -247,9 +246,4 @@
</packing>
</child>
</object>
<object class="GtkAdjustment" id="volume_adjustment">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
</interface>
......@@ -66,7 +66,7 @@ struct _GthMediaViewerPagePrivate {
gulong update_volume_id;
gdouble rate;
GtkWidget *mediabar;
GtkWidget *fullscreen_toolbar;
GtkWidget *mediabar_revealer;
gulong video_window_xid;
gboolean xwin_assigned;
GdkPixbuf *icon;
......@@ -289,6 +289,7 @@ volume_value_changed_cb (GtkAdjustment *adjustment,
gpointer user_data)
{
GthMediaViewerPage *self = user_data;
if (self->priv->playbin != NULL)
g_object_set (self->priv->playbin,
"volume",
......@@ -774,7 +775,8 @@ gth_media_viewer_page_real_activate (GthViewerPage *base,
self->priv->builder = _gtk_builder_new_from_file ("mediabar.ui", "gstreamer_tools");
self->priv->mediabar = GET_WIDGET ("mediabar");
gtk_widget_show (self->priv->mediabar);
gtk_widget_set_halign (self->priv->mediabar, GTK_ALIGN_FILL);
gtk_widget_set_valign (self->priv->mediabar, GTK_ALIGN_END);
g_signal_connect (GET_WIDGET ("volume_adjustment"),
"value-changed",
......@@ -817,9 +819,16 @@ gth_media_viewer_page_real_activate (GthViewerPage *base,
G_CALLBACK (play_faster_button_clicked_cb),
self);
self->priv->area_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (self->priv->area_box), self->priv->area, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (self->priv->area_box), self->priv->mediabar, FALSE, FALSE, 0);
self->priv->mediabar_revealer = gtk_revealer_new ();
gtk_revealer_set_transition_type (GTK_REVEALER (self->priv->mediabar_revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
gtk_widget_set_halign (self->priv->mediabar_revealer, GTK_ALIGN_FILL);
gtk_widget_set_valign (self->priv->mediabar_revealer, GTK_ALIGN_END);
gtk_widget_show (self->priv->mediabar_revealer);
gtk_container_add (GTK_CONTAINER (self->priv->mediabar_revealer), self->priv->mediabar);
self->priv->area_box = gtk_overlay_new ();
gtk_container_add (GTK_CONTAINER (self->priv->area_box), self->priv->area);
gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->area_box), self->priv->mediabar_revealer);
gtk_widget_show (self->priv->area_box);
gth_browser_set_viewer_widget (browser, self->priv->area_box);
......@@ -829,25 +838,6 @@ gth_media_viewer_page_real_activate (GthViewerPage *base,
}
static void
remove_fullscreen_toolbar (GthMediaViewerPage *self)
{
if (self->priv->fullscreen_toolbar == NULL)
return;
if (gtk_widget_get_parent (self->priv->mediabar) == self->priv->fullscreen_toolbar) {
g_object_ref (self->priv->mediabar);
gtk_container_remove (GTK_CONTAINER (self->priv->fullscreen_toolbar), self->priv->mediabar);
gtk_box_pack_start (GTK_BOX (self->priv->area_box), self->priv->mediabar, FALSE, FALSE, 0);
g_object_unref (self->priv->mediabar);
}
gth_browser_unregister_fullscreen_control (self->priv->browser, self->priv->fullscreen_toolbar);
gtk_widget_destroy (self->priv->fullscreen_toolbar);
self->priv->fullscreen_toolbar = NULL;
}
static void
save_volume (GthMediaViewerPage *self)
{
......@@ -894,8 +884,6 @@ gth_media_viewer_page_real_deactivate (GthViewerPage *base)
gtk_widget_destroy (self->priv->screenshot_button);
self->priv->screenshot_button = NULL;
remove_fullscreen_toolbar (self);
gth_browser_set_viewer_widget (self->priv->browser, NULL);
}
......@@ -1227,44 +1215,11 @@ gth_media_viewer_page_real_fullscreen (GthViewerPage *base,
gboolean active)
{
GthMediaViewerPage *self = (GthMediaViewerPage*) base;
GdkScreen *screen;
int n_monitor;
GdkRectangle work_area;
if (! active) {
remove_fullscreen_toolbar (self);
return;
}
/* active == TRUE */
screen = gtk_widget_get_screen (GTK_WIDGET (self->priv->browser));
n_monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET (self->priv->browser)));
gdk_screen_get_monitor_geometry (screen, n_monitor, &work_area);
if (self->priv->fullscreen_toolbar == NULL) {
self->priv->fullscreen_toolbar = gtk_window_new (GTK_WINDOW_POPUP);
gtk_container_set_border_width (GTK_CONTAINER (self->priv->fullscreen_toolbar), 0);
}
if (gtk_widget_get_parent (self->priv->mediabar) == self->priv->area_box) {
g_object_ref (self->priv->mediabar);
gtk_container_remove (GTK_CONTAINER (self->priv->area_box), self->priv->mediabar);
gtk_container_add (GTK_CONTAINER (self->priv->fullscreen_toolbar), self->priv->mediabar);
g_object_unref (self->priv->mediabar);
}
gtk_widget_realize (self->priv->fullscreen_toolbar);
gtk_window_set_screen (GTK_WINDOW (self->priv->fullscreen_toolbar), screen);
gtk_window_resize (GTK_WINDOW (self->priv->fullscreen_toolbar),
work_area.width,
gtk_widget_get_allocated_height (self->priv->fullscreen_toolbar));
gtk_window_move (GTK_WINDOW (self->priv->fullscreen_toolbar),
work_area.x,
work_area.height - gtk_widget_get_allocated_height (self->priv->fullscreen_toolbar));
gth_browser_register_fullscreen_control (self->priv->browser, self->priv->fullscreen_toolbar);
if (active)
gth_browser_register_fullscreen_control (self->priv->browser, self->priv->mediabar);
else
gth_browser_unregister_fullscreen_control (self->priv->browser, self->priv->mediabar);
}
......@@ -1279,15 +1234,10 @@ gth_media_viewer_page_real_show_pointer (GthViewerPage *base,
if (show && (self->priv->cursor != NULL))
gdk_window_set_cursor (gtk_widget_get_window (self->priv->area), self->priv->cursor);
if (! show && (self->priv->cursor_void != NULL))
if (! show && gth_browser_get_is_fullscreen (self->priv->browser) && (self->priv->cursor_void != NULL))
gdk_window_set_cursor (gtk_widget_get_window (self->priv->area), self->priv->cursor_void);
if (self->priv->fullscreen_toolbar != NULL) {
if (show)
gtk_widget_show (self->priv->fullscreen_toolbar);
else
gtk_widget_hide (self->priv->fullscreen_toolbar);
}
gtk_revealer_set_reveal_child (GTK_REVEALER (self->priv->mediabar_revealer), show);
}
......
<
......@@ -63,7 +63,7 @@
#define MAX_HISTORY_LENGTH 15
#define LOAD_FILE_DELAY 150
#define LOAD_METADATA_DELAY 150
#define HIDE_MOUSE_DELAY 1000
#define HIDE_MOUSE_DELAY 3000
#define MOTION_THRESHOLD 0
#define UPDATE_SELECTION_DELAY 200
#define MIN_SIDEBAR_SIZE 100
......@@ -186,8 +186,10 @@ struct _GthBrowserPrivate {
/* fullscreen */
gboolean fullscreen;
GtkWidget *fullscreen_toolbar;
gboolean was_fullscreen;
GtkWidget *fullscreen_headerbar;
GList *fullscreen_controls;
gboolean pointer_visible;
guint hide_mouse_timeout;
guint motion_signal;
gdouble last_mouse_x;
......@@ -1895,12 +1897,21 @@ gth_browser_ask_whether_to_save (GthBrowser *browser,
/* -- _gth_browser_close -- */
static void
_gth_browser_show_pointer_on_viewer (GthBrowser *browser,
gboolean show)
{
browser->priv->pointer_visible = show;
gth_viewer_page_show_pointer (GTH_VIEWER_PAGE (browser->priv->viewer_page), show);
}
static void
_gth_browser_deactivate_viewer_page (GthBrowser *browser)
{
if (browser->priv->viewer_page != NULL) {
if (browser->priv->fullscreen)
gth_viewer_page_show_pointer (GTH_VIEWER_PAGE (browser->priv->viewer_page), TRUE);
_gth_browser_show_pointer_on_viewer (browser, TRUE);
gth_hook_invoke ("gth-browser-deactivate-viewer-page", browser);
gth_viewer_page_deactivate (browser->priv->viewer_page);
gth_browser_set_viewer_widget (browser, NULL);
......@@ -2078,6 +2089,16 @@ _gth_browser_real_close (GthBrowser *browser)
/* remove timeouts */
if (browser->priv->motion_signal != 0) {
g_signal_handler_disconnect (browser, browser->priv->motion_signal);
browser->priv->motion_signal = 0;
}
if (browser->priv->hide_mouse_timeout != 0) {
g_source_remove (browser->priv->hide_mouse_timeout);
browser->priv->hide_mouse_timeout = 0;
}
if (browser->priv->construct_step2_event != 0) {
g_source_remove (browser->priv->construct_step2_event);
browser->priv->construct_step2_event = 0;
......@@ -2151,6 +2172,101 @@ _gth_browser_update_header_section_visibility (GthBrowser *browser,
}
typedef struct {
GthBrowser *browser;
GdkDevice *device;
} HideMouseData;
static gboolean
hide_mouse_pointer_cb (gpointer data)
{
HideMouseData *hmdata = data;
GthBrowser *browser = hmdata->browser;
int px, py;
GdkScreen *screen;
int n_monitor;
GdkRectangle work_area;
GList *scan;
gdk_window_get_device_position (gtk_widget_get_window (GTK_WIDGET (browser)),
hmdata->device,
&px,
&py,
0);
screen = gtk_widget_get_screen (GTK_WIDGET (browser));
n_monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET (browser)));
gdk_screen_get_monitor_geometry (screen, n_monitor, &work_area);
px += work_area.x;
py += work_area.y;
for (scan = browser->priv->fullscreen_controls; scan; scan = scan->next) {
GtkWidget *widget = scan->data;
int x, y, w, h;
gdk_window_get_geometry (gtk_widget_get_window (widget), &x, &y, &w, &h);
if ((px >= x) && (px <= x + w) && (py >= y) && (py <= y + h))
return FALSE;
}
browser->priv->pointer_visible = FALSE;
gtk_widget_hide (browser->priv->fullscreen_headerbar);
if (browser->priv->viewer_page != NULL)
_gth_browser_show_pointer_on_viewer (browser, FALSE);
browser->priv->hide_mouse_timeout = 0;
return FALSE;
}
static gboolean
viewer_motion_notify_event_cb (GtkWidget *widget,
GdkEventMotion *event,
gpointer data)
{
GthBrowser *browser = data;
HideMouseData *hmdata;
if (browser->priv->last_mouse_x == 0.0)
browser->priv->last_mouse_x = event->x;
if (browser->priv->last_mouse_y == 0.0)
browser->priv->last_mouse_y = event->y;
if ((abs (browser->priv->last_mouse_x - event->x) > MOTION_THRESHOLD)
|| (abs (browser->priv->last_mouse_y - event->y) > MOTION_THRESHOLD))
{
if (! browser->priv->pointer_visible) {
browser->priv->pointer_visible = TRUE;
if (browser->priv->fullscreen)
gtk_widget_show (browser->priv->fullscreen_headerbar);
if (browser->priv->viewer_page != NULL)
_gth_browser_show_pointer_on_viewer (browser, TRUE);
}
}
if (browser->priv->hide_mouse_timeout != 0)
g_source_remove (browser->priv->hide_mouse_timeout);
hmdata = g_new0 (HideMouseData, 1);
hmdata->browser = browser;
hmdata->device = event->device;
browser->priv->hide_mouse_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT,
HIDE_MOUSE_DELAY,
hide_mouse_pointer_cb,
hmdata,
g_free);
browser->priv->last_mouse_x = event->x;
browser->priv->last_mouse_y = event->y;
return FALSE;
}
static void
_gth_browser_real_set_current_page (GthWindow *window,
int page)
......@@ -2172,10 +2288,30 @@ _gth_browser_real_set_current_page (GthWindow *window,
_gth_browser_hide_infobar (browser);
if (browser->priv->viewer_page != NULL) {
if (page == GTH_BROWSER_PAGE_VIEWER)
if (page == GTH_BROWSER_PAGE_VIEWER) {
gth_viewer_page_show (browser->priv->viewer_page);
else
_gth_browser_show_pointer_on_viewer (browser, FALSE);
browser->priv->last_mouse_x = 0.0;
browser->priv->last_mouse_y = 0.0;
if (browser->priv->motion_signal == 0)
browser->priv->motion_signal = g_signal_connect (browser,
"motion_notify_event",
G_CALLBACK (viewer_motion_notify_event_cb),
browser);
}
else {
gth_viewer_page_hide (browser->priv->viewer_page);
if (browser->priv->motion_signal != 0) {
g_signal_handler_disconnect (browser, browser->priv->motion_signal);
browser->priv->motion_signal = 0;
}
if (browser->priv->hide_mouse_timeout != 0) {
g_source_remove (browser->priv->hide_mouse_timeout);
browser->priv->hide_mouse_timeout = 0;
}
}
}
_gth_browser_update_header_section_visibility (browser, GTH_BROWSER_HEADER_SECTION_BROWSER_NAVIGATION, page == GTH_BROWSER_PAGE_BROWSER);
......@@ -2232,14 +2368,14 @@ _gth_browser_real_set_current_page (GthWindow *window,
/* save the browser window size */
if ((prev_page == GTH_BROWSER_PAGE_BROWSER) && ! browser->priv->fullscreen) {
if ((prev_page == GTH_BROWSER_PAGE_BROWSER) && ! (browser->priv->fullscreen || browser->priv->was_fullscreen)) {
gtk_window_get_size (GTK_WINDOW (browser), &width, &height);
gth_window_save_page_size (GTH_WINDOW (browser), prev_page, width, height);
}
/* restore the browser window size */
if (page == GTH_BROWSER_PAGE_BROWSER)
if (page == GTH_BROWSER_PAGE_BROWSER && ! (browser->priv->fullscreen || browser->priv->was_fullscreen))
gth_window_apply_saved_size (GTH_WINDOW (window), page);
/* set the focus */
......@@ -3709,6 +3845,8 @@ gth_browser_init (GthBrowser *browser)
"use-header-bar", TRUE,
NULL);
gtk_widget_add_events (GTK_WIDGET (browser), GDK_POINTER_MOTION_HINT_MASK);
browser->priv = G_TYPE_INSTANCE_GET_PRIVATE (browser, GTH_TYPE_BROWSER, GthBrowserPrivate);
browser->priv->viewer_pages = NULL;
browser->priv->viewer_page = NULL;
......@@ -3747,8 +3885,9 @@ gth_browser_init (GthBrowser *browser)
browser->priv->location_free_space = NULL;
browser->priv->recalc_location_free_space = TRUE;
browser->priv->fullscreen = FALSE;
browser->priv->fullscreen_toolbar = NULL;
browser->priv->was_fullscreen = FALSE;
browser->priv->fullscreen_controls = NULL;
browser->priv->pointer_visible = TRUE;
browser->priv->hide_mouse_timeout = 0;
browser->priv->motion_signal = 0;
browser->priv->last_mouse_x = 0.0;
......@@ -3837,7 +3976,7 @@ gth_browser_init (GthBrowser *browser)
else
gtk_paned_pack2 (GTK_PANED (browser->priv->viewer_thumbnails_pane), browser->priv->viewer_sidebar_pane, TRUE, FALSE);
browser->priv->viewer_container = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
browser->priv->viewer_container = gtk_overlay_new ();
gtk_widget_set_size_request (browser->priv->viewer_container, MIN_VIEWER_SIZE, -1);
gtk_widget_show (browser->priv->viewer_container);
......@@ -3991,6 +4130,23 @@ gth_browser_init (GthBrowser *browser)
NULL);
}
/* fullscreen toolbar */
{
GtkWidget *button;
browser->priv->fullscreen_headerbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign (browser->priv->fullscreen_headerbar, GTK_ALIGN_END);
gtk_widget_set_valign (browser->priv->fullscreen_headerbar, GTK_ALIGN_START);
gtk_overlay_add_overlay (GTK_OVERLAY (browser->priv->viewer_container), browser->priv->fullscreen_headerbar);
button = gtk_button_new_from_icon_name ("view-restore-symbolic", GTK_ICON_SIZE_BUTTON);
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.unfullscreen");
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (browser->priv->fullscreen_headerbar), button, FALSE, FALSE, 0);
}
/* infobar */
browser->priv->infobar = gth_info_bar_new ();
......@@ -5088,7 +5244,11 @@ void
gth_browser_set_viewer_widget (GthBrowser *browser,
GtkWidget *widget)
{
_gtk_container_remove_children (GTK_CONTAINER (browser->priv->viewer_container), NULL, NULL);
GtkWidget *child;
child = gth_browser_get_viewer_widget (browser);
if (child != NULL)
gtk_widget_destroy (child);
if (widget != NULL)
gtk_container_add (GTK_CONTAINER (browser->priv->viewer_container), widget);
}
......@@ -5097,15 +5257,7 @@ gth_browser_set_viewer_widget (GthBrowser *browser,
GtkWidget *
gth_browser_get_viewer_widget (GthBrowser *browser)
{
GtkWidget *child = NULL;
GList *children;
children = gtk_container_get_children (GTK_CONTAINER (browser->priv->viewer_container));
if (children != NULL)
child = children->data;
g_list_free (children);