Skip to content

Commit

Permalink
feat: wrap modules in a revealer to support animated show/hide
Browse files Browse the repository at this point in the history
Resolves #72.
  • Loading branch information
JakeStanger committed Apr 22, 2023
1 parent 1855416 commit 83f44fd
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 19 deletions.
4 changes: 3 additions & 1 deletion src/bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}};
}
Expand Down
62 changes: 51 additions & 11 deletions src/config/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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>,
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -100,20 +128,32 @@ 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| {
send!(tx, success);
})
.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()
}
});
},
);
Expand Down
2 changes: 1 addition & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 5 additions & 1 deletion src/modules/custom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ impl Widget {
fn add_to(self, parent: &gtk::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,
)
};
}

Expand Down
28 changes: 23 additions & 5 deletions src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
}

0 comments on commit 83f44fd

Please sign in to comment.