I wanted to change the background color of a container and, using the twentyone project chapter 5 as a starting point, I was able to get it to work.
However, it would be much more intuitive if you could just write ‘container.set_background_color(color)’ or more generally 'widget.set_<some_attribute(attribute_value)> so I came up with this code:
use iced::widget::{container, row, text};
use iced::{Background, Color, Element, Sandbox, Settings};
use iced::theme::Container;
#[derive(Default)]
pub struct BackgroundColor {
color: Color,
}
impl BackgroundColor {
const fn new(color: Color) -> Self {
Self { color: color }
}
const RED: Color = Color::from_rgb(1.0, 0.0, 0.0);
const GREEN: Color = Color::from_rgb(0.0, 1.0, 0.0);
const BLUE: Color = Color::from_rgb(0.0, 0.0, 1.0);
const CYAN: Color = Color::from_rgb(0.0, 1.0, 1.0);
const YELLOW: Color = Color::from_rgb(1.0, 1.0, 0.0);
}
impl iced::widget::container::StyleSheet for BackgroundColor {
type Style = iced::Theme;
fn appearance(&self, _style: &Self::Style) -> container::Appearance {
container::Appearance {
background: Some(Background::from(self.color)),
..Default::default()
}
}
}
/////////////////////////////////////////////
pub trait SetAppearance {
fn set_background(self, color: Color) -> Self;
}
impl SetAppearance for container::Container<'_, Message> {
fn set_background(self, color: Color) -> Self {
self.style(Container::Custom(Box::new(BackgroundColor::new(color))))
}
}
/////////////////////////////////////////////
#[derive(Debug)]
enum Message {}
struct SimGui;
fn main() -> iced::Result {
SimGui::run(Settings::default())
}
impl Sandbox for SimGui {
type Message = Message;
fn new() -> Self {
Self
}
fn title(&self) -> String {
String::from("SimGui")
}
fn update(&mut self, message: Message) {
match message {}
}
fn view(&self) ->Element<'_, Message> {
let t1 = text("This Should have a red background");
let c1 = container(t1)
.set_background(BackgroundColor::RED)
.padding(10);
let t2 = text("This should have a green background");
let c2 = container(t2)
.set_background(BackgroundColor::GREEN)
.padding(10);
let t3 = text("This should have a blue background");
let c3 = container(t3)
.set_background(BackgroundColor::BLUE)
.padding(10);
row![c1,c2,c3].into()
}
}
which works but there is a problem in that if I wanted to add another function to the SetAppearance trait, say, set_border(), and chain set_background() and set_border(), then the second call would negate the first one because of the use of …Default::default() in the appearance() function.
What I really need to do is get the current Appearance of the widget and modify it rather than creating a new one but I could not find a way to do that.
So my first question is: is there a way to get the Appearance that a widget is displayed with?
The second thing that I wanted to do is move the BackgroundColor and SetAppearance into another file but I was not able to get it to work. Message is defined in the main.rs but it is needed by SetAppearance.