mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-17 23:01:04 +02:00
feat: ability to add custom modules instead native modules
Resolves #131
This commit is contained in:
parent
42ae915645
commit
994f4a4a12
21 changed files with 497 additions and 252 deletions
|
@ -9,14 +9,15 @@ use self::image::ImageWidget;
|
|||
use self::label::LabelWidget;
|
||||
use self::r#box::BoxWidget;
|
||||
use self::slider::SliderWidget;
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, ModuleConfig};
|
||||
use crate::modules::custom::button::ButtonWidget;
|
||||
use crate::modules::custom::progress::ProgressWidget;
|
||||
use crate::modules::{
|
||||
wrap_widget, Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext,
|
||||
wrap_widget, AnyModuleFactory, BarModuleFactory, Module, ModuleInfo, ModuleParts, ModulePopup,
|
||||
ModuleUpdateEvent, PopupButton, PopupModuleFactory, WidgetContext,
|
||||
};
|
||||
use crate::script::Script;
|
||||
use crate::{send_async, spawn};
|
||||
use crate::{module_impl, send_async, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, IconTheme, Orientation};
|
||||
|
@ -40,11 +41,18 @@ pub struct CustomModule {
|
|||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct WidgetConfig {
|
||||
#[serde(flatten)]
|
||||
widget: Widget,
|
||||
widget: WidgetOrModule,
|
||||
#[serde(flatten)]
|
||||
common: CommonConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub enum WidgetOrModule {
|
||||
Widget(Widget),
|
||||
Module(ModuleConfig),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum Widget {
|
||||
|
@ -58,10 +66,12 @@ pub enum Widget {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct CustomWidgetContext<'a> {
|
||||
info: &'a ModuleInfo<'a>,
|
||||
tx: &'a mpsc::Sender<ExecEvent>,
|
||||
bar_orientation: Orientation,
|
||||
icon_theme: &'a IconTheme,
|
||||
popup_buttons: Rc<RefCell<Vec<Button>>>,
|
||||
module_factory: AnyModuleFactory,
|
||||
}
|
||||
|
||||
trait CustomWidget {
|
||||
|
@ -114,6 +124,19 @@ fn try_get_orientation(orientation: &str) -> Result<Orientation> {
|
|||
}
|
||||
}
|
||||
|
||||
impl WidgetOrModule {
|
||||
fn add_to(self, parent: >k::Box, context: &CustomWidgetContext, common: CommonConfig) {
|
||||
match self {
|
||||
WidgetOrModule::Widget(widget) => widget.add_to(parent, context, common),
|
||||
WidgetOrModule::Module(config) => {
|
||||
if let Err(err) = config.create(&context.module_factory, parent, context.info) {
|
||||
error!("{err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget {
|
||||
/// Creates this widget and adds it to the parent container
|
||||
fn add_to(self, parent: >k::Box, context: &CustomWidgetContext, common: CommonConfig) {
|
||||
|
@ -151,9 +174,7 @@ impl Module<gtk::Box> for CustomModule {
|
|||
type SendMessage = ();
|
||||
type ReceiveMessage = ExecEvent;
|
||||
|
||||
fn name() -> &'static str {
|
||||
"custom"
|
||||
}
|
||||
module_impl!("custom");
|
||||
|
||||
fn spawn_controller(
|
||||
&self,
|
||||
|
@ -191,7 +212,7 @@ impl Module<gtk::Box> for CustomModule {
|
|||
|
||||
fn into_widget(
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
mut context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let orientation = info.bar_position.orientation();
|
||||
|
@ -200,10 +221,13 @@ impl Module<gtk::Box> for CustomModule {
|
|||
let popup_buttons = Rc::new(RefCell::new(Vec::new()));
|
||||
|
||||
let custom_context = CustomWidgetContext {
|
||||
info,
|
||||
tx: &context.controller_tx,
|
||||
bar_orientation: orientation,
|
||||
icon_theme: info.icon_theme,
|
||||
popup_buttons: popup_buttons.clone(),
|
||||
module_factory: BarModuleFactory::new(context.ironbar.clone(), context.popup.clone())
|
||||
.into(),
|
||||
};
|
||||
|
||||
self.bar.clone().into_iter().for_each(|widget| {
|
||||
|
@ -212,8 +236,22 @@ impl Module<gtk::Box> for CustomModule {
|
|||
.add_to(&container, &custom_context, widget.common);
|
||||
});
|
||||
|
||||
for button in popup_buttons.borrow().iter() {
|
||||
button.ensure_popup_id();
|
||||
}
|
||||
|
||||
context.button_id = popup_buttons
|
||||
.borrow()
|
||||
.first()
|
||||
.map_or(usize::MAX, |button| button.popup_id());
|
||||
|
||||
let popup = self
|
||||
.into_popup(context.controller_tx.clone(), context.subscribe(), info)
|
||||
.into_popup(
|
||||
context.controller_tx.clone(),
|
||||
context.subscribe(),
|
||||
context,
|
||||
info,
|
||||
)
|
||||
.into_popup_parts_owned(popup_buttons.take());
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
@ -226,6 +264,7 @@ impl Module<gtk::Box> for CustomModule {
|
|||
self,
|
||||
tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||
_rx: broadcast::Receiver<Self::SendMessage>,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Option<gtk::Box>
|
||||
where
|
||||
|
@ -235,10 +274,17 @@ impl Module<gtk::Box> for CustomModule {
|
|||
|
||||
if let Some(popup) = self.popup {
|
||||
let custom_context = CustomWidgetContext {
|
||||
info,
|
||||
tx: &tx,
|
||||
bar_orientation: info.bar_position.orientation(),
|
||||
icon_theme: info.icon_theme,
|
||||
popup_buttons: Rc::new(RefCell::new(vec![])),
|
||||
module_factory: PopupModuleFactory::new(
|
||||
context.ironbar,
|
||||
context.popup,
|
||||
context.button_id,
|
||||
)
|
||||
.into(),
|
||||
};
|
||||
|
||||
for widget in popup {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue