Add styling support for ComboBox
and Menu
This commit is contained in:
parent
0ff5a02550
commit
61f22b1db2
@ -1,3 +1,8 @@
|
|||||||
pub use iced_native::combo_box::State;
|
pub use iced_native::combo_box::State;
|
||||||
|
|
||||||
pub type ComboBox<'a, T, Message> = iced_native::ComboBox<'a, T, Message>;
|
pub use iced_graphics::combo_box::{Style, StyleSheet};
|
||||||
|
pub use iced_graphics::overlay::menu::Style as Menu;
|
||||||
|
|
||||||
|
/// A widget allowing the selection of a single value from a list of options.
|
||||||
|
pub type ComboBox<'a, T, Message> =
|
||||||
|
iced_native::ComboBox<'a, T, Message, crate::Renderer>;
|
||||||
|
@ -9,18 +9,18 @@
|
|||||||
#![forbid(rust_2018_idioms)]
|
#![forbid(rust_2018_idioms)]
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
mod antialiasing;
|
mod antialiasing;
|
||||||
mod overlay;
|
|
||||||
mod primitive;
|
mod primitive;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod transformation;
|
mod transformation;
|
||||||
mod viewport;
|
mod viewport;
|
||||||
mod widget;
|
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod defaults;
|
pub mod defaults;
|
||||||
pub mod font;
|
pub mod font;
|
||||||
pub mod layer;
|
pub mod layer;
|
||||||
|
pub mod overlay;
|
||||||
pub mod triangle;
|
pub mod triangle;
|
||||||
|
pub mod widget;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
@ -1 +1 @@
|
|||||||
mod menu;
|
pub mod menu;
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
use crate::backend::Backend;
|
use crate::backend::Backend;
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
mouse, overlay, Background, Color, Font, HorizontalAlignment, Point,
|
mouse, overlay, Color, Font, HorizontalAlignment, Point, Rectangle,
|
||||||
Rectangle, VerticalAlignment,
|
VerticalAlignment,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use iced_style::menu::Style;
|
||||||
|
|
||||||
impl<B> overlay::menu::Renderer for Renderer<B>
|
impl<B> overlay::menu::Renderer for Renderer<B>
|
||||||
where
|
where
|
||||||
B: Backend,
|
B: Backend,
|
||||||
{
|
{
|
||||||
|
type Style = Style;
|
||||||
|
|
||||||
fn decorate(
|
fn decorate(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
|
style: &Style,
|
||||||
(primitives, mouse_cursor): Self::Output,
|
(primitives, mouse_cursor): Self::Output,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
(
|
(
|
||||||
@ -20,11 +25,9 @@ where
|
|||||||
primitives: vec![
|
primitives: vec![
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color(
|
background: style.background,
|
||||||
[0.87, 0.87, 0.87].into(),
|
border_color: style.border_color,
|
||||||
),
|
border_width: style.border_width,
|
||||||
border_color: [0.7, 0.7, 0.7].into(),
|
|
||||||
border_width: 1,
|
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
},
|
},
|
||||||
primitives,
|
primitives,
|
||||||
@ -42,6 +45,7 @@ where
|
|||||||
hovered_option: Option<usize>,
|
hovered_option: Option<usize>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: &Style,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
|
||||||
@ -63,7 +67,7 @@ where
|
|||||||
if is_selected {
|
if is_selected {
|
||||||
primitives.push(Primitive::Quad {
|
primitives.push(Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color([0.4, 0.4, 1.0].into()),
|
background: style.selected_background,
|
||||||
border_color: Color::TRANSPARENT,
|
border_color: Color::TRANSPARENT,
|
||||||
border_width: 0,
|
border_width: 0,
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
@ -81,9 +85,9 @@ where
|
|||||||
size: f32::from(text_size),
|
size: f32::from(text_size),
|
||||||
font: Font::Default,
|
font: Font::Default,
|
||||||
color: if is_selected {
|
color: if is_selected {
|
||||||
Color::WHITE
|
style.selected_text_color
|
||||||
} else {
|
} else {
|
||||||
Color::BLACK
|
style.text_color
|
||||||
},
|
},
|
||||||
horizontal_alignment: HorizontalAlignment::Left,
|
horizontal_alignment: HorizontalAlignment::Left,
|
||||||
vertical_alignment: VerticalAlignment::Center,
|
vertical_alignment: VerticalAlignment::Center,
|
||||||
|
@ -1,18 +1,29 @@
|
|||||||
use crate::backend::{self, Backend};
|
use crate::backend::{self, Backend};
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
mouse, Background, Color, Font, HorizontalAlignment, Point, Rectangle,
|
mouse, Font, HorizontalAlignment, Point, Rectangle, VerticalAlignment,
|
||||||
VerticalAlignment,
|
|
||||||
};
|
};
|
||||||
|
use iced_style::menu;
|
||||||
|
|
||||||
pub use iced_native::ComboBox;
|
pub use iced_native::combo_box::State;
|
||||||
|
pub use iced_style::combo_box::{Style, StyleSheet};
|
||||||
|
|
||||||
|
/// A widget allowing the selection of a single value from a list of options.
|
||||||
|
pub type ComboBox<'a, T, Message, Backend> =
|
||||||
|
iced_native::ComboBox<'a, T, Message, Renderer<Backend>>;
|
||||||
|
|
||||||
impl<B> iced_native::combo_box::Renderer for Renderer<B>
|
impl<B> iced_native::combo_box::Renderer for Renderer<B>
|
||||||
where
|
where
|
||||||
B: Backend + backend::Text,
|
B: Backend + backend::Text,
|
||||||
{
|
{
|
||||||
|
type Style = Box<dyn StyleSheet>;
|
||||||
|
|
||||||
const DEFAULT_PADDING: u16 = 5;
|
const DEFAULT_PADDING: u16 = 5;
|
||||||
|
|
||||||
|
fn menu_style(style: &Box<dyn StyleSheet>) -> menu::Style {
|
||||||
|
style.menu()
|
||||||
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
@ -20,31 +31,34 @@ where
|
|||||||
selected: Option<String>,
|
selected: Option<String>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: &Box<dyn StyleSheet>,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
||||||
|
let style = if is_mouse_over {
|
||||||
|
style.hovered()
|
||||||
|
} else {
|
||||||
|
style.active()
|
||||||
|
};
|
||||||
|
|
||||||
let background = Primitive::Quad {
|
let background = Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color([0.87, 0.87, 0.87].into()),
|
background: style.background,
|
||||||
border_color: if is_mouse_over {
|
border_color: style.border_color,
|
||||||
Color::BLACK
|
border_width: style.border_width,
|
||||||
} else {
|
border_radius: style.border_radius,
|
||||||
[0.7, 0.7, 0.7].into()
|
|
||||||
},
|
|
||||||
border_width: 1,
|
|
||||||
border_radius: 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let arrow_down = Primitive::Text {
|
let arrow_down = Primitive::Text {
|
||||||
content: B::ARROW_DOWN_ICON.to_string(),
|
content: B::ARROW_DOWN_ICON.to_string(),
|
||||||
font: B::ICON_FONT,
|
font: B::ICON_FONT,
|
||||||
size: bounds.height * 0.7,
|
size: bounds.height * style.icon_size,
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: bounds.x + bounds.width - f32::from(padding) * 2.0,
|
x: bounds.x + bounds.width - f32::from(padding) * 2.0,
|
||||||
y: bounds.center_y(),
|
y: bounds.center_y(),
|
||||||
..bounds
|
..bounds
|
||||||
},
|
},
|
||||||
color: Color::BLACK,
|
color: style.text_color,
|
||||||
horizontal_alignment: HorizontalAlignment::Right,
|
horizontal_alignment: HorizontalAlignment::Right,
|
||||||
vertical_alignment: VerticalAlignment::Center,
|
vertical_alignment: VerticalAlignment::Center,
|
||||||
};
|
};
|
||||||
@ -56,7 +70,7 @@ where
|
|||||||
content: label,
|
content: label,
|
||||||
size: f32::from(text_size),
|
size: f32::from(text_size),
|
||||||
font: Font::Default,
|
font: Font::Default,
|
||||||
color: Color::BLACK,
|
color: style.text_color,
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: bounds.x + f32::from(padding),
|
x: bounds.x + f32::from(padding),
|
||||||
y: bounds.center_y(),
|
y: bounds.center_y(),
|
||||||
|
@ -10,6 +10,7 @@ pub struct Menu<'a, Message, Renderer: self::Renderer> {
|
|||||||
is_open: &'a mut bool,
|
is_open: &'a mut bool,
|
||||||
width: u16,
|
width: u16,
|
||||||
target_height: f32,
|
target_height: f32,
|
||||||
|
style: <Renderer as self::Renderer>::Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -43,6 +44,7 @@ where
|
|||||||
target_height: f32,
|
target_height: f32,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: <Renderer as self::Renderer>::Style,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
T: Clone + ToString,
|
T: Clone + ToString,
|
||||||
@ -55,6 +57,7 @@ where
|
|||||||
on_selected,
|
on_selected,
|
||||||
text_size,
|
text_size,
|
||||||
padding,
|
padding,
|
||||||
|
style.clone(),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.padding(1);
|
.padding(1);
|
||||||
@ -64,6 +67,7 @@ where
|
|||||||
is_open: &mut state.is_open,
|
is_open: &mut state.is_open,
|
||||||
width,
|
width,
|
||||||
target_height,
|
target_height,
|
||||||
|
style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,11 +160,16 @@ where
|
|||||||
self.container
|
self.container
|
||||||
.draw(renderer, defaults, layout, cursor_position);
|
.draw(renderer, defaults, layout, cursor_position);
|
||||||
|
|
||||||
renderer.decorate(layout.bounds(), cursor_position, primitives)
|
renderer.decorate(
|
||||||
|
layout.bounds(),
|
||||||
|
cursor_position,
|
||||||
|
&self.style,
|
||||||
|
primitives,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct List<'a, T, Message>
|
struct List<'a, T, Message, Renderer: self::Renderer>
|
||||||
where
|
where
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
{
|
{
|
||||||
@ -169,9 +178,10 @@ where
|
|||||||
on_selected: Box<dyn Fn(T) -> Message>,
|
on_selected: Box<dyn Fn(T) -> Message>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: <Renderer as self::Renderer>::Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Message> List<'a, T, Message>
|
impl<'a, T, Message, Renderer: self::Renderer> List<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
{
|
{
|
||||||
@ -181,6 +191,7 @@ where
|
|||||||
on_selected: Box<dyn Fn(T) -> Message>,
|
on_selected: Box<dyn Fn(T) -> Message>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: <Renderer as self::Renderer>::Style,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
List {
|
List {
|
||||||
hovered_option,
|
hovered_option,
|
||||||
@ -188,12 +199,13 @@ where
|
|||||||
on_selected,
|
on_selected,
|
||||||
text_size,
|
text_size,
|
||||||
padding,
|
padding,
|
||||||
|
style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Message, Renderer> Widget<'a, Message, Renderer>
|
impl<'a, T, Message, Renderer: self::Renderer> Widget<'a, Message, Renderer>
|
||||||
for List<'a, T, Message>
|
for List<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
T: ToString + Clone,
|
T: ToString + Clone,
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
@ -286,15 +298,19 @@ where
|
|||||||
*self.hovered_option,
|
*self.hovered_option,
|
||||||
self.text_size,
|
self.text_size,
|
||||||
self.padding,
|
self.padding,
|
||||||
|
&self.style,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Renderer: scrollable::Renderer + container::Renderer {
|
pub trait Renderer: scrollable::Renderer + container::Renderer {
|
||||||
|
type Style: Default + Clone;
|
||||||
|
|
||||||
fn decorate(
|
fn decorate(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
|
style: &<Self as Renderer>::Style,
|
||||||
primitive: Self::Output,
|
primitive: Self::Output,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
|
|
||||||
@ -306,16 +322,17 @@ pub trait Renderer: scrollable::Renderer + container::Renderer {
|
|||||||
hovered_option: Option<usize>,
|
hovered_option: Option<usize>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: &<Self as Renderer>::Style,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Message, Renderer> Into<Element<'a, Message, Renderer>>
|
impl<'a, T, Message, Renderer> Into<Element<'a, Message, Renderer>>
|
||||||
for List<'a, T, Message>
|
for List<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
T: ToString + Clone,
|
T: ToString + Clone,
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
Message: 'static,
|
Message: 'static,
|
||||||
Renderer: self::Renderer,
|
Renderer: 'a + self::Renderer,
|
||||||
{
|
{
|
||||||
fn into(self) -> Element<'a, Message, Renderer> {
|
fn into(self) -> Element<'a, Message, Renderer> {
|
||||||
Element::new(self)
|
Element::new(self)
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub struct ComboBox<'a, T, Message>
|
pub struct ComboBox<'a, T, Message, Renderer: self::Renderer>
|
||||||
where
|
where
|
||||||
[T]: ToOwned<Owned = Vec<T>>,
|
[T]: ToOwned<Owned = Vec<T>>,
|
||||||
{
|
{
|
||||||
@ -16,6 +16,7 @@ where
|
|||||||
width: Length,
|
width: Length,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
text_size: Option<u16>,
|
text_size: Option<u16>,
|
||||||
|
style: <Renderer as self::Renderer>::Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -28,7 +29,8 @@ pub struct Internal<'a, T, Message> {
|
|||||||
on_selected: Box<dyn Fn(T) -> Message>,
|
on_selected: Box<dyn Fn(T) -> Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a, Message> ComboBox<'a, T, Message>
|
impl<'a, T: 'a, Message, Renderer: self::Renderer>
|
||||||
|
ComboBox<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
T: ToString,
|
T: ToString,
|
||||||
[T]: ToOwned<Owned = Vec<T>>,
|
[T]: ToOwned<Owned = Vec<T>>,
|
||||||
@ -48,7 +50,8 @@ where
|
|||||||
selected,
|
selected,
|
||||||
width: Length::Shrink,
|
width: Length::Shrink,
|
||||||
text_size: None,
|
text_size: None,
|
||||||
padding: 5,
|
padding: Renderer::DEFAULT_PADDING,
|
||||||
|
style: <Renderer as self::Renderer>::Style::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,10 +75,21 @@ where
|
|||||||
self.text_size = Some(size);
|
self.text_size = Some(size);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the style of the [`ComboBox`].
|
||||||
|
///
|
||||||
|
/// [`ComboBox`]: struct.ComboBox.html
|
||||||
|
pub fn style(
|
||||||
|
mut self,
|
||||||
|
style: impl Into<<Renderer as self::Renderer>::Style>,
|
||||||
|
) -> Self {
|
||||||
|
self.style = style.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a, Message, Renderer> Widget<'a, Message, Renderer>
|
impl<'a, T: 'a, Message, Renderer> Widget<'a, Message, Renderer>
|
||||||
for ComboBox<'a, T, Message>
|
for ComboBox<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
T: Clone + ToString + Eq,
|
T: Clone + ToString + Eq,
|
||||||
[T]: ToOwned<Owned = Vec<T>>,
|
[T]: ToOwned<Owned = Vec<T>>,
|
||||||
@ -196,6 +210,7 @@ where
|
|||||||
self.selected.as_ref().map(ToString::to_string),
|
self.selected.as_ref().map(ToString::to_string),
|
||||||
self.text_size.unwrap_or(renderer.default_size()),
|
self.text_size.unwrap_or(renderer.default_size()),
|
||||||
self.padding,
|
self.padding,
|
||||||
|
&self.style,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +238,7 @@ where
|
|||||||
bounds.height,
|
bounds.height,
|
||||||
self.text_size.unwrap_or(20),
|
self.text_size.unwrap_or(20),
|
||||||
self.padding,
|
self.padding,
|
||||||
|
Renderer::menu_style(&self.style),
|
||||||
)),
|
)),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@ -235,8 +251,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Renderer: text::Renderer + menu::Renderer {
|
pub trait Renderer: text::Renderer + menu::Renderer {
|
||||||
|
type Style: Default;
|
||||||
|
|
||||||
const DEFAULT_PADDING: u16;
|
const DEFAULT_PADDING: u16;
|
||||||
|
|
||||||
|
fn menu_style(
|
||||||
|
style: &<Self as Renderer>::Style,
|
||||||
|
) -> <Self as menu::Renderer>::Style;
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
@ -244,11 +266,12 @@ pub trait Renderer: text::Renderer + menu::Renderer {
|
|||||||
selected: Option<String>,
|
selected: Option<String>,
|
||||||
text_size: u16,
|
text_size: u16,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
|
style: &<Self as Renderer>::Style,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a, Message, Renderer> Into<Element<'a, Message, Renderer>>
|
impl<'a, T: 'a, Message, Renderer> Into<Element<'a, Message, Renderer>>
|
||||||
for ComboBox<'a, T, Message>
|
for ComboBox<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
T: Clone + ToString + Eq,
|
T: Clone + ToString + Eq,
|
||||||
[T]: ToOwned<Owned = Vec<T>>,
|
[T]: ToOwned<Owned = Vec<T>>,
|
||||||
|
70
style/src/combo_box.rs
Normal file
70
style/src/combo_box.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use crate::menu;
|
||||||
|
use iced_core::{Background, Color};
|
||||||
|
|
||||||
|
/// The appearance of a combo box.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Style {
|
||||||
|
pub text_color: Color,
|
||||||
|
pub background: Background,
|
||||||
|
pub border_radius: u16,
|
||||||
|
pub border_width: u16,
|
||||||
|
pub border_color: Color,
|
||||||
|
pub icon_size: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for Style {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
text_color: Color::BLACK,
|
||||||
|
background: Background::Color([0.87, 0.87, 0.87].into()),
|
||||||
|
border_radius: 0,
|
||||||
|
border_width: 1,
|
||||||
|
border_color: [0.7, 0.7, 0.7].into(),
|
||||||
|
icon_size: 0.7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A set of rules that dictate the style of a container.
|
||||||
|
pub trait StyleSheet {
|
||||||
|
fn menu(&self) -> menu::Style;
|
||||||
|
|
||||||
|
fn active(&self) -> Style;
|
||||||
|
|
||||||
|
/// Produces the style of a container.
|
||||||
|
fn hovered(&self) -> Style;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Default;
|
||||||
|
|
||||||
|
impl StyleSheet for Default {
|
||||||
|
fn menu(&self) -> menu::Style {
|
||||||
|
menu::Style::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn active(&self) -> Style {
|
||||||
|
Style::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hovered(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
border_color: Color::BLACK,
|
||||||
|
..self.active()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for Box<dyn StyleSheet> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Box::new(Default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for Box<dyn StyleSheet>
|
||||||
|
where
|
||||||
|
T: 'static + StyleSheet,
|
||||||
|
{
|
||||||
|
fn from(style: T) -> Self {
|
||||||
|
Box::new(style)
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,9 @@ pub use iced_core::{Background, Color};
|
|||||||
|
|
||||||
pub mod button;
|
pub mod button;
|
||||||
pub mod checkbox;
|
pub mod checkbox;
|
||||||
|
pub mod combo_box;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
|
pub mod menu;
|
||||||
pub mod progress_bar;
|
pub mod progress_bar;
|
||||||
pub mod radio;
|
pub mod radio;
|
||||||
pub mod scrollable;
|
pub mod scrollable;
|
||||||
|
25
style/src/menu.rs
Normal file
25
style/src/menu.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use iced_core::{Background, Color};
|
||||||
|
|
||||||
|
/// The appearance of a menu.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Style {
|
||||||
|
pub text_color: Color,
|
||||||
|
pub background: Background,
|
||||||
|
pub border_width: u16,
|
||||||
|
pub border_color: Color,
|
||||||
|
pub selected_text_color: Color,
|
||||||
|
pub selected_background: Background,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for Style {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
text_color: Color::BLACK,
|
||||||
|
background: Background::Color([0.87, 0.87, 0.87].into()),
|
||||||
|
border_width: 1,
|
||||||
|
border_color: [0.7, 0.7, 0.7].into(),
|
||||||
|
selected_text_color: Color::WHITE,
|
||||||
|
selected_background: Background::Color([0.4, 0.4, 1.0].into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
pub use iced_native::combo_box::State;
|
pub use iced_native::combo_box::State;
|
||||||
|
|
||||||
pub type ComboBox<'a, T, Message> = iced_native::ComboBox<'a, T, Message>;
|
pub use iced_graphics::combo_box::{Style, StyleSheet};
|
||||||
|
pub use iced_graphics::overlay::menu::Style as Menu;
|
||||||
|
|
||||||
|
/// A widget allowing the selection of a single value from a list of options.
|
||||||
|
pub type ComboBox<'a, T, Message> =
|
||||||
|
iced_native::ComboBox<'a, T, Message, crate::Renderer>;
|
||||||
|
Loading…
Reference in New Issue
Block a user