Replies: 2 comments 1 reply
-
Hello @daladim |
Beta Was this translation helpful? Give feedback.
1 reply
-
One solution is to implement a custom widget that is just a proxy of Container. The widget ( use iced::{
advanced::Widget,
widget::{button, column, image::Handle, text, Container},
Sandbox,
};
fn main() -> iced::Result {
App::run(iced::Settings::default())
}
#[derive(Debug, Clone)]
enum Message {
DoNothing,
}
const PATH_TO_YOUR_IMAGE: &str = "/path/to/your/image";
struct App;
impl Sandbox for App {
type Message = Message;
fn new() -> Self {
Self
}
fn title(&self) -> String {
"Customized container with background".into()
}
fn update(&mut self, _message: Self::Message) {}
fn view(&self) -> iced::Element<'_, Self::Message> {
MyContainer::new(
column![text("Text"), button("Button").on_press(Message::DoNothing),],
PATH_TO_YOUR_IMAGE,
)
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.center_x()
.center_y()
.into()
}
}
pub struct MyContainer<'a, Message, Renderer>
where
Renderer: iced::advanced::Renderer,
Renderer::Theme: iced::widget::container::StyleSheet,
{
container: Container<'a, Message, Renderer>,
background: Handle,
}
impl<'a, Message, Renderer> MyContainer<'a, Message, Renderer>
where
Renderer: iced::advanced::Renderer,
Renderer::Theme: iced::widget::container::StyleSheet,
{
pub fn new<T, U>(content: T, background_path: U) -> Self
where
T: Into<iced::Element<'a, Message, Renderer>>,
U: Into<std::path::PathBuf>,
{
Self {
container: Container::new(content),
background: Handle::from_path(background_path),
}
}
pub fn id(mut self, id: iced::widget::container::Id) -> Self {
self.container = self.container.id(id);
self
}
pub fn padding<P: Into<iced::Padding>>(mut self, padding: P) -> Self {
self.container = self.container.padding(padding);
self
}
pub fn width(mut self, width: impl Into<iced::Length>) -> Self {
self.container = self.container.width(width);
self
}
pub fn height(mut self, height: impl Into<iced::Length>) -> Self {
self.container = self.container.height(height);
self
}
pub fn max_width(mut self, max_width: impl Into<iced::Pixels>) -> Self {
self.container = self.container.max_width(max_width);
self
}
pub fn max_height(mut self, max_height: impl Into<iced::Pixels>) -> Self {
self.container = self.container.max_height(max_height);
self
}
pub fn align_x(mut self, alignment: iced::alignment::Horizontal) -> Self {
self.container = self.container.align_x(alignment);
self
}
pub fn align_y(mut self, alignment: iced::alignment::Vertical) -> Self {
self.container = self.container.align_y(alignment);
self
}
pub fn center_x(mut self) -> Self {
self.container = self.container.center_x();
self
}
pub fn center_y(mut self) -> Self {
self.container = self.container.center_y();
self
}
pub fn style(
mut self,
style: impl Into<<Renderer::Theme as iced::widget::container::StyleSheet>::Style>,
) -> Self {
self.container = self.container.style(style);
self
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for MyContainer<'a, Message, Renderer>
where
Renderer: iced::advanced::Renderer + iced::advanced::image::Renderer<Handle = Handle>,
Renderer::Theme: iced::widget::container::StyleSheet,
{
fn width(&self) -> iced::Length {
Widget::width(&self.container)
}
fn height(&self) -> iced::Length {
Widget::height(&self.container)
}
fn layout(
&self,
renderer: &Renderer,
limits: &iced::advanced::layout::Limits,
) -> iced::advanced::layout::Node {
Widget::layout(&self.container, renderer, limits)
}
fn draw(
&self,
state: &iced::advanced::widget::Tree,
renderer: &mut Renderer,
theme: &Renderer::Theme,
style: &iced::advanced::renderer::Style,
layout: iced::advanced::Layout<'_>,
cursor: iced::advanced::mouse::Cursor,
viewport: &iced::Rectangle,
) {
iced::widget::image::draw(
renderer,
layout,
&self.background,
iced::ContentFit::Contain,
);
Widget::draw(
&self.container,
state,
renderer,
theme,
style,
layout,
cursor,
viewport,
)
}
fn tag(&self) -> iced::advanced::widget::tree::Tag {
Widget::tag(&self.container)
}
fn state(&self) -> iced::advanced::widget::tree::State {
Widget::state(&self.container)
}
fn children(&self) -> Vec<iced::advanced::widget::Tree> {
Widget::children(&self.container)
}
fn diff(&self, tree: &mut iced::advanced::widget::Tree) {
Widget::diff(&self.container, tree)
}
fn operate(
&self,
state: &mut iced::advanced::widget::Tree,
layout: iced::advanced::Layout<'_>,
renderer: &Renderer,
operation: &mut dyn iced::advanced::widget::Operation<Message>,
) {
Widget::operate(&self.container, state, layout, renderer, operation)
}
fn on_event(
&mut self,
state: &mut iced::advanced::widget::Tree,
event: iced::Event,
layout: iced::advanced::Layout<'_>,
cursor: iced::advanced::mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn iced::advanced::Clipboard,
shell: &mut iced::advanced::Shell<'_, Message>,
viewport: &iced::Rectangle,
) -> iced::event::Status {
Widget::on_event(
&mut self.container,
state,
event,
layout,
cursor,
renderer,
clipboard,
shell,
viewport,
)
}
fn mouse_interaction(
&self,
state: &iced::advanced::widget::Tree,
layout: iced::advanced::Layout<'_>,
cursor: iced::advanced::mouse::Cursor,
viewport: &iced::Rectangle,
renderer: &Renderer,
) -> iced::advanced::mouse::Interaction {
Widget::mouse_interaction(&self.container, state, layout, cursor, viewport, renderer)
}
fn overlay<'b>(
&'b mut self,
state: &'b mut iced::advanced::widget::Tree,
layout: iced::advanced::Layout<'_>,
renderer: &Renderer,
) -> Option<iced::advanced::overlay::Element<'b, Message, Renderer>> {
Widget::overlay(&mut self.container, state, layout, renderer)
}
}
impl<'a, Message, Renderer> From<MyContainer<'a, Message, Renderer>>
for iced::Element<'a, Message, Renderer>
where
Message: 'a,
Renderer: 'a + iced::advanced::Renderer + iced::advanced::image::Renderer<Handle = Handle>,
Renderer::Theme: iced::widget::container::StyleSheet,
{
fn from(
my_container: MyContainer<'a, Message, Renderer>,
) -> iced::Element<'a, Message, Renderer> {
iced::Element::new(my_container)
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello,
I am using
iced
to build native desktop apps.I'd like to have a background image on a widget (in my specific case, that's a
Column
widget), and still have the ability to add other widgets into thisColumn
.Unfortunately, the
Background
that is exposed though stylesheets only supports solid colors.Do you have any idea how I can achieve something similar to the following screenshot (that's an HTML page made outside of iced, using the
background-image
,background-position
,background-size
andbackground-repeat
CSS properties)?Maybe I could "cheat", and have two widgets (a
Column
with a transparent background, drawn on top of anImage
). To do so:Overlay
s, that look promising but they are not used in theexamples/
folder, so I'm not sure how to use them.Tooltip
s (especially because thetooltip
example indeed seems to draw widgets over other widgets), but it looks they are limited to text strings.Widget
implementations, but maybe I'll have to write a custom widget with a customdraw
implementation?Do you have any ideas?
Is this possible already? With a specific widget already doing so? With kind of a workaround?
Also, do you want me to create an issue or a feature request so that the
Background
enum could eventually support it?Thanks!
Beta Was this translation helpful? Give feedback.
All reactions