mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-01 02:31:04 +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 = Popup::new(info, popup_gap);
|
||||||
let popup = Arc::new(RwLock::new(popup));
|
let popup = Arc::new(RwLock::new(popup));
|
||||||
|
|
||||||
|
let orientation = info.bar_position.get_orientation();
|
||||||
|
|
||||||
macro_rules! add_module {
|
macro_rules! add_module {
|
||||||
($module:expr, $id:expr) => {{
|
($module:expr, $id:expr) => {{
|
||||||
let common = $module.common.take().expect("Common config did not exist");
|
let common = $module.common.take().expect("Common config did not exist");
|
||||||
let widget = create_module(*$module, $id, &info, &Arc::clone(&popup))?;
|
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);
|
content.add(&container);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::script::{Script, ScriptInput};
|
||||||
use crate::send;
|
use crate::send;
|
||||||
use gtk::gdk::ScrollDirection;
|
use gtk::gdk::ScrollDirection;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::EventBox;
|
use gtk::{EventBox, Orientation, Revealer, RevealerTransitionType};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
@ -13,6 +13,8 @@ use tracing::trace;
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct CommonConfig {
|
pub struct CommonConfig {
|
||||||
pub show_if: Option<ScriptInput>,
|
pub show_if: Option<ScriptInput>,
|
||||||
|
pub transition_type: Option<TransitionType>,
|
||||||
|
pub transition_duration: Option<u32>,
|
||||||
|
|
||||||
pub on_click_left: Option<ScriptInput>,
|
pub on_click_left: Option<ScriptInput>,
|
||||||
pub on_click_right: Option<ScriptInput>,
|
pub on_click_right: Option<ScriptInput>,
|
||||||
|
@ -25,10 +27,36 @@ pub struct CommonConfig {
|
||||||
pub tooltip: Option<String>,
|
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 {
|
impl CommonConfig {
|
||||||
/// Configures the module's container according to the common config options.
|
/// Configures the module's container according to the common config options.
|
||||||
pub fn install(mut self, container: &EventBox) {
|
pub fn install(mut self, container: &EventBox, revealer: &Revealer) {
|
||||||
self.install_show_if(container);
|
self.install_show_if(container, revealer);
|
||||||
|
|
||||||
let left_click_script = self.on_click_left.map(Script::new_polling);
|
let left_click_script = self.on_click_left.map(Script::new_polling);
|
||||||
let middle_click_script = self.on_click_middle.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(
|
self.show_if.take().map_or_else(
|
||||||
|| {
|
|| {
|
||||||
container.show_all();
|
container.show_all();
|
||||||
|
@ -100,6 +128,7 @@ impl CommonConfig {
|
||||||
let script = Script::new_polling(show_if);
|
let script = Script::new_polling(show_if);
|
||||||
let container = container.clone();
|
let container = container.clone();
|
||||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||||
|
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
script
|
script
|
||||||
.run(None, |_, success| {
|
.run(None, |_, success| {
|
||||||
|
@ -107,13 +136,24 @@ impl CommonConfig {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
});
|
});
|
||||||
rx.attach(None, move |success| {
|
|
||||||
if success {
|
{
|
||||||
container.show_all();
|
let revealer = revealer.clone();
|
||||||
} else {
|
let container = container.clone();
|
||||||
container.hide();
|
|
||||||
};
|
rx.attach(None, move |success| {
|
||||||
Continue(true)
|
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 serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use self::common::CommonConfig;
|
pub use self::common::{CommonConfig, TransitionType};
|
||||||
pub use self::truncate::{EllipsizeMode, TruncateMode};
|
pub use self::truncate::{EllipsizeMode, TruncateMode};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
|
|
@ -120,7 +120,11 @@ impl Widget {
|
||||||
fn add_to(self, parent: >k::Box, context: CustomWidgetContext, common: CommonConfig) {
|
fn add_to(self, parent: >k::Box, context: CustomWidgetContext, common: CommonConfig) {
|
||||||
macro_rules! create {
|
macro_rules! create {
|
||||||
($widget:expr) => {
|
($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;
|
pub mod workspaces;
|
||||||
|
|
||||||
use crate::bridge_channel::BridgeChannel;
|
use crate::bridge_channel::BridgeChannel;
|
||||||
use crate::config::{BarPosition, CommonConfig};
|
use crate::config::{BarPosition, CommonConfig, TransitionType};
|
||||||
use crate::popup::{Popup, WidgetGeometry};
|
use crate::popup::{Popup, WidgetGeometry};
|
||||||
use crate::{read_lock, send, write_lock};
|
use crate::{read_lock, send, write_lock};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use glib::IsA;
|
use glib::IsA;
|
||||||
use gtk::gdk::{EventMask, Monitor};
|
use gtk::gdk::{EventMask, Monitor};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Application, EventBox, IconTheme, Widget};
|
use gtk::{Application, EventBox, IconTheme, Orientation, Revealer, Widget};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
@ -234,12 +234,30 @@ fn setup_receiver<TSend>(
|
||||||
|
|
||||||
/// Takes a widget and adds it into a new `gtk::EventBox`.
|
/// Takes a widget and adds it into a new `gtk::EventBox`.
|
||||||
/// The event box container is returned.
|
/// 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();
|
let container = EventBox::new();
|
||||||
container.add_events(EventMask::SCROLL_MASK);
|
container.add_events(EventMask::SCROLL_MASK);
|
||||||
container.add(widget);
|
container.add(&revealer);
|
||||||
|
|
||||||
common.install(&container);
|
common.install(&container, &revealer);
|
||||||
|
|
||||||
container
|
container
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue