diff options
author | 2023-10-24 05:34:24 +0200 | |
---|---|---|
committer | 2024-02-02 02:27:25 +0100 | |
commit | 7cba9a3e7fe609ca29066fb4b2e5dbf5a1dbd316 (patch) | |
tree | c2da9f18dc390d5863123500d35365ff89584790 /examples/loupe | |
parent | f4d66486016076bb339a338bc589645119962d1e (diff) | |
download | iced-7cba9a3e7fe609ca29066fb4b2e5dbf5a1dbd316.tar.gz iced-7cba9a3e7fe609ca29066fb4b2e5dbf5a1dbd316.tar.bz2 iced-7cba9a3e7fe609ca29066fb4b2e5dbf5a1dbd316.zip |
Implement `loupe` example
Diffstat (limited to 'examples/loupe')
-rw-r--r-- | examples/loupe/Cargo.toml | 10 | ||||
-rw-r--r-- | examples/loupe/src/main.rs | 185 |
2 files changed, 195 insertions, 0 deletions
diff --git a/examples/loupe/Cargo.toml b/examples/loupe/Cargo.toml new file mode 100644 index 00000000..466905ba --- /dev/null +++ b/examples/loupe/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "loupe" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] +edition = "2021" +publish = false + +[dependencies] +iced.workspace = true +iced.features = ["advanced", "debug"]
\ No newline at end of file diff --git a/examples/loupe/src/main.rs b/examples/loupe/src/main.rs new file mode 100644 index 00000000..8602edb7 --- /dev/null +++ b/examples/loupe/src/main.rs @@ -0,0 +1,185 @@ +use iced::widget::{button, column, container, text}; +use iced::{Alignment, Element, Length, Sandbox, Settings}; + +use loupe::loupe; + +pub fn main() -> iced::Result { + Counter::run(Settings::default()) +} + +struct Counter { + value: i32, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + IncrementPressed, + DecrementPressed, +} + +impl Sandbox for Counter { + type Message = Message; + + fn new() -> Self { + Self { value: 0 } + } + + fn title(&self) -> String { + String::from("Counter - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::IncrementPressed => { + self.value += 1; + } + Message::DecrementPressed => { + self.value -= 1; + } + } + } + + fn view(&self) -> Element<Message> { + container(loupe( + 3.0, + column![ + button("Increment").on_press(Message::IncrementPressed), + text(self.value).size(50), + button("Decrement").on_press(Message::DecrementPressed) + ] + .padding(20) + .align_items(Alignment::Center), + )) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} + +mod loupe { + use iced::advanced::layout::{self, Layout}; + use iced::advanced::renderer; + use iced::advanced::widget::{self, Widget}; + use iced::advanced::Renderer as _; + use iced::mouse; + use iced::{ + Color, Element, Length, Rectangle, Renderer, Size, Theme, + Transformation, + }; + + pub fn loupe<'a, Message>( + zoom: f32, + content: impl Into<Element<'a, Message>>, + ) -> Loupe<'a, Message> + where + Message: 'static, + { + Loupe { + zoom, + content: content.into().explain(Color::BLACK), + } + } + + pub struct Loupe<'a, Message> { + zoom: f32, + content: Element<'a, Message>, + } + + impl<'a, Message> Widget<Message, Theme, Renderer> for Loupe<'a, Message> { + fn tag(&self) -> widget::tree::Tag { + self.content.as_widget().tag() + } + + fn state(&self) -> widget::tree::State { + self.content.as_widget().state() + } + + fn children(&self) -> Vec<widget::Tree> { + self.content.as_widget().children() + } + + fn diff(&self, tree: &mut widget::Tree) { + self.content.as_widget().diff(tree); + } + + fn size(&self) -> Size<Length> { + self.content.as_widget().size() + } + + fn layout( + &self, + tree: &mut widget::Tree, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + self.content.as_widget().layout(tree, renderer, limits) + } + + fn draw( + &self, + tree: &widget::Tree, + renderer: &mut Renderer, + theme: &Theme, + style: &renderer::Style, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + ) { + let bounds = layout.bounds(); + + if let Some(position) = cursor.position_in(bounds) { + renderer.with_layer(bounds, |renderer| { + renderer.with_transformation( + Transformation::translate( + bounds.x + position.x * (1.0 - self.zoom), + bounds.y + position.y * (1.0 - self.zoom), + ) * Transformation::scale(self.zoom) + * Transformation::translate(-bounds.x, -bounds.y), + |renderer| { + self.content.as_widget().draw( + tree, + renderer, + theme, + style, + layout, + mouse::Cursor::Unavailable, + viewport, + ); + }, + ); + }); + } else { + self.content.as_widget().draw( + tree, renderer, theme, style, layout, cursor, viewport, + ); + } + } + + fn mouse_interaction( + &self, + _state: &widget::Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + _renderer: &Renderer, + ) -> mouse::Interaction { + if cursor.is_over(layout.bounds()) { + mouse::Interaction::ZoomIn + } else { + mouse::Interaction::Idle + } + } + } + + impl<'a, Message> From<Loupe<'a, Message>> + for Element<'a, Message, Theme, Renderer> + where + Message: 'a, + { + fn from(loupe: Loupe<'a, Message>) -> Self { + Self::new(loupe) + } + } +} |