libcosmic updates

This commit is contained in:
Ashley Wulber 2024-10-16 20:36:46 -04:00 committed by Ashley Wulber
parent 9c62f19e4b
commit 0491c4baaa
91 changed files with 3550 additions and 2300 deletions

View file

@ -97,7 +97,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Menu<'a, S, Message> {
position: Point,
target_height: f32,
) -> overlay::Element<'a, Message, crate::Theme, crate::Renderer> {
overlay::Element::new(position, Box::new(Overlay::new(self, target_height)))
overlay::Element::new(Box::new(Overlay::new(self, target_height, position)))
}
}
@ -129,10 +129,15 @@ struct Overlay<'a, Message> {
width: f32,
target_height: f32,
style: (),
position: Point,
}
impl<'a, Message: 'a> Overlay<'a, Message> {
pub fn new<S: AsRef<str>>(menu: Menu<'a, S, Message>, target_height: f32) -> Self {
pub fn new<S: AsRef<str>>(
menu: Menu<'a, S, Message>,
target_height: f32,
position: Point,
) -> Self {
let Menu {
state,
options,
@ -160,7 +165,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
container = container
.padding(padding)
.style(crate::style::Container::Dropdown);
.class(crate::style::Container::Dropdown);
state.tree.diff(&mut container as &mut dyn Widget<_, _, _>);
@ -170,6 +175,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
width,
target_height,
style,
position,
}
}
}
@ -177,13 +183,8 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
impl<'a, Message> iced_core::Overlay<Message, crate::Theme, crate::Renderer>
for Overlay<'a, Message>
{
fn layout(
&mut self,
renderer: &crate::Renderer,
bounds: Size,
position: Point,
_translation: iced::Vector,
) -> layout::Node {
fn layout(&mut self, renderer: &crate::Renderer, bounds: Size) -> layout::Node {
let position = self.position;
let space_below = bounds.height - (position.y + self.target_height);
let space_above = position.y;
@ -447,10 +448,13 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Theme, crate::Renderer>
appearance.selected_background,
);
svg::Renderer::draw(
let svg_handle =
iced_core::Svg::new(crate::widget::common::object_select().clone())
.color(appearance.selected_text_color)
.border_radius(appearance.border_radius);
svg::Renderer::draw_svg(
renderer,
crate::widget::common::object_select().clone(),
Some(appearance.selected_text_color),
svg_handle,
Rectangle {
x: item_x + item_width - 16.0 - 8.0,
y: bounds.y + (bounds.height / 2.0 - 8.0),
@ -494,7 +498,7 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Theme, crate::Renderer>
text::Renderer::fill_text(
renderer,
Text {
content: option.as_ref(),
content: option.as_ref().to_string(),
bounds: bounds.size(),
size: Pixels(text_size),
line_height: self.text_line_height,
@ -502,7 +506,7 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Theme, crate::Renderer>
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
},
bounds.position(),
color,

View file

@ -97,7 +97,7 @@ where
position: Point,
target_height: f32,
) -> overlay::Element<'a, Message, crate::Theme, crate::Renderer> {
overlay::Element::new(position, Box::new(Overlay::new(self, target_height)))
overlay::Element::new(Box::new(Overlay::new(self, target_height, position)))
}
}
@ -129,12 +129,14 @@ struct Overlay<'a, Message> {
width: f32,
target_height: f32,
style: (),
position: Point,
}
impl<'a, Message: 'a> Overlay<'a, Message> {
pub fn new<S: AsRef<str>, Item: Clone + PartialEq>(
menu: Menu<'a, S, Item, Message>,
target_height: f32,
position: Point,
) -> Self {
let Menu {
state,
@ -163,7 +165,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
container = container
.padding(padding)
.style(crate::style::Container::Dropdown);
.class(crate::style::Container::Dropdown);
state.tree.diff(&mut container as &mut dyn Widget<_, _, _>);
@ -173,6 +175,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
width,
target_height,
style,
position,
}
}
}
@ -180,13 +183,8 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
impl<'a, Message> iced_core::Overlay<Message, crate::Theme, crate::Renderer>
for Overlay<'a, Message>
{
fn layout(
&mut self,
renderer: &crate::Renderer,
bounds: Size,
position: Point,
_translation: iced::Vector,
) -> layout::Node {
fn layout(&mut self, renderer: &crate::Renderer, bounds: Size) -> layout::Node {
let position = self.position;
let space_below = bounds.height - (position.y + self.target_height);
let space_above = position.y;
@ -537,10 +535,13 @@ where
appearance.selected_background,
);
svg::Renderer::draw(
let svg_handle =
svg::Svg::new(crate::widget::common::object_select().clone())
.color(appearance.selected_text_color)
.border_radius(appearance.border_radius);
svg::Renderer::draw_svg(
renderer,
crate::widget::common::object_select().clone(),
Some(appearance.selected_text_color),
svg_handle,
Rectangle {
x: item_x + item_width - 16.0 - 8.0,
y: bounds.y + (bounds.height / 2.0 - 8.0),
@ -587,7 +588,7 @@ where
text::Renderer::fill_text(
renderer,
Text {
content: option.as_ref(),
content: option.as_ref().to_string(),
bounds: bounds.size(),
size: iced::Pixels(text_size),
line_height: self.text_line_height,
@ -595,7 +596,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
},
bounds.position(),
color,
@ -636,7 +637,7 @@ where
text::Renderer::fill_text(
renderer,
Text {
content: description.as_ref(),
content: description.as_ref().to_string(),
bounds: bounds.size(),
size: iced::Pixels(text_size),
line_height: text::LineHeight::Absolute(Pixels(text_line_height + 4.0)),
@ -644,7 +645,7 @@ where
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
},
bounds.position(),
appearance.description_color,

View file

@ -9,7 +9,7 @@ pub mod menu;
pub use menu::Menu;
mod widget;
pub use widget::{Appearance, Dropdown, StyleSheet};
pub use widget::{Catalog, Dropdown, Style};
pub fn dropdown<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>(
model: &'a Model<S, Item>,

View file

@ -9,10 +9,13 @@ use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text};
use iced_core::widget::tree::{self, Tree};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch, Shadow};
use iced_core::{Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Widget};
use iced_core::{
Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Vector, Widget,
};
use iced_widget::pick_list;
use std::ffi::OsStr;
pub use iced_widget::style::pick_list::{Appearance, StyleSheet};
pub use iced_widget::pick_list::{Catalog, Style};
/// A widget for selecting a single value from a list of selections.
#[derive(Setters)]
@ -98,7 +101,7 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
for (_, item) in &list.options {
state
.selections
.push((item.clone(), crate::Paragraph::new()));
.push((item.clone(), crate::Plain::default()));
}
}
}
@ -182,6 +185,7 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let state = tree.state.downcast_mut::<State<Item>>();
@ -216,8 +220,8 @@ pub struct State<Item: Clone + PartialEq + 'static> {
keyboard_modifiers: keyboard::Modifiers,
is_open: bool,
hovered_option: Option<Item>,
selections: Vec<(Item, crate::Paragraph)>,
descriptions: Vec<crate::Paragraph>,
selections: Vec<(Item, crate::Plain)>,
descriptions: Vec<crate::Plain>,
}
impl<Item: Clone + PartialEq + 'static> State<Item> {
@ -259,7 +263,7 @@ pub fn layout(
text_size: f32,
text_line_height: text::LineHeight,
font: Option<crate::font::Font>,
selection: Option<(&str, &mut crate::Paragraph)>,
selection: Option<(&str, &mut crate::Plain)>,
) -> layout::Node {
use std::f32;
@ -267,7 +271,7 @@ pub fn layout(
let max_width = match width {
Length::Shrink => {
let measure = move |(label, paragraph): (_, &mut crate::Paragraph)| -> f32 {
let measure = move |(label, paragraph): (_, &mut crate::Plain)| -> f32 {
paragraph.update(Text {
content: label,
bounds: Size::new(f32::MAX, f32::MAX),
@ -277,7 +281,7 @@ pub fn layout(
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
});
paragraph.min_width().round()
};
@ -410,7 +414,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static
)
.width({
let measure =
|label: &str, paragraph: &mut crate::Paragraph, line_height: text::LineHeight| {
|label: &str, paragraph: &mut crate::Plain, line_height: text::LineHeight| {
paragraph.update(Text {
content: label,
bounds: Size::new(f32::MAX, f32::MAX),
@ -420,7 +424,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
});
paragraph.min_width().round()
};
@ -433,7 +437,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static
let paragraph = if state.descriptions.len() > desc_count {
&mut state.descriptions[desc_count]
} else {
state.descriptions.push(crate::Paragraph::new());
state.descriptions.push(crate::Plain::default());
state.descriptions.last_mut().unwrap()
};
desc_count += 1;
@ -448,7 +452,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static
None => {
state
.selections
.push((item.clone(), crate::Paragraph::new()));
.push((item.clone(), crate::Plain::default()));
state.selections.len() - 1
}
};
@ -499,9 +503,9 @@ pub fn draw<'a, S, Item: Clone + PartialEq + 'static>(
let is_mouse_over = cursor.is_over(bounds);
let style = if is_mouse_over {
theme.hovered(&())
theme.style(&(), pick_list::Status::Hovered)
} else {
theme.active(&())
theme.style(&(), pick_list::Status::Active)
};
iced_core::Renderer::fill_quad(
@ -515,10 +519,10 @@ pub fn draw<'a, S, Item: Clone + PartialEq + 'static>(
);
if let Some(handle) = state.icon.clone() {
svg::Renderer::draw(
let svg_handle = iced_core::Svg::new(handle).color(style.text_color);
svg::Renderer::draw_svg(
renderer,
handle,
Some(style.text_color),
svg_handle,
Rectangle {
x: bounds.x + bounds.width - gap - 16.0,
y: bounds.center_y() - 8.0,
@ -541,7 +545,7 @@ pub fn draw<'a, S, Item: Clone + PartialEq + 'static>(
text::Renderer::fill_text(
renderer,
Text {
content,
content: content.to_string(),
size: iced::Pixels(text_size),
line_height: text_line_height,
font,
@ -549,7 +553,7 @@ pub fn draw<'a, S, Item: Clone + PartialEq + 'static>(
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
},
bounds.position(),
style.text_color,

View file

@ -5,16 +5,18 @@
use super::menu::{self, Menu};
use crate::widget::icon;
use derive_setters::Setters;
use iced::Radians;
use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text};
use iced_core::widget::tree::{self, Tree};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch, Shadow};
use iced_core::{Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Widget};
use iced_core::{
Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Vector, Widget,
};
use iced_widget::pick_list::{self, Catalog};
use std::ffi::OsStr;
use std::hash::{DefaultHasher, Hash, Hasher};
pub use iced_widget::style::pick_list::{Appearance, StyleSheet};
/// A widget for selecting a single value from a list of selections.
#[derive(Setters)]
pub struct Dropdown<'a, S: AsRef<str>, Message> {
@ -62,6 +64,29 @@ impl<'a, S: AsRef<str>, Message> Dropdown<'a, S, Message> {
font: None,
}
}
fn update_paragraphs(&self, state: &mut tree::State) {
let state = state.downcast_mut::<State>();
state
.selections
.resize_with(self.selections.len(), crate::Plain::default);
for (i, selection) in self.selections.iter().enumerate() {
state.selections[i].update(Text {
content: selection.as_ref(),
bounds: Size::INFINITY,
// TODO use the renderer default size
size: iced::Pixels(self.text_size.unwrap_or(14.0)),
line_height: self.text_line_height,
font: self.font.unwrap_or(crate::font::default()),
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::default(),
});
}
}
}
impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Theme, crate::Renderer>
@ -80,7 +105,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Theme, crate::Render
state
.selections
.resize_with(self.selections.len(), crate::Paragraph::new);
.resize_with(self.selections.len(), crate::Plain::default);
state.hashes.resize(self.selections.len(), 0);
for (i, selection) in self.selections.iter().enumerate() {
@ -103,7 +128,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Theme, crate::Render
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
});
}
}
@ -202,6 +227,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Theme, crate::Render
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let state = tree.state.downcast_mut::<State>();
@ -237,8 +263,8 @@ pub struct State {
keyboard_modifiers: keyboard::Modifiers,
is_open: bool,
hovered_option: Option<usize>,
selections: Vec<crate::Paragraph>,
hashes: Vec<u64>,
selections: Vec<crate::Plain>,
}
impl State {
@ -280,7 +306,7 @@ pub fn layout(
text_size: f32,
text_line_height: text::LineHeight,
font: Option<crate::font::Font>,
selection: Option<(&str, &mut crate::Paragraph)>,
selection: Option<(&str, &mut crate::Plain)>,
) -> layout::Node {
use std::f32;
@ -288,7 +314,7 @@ pub fn layout(
let max_width = match width {
Length::Shrink => {
let measure = move |(label, paragraph): (_, &mut crate::Paragraph)| -> f32 {
let measure = move |(label, paragraph): (_, &mut crate::Plain)| -> f32 {
paragraph.update(Text {
content: label,
bounds: Size::new(f32::MAX, f32::MAX),
@ -298,7 +324,7 @@ pub fn layout(
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
});
paragraph.min_width().round()
};
@ -430,14 +456,14 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a>(
None,
)
.width({
let measure = |_label: &str, selection_paragraph: &mut crate::Paragraph| -> f32 {
let measure = |_label: &str, selection_paragraph: &crate::Paragraph| -> f32 {
selection_paragraph.min_width().round()
};
selections
.iter()
.zip(state.selections.iter_mut())
.map(|(label, selection)| measure(label.as_ref(), selection))
.map(|(label, selection)| measure(label.as_ref(), selection.raw()))
.fold(0.0, |next, current| current.max(next))
+ gap
+ 16.0
@ -477,9 +503,9 @@ pub fn draw<'a, S>(
let is_mouse_over = cursor.is_over(bounds);
let style = if is_mouse_over {
theme.hovered(&())
theme.style(&(), pick_list::Status::Hovered)
} else {
theme.active(&())
theme.style(&(), pick_list::Status::Active)
};
iced_core::Renderer::fill_quad(
@ -493,10 +519,11 @@ pub fn draw<'a, S>(
);
if let Some(handle) = state.icon.clone() {
svg::Renderer::draw(
let svg_handle = svg::Svg::new(handle).color(style.text_color);
svg::Renderer::draw_svg(
renderer,
handle,
Some(style.text_color),
svg_handle,
Rectangle {
x: bounds.x + bounds.width - gap - 16.0,
y: bounds.center_y() - 8.0,
@ -517,7 +544,7 @@ pub fn draw<'a, S>(
text::Renderer::fill_text(
renderer,
Text {
content,
content: content.to_string(),
size: iced::Pixels(text_size),
line_height: text_line_height,
font,
@ -525,7 +552,7 @@ pub fn draw<'a, S>(
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrap: text::Wrap::default(),
wrapping: text::Wrapping::default(),
},
bounds.position(),
style.text_color,