Commit ba583366 authored by Felix Häcker's avatar Felix Häcker

Optimize window layout, implement new bottom toolbar player

parent 97646c2a
......@@ -55,8 +55,8 @@
"sources" : [
{
"type" : "git",
"url" : "https://source.puri.sm/Librem5/libhandy.git",
"commit" : "2d777677352d037b6f5cc24d9c1c8d9a74ac0ded"
"url" : "https://source.puri.sm/exalm/libhandy.git",
"commit" : "29e97a4ffeac522f34040ba082b43419c597ecf5"
}
]
},
......
......@@ -12,7 +12,8 @@
<file compressed="true" preprocess="xml-stripblanks">gtk/notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/song_listbox.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/song_row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/gtk_controller.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/sidebar_controller.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/mini_controller.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/station_dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/tile_button.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/search.ui</file>
......
......@@ -4,6 +4,7 @@
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkBox" id="library">
<property name="width_request">350</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkBox" id="mini_controller">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="spacing">3</property>
<child>
<object class="GtkButton" id="show_player_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="margin_right">6</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-more-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="action_revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="transition_type">slide-left</property>
<child>
<object class="GtkStack" id="playback_button_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="stop_playback_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-stop-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="name">stop_playback</property>
</packing>
</child>
<child>
<object class="GtkButton" id="loading_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="active">True</property>
</object>
</child>
</object>
<packing>
<property name="name">loading</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="start_playback_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-start-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="name">start_playback</property>
<property name="position">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkImage" id="favicon_image">
<property name="width_request">46</property>
<property name="height_request">46</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="pixel_size">24</property>
<property name="icon_name">emblem-music-symbolic</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="title_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">No playback</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="subtitle_revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="subtitle_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">subtitle</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</interface>
......@@ -65,7 +65,7 @@
</object>
</child>
</object>
<object class="GtkBox" id="gtk_controller">
<object class="GtkBox" id="sidebar_controller">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
......
......@@ -4,6 +4,7 @@
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkBox" id="storefront">
<property name="width_request">350</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
......@@ -87,21 +88,7 @@
</packing>
</child>
<child>
<object class="GtkLabel" id="leaflet_width_breakpoint">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes"> </property>
<property name="ellipsize">start</property>
<style>
<class name="hide"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
<placeholder/>
</child>
</object>
<packing>
......
......@@ -9,174 +9,125 @@
<property name="default_height">600</property>
<property name="icon_name">de.haeckerfelix.Shortwave</property>
<child type="titlebar">
<object class="HdyTitleBar">
<object class="GtkHeaderBar" id="view_headerbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="show_close_button">True</property>
<child>
<object class="HdyLeaflet" id="header_leaflet">
<object class="GtkButton" id="add_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="back_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child type="title">
<object class="GtkStack" id="header_switcher_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="mode_transition_type">slide</property>
<property name="child_transition_type">crossfade</property>
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<property name="interpolate_size">True</property>
<child>
<object class="GtkHeaderBar" id="view_headerbar">
<object class="HdyViewSwitcher" id="discover_header_switcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton" id="add_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="back_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="title">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkStack" id="header_switcher_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<property name="interpolate_size">True</property>
<child>
<object class="HdyViewSwitcher" id="discover_header_switcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="narrow_ellipsize">end</property>
</object>
<packing>
<property name="name">discover</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="app_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="label">Shortwave</property>
<style>
<class name="title"/>
</style>
</object>
<packing>
<property name="name">main</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="appmenu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">open-menu-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
<property name="halign">center</property>
<property name="narrow_ellipsize">end</property>
</object>
<packing>
<property name="name">content</property>
<property name="name">discover</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<object class="GtkLabel" id="app_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="label">Shortwave</property>
<style>
<class name="sidebar"/>
<class name="vertical"/>
<class name="title"/>
</style>
</object>
<packing>
<property name="name">main</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="appmenu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkHeaderBar" id="sidebar_headerbar">
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Playback</property>
<property name="show_close_button">True</property>
<child>
<placeholder/>
</child>
<property name="icon_name">open-menu-symbolic</property>
</object>
<packing>
<property name="name">playback</property>
</packing>
</child>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkOverlay" id="overlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="width_request">350</property>
<property name="height_request">400</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="HdyLeaflet" id="content_leaflet">
<object class="HdyLeaflet" id="leaflet">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="mode_transition_type">slide</property>
<property name="child_transition_type">crossfade</property>
<property name="child_transition_type">over</property>
<property name="can_swipe_back">True</property>
<property name="can_swipe_forward">True</property>
<child>
<object class="GtkStack" id="view_stack">
<property name="visible">True</property>
......@@ -214,29 +165,12 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="stack_player_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="width_request">350</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="name">playback</property>
<property name="title" translatable="yes">Playback</property>
<property name="icon_name">emblem-music-symbolic</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">content</property>
</packing>
</child>
<child>
<child type="separator">
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
......@@ -252,7 +186,7 @@
<property name="vexpand">False</property>
<property name="maximum_width">400</property>
<child>
<object class="GtkBox" id="sidebar_player_box">
<object class="GtkBox" id="player_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
......@@ -263,7 +197,7 @@
</child>
</object>
<packing>
<property name="name">playback</property>
<property name="name">player</property>
</packing>
</child>
</object>
......@@ -284,24 +218,48 @@
<property name="can_focus">False</property>
<property name="transition_type">crossfade</property>
<child>
<object class="HdyViewSwitcherBar" id="main_bottom_switcher">
<object class="HdyViewSwitcherBar" id="discover_bottom_switcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stack">view_stack</property>
<property name="reveal">True</property>
</object>
<packing>
<property name="name">main</property>
<property name="name">discover</property>
</packing>
</child>
<child>
<object class="HdyViewSwitcherBar" id="discover_bottom_switcher">
<object class="GtkBox" id="mini_controller">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="reveal">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="mini_controller_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">discover</property>
<property name="name">main</property>
<property name="position">1</property>
</packing>
</child>
......@@ -322,22 +280,4 @@
</object>
</child>
</object>
<object class="HdyHeaderGroup">
<headerbars>
<headerbar name="view_headerbar"/>
<headerbar name="sidebar_headerbar"/>
</headerbars>
</object>
<object class="GtkSizeGroup" id="sidebar_stackgroup">
<widgets>
<widget name="sidebar_headerbar"/>
<widget name="sidebar_column"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="view_stackgroup">
<widgets>
<widget name="view_headerbar"/>
<widget name="view_stack"/>
</widgets>
</object>
</interface>
......@@ -22,6 +22,7 @@ use crate::utils::{Order, Sorting};
pub enum Action {
ViewShowDiscover,
ViewShowLibrary,
ViewShowPlayer,
ViewShowNotification(String),
ViewRaise,
ViewSetSorting(Sorting, Order),
......@@ -62,7 +63,8 @@ impl App {
let library = Library::new(sender.clone());
let storefront = StoreFront::new(sender.clone());
window.sidebar_player_box.add(&player.widget);
window.player_box.add(&player.widget);
window.mini_controller_box.add(&player.mini_controller_widget);
window.library_box.add(&library.widget);
window.discover_box.add(&storefront.widget);
window.set_view(View::Library);
......@@ -200,6 +202,7 @@ impl App {
match action {
Action::ViewShowDiscover => self.window.set_view(View::Discover),
Action::ViewShowLibrary => self.window.set_view(View::Library),
Action::ViewShowPlayer => self.window.set_view(View::Player),
Action::ViewRaise => self.window.widget.present_with_time((glib::get_monotonic_time() / 1000) as u32),
Action::ViewShowNotification(text) => self.window.show_notification(text),
Action::ViewSetSorting(sorting, order) => self.library.set_sorting(sorting, order),
......
use glib::Sender;
use gtk::prelude::*;
use std::cell::RefCell;
use std::rc::Rc;
use crate::api::Station;
use crate::app::Action;
use crate::audio::Controller;
use crate::audio::PlaybackState;
pub struct MiniController {
pub widget: gtk::Box,
sender: Sender<Action>,
station: Rc<RefCell<Option<Station>>>,
title_label: gtk::Label,
subtitle_label: gtk::Label,
subtitle_revealer: gtk::Revealer,
action_revealer: gtk::Revealer,
playback_button_stack: gtk::Stack,
start_playback_button: gtk::Button,
stop_playback_button: gtk::Button,
show_player_button: gtk::Button,
}
impl MiniController {
pub fn new(sender: Sender<Action>) -> Self {
let builder = gtk::Builder::new_from_resource("/de/haeckerfelix/Shortwave/gtk/mini_controller.ui");
let station = Rc::new(RefCell::new(None));
let widget: gtk::Box = builder.get_object("mini_controller").unwrap();
let title_label: gtk::Label = builder.get_object("title_label").unwrap();
let subtitle_label: gtk::Label = builder.get_object("subtitle_label").unwrap();
let subtitle_revealer: gtk::Revealer = builder.get_object("subtitle_revealer").unwrap();
let action_revealer: gtk::Revealer = builder.get_object("action_revealer").unwrap();
let playback_button_stack: gtk::Stack = builder.get_object("playback_button_stack").unwrap();
let start_playback_button: gtk::Button = builder.get_object("start_playback_button").unwrap();
let stop_playback_button: gtk::Button = builder.get_object("stop_playback_button").unwrap();
let show_player_button: gtk::Button = builder.get_object("show_player_button").unwrap();
let controller = Self {
widget,
sender,
station,
title_label,
subtitle_label,
action_revealer,
subtitle_revealer,
playback_button_stack,
start_playback_button,
stop_playback_button,
show_player_button,