feat(applets): configurable applet overlap and padding increases
This commit is contained in:
parent
2c93a4094f
commit
2296e8e94d
5 changed files with 1135 additions and 61 deletions
|
|
@ -1,13 +1,14 @@
|
|||
#[cfg(feature = "applet-token")]
|
||||
pub mod token;
|
||||
|
||||
use crate::app::cosmic;
|
||||
use crate::{
|
||||
Application, Element, Renderer,
|
||||
app::iced_settings,
|
||||
cctk::sctk,
|
||||
iced::{
|
||||
self, Color, Length, Limits, Rectangle,
|
||||
alignment::{Horizontal, Vertical},
|
||||
alignment::{Alignment, Horizontal, Vertical},
|
||||
widget::Container,
|
||||
window,
|
||||
},
|
||||
|
|
@ -16,18 +17,24 @@ use crate::{
|
|||
widget::{
|
||||
self,
|
||||
autosize::{self, Autosize, autosize},
|
||||
layer_container,
|
||||
column::Column,
|
||||
horizontal_space, layer_container,
|
||||
row::Row,
|
||||
vertical_space,
|
||||
},
|
||||
};
|
||||
pub use cosmic_panel_config;
|
||||
use cosmic_panel_config::{CosmicPanelBackground, PanelAnchor, PanelSize};
|
||||
use iced_core::{Padding, Shadow};
|
||||
use iced_widget::Text;
|
||||
use iced_widget::runtime::platform_specific::wayland::popup::{SctkPopupSettings, SctkPositioner};
|
||||
use sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{Anchor, Gravity};
|
||||
use std::{borrow::Cow, num::NonZeroU32, rc::Rc, sync::LazyLock, time::Duration};
|
||||
use tracing::info;
|
||||
|
||||
use crate::app::cosmic;
|
||||
pub mod column;
|
||||
pub mod row;
|
||||
|
||||
static AUTOSIZE_ID: LazyLock<iced::id::Id> =
|
||||
LazyLock::new(|| iced::id::Id::new("cosmic-applet-autosize"));
|
||||
static AUTOSIZE_MAIN_ID: LazyLock<iced::id::Id> =
|
||||
|
|
@ -46,6 +53,8 @@ pub struct Context {
|
|||
/// Includes the configured size of the window.
|
||||
/// This can be used by apples to handle overflow themselves.
|
||||
pub suggested_bounds: Option<iced::Size>,
|
||||
/// Ratio of overlap for applet padding.
|
||||
pub padding_overlap: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
@ -104,6 +113,10 @@ impl Default for Context {
|
|||
.unwrap_or(CosmicPanelBackground::ThemeDefault),
|
||||
output_name: std::env::var("COSMIC_PANEL_OUTPUT").unwrap_or_default(),
|
||||
panel_type: PanelType::from(std::env::var("COSMIC_PANEL_NAME").unwrap_or_default()),
|
||||
padding_overlap: str::parse(
|
||||
&std::env::var("COSMIC_PANEL_PADDING_OVERLAP").unwrap_or_default(),
|
||||
)
|
||||
.unwrap_or(0.0),
|
||||
suggested_bounds: None,
|
||||
}
|
||||
}
|
||||
|
|
@ -124,13 +137,19 @@ impl Context {
|
|||
#[must_use]
|
||||
pub fn suggested_window_size(&self) -> (NonZeroU32, NonZeroU32) {
|
||||
let suggested = self.suggested_size(true);
|
||||
let applet_padding = self.suggested_padding(true);
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
|
||||
let configured_width = self
|
||||
.suggested_bounds
|
||||
.as_ref()
|
||||
.and_then(|c| NonZeroU32::new(c.width as u32)) // TODO: should this be physical size instead of logical?
|
||||
.unwrap_or_else(|| {
|
||||
NonZeroU32::new(suggested.0 as u32 + applet_padding as u32 * 2).unwrap()
|
||||
NonZeroU32::new(suggested.0 as u32 + horizontal_padding as u32 * 2).unwrap()
|
||||
});
|
||||
|
||||
let configured_height = self
|
||||
|
|
@ -138,17 +157,20 @@ impl Context {
|
|||
.as_ref()
|
||||
.and_then(|c| NonZeroU32::new(c.height as u32))
|
||||
.unwrap_or_else(|| {
|
||||
NonZeroU32::new(suggested.1 as u32 + applet_padding as u32 * 2).unwrap()
|
||||
NonZeroU32::new(suggested.1 as u32 + vertical_padding as u32 * 2).unwrap()
|
||||
});
|
||||
info!("{configured_height:?}");
|
||||
(configured_width, configured_height)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn suggested_padding(&self, is_symbolic: bool) -> u16 {
|
||||
pub fn suggested_padding(&self, is_symbolic: bool) -> (u16, u16) {
|
||||
match &self.size {
|
||||
Size::PanelSize(size) => size.get_applet_padding(is_symbolic),
|
||||
Size::Hardcoded(_) => 8,
|
||||
Size::PanelSize(size) => (
|
||||
size.get_applet_shrinkable_padding(is_symbolic),
|
||||
size.get_applet_padding(is_symbolic),
|
||||
),
|
||||
Size::Hardcoded(_) => (12, 8),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,9 +182,15 @@ impl Context {
|
|||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn window_settings(&self) -> crate::app::Settings {
|
||||
let (width, height) = self.suggested_size(true);
|
||||
let applet_padding = self.suggested_padding(true);
|
||||
let width = f32::from(width) + applet_padding as f32 * 2.;
|
||||
let height = f32::from(height) + applet_padding as f32 * 2.;
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
|
||||
let width = f32::from(width) + horizontal_padding as f32 * 2.;
|
||||
let height = f32::from(height) + vertical_padding as f32 * 2.;
|
||||
let mut settings = crate::app::Settings::default()
|
||||
.size(iced_core::Size::new(width, height))
|
||||
.size_limits(Limits::NONE.min_height(height).min_width(width))
|
||||
|
|
@ -187,28 +215,70 @@ impl Context {
|
|||
icon: widget::icon::Handle,
|
||||
) -> crate::widget::Button<'a, Message> {
|
||||
let suggested = self.suggested_size(icon.symbolic);
|
||||
let applet_padding = self.suggested_padding(icon.symbolic);
|
||||
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
let symbolic = icon.symbolic;
|
||||
let icon = widget::icon(icon)
|
||||
.class(if symbolic {
|
||||
theme::Svg::Custom(Rc::new(|theme| crate::iced_widget::svg::Style {
|
||||
color: Some(theme.cosmic().background.on.into()),
|
||||
}))
|
||||
} else {
|
||||
theme::Svg::default()
|
||||
})
|
||||
.width(Length::Fixed(suggested.0 as f32))
|
||||
.height(Length::Fixed(suggested.1 as f32));
|
||||
self.button_from_element(icon, symbolic)
|
||||
}
|
||||
|
||||
pub fn button_from_element<'a, Message: Clone + 'static>(
|
||||
&self,
|
||||
content: impl Into<Element<'a, Message>>,
|
||||
use_symbolic_size: bool,
|
||||
) -> crate::widget::Button<'a, Message> {
|
||||
let suggested = self.suggested_size(use_symbolic_size);
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
|
||||
crate::widget::button::custom(layer_container(content).center(Length::Fill))
|
||||
.width(Length::Fixed((suggested.0 + 2 * horizontal_padding) as f32))
|
||||
.height(Length::Fixed((suggested.1 + 2 * vertical_padding) as f32))
|
||||
.class(Button::AppletIcon)
|
||||
}
|
||||
|
||||
pub fn text_button<'a, Message: Clone + 'static>(
|
||||
&self,
|
||||
text: impl Into<Text<'a, crate::Theme, crate::Renderer>>,
|
||||
message: Message,
|
||||
) -> crate::widget::Button<'a, Message> {
|
||||
let text = text.into();
|
||||
let suggested = self.suggested_size(true);
|
||||
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
crate::widget::button::custom(
|
||||
layer_container(
|
||||
widget::icon(icon)
|
||||
.class(if symbolic {
|
||||
theme::Svg::Custom(Rc::new(|theme| crate::iced_widget::svg::Style {
|
||||
color: Some(theme.cosmic().background.on.into()),
|
||||
}))
|
||||
} else {
|
||||
theme::Svg::default()
|
||||
})
|
||||
.width(Length::Fixed(suggested.0 as f32))
|
||||
.height(Length::Fixed(suggested.1 as f32)),
|
||||
Text::from(text)
|
||||
.height(Length::Fill)
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.center(Length::Fill),
|
||||
.center_y(Length::Fixed(f32::from(suggested.1 + 2 * vertical_padding))),
|
||||
)
|
||||
.width(Length::Fixed((suggested.0 + 2 * applet_padding) as f32))
|
||||
.height(Length::Fixed((suggested.1 + 2 * applet_padding) as f32))
|
||||
.class(Button::AppletIcon)
|
||||
.on_press_down(message)
|
||||
.padding([0, horizontal_padding])
|
||||
.class(crate::theme::Button::AppletIcon)
|
||||
}
|
||||
|
||||
pub fn icon_button<'a, Message: Clone + 'static>(
|
||||
|
|
@ -345,7 +415,12 @@ impl Context {
|
|||
height_padding: Option<i32>,
|
||||
) -> SctkPopupSettings {
|
||||
let (width, height) = self.suggested_size(true);
|
||||
let applet_padding = self.suggested_padding(true);
|
||||
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
|
||||
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
|
||||
(applet_padding_major_axis, applet_padding_minor_axis)
|
||||
} else {
|
||||
(applet_padding_minor_axis, applet_padding_major_axis)
|
||||
};
|
||||
let pixel_offset = 4;
|
||||
let (offset, anchor, gravity) = match self.anchor {
|
||||
PanelAnchor::Left => ((pixel_offset, 0), Anchor::Right, Gravity::Right),
|
||||
|
|
@ -364,8 +439,10 @@ impl Context {
|
|||
anchor_rect: Rectangle {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: width_padding.unwrap_or(applet_padding as i32) * 2 + i32::from(width),
|
||||
height: height_padding.unwrap_or(applet_padding as i32) * 2 + i32::from(height),
|
||||
width: width_padding.unwrap_or(horizontal_padding as i32) * 2
|
||||
+ i32::from(width),
|
||||
height: height_padding.unwrap_or(vertical_padding as i32) * 2
|
||||
+ i32::from(height),
|
||||
},
|
||||
reactive: true,
|
||||
constraint_adjustment: 15, // slide_y, slide_x, flip_x, flip_y
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue