2023-08-11 18:15:22 +02:00
|
|
|
use crate::{
|
2026-04-21 18:19:01 +02:00
|
|
|
backend::render::element::AsGlowRenderer,
|
2023-08-11 18:15:22 +02:00
|
|
|
fl,
|
2026-04-21 18:19:01 +02:00
|
|
|
utils::iced::{IcedElement, IcedRenderElement, Program},
|
2023-08-11 18:15:22 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use calloop::LoopHandle;
|
|
|
|
|
use cosmic::{
|
2025-10-16 18:53:57 +02:00
|
|
|
Apply,
|
2026-04-17 11:48:11 +02:00
|
|
|
iced::{
|
|
|
|
|
core::{Alignment, Background, Border, Color, Length},
|
|
|
|
|
widget::{container, row, space},
|
|
|
|
|
},
|
2023-08-11 18:15:22 +02:00
|
|
|
theme,
|
2023-10-02 19:37:23 +02:00
|
|
|
widget::{icon::from_name, text},
|
2023-08-11 18:15:22 +02:00
|
|
|
};
|
2026-04-21 18:19:01 +02:00
|
|
|
use smithay::{
|
|
|
|
|
backend::renderer::ImportMem,
|
|
|
|
|
desktop::space::SpaceElement,
|
|
|
|
|
output::Output,
|
|
|
|
|
utils::{Logical, Physical, Point, Rectangle, Scale, Size},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct SwapIndicator {
|
|
|
|
|
location: Point<i32, Logical>,
|
|
|
|
|
elem: IcedElement<SwapIndicatorInternal>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl SwapIndicator {
|
|
|
|
|
pub fn new(
|
|
|
|
|
evlh: LoopHandle<'static, crate::state::State>,
|
|
|
|
|
mut theme: cosmic::Theme,
|
|
|
|
|
) -> SwapIndicator {
|
|
|
|
|
theme.transparent = theme.cosmic().frosted_system_interface;
|
|
|
|
|
SwapIndicator {
|
|
|
|
|
location: Point::default(),
|
|
|
|
|
elem: IcedElement::new(SwapIndicatorInternal, Size::from((1, 1)), evlh, theme),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn resize(&mut self, size: Size<i32, Logical>) {
|
|
|
|
|
let minimum = self.elem.minimum_size();
|
|
|
|
|
let new_size = Size::<i32, Logical>::new(size.w.min(minimum.w), size.h.min(minimum.h));
|
|
|
|
|
let location = Point::new(
|
|
|
|
|
size.w.saturating_sub(new_size.w) / 2,
|
|
|
|
|
size.h.saturating_sub(new_size.h) / 2,
|
|
|
|
|
);
|
|
|
|
|
self.elem.resize(new_size);
|
|
|
|
|
self.location = location;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn push_render_elements<R>(
|
|
|
|
|
&self,
|
|
|
|
|
renderer: &mut R,
|
|
|
|
|
location: Point<i32, Physical>,
|
|
|
|
|
scale: Scale<f64>,
|
|
|
|
|
alpha: f32,
|
|
|
|
|
push_above: &mut dyn FnMut(IcedRenderElement<R>),
|
|
|
|
|
push_below: Option<&mut dyn FnMut(IcedRenderElement<R>)>,
|
|
|
|
|
) where
|
|
|
|
|
R: AsGlowRenderer + ImportMem,
|
|
|
|
|
R::TextureId: Send + Clone + 'static,
|
|
|
|
|
{
|
|
|
|
|
self.elem.push_render_elements(
|
|
|
|
|
renderer,
|
|
|
|
|
location + self.location.to_physical_precise_round(scale),
|
|
|
|
|
scale,
|
|
|
|
|
alpha,
|
|
|
|
|
self.elem
|
|
|
|
|
.with_theme(|theme| theme.cosmic().radius_s())
|
|
|
|
|
.map(|x| x.round() as u8),
|
|
|
|
|
push_above,
|
|
|
|
|
push_below,
|
|
|
|
|
);
|
|
|
|
|
}
|
2023-08-11 18:15:22 +02:00
|
|
|
|
2026-04-21 18:19:01 +02:00
|
|
|
pub fn output_enter(&self, output: &Output) {
|
|
|
|
|
self.elem
|
|
|
|
|
.output_enter(output, Rectangle::default() /*unused*/);
|
|
|
|
|
}
|
2023-08-11 18:15:22 +02:00
|
|
|
|
2026-04-21 18:19:01 +02:00
|
|
|
pub fn output_leave(&self, output: &Output) {
|
|
|
|
|
self.elem.output_leave(output);
|
|
|
|
|
}
|
2023-08-11 18:15:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct SwapIndicatorInternal;
|
|
|
|
|
|
|
|
|
|
impl Program for SwapIndicatorInternal {
|
|
|
|
|
type Message = ();
|
|
|
|
|
|
2024-02-09 16:48:03 -08:00
|
|
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
2023-08-11 18:15:22 +02:00
|
|
|
row(vec![
|
2023-10-02 19:37:23 +02:00
|
|
|
from_name("window-swap-symbolic")
|
|
|
|
|
.size(32)
|
|
|
|
|
.prefer_svg(true)
|
|
|
|
|
.icon()
|
|
|
|
|
.into(),
|
2026-02-24 15:18:57 -05:00
|
|
|
space::horizontal().width(16).into(),
|
2024-09-28 13:58:51 +02:00
|
|
|
text::title3(fl!("swap-windows")).into(),
|
2023-08-11 18:15:22 +02:00
|
|
|
])
|
2024-10-24 00:15:05 +02:00
|
|
|
.align_y(Alignment::Center)
|
2023-08-11 18:15:22 +02:00
|
|
|
.apply(container)
|
2024-10-24 00:15:05 +02:00
|
|
|
.align_x(Alignment::Center)
|
|
|
|
|
.align_y(Alignment::Center)
|
2023-08-11 18:15:22 +02:00
|
|
|
.padding(16)
|
|
|
|
|
.apply(container)
|
2026-04-17 11:48:11 +02:00
|
|
|
.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,
|
|
|
|
|
},
|
|
|
|
|
shadow: Default::default(),
|
|
|
|
|
}
|
2023-08-11 18:15:22 +02:00
|
|
|
}))
|
|
|
|
|
.width(Length::Shrink)
|
|
|
|
|
.height(Length::Shrink)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
}
|