Cosmic advanced text (#103)
* wip: update to use cosmic-advanced-text * use cosmic-advanced-text branch of iced * fix: line height and spacing for segmented button and update to get svg fix * fix: spin button styling & spacing * update iced to fix segmented button border radius * feat: example improvements * feat: helper for loading fonts * feat: add focus style to button * fix: slider height and iced fixed * feat: hash icon width and height * cleanup * update ci * refactor: always use lazy feature of iced * update iced * update iced * cleanup & update iced * update iced: new slider & tiny-skia quad updates * update iced: fixes for tiny-skia quad rendering with edge case border radius * re-export iced_runtime & iced_widget * merge master * udpate iced * update iced * update iced * update iced * fix: make rectangle_tracker subscription only return update if there is some * feat: derive macro for loading a cosmic-config * feat (cosmic-config): iced subscription * fix (example): update to rectangle tracker subscription * fix (cosmic-config) * refactor(cosmic-config-derive): add support for types with generic parameters * fix (cosmic-config): feature gate updates for subscription helpers * feat: support for custom & system themes + move cosmic-theme to libcosmic * feat: sorta hacky way of creating header bars for libcosmic + update iced to get support for resizable windows in iced-sctk * update iced * update and reexport sctk * fix: applet border radius * feat (cosmic-theme): add id and name methods * fix(cosmic-theme): reexport palette from cosmic-theme * fix(cosmic-config-derive): allow use with reexported cosmic-config * feat: update iced with fix and refactor applet env vars * update iced
This commit is contained in:
parent
a173794bed
commit
e056e8c830
65 changed files with 3431 additions and 405 deletions
|
|
@ -8,7 +8,7 @@ use super::style::StyleSheet;
|
|||
use super::widget::{SegmentedButton, SegmentedVariant};
|
||||
|
||||
use iced::{Length, Rectangle, Size};
|
||||
use iced_native::layout;
|
||||
use iced_core::layout;
|
||||
|
||||
/// Horizontal [`SegmentedButton`].
|
||||
pub type HorizontalSegmentedButton<'a, SelectionMode, Message, Renderer> =
|
||||
|
|
@ -25,10 +25,10 @@ pub fn horizontal<SelectionMode: Default, Message, Renderer>(
|
|||
model: &Model<SelectionMode>,
|
||||
) -> SegmentedButton<Horizontal, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Model<SelectionMode>: Selectable,
|
||||
{
|
||||
|
|
@ -38,10 +38,10 @@ where
|
|||
impl<'a, SelectionMode, Message, Renderer> SegmentedVariant
|
||||
for SegmentedButton<'a, Horizontal, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Model<SelectionMode>: Selectable,
|
||||
SelectionMode: Default,
|
||||
|
|
@ -49,8 +49,8 @@ where
|
|||
type Renderer = Renderer;
|
||||
|
||||
fn variant_appearance(
|
||||
theme: &<Self::Renderer as iced_native::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style,
|
||||
theme: &<Self::Renderer as iced_core::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_core::Renderer>::Theme as StyleSheet>::Style,
|
||||
) -> super::Appearance {
|
||||
theme.horizontal(style)
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ where
|
|||
}
|
||||
|
||||
let size = limits
|
||||
.height(Length::Units(height as u16))
|
||||
.height(Length::Fixed(height))
|
||||
.resolve(Size::new(width, height));
|
||||
|
||||
layout::Node::new(size)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2022 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use iced_core::{Background, BorderRadius, Color};
|
||||
use iced_core::{renderer::BorderRadius, Background, Color};
|
||||
|
||||
/// Appearance of the segmented button.
|
||||
#[derive(Default, Clone, Copy)]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use super::style::StyleSheet;
|
|||
use super::widget::{SegmentedButton, SegmentedVariant};
|
||||
|
||||
use iced::{Length, Rectangle, Size};
|
||||
use iced_native::layout;
|
||||
use iced_core::layout;
|
||||
|
||||
/// A type marker defining the vertical variant of a [`SegmentedButton`].
|
||||
pub struct Vertical;
|
||||
|
|
@ -25,10 +25,10 @@ pub fn vertical<SelectionMode, Message, Renderer>(
|
|||
model: &Model<SelectionMode>,
|
||||
) -> SegmentedButton<Vertical, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Model<SelectionMode>: Selectable,
|
||||
SelectionMode: Default,
|
||||
|
|
@ -39,10 +39,10 @@ where
|
|||
impl<'a, SelectionMode, Message, Renderer> SegmentedVariant
|
||||
for SegmentedButton<'a, Vertical, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Model<SelectionMode>: Selectable,
|
||||
SelectionMode: Default,
|
||||
|
|
@ -50,8 +50,8 @@ where
|
|||
type Renderer = Renderer;
|
||||
|
||||
fn variant_appearance(
|
||||
theme: &<Self::Renderer as iced_native::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style,
|
||||
theme: &<Self::Renderer as iced_core::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_core::Renderer>::Theme as StyleSheet>::Style,
|
||||
) -> super::Appearance {
|
||||
theme.vertical(style)
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ where
|
|||
}
|
||||
|
||||
let size = limits
|
||||
.height(Length::Units(height as u16))
|
||||
.height(Length::Fixed(height))
|
||||
.resolve(Size::new(width, height));
|
||||
|
||||
layout::Node::new(size)
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ use iced::{
|
|||
alignment, event, keyboard, mouse, touch, Background, Color, Command, Element, Event, Length,
|
||||
Point, Rectangle, Size,
|
||||
};
|
||||
use iced_core::BorderRadius;
|
||||
use iced_native::widget::{self, operation, tree, Operation};
|
||||
use iced_native::{layout, renderer, widget::Tree, Clipboard, Layout, Shell, Widget};
|
||||
use iced_core::renderer::BorderRadius;
|
||||
use iced_core::text::{LineHeight, Shaping};
|
||||
use iced_core::widget::{self, operation, tree};
|
||||
use iced_core::{layout, renderer, widget::Tree, Clipboard, Layout, Shell, Widget};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// State that is maintained by each individual widget.
|
||||
|
|
@ -46,15 +47,15 @@ impl operation::Focusable for LocalState {
|
|||
|
||||
/// Isolates variant-specific behaviors from [`SegmentedButton`].
|
||||
pub trait SegmentedVariant {
|
||||
type Renderer: iced_native::Renderer;
|
||||
type Renderer: iced_core::Renderer;
|
||||
|
||||
/// Get the appearance for this variant of the widget.
|
||||
fn variant_appearance(
|
||||
theme: &<Self::Renderer as iced_native::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style,
|
||||
theme: &<Self::Renderer as iced_core::Renderer>::Theme,
|
||||
style: &<<Self::Renderer as iced_core::Renderer>::Theme as StyleSheet>::Style,
|
||||
) -> super::Appearance
|
||||
where
|
||||
<Self::Renderer as iced_native::Renderer>::Theme: StyleSheet;
|
||||
<Self::Renderer as iced_core::Renderer>::Theme: StyleSheet;
|
||||
|
||||
/// Calculates the bounds for the given button by its position.
|
||||
fn variant_button_bounds(&self, bounds: Rectangle, position: usize) -> Rectangle;
|
||||
|
|
@ -67,10 +68,10 @@ pub trait SegmentedVariant {
|
|||
#[derive(Setters)]
|
||||
pub struct SegmentedButton<'a, Variant, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Model<SelectionMode>: Selectable,
|
||||
SelectionMode: Default,
|
||||
|
|
@ -91,13 +92,13 @@ where
|
|||
/// Spacing between icon and text in button.
|
||||
pub(super) button_spacing: u16,
|
||||
/// Desired font for active tabs.
|
||||
pub(super) font_active: Renderer::Font,
|
||||
pub(super) font_active: Option<Renderer::Font>,
|
||||
/// Desired font for hovered tabs.
|
||||
pub(super) font_hovered: Renderer::Font,
|
||||
pub(super) font_hovered: Option<Renderer::Font>,
|
||||
/// Desired font for inactive tabs.
|
||||
pub(super) font_inactive: Renderer::Font,
|
||||
pub(super) font_inactive: Option<Renderer::Font>,
|
||||
/// Size of the font.
|
||||
pub(super) font_size: u16,
|
||||
pub(super) font_size: f32,
|
||||
/// Size of icon
|
||||
pub(super) icon_size: u16,
|
||||
/// Desired width of the widget.
|
||||
|
|
@ -106,6 +107,8 @@ where
|
|||
pub(super) height: Length,
|
||||
/// Desired spacing between items.
|
||||
pub(super) spacing: u16,
|
||||
/// LineHeight of the font.
|
||||
pub(super) line_height: LineHeight,
|
||||
/// Style to draw the widget in.
|
||||
#[setters(into)]
|
||||
pub(super) style: <Renderer::Theme as StyleSheet>::Style,
|
||||
|
|
@ -122,10 +125,10 @@ where
|
|||
impl<'a, Variant, SelectionMode, Message, Renderer>
|
||||
SegmentedButton<'a, Variant, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Self: SegmentedVariant<Renderer = Renderer>,
|
||||
Model<SelectionMode>: Selectable,
|
||||
|
|
@ -141,14 +144,15 @@ where
|
|||
button_padding: [4, 4, 4, 4],
|
||||
button_height: 32,
|
||||
button_spacing: 4,
|
||||
font_active: Renderer::Font::default(),
|
||||
font_hovered: Renderer::Font::default(),
|
||||
font_inactive: Renderer::Font::default(),
|
||||
font_size: 17,
|
||||
font_active: None,
|
||||
font_hovered: None,
|
||||
font_inactive: None,
|
||||
font_size: 17.0,
|
||||
icon_size: 16,
|
||||
height: Length::Shrink,
|
||||
width: Length::Fill,
|
||||
spacing: 0,
|
||||
line_height: LineHeight::default(),
|
||||
style: <Renderer::Theme as StyleSheet>::Style::default(),
|
||||
on_activate: None,
|
||||
on_close: None,
|
||||
|
|
@ -212,6 +216,7 @@ where
|
|||
pub(super) fn max_button_dimensions(&self, renderer: &Renderer, bounds: Size) -> (f32, f32) {
|
||||
let mut width = 0.0f32;
|
||||
let mut height = 0.0f32;
|
||||
let font = renderer.default_font();
|
||||
|
||||
for key in self.model.order.iter().copied() {
|
||||
let mut button_width = 0.0f32;
|
||||
|
|
@ -219,7 +224,14 @@ where
|
|||
|
||||
// Add text to measurement if text was given.
|
||||
if let Some(text) = self.model.text(key) {
|
||||
let (w, h) = renderer.measure(text, self.font_size, Default::default(), bounds);
|
||||
let (w, h) = renderer.measure(
|
||||
text,
|
||||
self.font_size,
|
||||
self.line_height,
|
||||
font,
|
||||
bounds,
|
||||
Shaping::Advanced,
|
||||
);
|
||||
|
||||
button_width = w;
|
||||
button_height = h;
|
||||
|
|
@ -253,10 +265,10 @@ where
|
|||
impl<'a, Variant, SelectionMode, Message, Renderer> Widget<Message, Renderer>
|
||||
for SegmentedButton<'a, Variant, SelectionMode, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer,
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer,
|
||||
Renderer::Theme: StyleSheet,
|
||||
Self: SegmentedVariant<Renderer = Renderer>,
|
||||
Model<SelectionMode>: Selectable,
|
||||
|
|
@ -379,7 +391,10 @@ where
|
|||
&self,
|
||||
tree: &mut Tree,
|
||||
_layout: Layout<'_>,
|
||||
operation: &mut dyn Operation<Message>,
|
||||
_renderer: &Renderer,
|
||||
operation: &mut dyn iced_core::widget::Operation<
|
||||
iced_core::widget::OperationOutputWrapper<Message>,
|
||||
>,
|
||||
) {
|
||||
let state = tree.state.downcast_mut::<LocalState>();
|
||||
operation.focusable(state, self.id.as_ref().map(|id| &id.0));
|
||||
|
|
@ -392,7 +407,7 @@ where
|
|||
cursor_position: iced::Point,
|
||||
_viewport: &iced::Rectangle,
|
||||
_renderer: &Renderer,
|
||||
) -> iced_native::mouse::Interaction {
|
||||
) -> iced_core::mouse::Interaction {
|
||||
let bounds = layout.bounds();
|
||||
|
||||
if bounds.contains(cursor_position) {
|
||||
|
|
@ -402,15 +417,15 @@ where
|
|||
.contains(cursor_position)
|
||||
{
|
||||
return if self.model.items[key].enabled {
|
||||
iced_native::mouse::Interaction::Pointer
|
||||
iced_core::mouse::Interaction::Pointer
|
||||
} else {
|
||||
iced_native::mouse::Interaction::Idle
|
||||
iced_core::mouse::Interaction::Idle
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iced_native::mouse::Interaction::Idle
|
||||
iced_core::mouse::Interaction::Idle
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
|
|
@ -418,7 +433,7 @@ where
|
|||
&self,
|
||||
tree: &Tree,
|
||||
renderer: &mut Renderer,
|
||||
theme: &<Renderer as iced_native::Renderer>::Theme,
|
||||
theme: &<Renderer as iced_core::Renderer>::Theme,
|
||||
_style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
_cursor_position: iced::Point,
|
||||
|
|
@ -458,6 +473,7 @@ where
|
|||
} else {
|
||||
(appearance.inactive, &self.font_inactive)
|
||||
};
|
||||
let font = font.unwrap_or_else(|| renderer.default_font());
|
||||
|
||||
let button_appearance = if nth == 0 {
|
||||
status_appearance.first
|
||||
|
|
@ -536,7 +552,7 @@ where
|
|||
unimplemented!()
|
||||
}
|
||||
icon::Handle::Svg(handle) => {
|
||||
iced_native::svg::Renderer::draw(renderer, handle, icon_color, icon_bounds);
|
||||
iced_core::svg::Renderer::draw(renderer, handle, icon_color, icon_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,14 +566,16 @@ where
|
|||
bounds.y = y;
|
||||
|
||||
// Draw the text in this button.
|
||||
renderer.fill_text(iced_native::text::Text {
|
||||
renderer.fill_text(iced_core::text::Text {
|
||||
content: text,
|
||||
size: f32::from(self.font_size),
|
||||
size: self.font_size,
|
||||
bounds,
|
||||
color: status_appearance.text_color,
|
||||
font: font.clone(),
|
||||
font,
|
||||
horizontal_alignment,
|
||||
vertical_alignment: alignment::Vertical::Center,
|
||||
shaping: Shaping::Advanced,
|
||||
line_height: self.line_height,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -575,7 +593,7 @@ where
|
|||
unimplemented!()
|
||||
}
|
||||
icon::Handle::Svg(handle) => {
|
||||
iced_native::svg::Renderer::draw(
|
||||
iced_core::svg::Renderer::draw(
|
||||
renderer,
|
||||
handle,
|
||||
Some(status_appearance.text_color),
|
||||
|
|
@ -588,11 +606,11 @@ where
|
|||
}
|
||||
|
||||
fn overlay<'b>(
|
||||
&'b self,
|
||||
&'b mut self,
|
||||
_tree: &'b mut Tree,
|
||||
_layout: iced_native::Layout<'_>,
|
||||
_layout: iced_core::Layout<'_>,
|
||||
_renderer: &Renderer,
|
||||
) -> Option<iced_native::overlay::Element<'b, Message, Renderer>> {
|
||||
) -> Option<iced_core::overlay::Element<'b, Message, Renderer>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -601,10 +619,10 @@ impl<'a, Variant, SelectionMode, Message, Renderer>
|
|||
From<SegmentedButton<'a, Variant, SelectionMode, Message, Renderer>>
|
||||
for Element<'a, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer
|
||||
+ iced_native::text::Renderer
|
||||
+ iced_native::image::Renderer
|
||||
+ iced_native::svg::Renderer
|
||||
Renderer: iced_core::Renderer
|
||||
+ iced_core::text::Renderer
|
||||
+ iced_core::image::Renderer
|
||||
+ iced_core::svg::Renderer
|
||||
+ 'a,
|
||||
Renderer::Theme: StyleSheet,
|
||||
SegmentedButton<'a, Variant, SelectionMode, Message, Renderer>:
|
||||
|
|
@ -624,7 +642,6 @@ where
|
|||
}
|
||||
|
||||
/// A command that focuses a segmented item stored in a widget.
|
||||
#[must_use]
|
||||
pub fn focus<Message: 'static>(id: Id) -> Command<Message> {
|
||||
Command::widget(operation::focusable::focus(id.0))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue