2026-04-17 11:48:11 +02:00
|
|
|
use std::sync::{Arc, Mutex};
|
2023-07-06 00:03:26 +02:00
|
|
|
|
|
|
|
|
use crate::{
|
2024-04-03 16:02:27 +02:00
|
|
|
config::Config,
|
2023-07-06 00:03:26 +02:00
|
|
|
fl,
|
2024-04-03 16:02:27 +02:00
|
|
|
shell::grabs::ResizeEdge,
|
2023-07-06 00:03:26 +02:00
|
|
|
utils::iced::{IcedElement, Program},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use calloop::LoopHandle;
|
|
|
|
|
use cosmic::{
|
2025-10-16 18:53:57 +02:00
|
|
|
Apply,
|
2024-10-24 00:15:05 +02:00
|
|
|
iced::{
|
|
|
|
|
Alignment,
|
2026-04-17 11:48:11 +02:00
|
|
|
core::{Background, Border, Color, Length},
|
|
|
|
|
widget::{container, row, space},
|
2024-10-24 00:15:05 +02:00
|
|
|
},
|
2023-07-06 00:03:26 +02:00
|
|
|
theme,
|
2023-10-02 19:37:23 +02:00
|
|
|
widget::{icon::from_name, text},
|
2023-07-06 00:03:26 +02:00
|
|
|
};
|
2024-04-03 16:02:27 +02:00
|
|
|
use cosmic_settings_config::shortcuts::action::{Action, ResizeDirection};
|
2023-07-06 00:03:26 +02:00
|
|
|
use smithay::utils::Size;
|
|
|
|
|
|
|
|
|
|
pub type ResizeIndicator = IcedElement<ResizeIndicatorInternal>;
|
|
|
|
|
|
|
|
|
|
pub fn resize_indicator(
|
|
|
|
|
direction: ResizeDirection,
|
|
|
|
|
config: &Config,
|
2023-09-29 21:33:16 +02:00
|
|
|
evlh: LoopHandle<'static, crate::state::State>,
|
2023-10-10 13:55:34 -04:00
|
|
|
theme: cosmic::Theme,
|
2023-07-06 00:03:26 +02:00
|
|
|
) -> ResizeIndicator {
|
|
|
|
|
ResizeIndicator::new(
|
|
|
|
|
ResizeIndicatorInternal {
|
|
|
|
|
edges: Mutex::new(ResizeEdge::all()),
|
|
|
|
|
direction,
|
|
|
|
|
shortcut1: config
|
2024-04-03 16:02:27 +02:00
|
|
|
.shortcuts
|
2023-07-06 00:03:26 +02:00
|
|
|
.iter()
|
|
|
|
|
.find_map(|(pattern, action)| {
|
|
|
|
|
(*action == Action::Resizing(ResizeDirection::Outwards)).then_some(pattern)
|
|
|
|
|
})
|
|
|
|
|
.map(|pattern| format!("{}: ", pattern.to_string()))
|
|
|
|
|
.unwrap_or_else(|| crate::fl!("unknown-keybinding")),
|
|
|
|
|
shortcut2: config
|
2024-04-03 16:02:27 +02:00
|
|
|
.shortcuts
|
2023-07-06 00:03:26 +02:00
|
|
|
.iter()
|
|
|
|
|
.find_map(|(pattern, action)| {
|
|
|
|
|
(*action == Action::Resizing(ResizeDirection::Inwards)).then_some(pattern)
|
|
|
|
|
})
|
|
|
|
|
.map(|pattern| format!("{}: ", pattern.to_string()))
|
|
|
|
|
.unwrap_or_else(|| crate::fl!("unknown-keybinding")),
|
|
|
|
|
},
|
|
|
|
|
Size::from((1, 1)),
|
|
|
|
|
evlh,
|
2023-10-10 13:55:34 -04:00
|
|
|
theme,
|
2023-07-06 00:03:26 +02:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct ResizeIndicatorInternal {
|
|
|
|
|
pub edges: Mutex<ResizeEdge>,
|
|
|
|
|
pub direction: ResizeDirection,
|
|
|
|
|
pub shortcut1: String,
|
|
|
|
|
pub shortcut2: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Program for ResizeIndicatorInternal {
|
|
|
|
|
type Message = ();
|
|
|
|
|
|
2024-02-09 16:48:03 -08:00
|
|
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
2026-04-17 11:48:11 +02:00
|
|
|
row(vec![
|
|
|
|
|
text::heading(&self.shortcut1).into(),
|
|
|
|
|
text::body(fl!("grow-window")).into(),
|
|
|
|
|
space::horizontal().width(40).into(),
|
|
|
|
|
text::heading(&self.shortcut2).into(),
|
|
|
|
|
text::body(fl!("shrink-window")).into(),
|
|
|
|
|
])
|
|
|
|
|
.apply(container)
|
|
|
|
|
.align_x(Alignment::Center)
|
|
|
|
|
.align_y(Alignment::Center)
|
|
|
|
|
.padding(16)
|
|
|
|
|
.apply(container)
|
|
|
|
|
.class(theme::Container::custom(|theme| {
|
|
|
|
|
let mut background = theme.cosmic().accent_color();
|
|
|
|
|
if theme.transparent {
|
|
|
|
|
background.alpha = theme
|
|
|
|
|
.cosmic()
|
|
|
|
|
.alpha_map
|
|
|
|
|
.blurred_alpha(theme.cosmic().frosted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
container::Style {
|
2026-02-24 15:18:57 -05:00
|
|
|
snap: true,
|
2023-10-02 19:37:23 +02:00
|
|
|
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
|
|
|
|
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
2026-04-17 11:48:11 +02:00
|
|
|
background: Some(Background::Color(background.into())),
|
2024-02-09 16:48:03 -08:00
|
|
|
border: Border {
|
|
|
|
|
radius: 18.0.into(),
|
|
|
|
|
width: 0.0,
|
|
|
|
|
color: Color::TRANSPARENT,
|
|
|
|
|
},
|
|
|
|
|
shadow: Default::default(),
|
2026-04-17 11:48:11 +02:00
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
.width(Length::Shrink)
|
|
|
|
|
.height(Length::Shrink)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-02 19:37:23 +02:00
|
|
|
|
2026-04-17 11:48:11 +02:00
|
|
|
pub struct ResizeIndicatorArrow {
|
|
|
|
|
direction: Arc<Mutex<ResizeDirection>>,
|
|
|
|
|
icon_outwards: &'static str,
|
|
|
|
|
icon_inwards: &'static str,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Program for ResizeIndicatorArrow {
|
|
|
|
|
type Message = ();
|
|
|
|
|
|
|
|
|
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
|
|
|
|
from_name(
|
|
|
|
|
if *self.direction.lock().unwrap() == ResizeDirection::Outwards {
|
|
|
|
|
self.icon_outwards
|
2023-07-06 00:03:26 +02:00
|
|
|
} else {
|
2026-04-17 11:48:11 +02:00
|
|
|
self.icon_inwards
|
2023-07-06 00:03:26 +02:00
|
|
|
},
|
2026-04-17 11:48:11 +02:00
|
|
|
)
|
|
|
|
|
.size(20)
|
|
|
|
|
.prefer_svg(true)
|
|
|
|
|
.apply(container)
|
|
|
|
|
.padding(8)
|
|
|
|
|
.class(theme::Container::custom(|theme| {
|
|
|
|
|
let mut background = theme.cosmic().accent_color();
|
|
|
|
|
if theme.transparent {
|
|
|
|
|
background.alpha = theme
|
|
|
|
|
.cosmic()
|
|
|
|
|
.alpha_map
|
|
|
|
|
.blurred_alpha(theme.cosmic().frosted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
container::Style {
|
|
|
|
|
snap: true,
|
|
|
|
|
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
|
|
|
|
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
|
|
|
|
background: Some(Background::Color(background.into())),
|
|
|
|
|
border: Border {
|
|
|
|
|
radius: theme.cosmic().radius_s().into(),
|
|
|
|
|
width: 0.0,
|
|
|
|
|
color: Color::TRANSPARENT,
|
2023-07-06 00:03:26 +02:00
|
|
|
},
|
2026-04-17 11:48:11 +02:00
|
|
|
shadow: Default::default(),
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
.width(Length::Shrink)
|
2023-07-06 00:03:26 +02:00
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
}
|