[fractal/clippy-ci: 4/25] Improve styling of videos in media viewer



commit 2b616197028b2f0db275c8ba7c725cd6fef47edf
Author: Sonja Heinze <sonjaleaheinze gmail com>
Date:   Mon Feb 10 19:47:13 2020 +0100

    Improve styling of videos in media viewer
    
    This commit implements the design/styling improvement ideas of issue #581
    that concern the video player in the media viewer.

 fractal-gtk/res/app.css                  | 11 ++++
 fractal-gtk/src/widgets/inline_player.rs | 88 +++++++++++++++++++++-----------
 fractal-gtk/src/widgets/media_viewer.rs  | 76 ++++++++++++++++++++-------
 3 files changed, 128 insertions(+), 47 deletions(-)
---
diff --git a/fractal-gtk/res/app.css b/fractal-gtk/res/app.css
index 95ada2da..39c2ac67 100644
--- a/fractal-gtk/res/app.css
+++ b/fractal-gtk/res/app.css
@@ -215,6 +215,17 @@ row .timestamp {
     padding-left: 6px;
 }
 
+/** media viewer **/
+.fullscreen-control-box {
+  background-color: rgba(0,0,0,.8);
+  padding: 12;
+}
+
+.window-control-box {
+  background-color: rgba(0,0,0,.6);
+  padding: 6;
+}
+
 /** autocomplete popover **/
 .autocomplete {
   margin-left: 150px;
diff --git a/fractal-gtk/src/widgets/inline_player.rs b/fractal-gtk/src/widgets/inline_player.rs
index 00adff24..063f8d92 100644
--- a/fractal-gtk/src/widgets/inline_player.rs
+++ b/fractal-gtk/src/widgets/inline_player.rs
@@ -371,9 +371,8 @@ impl VideoPlayerWidget {
         });
     }
 
-    pub fn auto_adjust_widget_to_video_dimensions<T: IsA<gtk::Widget>>(
+    pub fn auto_adjust_box_size_to_video_dimensions(
         bx: &gtk::Box,
-        widget: &T,
         player: &Rc<VideoPlayerWidget>,
     ) -> (glib::SignalHandlerId, glib::SignalHandlerId) {
         /* When gtk allocates a different size to the video widget than its minimal preferred size
@@ -381,16 +380,9 @@ impl VideoPlayerWidget {
         When that happens and furthermore, the video widget is embedded in a vertically oriented box,
         this function here can be called. Here, the widget's height gets adjusted as a consequence of
         adjusting the distance between the top/bottom of the widget and the top/bottom of the box,
-        rather than through the widget's preferred height. Adjusting those distances through the
-        spacing instead of margins has the advantage that the top and bottom distance get adjusted
-        at the same time. */
-
-        let top_box = gtk::Box::new(gtk::Orientation::Vertical, 6);
-        bx.pack_start(&top_box, true, true, 0);
-        let bottom_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
-        bx.pack_start(&bottom_box, true, true, 0);
-        bx.reorder_child(widget, 1);
-        /* The followign callbacks requires `Send` but is handled by the gtk main loop */
+        rather than through the widget's preferred height. */
+
+        /* The followign callback requires `Send` but is handled by the gtk main loop */
         let dimensions_weak = Fragile::new(Rc::downgrade(&player.dimensions));
         let bx_weak = Fragile::new(bx.downgrade());
         let dimension_id =
@@ -401,17 +393,25 @@ impl VideoPlayerWidget {
                         *dimensions.borrow_mut() = Some((video_width, video_height));
                     });
                     bx_weak.get().upgrade().map(|bx| {
-                        adjust_box_spacing_to_video_dimensions(&bx, video_width, video_height);
+                        adjust_box_margins_to_video_dimensions(&bx, video_width, video_height);
                     });
                 });
         let player_weak = Rc::downgrade(player);
-        let size_id = bx.connect_size_allocate(move |bx, _| {
-            player_weak.upgrade().map(|player| {
+        let size_id =
+            bx.connect_size_allocate(move |bx, _| {
+                player_weak.upgrade().map(|player| {
                 if let Some((video_width, video_height)) = *player.dimensions.borrow() {
-                    adjust_box_spacing_to_video_dimensions(&bx, video_width, video_height);
+                    /* The timeout is necessary for the edge cases, i.e. when resizing to minimum width or 
height.
+                    When approaching the minimum fast, the last connect_size_allocate signal gets emitted 
before
+                    reaching the minimum size. So without timeout, the values used to adjust the the video 
size
+                    are bigger than they should be. */
+                    gtk::timeout_add(50, clone!(bx, video_width, video_height => move || {
+                        adjust_box_margins_to_video_dimensions(&bx, video_width, video_height);
+                        Continue(false)
+                    }));
                 }
             });
-        });
+            });
         (dimension_id, size_id)
     }
 
@@ -565,13 +565,17 @@ impl<T: MediaPlayer + 'static> PlayerExt for T {
         let player = player_widget.get_player();
         if player.get_mute() {
             player.set_mute(false);
-            let image =
-                gtk::Image::new_from_icon_name(Some("audio-volume-high"), gtk::IconSize::Button);
+            let image = gtk::Image::new_from_icon_name(
+                Some("audio-volume-high-symbolic"),
+                gtk::IconSize::Button,
+            );
             button.set_image(Some(&image));
         } else {
             player.set_mute(true);
-            let image =
-                gtk::Image::new_from_icon_name(Some("audio-volume-muted"), gtk::IconSize::Button);
+            let image = gtk::Image::new_from_icon_name(
+                Some("audio-volume-muted-symbolic"),
+                gtk::IconSize::Button,
+            );
             button.set_image(Some(&image));
         }
     }
@@ -665,14 +669,40 @@ fn connect_update_slider(slider: &gtk::Scale, player: &gst_player::Player) -> Si
     }))
 }
 
-fn adjust_box_spacing_to_video_dimensions(bx: &gtk::Box, video_width: i32, video_height: i32) {
-    if video_width != 0 {
-        let current_width = bx.get_allocated_width();
-        let adjusted_height = current_width * video_height / video_width;
-        if let Some(scrolled_window) = bx.get_parent().and_then(|viewport| viewport.get_parent()) {
-            let height_visible_area = scrolled_window.get_allocated_height();
-            let margin = (height_visible_area - adjusted_height) / 2;
-            bx.set_spacing(margin);
+fn adjust_box_margins_to_video_dimensions(bx: &gtk::Box, video_width: i32, video_height: i32) {
+    if let Some(parent) = bx.get_parent() {
+        let parent_height = parent.get_allocated_height();
+        let parent_width = parent.get_allocated_width();
+        if video_height * parent_width >= parent_height * video_width
+            && parent_height < video_height
+        {
+            if video_height != 0 {
+                let adjusted_width = if parent_height < video_height {
+                    let box_height = bx.get_allocated_height();
+                    box_height * video_width / video_height
+                } else {
+                    video_width
+                };
+                let margin = (parent_width - adjusted_width) / 2;
+                bx.set_margin_start(margin);
+                bx.set_margin_end(margin);
+                bx.set_margin_top(0);
+                bx.set_margin_bottom(0);
+            }
+        } else {
+            if video_width != 0 {
+                let adjusted_height = if parent_width < video_width {
+                    let box_width = bx.get_allocated_width();
+                    box_width * video_height / video_width
+                } else {
+                    video_height
+                };
+                let margin = (parent_height - adjusted_height) / 2;
+                bx.set_margin_top(margin);
+                bx.set_margin_bottom(margin);
+                bx.set_margin_start(0);
+                bx.set_margin_end(0);
+            }
         }
     }
 }
diff --git a/fractal-gtk/src/widgets/media_viewer.rs b/fractal-gtk/src/widgets/media_viewer.rs
index bf389abe..93ea8064 100644
--- a/fractal-gtk/src/widgets/media_viewer.rs
+++ b/fractal-gtk/src/widgets/media_viewer.rs
@@ -55,34 +55,64 @@ impl VideoWidget {
             self.player.get_player().disconnect(dimension_id);
             self.outer_box.disconnect(size_id);
         }
-        self.outer_box.set_margin_start(0);
-        self.outer_box.set_margin_end(0);
-        self.outer_box.foreach(|widget| {
-            self.outer_box.remove(widget);
-        });
-        self.outer_box.pack_start(&self.inner_box, true, true, 0);
+
+        self.outer_box
+            .set_child_packing(&self.inner_box, true, true, 0, gtk::PackType::Start);
 
         self.inner_box.set_valign(gtk::Align::Fill);
         self.inner_box.set_halign(gtk::Align::Fill);
+
+        let bx = self.outer_box.clone();
+        gtk::timeout_add(50, move || {
+            bx.set_margin_top(0);
+            bx.set_margin_bottom(0);
+            Continue(false)
+        });
+
+        for widget in self.inner_box.get_children() {
+            if widget.is::<gtk::Revealer>() {
+                let control_box = widget
+                    .downcast::<gtk::Revealer>()
+                    .unwrap()
+                    .get_child()
+                    .expect("The control box has to be added to the control box reavealer.");
+                control_box
+                    .get_style_context()
+                    .remove_class("window-control-box");
+                control_box
+                    .get_style_context()
+                    .add_class("fullscreen-control-box");
+            }
+        }
     }
 
     fn set_window_mode(&mut self) {
-        self.outer_box.set_margin_start(70);
-        self.outer_box.set_margin_end(70);
-
-        self.outer_box.foreach(|widget| {
-            self.outer_box.remove(widget);
-        });
-        self.outer_box.pack_start(&self.inner_box, false, false, 0);
+        self.outer_box
+            .set_child_packing(&self.inner_box, false, false, 0, gtk::PackType::Start);
 
         self.inner_box.set_valign(gtk::Align::Center);
         self.inner_box.set_halign(gtk::Align::Center);
-        let ids = VideoPlayerWidget::auto_adjust_widget_to_video_dimensions(
+        let ids = VideoPlayerWidget::auto_adjust_box_size_to_video_dimensions(
             &self.outer_box,
-            &self.inner_box,
             &self.player,
         );
         self.auto_adjust_ids = Some(ids);
+
+        for widget in self.inner_box.get_children() {
+            if widget.is::<gtk::Revealer>() {
+                let control_box = widget
+                    .downcast::<gtk::Revealer>()
+                    .unwrap()
+                    .get_child()
+                    .expect("The control box reavealer has to contain the control box.");
+                control_box
+                    .get_style_context()
+                    .remove_class("fullscreen-control-box");
+                control_box
+                    .get_style_context()
+                    .add_class("window-control-box");
+            }
+        }
     }
 }
 
@@ -383,12 +413,22 @@ impl Data {
         let overlay = Overlay::new();
         overlay.add(&player.get_video_widget());
 
-        let full_control_box = gtk::Box::new(gtk::Orientation::Horizontal, 6);
+        let full_control_box = gtk::Box::new(gtk::Orientation::Horizontal, 12);
+        if self.is_fullscreen {
+            full_control_box
+                .get_style_context()
+                .add_class("fullscreen-control-box");
+        } else {
+            full_control_box
+                .get_style_context()
+                .add_class("window-control-box");
+        }
+
         let control_box = PlayerExt::get_controls_container(&player).unwrap();
         full_control_box.pack_start(&control_box, false, true, 0);
 
         let mute_button = gtk::Button::new_from_icon_name(
-            Some("audio-volume-high"),
+            Some("audio-volume-high-symbolic"),
             gtk::IconSize::Button.into(),
         );
         let player_weak = Rc::downgrade(&player);
@@ -397,7 +437,7 @@ impl Data {
                 VideoPlayerWidget::switch_mute_state(&player, &button);
             });
         });
-        full_control_box.pack_start(&mute_button, false, false, 3);
+        full_control_box.pack_start(&mute_button, false, false, 0);
 
         let control_revealer = gtk::Revealer::new();
         control_revealer.add(&full_control_box);


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