chore: update iced/libcosmic
This commit is contained in:
parent
0d0b89d538
commit
7de52054ff
12 changed files with 502 additions and 549 deletions
603
Cargo.lock
generated
603
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -9,7 +9,10 @@ use crate::{
|
||||||
|
|
||||||
use calloop::LoopHandle;
|
use calloop::LoopHandle;
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::widget::{column, container, horizontal_space, row, vertical_space},
|
iced::{
|
||||||
|
widget::{column, container, horizontal_space, row, vertical_space},
|
||||||
|
Alignment,
|
||||||
|
},
|
||||||
iced_core::{Background, Border, Color, Length},
|
iced_core::{Background, Border, Color, Length},
|
||||||
theme,
|
theme,
|
||||||
widget::{icon::from_name, text},
|
widget::{icon::from_name, text},
|
||||||
|
|
@ -66,7 +69,7 @@ impl Program for ResizeIndicatorInternal {
|
||||||
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
||||||
let edges = self.edges.lock().unwrap();
|
let edges = self.edges.lock().unwrap();
|
||||||
let icon_container_style = || {
|
let icon_container_style = || {
|
||||||
theme::Container::custom(|theme| container::Appearance {
|
theme::Container::custom(|theme| container::Style {
|
||||||
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
||||||
|
|
@ -90,14 +93,13 @@ impl Program for ResizeIndicatorInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.style(icon_container_style())
|
.class(icon_container_style())
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_x()
|
.center_x(Length::Fill)
|
||||||
.width(Length::Fill)
|
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
vertical_space(36).into()
|
vertical_space().height(36).into()
|
||||||
},
|
},
|
||||||
row(vec![
|
row(vec![
|
||||||
if edges.contains(ResizeEdge::LEFT) {
|
if edges.contains(ResizeEdge::LEFT) {
|
||||||
|
|
@ -110,35 +112,32 @@ impl Program for ResizeIndicatorInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.style(icon_container_style())
|
.class(icon_container_style())
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_y()
|
.center_y(Length::Fill)
|
||||||
.height(Length::Fill)
|
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
horizontal_space(36).into()
|
horizontal_space().width(36).into()
|
||||||
},
|
},
|
||||||
row(vec![
|
row(vec![
|
||||||
text::heading(&self.shortcut1).into(),
|
text::heading(&self.shortcut1).into(),
|
||||||
text::body(fl!("grow-window")).into(),
|
text::body(fl!("grow-window")).into(),
|
||||||
horizontal_space(40).into(),
|
horizontal_space().width(40).into(),
|
||||||
text::heading(&self.shortcut2).into(),
|
text::heading(&self.shortcut2).into(),
|
||||||
text::body(fl!("shrink-window")).into(),
|
text::body(fl!("shrink-window")).into(),
|
||||||
])
|
])
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_x()
|
.align_x(Alignment::Center)
|
||||||
.center_y()
|
.align_y(Alignment::Center)
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.style(icon_container_style())
|
.class(icon_container_style())
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.height(Length::Shrink)
|
.height(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.height(Length::Fill)
|
.center_x(Length::Fill)
|
||||||
.width(Length::Fill)
|
.center_y(Length::Fill)
|
||||||
.center_x()
|
|
||||||
.center_y()
|
|
||||||
.into(),
|
.into(),
|
||||||
if edges.contains(ResizeEdge::RIGHT) {
|
if edges.contains(ResizeEdge::RIGHT) {
|
||||||
from_name(if self.direction == ResizeDirection::Outwards {
|
from_name(if self.direction == ResizeDirection::Outwards {
|
||||||
|
|
@ -150,14 +149,13 @@ impl Program for ResizeIndicatorInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.style(icon_container_style())
|
.class(icon_container_style())
|
||||||
.height(Length::Shrink)
|
.height(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_y()
|
.center_y(Length::Fill)
|
||||||
.height(Length::Fill)
|
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
horizontal_space(36).into()
|
horizontal_space().width(36).into()
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|
@ -173,14 +171,13 @@ impl Program for ResizeIndicatorInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.style(icon_container_style())
|
.class(icon_container_style())
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_x()
|
.center_x(Length::Fill)
|
||||||
.width(Length::Fill)
|
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
vertical_space(36).into()
|
vertical_space().height(36).into()
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.into()
|
.into()
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use calloop::LoopHandle;
|
use calloop::LoopHandle;
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::{id::Id, widget as iced_widget},
|
iced::{id::Id, widget as iced_widget, Alignment},
|
||||||
iced_core::{border::Radius, Background, Border, Color, Length},
|
iced_core::{border::Radius, Background, Border, Color, Length},
|
||||||
iced_runtime::Command,
|
iced_runtime::Task,
|
||||||
iced_widget::scrollable::AbsoluteOffset,
|
iced_widget::scrollable::AbsoluteOffset,
|
||||||
theme, widget as cosmic_widget, Apply, Element as CosmicElement, Theme,
|
theme, widget as cosmic_widget, Apply, Element as CosmicElement, Theme,
|
||||||
};
|
};
|
||||||
|
|
@ -712,7 +712,7 @@ impl Program for CosmicStackInternal {
|
||||||
&mut self,
|
&mut self,
|
||||||
message: Self::Message,
|
message: Self::Message,
|
||||||
loop_handle: &LoopHandle<'static, crate::state::State>,
|
loop_handle: &LoopHandle<'static, crate::state::State>,
|
||||||
) -> Command<Self::Message> {
|
) -> Task<Self::Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::DragStart => {
|
Message::DragStart => {
|
||||||
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
|
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
|
||||||
|
|
@ -874,7 +874,7 @@ impl Program for CosmicStackInternal {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
Command::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> CosmicElement<'_, Self::Message> {
|
fn view(&self) -> CosmicElement<'_, Self::Message> {
|
||||||
|
|
@ -890,8 +890,8 @@ impl Program for CosmicStackInternal {
|
||||||
.size(16)
|
.size(16)
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.style(if group_focused {
|
.class(if group_focused {
|
||||||
theme::Svg::custom(|theme| iced_widget::svg::Appearance {
|
theme::Svg::custom(|theme| iced_widget::svg::Style {
|
||||||
color: Some(if theme.cosmic().is_dark {
|
color: Some(if theme.cosmic().is_dark {
|
||||||
Color::BLACK
|
Color::BLACK
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -903,7 +903,7 @@ impl Program for CosmicStackInternal {
|
||||||
})
|
})
|
||||||
.apply(iced_widget::container)
|
.apply(iced_widget::container)
|
||||||
.padding([4, 24])
|
.padding([4, 24])
|
||||||
.center_y()
|
.align_y(Alignment::Center)
|
||||||
.apply(iced_widget::mouse_area)
|
.apply(iced_widget::mouse_area)
|
||||||
.on_press(Message::DragStart)
|
.on_press(Message::DragStart)
|
||||||
.on_right_press(Message::Menu)
|
.on_right_press(Message::Menu)
|
||||||
|
|
@ -935,7 +935,8 @@ impl Program for CosmicStackInternal {
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
),
|
),
|
||||||
iced_widget::horizontal_space(0)
|
iced_widget::horizontal_space()
|
||||||
|
.width(Length::Fixed(0.0))
|
||||||
.apply(iced_widget::container)
|
.apply(iced_widget::container)
|
||||||
.padding([64, 24])
|
.padding([64, 24])
|
||||||
.apply(iced_widget::mouse_area)
|
.apply(iced_widget::mouse_area)
|
||||||
|
|
@ -953,10 +954,10 @@ impl Program for CosmicStackInternal {
|
||||||
|
|
||||||
iced_widget::row(elements)
|
iced_widget::row(elements)
|
||||||
.height(TAB_HEIGHT as u16)
|
.height(TAB_HEIGHT as u16)
|
||||||
.width(Length::Fill) //width as u16)
|
.width(Length::Fill)
|
||||||
.apply(iced_widget::container)
|
.apply(iced_widget::container)
|
||||||
.center_y()
|
.align_y(Alignment::Center)
|
||||||
.style(theme::Container::custom(move |theme| {
|
.class(theme::Container::custom(move |theme| {
|
||||||
let background = if group_focused {
|
let background = if group_focused {
|
||||||
Some(Background::Color(theme.cosmic().accent_color().into()))
|
Some(Background::Color(theme.cosmic().accent_color().into()))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -965,7 +966,7 @@ impl Program for CosmicStackInternal {
|
||||||
)))
|
)))
|
||||||
};
|
};
|
||||||
|
|
||||||
iced_widget::container::Appearance {
|
iced_widget::container::Style {
|
||||||
icon_color: Some(Color::from(theme.cosmic().background.on)),
|
icon_color: Some(Color::from(theme.cosmic().background.on)),
|
||||||
text_color: Some(Color::from(theme.cosmic().background.on)),
|
text_color: Some(Color::from(theme.cosmic().background.on)),
|
||||||
background,
|
background,
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,7 @@ use cosmic::{
|
||||||
alignment, event,
|
alignment, event,
|
||||||
layout::{Layout, Limits, Node},
|
layout::{Layout, Limits, Node},
|
||||||
mouse, overlay, renderer,
|
mouse, overlay, renderer,
|
||||||
widget::{
|
widget::{operation::Operation, tree::Tree, Id, Widget},
|
||||||
operation::{Operation, OperationOutputWrapper},
|
|
||||||
tree::Tree,
|
|
||||||
Id, Widget,
|
|
||||||
},
|
|
||||||
Border, Clipboard, Color, Length, Rectangle, Shell, Size,
|
Border, Clipboard, Color, Length, Rectangle, Shell, Size,
|
||||||
},
|
},
|
||||||
iced_widget::scrollable::AbsoluteOffset,
|
iced_widget::scrollable::AbsoluteOffset,
|
||||||
|
|
@ -54,19 +50,19 @@ pub(super) enum TabRuleTheme {
|
||||||
impl From<TabRuleTheme> for theme::Rule {
|
impl From<TabRuleTheme> for theme::Rule {
|
||||||
fn from(theme: TabRuleTheme) -> Self {
|
fn from(theme: TabRuleTheme) -> Self {
|
||||||
match theme {
|
match theme {
|
||||||
TabRuleTheme::ActiveActivated => Self::custom(|theme| widget::rule::Appearance {
|
TabRuleTheme::ActiveActivated => Self::custom(|theme| widget::rule::Style {
|
||||||
color: theme.cosmic().accent_color().into(),
|
color: theme.cosmic().accent_color().into(),
|
||||||
width: 4,
|
width: 4,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
fill_mode: FillMode::Full,
|
fill_mode: FillMode::Full,
|
||||||
}),
|
}),
|
||||||
TabRuleTheme::ActiveDeactivated => Self::custom(|theme| widget::rule::Appearance {
|
TabRuleTheme::ActiveDeactivated => Self::custom(|theme| widget::rule::Style {
|
||||||
color: theme.cosmic().palette.neutral_5.into(),
|
color: theme.cosmic().palette.neutral_5.into(),
|
||||||
width: 4,
|
width: 4,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
fill_mode: FillMode::Full,
|
fill_mode: FillMode::Full,
|
||||||
}),
|
}),
|
||||||
TabRuleTheme::Default => Self::custom(|theme| widget::rule::Appearance {
|
TabRuleTheme::Default => Self::custom(|theme| widget::rule::Style {
|
||||||
color: theme.cosmic().palette.neutral_5.into(),
|
color: theme.cosmic().palette.neutral_5.into(),
|
||||||
width: 4,
|
width: 4,
|
||||||
radius: 8.0.into(),
|
radius: 8.0.into(),
|
||||||
|
|
@ -96,11 +92,11 @@ impl TabBackgroundTheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TabBackgroundTheme> for theme::Container {
|
impl From<TabBackgroundTheme> for theme::Container<'_> {
|
||||||
fn from(background_theme: TabBackgroundTheme) -> Self {
|
fn from(background_theme: TabBackgroundTheme) -> Self {
|
||||||
match background_theme {
|
match background_theme {
|
||||||
TabBackgroundTheme::ActiveActivated => {
|
TabBackgroundTheme::ActiveActivated => {
|
||||||
Self::custom(move |theme| widget::container::Appearance {
|
Self::custom(move |theme| widget::container::Style {
|
||||||
icon_color: Some(Color::from(theme.cosmic().accent_text_color())),
|
icon_color: Some(Color::from(theme.cosmic().accent_text_color())),
|
||||||
text_color: Some(Color::from(theme.cosmic().accent_text_color())),
|
text_color: Some(Color::from(theme.cosmic().accent_text_color())),
|
||||||
background: Some(background_theme.background_color(theme).into()),
|
background: Some(background_theme.background_color(theme).into()),
|
||||||
|
|
@ -113,7 +109,7 @@ impl From<TabBackgroundTheme> for theme::Container {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
TabBackgroundTheme::ActiveDeactivated => {
|
TabBackgroundTheme::ActiveDeactivated => {
|
||||||
Self::custom(move |theme| widget::container::Appearance {
|
Self::custom(move |theme| widget::container::Style {
|
||||||
icon_color: None,
|
icon_color: None,
|
||||||
text_color: None,
|
text_color: None,
|
||||||
background: Some(background_theme.background_color(theme).into()),
|
background: Some(background_theme.background_color(theme).into()),
|
||||||
|
|
@ -215,20 +211,19 @@ impl<Message: TabMessage + 'static> Tab<Message> {
|
||||||
.icon()
|
.icon()
|
||||||
.apply(widget::button)
|
.apply(widget::button)
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.style(theme::iced::Button::Text);
|
.class(theme::iced::Button::Text);
|
||||||
if let Some(close_message) = self.close_message {
|
if let Some(close_message) = self.close_message {
|
||||||
close_button = close_button.on_press(close_message);
|
close_button = close_button.on_press(close_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = vec![
|
let items = vec![
|
||||||
widget::vertical_rule(4).style(self.rule_theme).into(),
|
widget::vertical_rule(4).class(self.rule_theme).into(),
|
||||||
self.app_icon
|
self.app_icon
|
||||||
.clone()
|
.clone()
|
||||||
.apply(widget::container)
|
.apply(widget::container)
|
||||||
.height(Length::Fill)
|
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.padding([2, 4])
|
.padding([2, 4])
|
||||||
.center_y()
|
.center_y(Length::Fill)
|
||||||
.into(),
|
.into(),
|
||||||
tab_text(self.title, self.active)
|
tab_text(self.title, self.active)
|
||||||
.font(self.font)
|
.font(self.font)
|
||||||
|
|
@ -238,10 +233,9 @@ impl<Message: TabMessage + 'static> Tab<Message> {
|
||||||
.into(),
|
.into(),
|
||||||
close_button
|
close_button
|
||||||
.apply(widget::container)
|
.apply(widget::container)
|
||||||
.height(Length::Fill)
|
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.padding([2, 4])
|
.padding([2, 4])
|
||||||
.center_y()
|
.center_y(Length::Fill)
|
||||||
.align_x(alignment::Horizontal::Right)
|
.align_x(alignment::Horizontal::Right)
|
||||||
.into(),
|
.into(),
|
||||||
];
|
];
|
||||||
|
|
@ -269,7 +263,7 @@ pub(super) struct TabInternal<'a, Message: TabMessage> {
|
||||||
id: Id,
|
id: Id,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
active: bool,
|
active: bool,
|
||||||
background: theme::Container,
|
background: theme::Container<'a>,
|
||||||
elements: Vec<cosmic::Element<'a, Message>>,
|
elements: Vec<cosmic::Element<'a, Message>>,
|
||||||
press_message: Option<Message>,
|
press_message: Option<Message>,
|
||||||
right_click_message: Option<Message>,
|
right_click_message: Option<Message>,
|
||||||
|
|
@ -347,7 +341,7 @@ where
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
|
operation: &mut dyn Operation<()>,
|
||||||
) {
|
) {
|
||||||
operation.container(None, layout.bounds(), &mut |operation| {
|
operation.container(None, layout.bounds(), &mut |operation| {
|
||||||
self.elements
|
self.elements
|
||||||
|
|
@ -454,8 +448,8 @@ where
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
use cosmic::widget::container::StyleSheet;
|
use cosmic::widget::container::Catalog;
|
||||||
let style = theme.appearance(&self.background);
|
let style = theme.style(&self.background);
|
||||||
|
|
||||||
draw_background(renderer, &style, layout.bounds());
|
draw_background(renderer, &style, layout.bounds());
|
||||||
|
|
||||||
|
|
@ -486,7 +480,8 @@ where
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
|
translation: cosmic::iced::Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
||||||
overlay::from_children(&mut self.elements, tree, layout, renderer)
|
overlay::from_children(&mut self.elements, tree, layout, renderer, translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ impl TabText {
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
shaping: Shaping::Advanced,
|
shaping: Shaping::Advanced,
|
||||||
line_height: LineHeight::default(),
|
line_height: LineHeight::default(),
|
||||||
wrap: cosmic::iced::advanced::text::Wrap::None,
|
wrapping: cosmic::iced::advanced::text::Wrapping::None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use cosmic::{
|
||||||
widget::{
|
widget::{
|
||||||
operation::{
|
operation::{
|
||||||
scrollable::{AbsoluteOffset, RelativeOffset},
|
scrollable::{AbsoluteOffset, RelativeOffset},
|
||||||
Operation, OperationOutputWrapper, Scrollable,
|
Operation, Scrollable,
|
||||||
},
|
},
|
||||||
tree::{self, Tree},
|
tree::{self, Tree},
|
||||||
Widget,
|
Widget,
|
||||||
|
|
@ -16,10 +16,9 @@ use cosmic::{
|
||||||
Background, Border, Clipboard, Color, Length, Point, Rectangle, Renderer, Shell, Size,
|
Background, Border, Clipboard, Color, Length, Point, Rectangle, Renderer, Shell, Size,
|
||||||
Vector,
|
Vector,
|
||||||
},
|
},
|
||||||
iced_style::container::StyleSheet as ContainerStyleSheet,
|
|
||||||
iced_widget::container::draw_background,
|
iced_widget::container::draw_background,
|
||||||
theme,
|
theme,
|
||||||
widget::icon::from_name,
|
widget::{container::Catalog, icon::from_name},
|
||||||
Apply,
|
Apply,
|
||||||
};
|
};
|
||||||
use keyframe::{
|
use keyframe::{
|
||||||
|
|
@ -45,6 +44,7 @@ struct ScrollAnimationState {
|
||||||
start_time: Instant,
|
start_time: Instant,
|
||||||
start: Offset,
|
start: Offset,
|
||||||
end: Offset,
|
end: Offset,
|
||||||
|
extra: Offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -75,9 +75,24 @@ impl Scrollable for State {
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
start: self.offset_x,
|
start: self.offset_x,
|
||||||
end: new_offset,
|
end: new_offset,
|
||||||
|
extra: Offset::Absolute(0.),
|
||||||
});
|
});
|
||||||
self.offset_x = new_offset;
|
self.offset_x = new_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn scroll_by(
|
||||||
|
&mut self,
|
||||||
|
offset: AbsoluteOffset,
|
||||||
|
_bounds: Rectangle,
|
||||||
|
_content_bounds: Rectangle,
|
||||||
|
) {
|
||||||
|
self.scroll_animation = Some(ScrollAnimationState {
|
||||||
|
start_time: Instant::now(),
|
||||||
|
start: self.offset_x,
|
||||||
|
end: self.offset_x,
|
||||||
|
extra: Offset::Absolute(offset.x.max(0.0)),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for State {
|
impl Default for State {
|
||||||
|
|
@ -145,7 +160,7 @@ where
|
||||||
Element::new(tab.internal(i))
|
Element::new(tab.internal(i))
|
||||||
});
|
});
|
||||||
|
|
||||||
let tabs_rule = widget::vertical_rule(4).style(if tabs.len() - 1 == active {
|
let tabs_rule = widget::vertical_rule(4).class(if tabs.len() - 1 == active {
|
||||||
if activated {
|
if activated {
|
||||||
TabRuleTheme::ActiveActivated
|
TabRuleTheme::ActiveActivated
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -166,7 +181,7 @@ where
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.apply(widget::button)
|
.apply(widget::button)
|
||||||
.style(theme::iced::Button::Text)
|
.class(theme::iced::Button::Text)
|
||||||
.on_press(Message::scroll_back());
|
.on_press(Message::scroll_back());
|
||||||
|
|
||||||
let next_button = from_name("go-next-symbolic")
|
let next_button = from_name("go-next-symbolic")
|
||||||
|
|
@ -174,17 +189,17 @@ where
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.apply(widget::button)
|
.apply(widget::button)
|
||||||
.style(theme::iced::Button::Text)
|
.class(theme::iced::Button::Text)
|
||||||
.on_press(Message::scroll_further());
|
.on_press(Message::scroll_further());
|
||||||
|
|
||||||
let mut elements = Vec::with_capacity(tabs.len() + 5);
|
let mut elements = Vec::with_capacity(tabs.len() + 5);
|
||||||
|
|
||||||
elements.push(widget::vertical_rule(4).style(rule_style).into());
|
elements.push(widget::vertical_rule(4).class(rule_style).into());
|
||||||
elements.push(prev_button.into());
|
elements.push(prev_button.into());
|
||||||
elements.extend(tabs);
|
elements.extend(tabs);
|
||||||
elements.push(tabs_rule.into());
|
elements.push(tabs_rule.into());
|
||||||
elements.push(next_button.into());
|
elements.push(next_button.into());
|
||||||
elements.push(widget::vertical_rule(4).style(rule_style).into());
|
elements.push(widget::vertical_rule(4).class(rule_style).into());
|
||||||
|
|
||||||
Tabs {
|
Tabs {
|
||||||
elements,
|
elements,
|
||||||
|
|
@ -239,6 +254,7 @@ impl State {
|
||||||
|
|
||||||
Vector::new(
|
Vector::new(
|
||||||
animation.start.absolute(bounds.width, content_bounds.width)
|
animation.start.absolute(bounds.width, content_bounds.width)
|
||||||
|
+ animation.extra.absolute(bounds.width, content_bounds.width) * percentage
|
||||||
+ (animation.end.absolute(bounds.width, content_bounds.width)
|
+ (animation.end.absolute(bounds.width, content_bounds.width)
|
||||||
- animation.start.absolute(bounds.width, content_bounds.width))
|
- animation.start.absolute(bounds.width, content_bounds.width))
|
||||||
* percentage,
|
* percentage,
|
||||||
|
|
@ -490,9 +506,9 @@ where
|
||||||
height: b.bounds().height,
|
height: b.bounds().height,
|
||||||
});
|
});
|
||||||
|
|
||||||
let background_style = ContainerStyleSheet::appearance(
|
let background_style = Catalog::style(
|
||||||
theme,
|
theme,
|
||||||
&theme::Container::custom(|theme| widget::container::Appearance {
|
&theme::Container::custom(|theme| widget::container::Style {
|
||||||
icon_color: None,
|
icon_color: None,
|
||||||
text_color: None,
|
text_color: None,
|
||||||
background: Some(Background::Color(super::tab::primary_container_color(
|
background: Some(Background::Color(super::tab::primary_container_color(
|
||||||
|
|
@ -666,10 +682,12 @@ where
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
|
operation: &mut dyn Operation<()>,
|
||||||
) {
|
) {
|
||||||
let state = tree.state.downcast_mut::<State>();
|
let state = tree.state.downcast_mut::<State>();
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
let content_layout = layout.children().next().unwrap();
|
||||||
|
let content_bounds = content_layout.bounds();
|
||||||
|
|
||||||
state.cleanup_old_animations();
|
state.cleanup_old_animations();
|
||||||
|
|
||||||
|
|
@ -677,6 +695,7 @@ where
|
||||||
state,
|
state,
|
||||||
self.id.as_ref(),
|
self.id.as_ref(),
|
||||||
bounds,
|
bounds,
|
||||||
|
content_bounds,
|
||||||
Vector { x: 0.0, y: 0.0 }, /* seemingly unused */
|
Vector { x: 0.0, y: 0.0 }, /* seemingly unused */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -819,6 +838,7 @@ where
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
start: Offset::Absolute(offset.x),
|
start: Offset::Absolute(offset.x),
|
||||||
end: Offset::Absolute(new_offset.x),
|
end: Offset::Absolute(new_offset.x),
|
||||||
|
extra: Offset::Absolute(0.),
|
||||||
});
|
});
|
||||||
state.offset_x = Offset::Absolute(new_offset.x);
|
state.offset_x = Offset::Absolute(new_offset.x);
|
||||||
}
|
}
|
||||||
|
|
@ -993,7 +1013,8 @@ where
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
|
translation: cosmic::iced::Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
||||||
overlay::from_children(&mut self.elements, tree, layout, renderer)
|
overlay::from_children(&mut self.elements, tree, layout, renderer, translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,16 +38,16 @@ impl Program for StackHoverInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.into(),
|
.into(),
|
||||||
horizontal_space(16).into(),
|
horizontal_space().width(16).into(),
|
||||||
text::title3(fl!("stack-windows")).into(),
|
text::title3(fl!("stack-windows")).into(),
|
||||||
])
|
])
|
||||||
.align_items(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_x()
|
.align_x(Alignment::Center)
|
||||||
.center_y()
|
.align_y(Alignment::Center)
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.style(theme::Container::custom(|theme| container::Appearance {
|
.class(theme::Container::custom(|theme| container::Style {
|
||||||
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
||||||
|
|
@ -61,10 +61,8 @@ impl Program for StackHoverInternal {
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.height(Length::Shrink)
|
.height(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.width(Length::Fill)
|
.center_x(Length::Fill)
|
||||||
.height(Length::Fill)
|
.center_y(Length::Fill)
|
||||||
.center_x()
|
|
||||||
.center_y()
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,16 @@ impl Program for SwapIndicatorInternal {
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.into(),
|
.into(),
|
||||||
horizontal_space(16).into(),
|
horizontal_space().width(16).into(),
|
||||||
text::title3(fl!("swap-windows")).into(),
|
text::title3(fl!("swap-windows")).into(),
|
||||||
])
|
])
|
||||||
.align_items(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.center_x()
|
.align_x(Alignment::Center)
|
||||||
.center_y()
|
.align_y(Alignment::Center)
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.style(theme::Container::custom(|theme| container::Appearance {
|
.class(theme::Container::custom(|theme| container::Style {
|
||||||
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
icon_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
text_color: Some(Color::from(theme.cosmic().accent.on)),
|
||||||
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
background: Some(Background::Color(theme.cosmic().accent_color().into())),
|
||||||
|
|
@ -57,10 +57,8 @@ impl Program for SwapIndicatorInternal {
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.height(Length::Shrink)
|
.height(Length::Shrink)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.height(Length::Fill)
|
.center_x(Length::Fill)
|
||||||
.width(Length::Fill)
|
.center_y(Length::Fill)
|
||||||
.center_x()
|
|
||||||
.center_y()
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use calloop::LoopHandle;
|
use calloop::LoopHandle;
|
||||||
use cosmic::iced::{Color, Command};
|
use cosmic::iced::{Color, Task};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
input::KeyState,
|
input::KeyState,
|
||||||
|
|
@ -404,7 +404,7 @@ impl Program for CosmicWindowInternal {
|
||||||
&mut self,
|
&mut self,
|
||||||
message: Self::Message,
|
message: Self::Message,
|
||||||
loop_handle: &LoopHandle<'static, crate::state::State>,
|
loop_handle: &LoopHandle<'static, crate::state::State>,
|
||||||
) -> Command<Self::Message> {
|
) -> Task<Self::Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::DragStart => {
|
Message::DragStart => {
|
||||||
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
|
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
|
||||||
|
|
@ -504,7 +504,7 @@ impl Program for CosmicWindowInternal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Command::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background_color(&self, theme: &cosmic::Theme) -> Color {
|
fn background_color(&self, theme: &cosmic::Theme) -> Color {
|
||||||
|
|
@ -517,7 +517,7 @@ impl Program for CosmicWindowInternal {
|
||||||
|
|
||||||
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
||||||
let mut header = cosmic::widget::header_bar()
|
let mut header = cosmic::widget::header_bar()
|
||||||
.start(cosmic::widget::horizontal_space(32))
|
.start(cosmic::widget::horizontal_space().width(32))
|
||||||
.title(self.last_title.lock().unwrap().clone())
|
.title(self.last_title.lock().unwrap().clone())
|
||||||
.on_drag(Message::DragStart)
|
.on_drag(Message::DragStart)
|
||||||
.on_close(Message::Close)
|
.on_close(Message::Close)
|
||||||
|
|
@ -528,12 +528,12 @@ impl Program for CosmicWindowInternal {
|
||||||
if cosmic::config::show_minimize() {
|
if cosmic::config::show_minimize() {
|
||||||
header = header
|
header = header
|
||||||
.on_minimize(Message::Minimize)
|
.on_minimize(Message::Minimize)
|
||||||
.start(cosmic::widget::horizontal_space(40)); // 32 + 8 spacing
|
.start(cosmic::widget::horizontal_space().width(40)); // 32 + 8 spacing
|
||||||
}
|
}
|
||||||
if cosmic::config::show_maximize() {
|
if cosmic::config::show_maximize() {
|
||||||
header = header
|
header = header
|
||||||
.on_maximize(Message::Maximize)
|
.on_maximize(Message::Maximize)
|
||||||
.start(cosmic::widget::horizontal_space(40)); // 32 + 8 spacing
|
.start(cosmic::widget::horizontal_space().width(40)); // 32 + 8 spacing
|
||||||
}
|
}
|
||||||
|
|
||||||
header.into()
|
header.into()
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,17 @@ use cosmic::{
|
||||||
iced_core::{
|
iced_core::{
|
||||||
event, layout, mouse, overlay,
|
event, layout, mouse, overlay,
|
||||||
renderer::{Quad, Style},
|
renderer::{Quad, Style},
|
||||||
widget::{tree, Id, OperationOutputWrapper, Tree, Widget},
|
widget::{tree, Id, Tree, Widget},
|
||||||
Background, Border, Clipboard, Color, Event, Layout, Length, Rectangle,
|
Background, Border, Clipboard, Color, Event, Layout, Length, Rectangle,
|
||||||
Renderer as IcedRenderer, Shell, Size,
|
Renderer as IcedRenderer, Shell, Size,
|
||||||
},
|
},
|
||||||
widget::button::StyleSheet,
|
widget::button::Catalog,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SubmenuItem<'a, Message> {
|
pub struct SubmenuItem<'a, Message> {
|
||||||
elem: cosmic::Element<'a, Message>,
|
elem: cosmic::Element<'a, Message>,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
styling: <cosmic::Theme as StyleSheet>::Style,
|
styling: <cosmic::Theme as Catalog>::Class,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> SubmenuItem<'a, Message> {
|
impl<'a, Message> SubmenuItem<'a, Message> {
|
||||||
|
|
@ -25,7 +25,7 @@ impl<'a, Message> SubmenuItem<'a, Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style(mut self, style: <cosmic::Theme as StyleSheet>::Style) -> Self {
|
pub fn style(mut self, style: <cosmic::Theme as Catalog>::Class) -> Self {
|
||||||
self.styling = style;
|
self.styling = style;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ where
|
||||||
state: &mut Tree,
|
state: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
operation: &mut dyn cosmic::widget::Operation<OperationOutputWrapper<Message>>,
|
operation: &mut dyn cosmic::widget::Operation<()>,
|
||||||
) {
|
) {
|
||||||
let state = &mut state.children[0];
|
let state = &mut state.children[0];
|
||||||
let layout = layout.children().next().unwrap();
|
let layout = layout.children().next().unwrap();
|
||||||
|
|
@ -206,10 +206,13 @@ where
|
||||||
state: &'b mut Tree,
|
state: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &cosmic::Renderer,
|
renderer: &cosmic::Renderer,
|
||||||
|
translation: cosmic::iced::Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
|
||||||
let state = &mut state.children[0];
|
let state = &mut state.children[0];
|
||||||
let layout = layout.children().next().unwrap();
|
let layout = layout.children().next().unwrap();
|
||||||
self.elem.as_widget_mut().overlay(state, layout, renderer)
|
self.elem
|
||||||
|
.as_widget_mut()
|
||||||
|
.overlay(state, layout, renderer, translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ use calloop::LoopHandle;
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::{Alignment, Background},
|
iced::{Alignment, Background},
|
||||||
iced_core::{alignment::Horizontal, Border, Length, Rectangle as IcedRectangle},
|
iced_core::{alignment::Horizontal, Border, Length, Rectangle as IcedRectangle},
|
||||||
iced_widget::{self, text::Appearance as TextAppearance, Column, Row},
|
iced_widget::{self, text::Style as TextStyle, Column, Row},
|
||||||
theme,
|
theme,
|
||||||
widget::{button, divider, horizontal_space, icon::from_name, text},
|
widget::{button, divider, horizontal_space, icon::from_name, text},
|
||||||
Apply as _, Command,
|
Apply as _, Task,
|
||||||
};
|
};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
|
|
@ -202,7 +202,7 @@ impl Program for ContextMenu {
|
||||||
&mut self,
|
&mut self,
|
||||||
message: Self::Message,
|
message: Self::Message,
|
||||||
loop_handle: &LoopHandle<'static, crate::state::State>,
|
loop_handle: &LoopHandle<'static, crate::state::State>,
|
||||||
) -> Command<Self::Message> {
|
) -> Task<Self::Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::ItemPressed(idx) => {
|
Message::ItemPressed(idx) => {
|
||||||
if let Some(Item::Entry { on_press, .. }) = self.items.get_mut(idx) {
|
if let Some(Item::Entry { on_press, .. }) = self.items.get_mut(idx) {
|
||||||
|
|
@ -331,7 +331,7 @@ impl Program for ContextMenu {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Command::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
||||||
|
|
@ -350,7 +350,7 @@ impl Program for ContextMenu {
|
||||||
match item {
|
match item {
|
||||||
Item::Separator => divider::horizontal::light().into(),
|
Item::Separator => divider::horizontal::light().into(),
|
||||||
Item::Submenu { title, .. } => Row::with_children(vec![
|
Item::Submenu { title, .. } => Row::with_children(vec![
|
||||||
horizontal_space(16).into(),
|
horizontal_space().width(16).into(),
|
||||||
text::body(title).width(mode).into(),
|
text::body(title).width(mode).into(),
|
||||||
from_name("go-next-symbolic")
|
from_name("go-next-symbolic")
|
||||||
.size(16)
|
.size(16)
|
||||||
|
|
@ -361,7 +361,7 @@ impl Program for ContextMenu {
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.width(width)
|
.width(width)
|
||||||
.padding([8, 16])
|
.padding([8, 16])
|
||||||
.align_items(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.apply(|row| item::SubmenuItem::new(row, idx))
|
.apply(|row| item::SubmenuItem::new(row, idx))
|
||||||
.style(theme::Button::MenuItem)
|
.style(theme::Button::MenuItem)
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -378,20 +378,20 @@ impl Program for ContextMenu {
|
||||||
.size(16)
|
.size(16)
|
||||||
.prefer_svg(true)
|
.prefer_svg(true)
|
||||||
.icon()
|
.icon()
|
||||||
.style(theme::Svg::custom(|theme| iced_widget::svg::Appearance {
|
.class(theme::Svg::custom(|theme| iced_widget::svg::Style {
|
||||||
color: Some(theme.cosmic().accent.base.into()),
|
color: Some(theme.cosmic().accent.base.into()),
|
||||||
}))
|
}))
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
horizontal_space(16).into()
|
horizontal_space().width(16).into()
|
||||||
},
|
},
|
||||||
text::body(title)
|
text::body(title)
|
||||||
.width(mode)
|
.width(mode)
|
||||||
.style(if *disabled {
|
.class(if *disabled {
|
||||||
theme::Text::Custom(|theme| {
|
theme::Text::Custom(|theme| {
|
||||||
let mut color = theme.cosmic().background.component.on;
|
let mut color = theme.cosmic().background.component.on;
|
||||||
color.alpha *= 0.5;
|
color.alpha *= 0.5;
|
||||||
TextAppearance {
|
TextStyle {
|
||||||
color: Some(color.into()),
|
color: Some(color.into()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -399,17 +399,17 @@ impl Program for ContextMenu {
|
||||||
theme::Text::Default
|
theme::Text::Default
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
horizontal_space(16).into(),
|
horizontal_space().width(16).into(),
|
||||||
];
|
];
|
||||||
if let Some(shortcut) = shortcut.as_ref() {
|
if let Some(shortcut) = shortcut.as_ref() {
|
||||||
components.push(
|
components.push(
|
||||||
text::body(shortcut)
|
text::body(shortcut)
|
||||||
.horizontal_alignment(Horizontal::Right)
|
.align_x(Horizontal::Right)
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.style(theme::Text::Custom(|theme| {
|
.class(theme::Text::Custom(|theme| {
|
||||||
let mut color = theme.cosmic().background.component.on;
|
let mut color = theme.cosmic().background.component.on;
|
||||||
color.alpha *= 0.75;
|
color.alpha *= 0.75;
|
||||||
TextAppearance {
|
TextStyle {
|
||||||
color: Some(color.into()),
|
color: Some(color.into()),
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
@ -420,12 +420,12 @@ impl Program for ContextMenu {
|
||||||
Row::with_children(components)
|
Row::with_children(components)
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.width(mode)
|
.width(mode)
|
||||||
.align_items(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.apply(button::custom)
|
.apply(button::custom)
|
||||||
.width(width)
|
.width(width)
|
||||||
.padding([8, 16])
|
.padding([8, 16])
|
||||||
.on_press_maybe((!disabled).then_some(Message::ItemPressed(idx)))
|
.on_press_maybe((!disabled).then_some(Message::ItemPressed(idx)))
|
||||||
.style(theme::Button::MenuItem)
|
.class(theme::Button::MenuItem)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -433,10 +433,10 @@ impl Program for ContextMenu {
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.apply(iced_widget::container)
|
.apply(iced_widget::container)
|
||||||
.padding(1)
|
.padding(1)
|
||||||
.style(theme::Container::custom(|theme| {
|
.class(theme::Container::custom(|theme| {
|
||||||
let cosmic = theme.cosmic();
|
let cosmic = theme.cosmic();
|
||||||
let component = &cosmic.background.component;
|
let component = &cosmic.background.component;
|
||||||
iced_widget::container::Appearance {
|
iced_widget::container::Style {
|
||||||
icon_color: Some(cosmic.accent.base.into()),
|
icon_color: Some(cosmic.accent.base.into()),
|
||||||
text_color: Some(component.on.into()),
|
text_color: Some(component.on.into()),
|
||||||
background: Some(Background::Color(component.base.into())),
|
background: Some(Background::Color(component.base.into())),
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,24 @@ use cosmic::{
|
||||||
iced::{
|
iced::{
|
||||||
advanced::widget::Tree,
|
advanced::widget::Tree,
|
||||||
event::Event,
|
event::Event,
|
||||||
|
futures::{FutureExt, StreamExt},
|
||||||
keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers},
|
keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers},
|
||||||
mouse::{Button as MouseButton, Cursor, Event as MouseEvent, ScrollDelta},
|
mouse::{Button as MouseButton, Cursor, Event as MouseEvent, ScrollDelta},
|
||||||
touch::{Event as TouchEvent, Finger},
|
touch::{Event as TouchEvent, Finger},
|
||||||
window::{Event as WindowEvent, Id},
|
window::Event as WindowEvent,
|
||||||
Command, Limits, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize,
|
Limits, Point as IcedPoint, Size as IcedSize, Task,
|
||||||
},
|
},
|
||||||
iced_core::{clipboard::Null as NullClipboard, renderer::Style, Color, Length, Pixels},
|
iced_core::{clipboard::Null as NullClipboard, id::Id, renderer::Style, Color, Length, Pixels},
|
||||||
iced_renderer::graphics::Renderer as IcedGraphicsRenderer,
|
|
||||||
iced_runtime::{
|
iced_runtime::{
|
||||||
command::Action,
|
|
||||||
program::{Program as IcedProgram, State},
|
program::{Program as IcedProgram, State},
|
||||||
Debug,
|
task::into_stream,
|
||||||
|
Action, Debug,
|
||||||
},
|
},
|
||||||
Theme,
|
Theme,
|
||||||
};
|
};
|
||||||
use iced_tiny_skia::{
|
use iced_tiny_skia::{graphics::Viewport, Primitive};
|
||||||
graphics::{damage, Viewport},
|
|
||||||
Backend, Primitive,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
|
|
@ -67,6 +65,8 @@ use smithay::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ID: Lazy<Id> = Lazy::new(|| Id::new("Program"));
|
||||||
|
|
||||||
pub struct IcedElement<P: Program + Send + 'static>(pub(crate) Arc<Mutex<IcedElementInternal<P>>>);
|
pub struct IcedElement<P: Program + Send + 'static>(pub(crate) Arc<Mutex<IcedElementInternal<P>>>);
|
||||||
|
|
||||||
impl<P: Program + Send + 'static> fmt::Debug for IcedElement<P> {
|
impl<P: Program + Send + 'static> fmt::Debug for IcedElement<P> {
|
||||||
|
|
@ -104,9 +104,9 @@ pub trait Program {
|
||||||
&mut self,
|
&mut self,
|
||||||
message: Self::Message,
|
message: Self::Message,
|
||||||
loop_handle: &LoopHandle<'static, crate::state::State>,
|
loop_handle: &LoopHandle<'static, crate::state::State>,
|
||||||
) -> Command<Self::Message> {
|
) -> Task<Self::Message> {
|
||||||
let _ = (message, loop_handle);
|
let _ = (message, loop_handle);
|
||||||
Command::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
fn view(&self) -> cosmic::Element<'_, Self::Message>;
|
fn view(&self) -> cosmic::Element<'_, Self::Message>;
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
|
||||||
type Renderer = cosmic::Renderer;
|
type Renderer = cosmic::Renderer;
|
||||||
type Theme = cosmic::Theme;
|
type Theme = cosmic::Theme;
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
|
||||||
self.0.update(message, &self.1)
|
self.0.update(message, &self.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,9 +159,9 @@ pub(crate) struct IcedElementInternal<P: Program + Send + 'static> {
|
||||||
|
|
||||||
// futures
|
// futures
|
||||||
handle: LoopHandle<'static, crate::state::State>,
|
handle: LoopHandle<'static, crate::state::State>,
|
||||||
scheduler: Scheduler<<P as Program>::Message>,
|
scheduler: Scheduler<Option<<P as Program>::Message>>,
|
||||||
executor_token: Option<RegistrationToken>,
|
executor_token: Option<RegistrationToken>,
|
||||||
rx: Receiver<<P as Program>::Message>,
|
rx: Receiver<Option<<P as Program>::Message>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
|
impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
|
||||||
|
|
@ -178,14 +178,10 @@ impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
|
||||||
if !self.state.is_queue_empty() {
|
if !self.state.is_queue_empty() {
|
||||||
tracing::warn!("Missing force_update call");
|
tracing::warn!("Missing force_update call");
|
||||||
}
|
}
|
||||||
let mut renderer = cosmic::Renderer::TinySkia(IcedGraphicsRenderer::new(
|
let mut renderer = cosmic::Renderer::new(cosmic::font::default(), Pixels(16.0));
|
||||||
Backend::new(),
|
|
||||||
cosmic::font::default(),
|
|
||||||
Pixels(16.0),
|
|
||||||
));
|
|
||||||
let mut debug = Debug::new();
|
let mut debug = Debug::new();
|
||||||
let state = State::new(
|
let state = State::new(
|
||||||
Id::MAIN,
|
ID.clone(),
|
||||||
ProgramWrapper(self.state.program().0.clone(), handle.clone()),
|
ProgramWrapper(self.state.program().0.clone(), handle.clone()),
|
||||||
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
@ -244,15 +240,11 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
theme: cosmic::Theme,
|
theme: cosmic::Theme,
|
||||||
) -> IcedElement<P> {
|
) -> IcedElement<P> {
|
||||||
let size = size.into();
|
let size = size.into();
|
||||||
let mut renderer = cosmic::Renderer::TinySkia(IcedGraphicsRenderer::new(
|
let mut renderer = cosmic::Renderer::new(cosmic::font::default(), Pixels(16.0));
|
||||||
Backend::new(),
|
|
||||||
cosmic::font::default(),
|
|
||||||
Pixels(16.0),
|
|
||||||
));
|
|
||||||
let mut debug = Debug::new();
|
let mut debug = Debug::new();
|
||||||
|
|
||||||
let state = State::new(
|
let state = State::new(
|
||||||
Id::MAIN,
|
ID.clone(),
|
||||||
ProgramWrapper(program, handle.clone()),
|
ProgramWrapper(program, handle.clone()),
|
||||||
IcedSize::new(size.w as f32, size.h as f32),
|
IcedSize::new(size.w as f32, size.h as f32),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
@ -368,8 +360,8 @@ impl<P: Program + Send + 'static + Clone> IcedElement<P> {
|
||||||
|
|
||||||
impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
||||||
#[profiling::function]
|
#[profiling::function]
|
||||||
fn update(&mut self, mut force: bool) -> Vec<Action<<P as Program>::Message>> {
|
fn update(&mut self, mut force: bool) -> Vec<Task<<P as Program>::Message>> {
|
||||||
while let Ok(message) = self.rx.try_recv() {
|
while let Ok(Some(message)) = self.rx.try_recv() {
|
||||||
self.state.queue_message(message);
|
self.state.queue_message(message);
|
||||||
force = true;
|
force = true;
|
||||||
}
|
}
|
||||||
|
|
@ -383,17 +375,16 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
||||||
.map(|p| IcedPoint::new(p.x as f32, p.y as f32))
|
.map(|p| IcedPoint::new(p.x as f32, p.y as f32))
|
||||||
.map(Cursor::Available)
|
.map(Cursor::Available)
|
||||||
.unwrap_or(Cursor::Unavailable);
|
.unwrap_or(Cursor::Unavailable);
|
||||||
|
|
||||||
let actions = self
|
let actions = self
|
||||||
.state
|
.state
|
||||||
.update(
|
.update(
|
||||||
Id::MAIN,
|
ID.clone(),
|
||||||
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
||||||
cursor,
|
cursor,
|
||||||
&mut self.renderer,
|
&mut self.renderer,
|
||||||
&self.theme,
|
&self.theme,
|
||||||
&Style {
|
&Style {
|
||||||
scale_factor: 1.0, //TODO: why is this
|
scale_factor: 1.0, // TODO: why is this
|
||||||
icon_color: self.theme.cosmic().on_bg_color().into(),
|
icon_color: self.theme.cosmic().on_bg_color().into(),
|
||||||
text_color: self.theme.cosmic().on_bg_color().into(),
|
text_color: self.theme.cosmic().on_bg_color().into(),
|
||||||
},
|
},
|
||||||
|
|
@ -402,17 +393,15 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
||||||
)
|
)
|
||||||
.1;
|
.1;
|
||||||
|
|
||||||
actions
|
if let Some(action) = actions {
|
||||||
.into_iter()
|
if let Some(t) = into_stream(action) {
|
||||||
.filter_map(|action| {
|
let _ = self.scheduler.schedule(t.into_future().map(|f| match f.0 {
|
||||||
if let Action::Future(future) = action {
|
Some(Action::Output(msg)) => Some(msg),
|
||||||
let _ = self.scheduler.schedule(future);
|
_ => None,
|
||||||
None
|
}));
|
||||||
} else {
|
}
|
||||||
Some(action)
|
}
|
||||||
}
|
Vec::new()
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -751,14 +740,11 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
|
||||||
|
|
||||||
fn set_activate(&self, activated: bool) {
|
fn set_activate(&self, activated: bool) {
|
||||||
let mut internal = self.0.lock().unwrap();
|
let mut internal = self.0.lock().unwrap();
|
||||||
internal.state.queue_event(Event::Window(
|
internal.state.queue_event(Event::Window(if activated {
|
||||||
Id::MAIN,
|
WindowEvent::Focused
|
||||||
if activated {
|
} else {
|
||||||
WindowEvent::Focused
|
WindowEvent::Unfocused
|
||||||
} else {
|
}));
|
||||||
WindowEvent::Unfocused
|
|
||||||
},
|
|
||||||
));
|
|
||||||
let _ = internal.update(true); // TODO
|
let _ = internal.update(true); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -860,83 +846,62 @@ where
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
if force {
|
||||||
|
internal_ref.pending_update = None;
|
||||||
|
}
|
||||||
let _ = internal_ref.update(force);
|
let _ = internal_ref.update(force);
|
||||||
|
if let Some((buffer, _)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) {
|
||||||
if let Some((buffer, ref mut old_primitives)) =
|
|
||||||
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
|
|
||||||
{
|
|
||||||
let size: Size<i32, BufferCoords> = internal_ref
|
let size: Size<i32, BufferCoords> = internal_ref
|
||||||
.size
|
.size
|
||||||
.to_f64()
|
.to_f64()
|
||||||
.to_buffer(scale.x, Transform::Normal)
|
.to_buffer(scale.x, Transform::Normal)
|
||||||
.to_i32_round();
|
.to_i32_round();
|
||||||
|
|
||||||
if size.w > 0 && size.h > 0 {
|
if size.w > 0 && size.h > 0 {
|
||||||
let cosmic::Renderer::TinySkia(renderer) = &mut internal_ref.renderer;
|
|
||||||
let state_ref = &internal_ref.state;
|
let state_ref = &internal_ref.state;
|
||||||
let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
|
let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
|
||||||
let overlay = internal_ref.debug.overlay();
|
let overlay = internal_ref.debug.overlay();
|
||||||
let theme = &internal_ref.theme;
|
let theme = &internal_ref.theme;
|
||||||
|
|
||||||
buffer
|
_ = buffer.render().draw(|buf| {
|
||||||
.render()
|
let mut pixels =
|
||||||
.draw(move |buf| {
|
tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32)
|
||||||
let mut pixels =
|
.expect("Failed to create pixel map");
|
||||||
tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32)
|
|
||||||
.expect("Failed to create pixel map");
|
|
||||||
|
|
||||||
renderer.with_primitives(|backend, primitives| {
|
let background_color = state_ref.program().0.background_color(theme);
|
||||||
let background_color = state_ref.program().0.background_color(theme);
|
let bounds = IcedSize::new(size.w as u32, size.h as u32);
|
||||||
let bounds = IcedSize::new(size.w as u32, size.h as u32);
|
let viewport = Viewport::with_physical_size(bounds, scale.x);
|
||||||
let viewport = Viewport::with_physical_size(bounds, scale.x);
|
|
||||||
|
|
||||||
let mut damage = old_primitives
|
let damage = vec![cosmic::iced::Rectangle::new(
|
||||||
.as_ref()
|
cosmic::iced::Point::default(),
|
||||||
.and_then(|(last_primitives, last_color)| {
|
viewport.logical_size(),
|
||||||
(last_color == &background_color)
|
)];
|
||||||
.then(|| damage::list(last_primitives, primitives))
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
vec![IcedRectangle::with_size(viewport.logical_size())]
|
|
||||||
});
|
|
||||||
damage = damage::group(damage, scale.x as f32, bounds);
|
|
||||||
|
|
||||||
if !damage.is_empty() {
|
internal_ref.renderer.draw(
|
||||||
backend.draw(
|
&mut pixels,
|
||||||
&mut pixels,
|
&mut clip_mask,
|
||||||
&mut clip_mask,
|
&viewport,
|
||||||
primitives,
|
&damage,
|
||||||
&viewport,
|
background_color,
|
||||||
&damage,
|
&overlay,
|
||||||
background_color,
|
);
|
||||||
&overlay,
|
|
||||||
);
|
|
||||||
|
|
||||||
*old_primitives = Some((primitives.to_vec(), background_color));
|
let damage = damage
|
||||||
}
|
.into_iter()
|
||||||
|
.filter_map(|x| x.snap())
|
||||||
let damage = damage
|
.map(|damage_rect| {
|
||||||
.into_iter()
|
Rectangle::from_loc_and_size(
|
||||||
.map(|x| x.snap())
|
(damage_rect.x as i32, damage_rect.y as i32),
|
||||||
.map(|damage_rect| {
|
(damage_rect.width as i32, damage_rect.height as i32),
|
||||||
Rectangle::from_loc_and_size(
|
)
|
||||||
(damage_rect.x as i32, damage_rect.y as i32),
|
|
||||||
(damage_rect.width as i32, damage_rect.height as i32),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
state_ref.program().0.foreground(
|
|
||||||
&mut pixels,
|
|
||||||
&damage,
|
|
||||||
scale.x as f32,
|
|
||||||
theme,
|
|
||||||
);
|
|
||||||
|
|
||||||
Result::<_, ()>::Ok(damage)
|
|
||||||
})
|
})
|
||||||
})
|
.collect::<Vec<_>>();
|
||||||
.unwrap();
|
state_ref
|
||||||
|
.program()
|
||||||
|
.0
|
||||||
|
.foreground(&mut pixels, &damage, scale.x as f32, theme);
|
||||||
|
|
||||||
|
Result::<_, ()>::Ok(damage)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer(
|
if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer(
|
||||||
|
|
@ -946,9 +911,11 @@ where
|
||||||
Some(alpha),
|
Some(alpha),
|
||||||
Some(Rectangle::from_loc_and_size(
|
Some(Rectangle::from_loc_and_size(
|
||||||
(0., 0.),
|
(0., 0.),
|
||||||
size.to_f64().to_logical(1.0, Transform::Normal),
|
size.to_f64()
|
||||||
|
.to_logical(1., Transform::Normal)
|
||||||
|
.to_i32_round(),
|
||||||
)),
|
)),
|
||||||
Some(internal_ref.size),
|
Some(size.to_logical(1, Transform::Normal)),
|
||||||
Kind::Unspecified,
|
Kind::Unspecified,
|
||||||
) {
|
) {
|
||||||
return vec![C::from(buffer)];
|
return vec![C::from(buffer)];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue