From 66fdd2525dd494872a2a596d1efb38be26e2f310 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 6 Oct 2023 13:37:38 -0600 Subject: [PATCH] Add image container to draw background, more adjustment to design --- .gitattributes | 1 + res/background.png | 3 + src/image_container.rs | 150 +++++++++++++++++++++++++++++++++++++++++ src/locker.rs | 66 ++++++++++-------- src/main.rs | 1 + 5 files changed, 193 insertions(+), 28 deletions(-) create mode 100644 .gitattributes create mode 100644 res/background.png create mode 100644 src/image_container.rs diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..24a8e87 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/res/background.png b/res/background.png new file mode 100644 index 0000000..8201dbc --- /dev/null +++ b/res/background.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5b3b5384bc5ad9c9f733507db02097b4fbcc017fffac565775ba3d7eb77577c +size 4468456 diff --git a/src/image_container.rs b/src/image_container.rs new file mode 100644 index 0000000..67d54cd --- /dev/null +++ b/src/image_container.rs @@ -0,0 +1,150 @@ +use cosmic::iced::widget::{image::Handle, Container}; +use cosmic::iced_core::event::{self, Event}; +use cosmic::iced_core::layout; +use cosmic::iced_core::mouse; +use cosmic::iced_core::overlay; +use cosmic::iced_core::renderer; +use cosmic::iced_core::widget::{Operation, Tree}; +use cosmic::iced_core::{Clipboard, Element, Layout, Length, Rectangle, Shell, Widget}; +use cosmic::iced_renderer::core::widget::OperationOutputWrapper; + +pub use cosmic::iced_style::container::{Appearance, StyleSheet}; + +pub struct ImageContainer<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer, + Renderer::Theme: StyleSheet, +{ + container: Container<'a, Message, Renderer>, + image_opt: Option, +} + +impl<'a, Message, Renderer> ImageContainer<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer, + Renderer::Theme: StyleSheet, +{ + pub fn new(container: Container<'a, Message, Renderer>) -> Self { + Self { + container, + image_opt: None, + } + } + + pub fn image(mut self, image: Handle) -> Self { + self.image_opt = Some(image); + self + } +} + +impl<'a, Message, Renderer> Widget for ImageContainer<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer, + Renderer::Theme: StyleSheet, +{ + fn children(&self) -> Vec { + self.container.children() + } + + fn diff(&mut self, tree: &mut Tree) { + self.container.diff(tree) + } + + fn width(&self) -> Length { + Widget::width(&self.container) + } + + fn height(&self) -> Length { + Widget::height(&self.container) + } + + fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node { + self.container.layout(renderer, limits) + } + + fn operate( + &self, + tree: &mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + operation: &mut dyn Operation>, + ) { + self.container.operate(tree, layout, renderer, operation) + } + + fn on_event( + &mut self, + tree: &mut Tree, + event: Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + viewport: &Rectangle, + ) -> event::Status { + self.container.on_event( + tree, event, layout, cursor, renderer, clipboard, shell, viewport, + ) + } + + fn mouse_interaction( + &self, + tree: &Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + renderer: &Renderer, + ) -> mouse::Interaction { + self.container + .mouse_interaction(tree, layout, cursor, viewport, renderer) + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + theme: &Renderer::Theme, + renderer_style: &renderer::Style, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + ) { + match &self.image_opt { + Some(image) => renderer.draw(image.clone(), layout.bounds()), + None => {} + } + + self.container.draw( + tree, + renderer, + theme, + renderer_style, + layout, + cursor, + viewport, + ) + } + + fn overlay<'b>( + &'b mut self, + tree: &'b mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + ) -> Option> { + self.container.overlay(tree, layout, renderer) + } +} + +impl<'a, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + Message: 'a, + Renderer: + 'a + cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer, + Renderer::Theme: StyleSheet, +{ + fn from(container: ImageContainer<'a, Message, Renderer>) -> Element<'a, Message, Renderer> { + Element::new(container) + } +} diff --git a/src/locker.rs b/src/locker.rs index 8ec6631..3a9744c 100644 --- a/src/locker.rs +++ b/src/locker.rs @@ -45,9 +45,13 @@ pub fn main(current_user: pwd::Passwd) -> Result<(), Box> None }; + //TODO: use background config + let background = widget::image::Handle::from_memory(include_bytes!("../res/background.png")); + let flags = Flags { current_user, icon_opt, + background, }; let settings = Settings::default() @@ -141,6 +145,7 @@ impl pam_client::ConversationHandler for Conversation { pub struct Flags { current_user: pwd::Passwd, icon_opt: Option, + background: widget::image::Handle, } /// Messages that are used specifically by our [`App`]. @@ -223,6 +228,12 @@ impl cosmic::Application for App { OutputEvent::Created(_output_info_opt) => { log::info!("output {}: created", output.id()); + //TODO: COVER ALL OUTPUTS AFTER FIXING FOCUS BUG + if !self.surface_ids.is_empty() { + log::error!("COVER ALL OUTPUTS AFTER FIXING FOCUS BUG"); + return Command::none(); + } + let surface_id = self.next_surface_id; self.next_surface_id.0 += 1; @@ -446,36 +457,35 @@ impl cosmic::Application for App { .width(Length::Fill) }; - widget::container( - widget::cosmic_container::container( - iced::widget::row![left_element, right_element] - .align_items(alignment::Alignment::Center), + crate::image_container::ImageContainer::new( + widget::container( + widget::cosmic_container::container( + iced::widget::row![left_element, right_element] + .align_items(alignment::Alignment::Center), + ) + .layer(cosmic::cosmic_theme::Layer::Background) + .padding(16) + .style(cosmic::theme::Container::Custom(Box::new( + |theme: &cosmic::Theme| { + // Use background appearance as the base + let mut appearance = widget::container::StyleSheet::appearance( + theme, + &cosmic::theme::Container::Background, + ); + appearance.border_radius = 16.0.into(); + appearance + }, + ))) + .width(Length::Fixed(800.0)), ) - .layer(cosmic::cosmic_theme::Layer::Background) - .padding(16) - .style(cosmic::theme::Container::Custom(Box::new( - |theme: &cosmic::Theme| { - // Use background appearance as the base - let mut appearance = widget::container::StyleSheet::appearance( - theme, - &cosmic::theme::Container::Background, - ); - appearance.border_radius = 16.0.into(); - appearance - }, - ))) - .width(Length::Fixed(800.0)), + .padding([32.0, 0.0, 0.0, 0.0]) + .width(Length::Fill) + .height(Length::Fill) + .align_x(alignment::Horizontal::Center) + .align_y(alignment::Vertical::Top) + .style(cosmic::theme::Container::Transparent), ) - .padding([32.0, 0.0, 0.0, 0.0]) - .width(Length::Fill) - .height(Length::Fill) - .align_x(alignment::Horizontal::Center) - .align_y(alignment::Vertical::Top) - .style(cosmic::theme::Container::Custom(Box::new(|_| { - let mut appearance = widget::container::Appearance::default(); - appearance.background = Some(iced::Background::Color(iced::Color::BLACK)); - appearance - }))) + .image(self.flags.background.clone()) .into() } diff --git a/src/main.rs b/src/main.rs index e0e69a4..c76cd38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only mod greeter; +mod image_container; mod locker; fn main() -> Result<(), Box> {