mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-04-19 19:34:24 +02:00
feat: wrap modules in a revealer to support animated show/hide
Resolves #72.
This commit is contained in:
parent
1855416db4
commit
83f44fd92f
5 changed files with 83 additions and 19 deletions
|
@ -190,11 +190,13 @@ fn add_modules(
|
|||
let popup = Popup::new(info, popup_gap);
|
||||
let popup = Arc::new(RwLock::new(popup));
|
||||
|
||||
let orientation = info.bar_position.get_orientation();
|
||||
|
||||
macro_rules! add_module {
|
||||
($module:expr, $id:expr) => {{
|
||||
let common = $module.common.take().expect("Common config did not exist");
|
||||
let widget = create_module(*$module, $id, &info, &Arc::clone(&popup))?;
|
||||
let container = wrap_widget(&widget, common);
|
||||
let container = wrap_widget(&widget, common, orientation);
|
||||
content.add(&container);
|
||||
}};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::script::{Script, ScriptInput};
|
|||
use crate::send;
|
||||
use gtk::gdk::ScrollDirection;
|
||||
use gtk::prelude::*;
|
||||
use gtk::EventBox;
|
||||
use gtk::{EventBox, Orientation, Revealer, RevealerTransitionType};
|
||||
use serde::Deserialize;
|
||||
use tokio::spawn;
|
||||
use tracing::trace;
|
||||
|
@ -13,6 +13,8 @@ use tracing::trace;
|
|||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct CommonConfig {
|
||||
pub show_if: Option<ScriptInput>,
|
||||
pub transition_type: Option<TransitionType>,
|
||||
pub transition_duration: Option<u32>,
|
||||
|
||||
pub on_click_left: Option<ScriptInput>,
|
||||
pub on_click_right: Option<ScriptInput>,
|
||||
|
@ -25,10 +27,36 @@ pub struct CommonConfig {
|
|||
pub tooltip: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TransitionType {
|
||||
None,
|
||||
Crossfade,
|
||||
SlideStart,
|
||||
SlideEnd,
|
||||
}
|
||||
|
||||
impl TransitionType {
|
||||
pub fn to_revealer_transition_type(&self, orientation: Orientation) -> RevealerTransitionType {
|
||||
match (self, orientation) {
|
||||
(TransitionType::SlideStart, Orientation::Horizontal) => {
|
||||
RevealerTransitionType::SlideLeft
|
||||
}
|
||||
(TransitionType::SlideStart, Orientation::Vertical) => RevealerTransitionType::SlideUp,
|
||||
(TransitionType::SlideEnd, Orientation::Horizontal) => {
|
||||
RevealerTransitionType::SlideRight
|
||||
}
|
||||
(TransitionType::SlideEnd, Orientation::Vertical) => RevealerTransitionType::SlideDown,
|
||||
(TransitionType::Crossfade, _) => RevealerTransitionType::Crossfade,
|
||||
_ => RevealerTransitionType::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CommonConfig {
|
||||
/// Configures the module's container according to the common config options.
|
||||
pub fn install(mut self, container: &EventBox) {
|
||||
self.install_show_if(container);
|
||||
pub fn install(mut self, container: &EventBox, revealer: &Revealer) {
|
||||
self.install_show_if(container, revealer);
|
||||
|
||||
let left_click_script = self.on_click_left.map(Script::new_polling);
|
||||
let middle_click_script = self.on_click_middle.map(Script::new_polling);
|
||||
|
@ -91,7 +119,7 @@ impl CommonConfig {
|
|||
}
|
||||
}
|
||||
|
||||
fn install_show_if(&mut self, container: &EventBox) {
|
||||
fn install_show_if(&mut self, container: &EventBox, revealer: &Revealer) {
|
||||
self.show_if.take().map_or_else(
|
||||
|| {
|
||||
container.show_all();
|
||||
|
@ -100,6 +128,7 @@ impl CommonConfig {
|
|||
let script = Script::new_polling(show_if);
|
||||
let container = container.clone();
|
||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||
|
||||
spawn(async move {
|
||||
script
|
||||
.run(None, |_, success| {
|
||||
|
@ -107,13 +136,24 @@ impl CommonConfig {
|
|||
})
|
||||
.await;
|
||||
});
|
||||
rx.attach(None, move |success| {
|
||||
if success {
|
||||
container.show_all();
|
||||
} else {
|
||||
container.hide();
|
||||
};
|
||||
Continue(true)
|
||||
|
||||
{
|
||||
let revealer = revealer.clone();
|
||||
let container = container.clone();
|
||||
|
||||
rx.attach(None, move |success| {
|
||||
if success {
|
||||
container.show_all();
|
||||
}
|
||||
revealer.set_reveal_child(success);
|
||||
Continue(true)
|
||||
});
|
||||
}
|
||||
|
||||
revealer.connect_child_revealed_notify(move |revealer| {
|
||||
if !revealer.reveals_child() {
|
||||
container.hide()
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::modules::workspaces::WorkspacesModule;
|
|||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub use self::common::CommonConfig;
|
||||
pub use self::common::{CommonConfig, TransitionType};
|
||||
pub use self::truncate::{EllipsizeMode, TruncateMode};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
|
|
|
@ -120,7 +120,11 @@ impl Widget {
|
|||
fn add_to(self, parent: >k::Box, context: CustomWidgetContext, common: CommonConfig) {
|
||||
macro_rules! create {
|
||||
($widget:expr) => {
|
||||
wrap_widget(&$widget.into_widget(context), common)
|
||||
wrap_widget(
|
||||
&$widget.into_widget(context),
|
||||
common,
|
||||
context.bar_orientation,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -23,14 +23,14 @@ pub mod tray;
|
|||
pub mod workspaces;
|
||||
|
||||
use crate::bridge_channel::BridgeChannel;
|
||||
use crate::config::{BarPosition, CommonConfig};
|
||||
use crate::config::{BarPosition, CommonConfig, TransitionType};
|
||||
use crate::popup::{Popup, WidgetGeometry};
|
||||
use crate::{read_lock, send, write_lock};
|
||||
use color_eyre::Result;
|
||||
use glib::IsA;
|
||||
use gtk::gdk::{EventMask, Monitor};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Application, EventBox, IconTheme, Widget};
|
||||
use gtk::{Application, EventBox, IconTheme, Orientation, Revealer, Widget};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::debug;
|
||||
|
@ -234,12 +234,30 @@ fn setup_receiver<TSend>(
|
|||
|
||||
/// Takes a widget and adds it into a new `gtk::EventBox`.
|
||||
/// The event box container is returned.
|
||||
pub fn wrap_widget<W: IsA<Widget>>(widget: &W, common: CommonConfig) -> EventBox {
|
||||
pub fn wrap_widget<W: IsA<Widget>>(
|
||||
widget: &W,
|
||||
common: CommonConfig,
|
||||
orientation: Orientation,
|
||||
) -> EventBox {
|
||||
let revealer = Revealer::builder()
|
||||
.transition_type(
|
||||
common
|
||||
.transition_type
|
||||
.as_ref()
|
||||
.unwrap_or(&TransitionType::SlideStart)
|
||||
.to_revealer_transition_type(orientation),
|
||||
)
|
||||
.transition_duration(common.transition_duration.unwrap_or(250))
|
||||
.build();
|
||||
|
||||
revealer.add(widget);
|
||||
revealer.set_reveal_child(true);
|
||||
|
||||
let container = EventBox::new();
|
||||
container.add_events(EventMask::SCROLL_MASK);
|
||||
container.add(widget);
|
||||
container.add(&revealer);
|
||||
|
||||
common.install(&container);
|
||||
common.install(&container, &revealer);
|
||||
|
||||
container
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue