Skip to content

Commit

Permalink
Add support for images (#116)
Browse files Browse the repository at this point in the history
* Add support for images

* Elide explicit lifetime in draw_img + code formatting

* Change draw_img of VgerRenderer to accept the img by ref

* Apply improvements suggested by clippy

* Code formatting
  • Loading branch information
presiyan-ivanov authored Oct 9, 2023
1 parent 2ef077e commit 8d8e7a3
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ floem_vger = { path = "vger" }
floem_reactive = { path = "reactive" }
winit = { git = "https://github.com/lapce/winit", rev = "25edc72fa4869d0fa83c61c26f0e38d7d7be9b0d" }
# winit = { path = "../winit" }
image = { version = "0.24", features = ["jpeg", "png"] }

[features]
serde = ["winit/serde"]
Expand Down
31 changes: 31 additions & 0 deletions examples/animations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
> [!WARNING]
> **Work in progress, which is subject to frequent change.**
If you plan to add changes, please make sure you reach out in our discord first.

The end-goal is to support reactive animations, similar to Swift UI(including spring animations).
The API we are currently aiming for looks something like this:
```rust
let (is_hovered, set_is_hovered) = create_signal(false);
let (scroll_offset_pct, set_scroll_offset_pct) = create_signal(0.);

scroll({
button()
.style(|s| {
s.width(move || {50.0})
})
.animation(|s| {
s.width(300)
// we get animation on scroll "for free", since everything is integrated with the reactive system
.opacity(move || scroll_offset_pct)
.scale(move || is_hovered.get() {1.2} else {1.0} )
.easing_fn(EasingFn::Cubic)
.ease_in_out()
.duration(Duration::from_secs(1))
})
}.on_scroll(move |scroll| {
let offset_pct = ......snip........
set_scroll_offset_pct.update(|value| *value = offset_pct);
true
})
)
```
Binary file added examples/widget-gallery/assets/ferris.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/widget-gallery/assets/sunflower.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions examples/widget-gallery/src/images.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use floem::{
unit::UnitExt,
view::View,
views::{img, scroll, Decorators},
};

use crate::form::{form, form_item};

pub fn img_view() -> impl View {
let ferris = include_bytes!("./../assets/ferris.png");
let sunflower = include_bytes!("./../assets/sunflower.jpg");

scroll(form({
(
form_item("PNG:".to_string(), 120.0, move || {
img(move || ferris.to_vec())
}),
form_item("PNG(resized):".to_string(), 120.0, move || {
img(move || ferris.to_vec()).style(|s| s.width(230.px()).height(153.px()))
}),
form_item("JPG:".to_string(), 120.0, move || {
img(move || sunflower.to_vec())
}),
form_item("JPG(resized):".to_string(), 120.0, move || {
img(move || sunflower.to_vec()).style(|s| s.width(320.px()).height(490.px()))
}),
//TODO: support percentages for width/height
// img(move || ferris.to_vec()).style(|s| s.width(90.pct()).height(90.pct()))
//
//TODO: object fit and object position
// img(move || ferris.to_vec())
// .object_fit(ObjectFit::Contain).object_position(VertPosition::Top, HorizPosition::Left))
//
)
}))
.style(|s| s.flex_col().min_width(1000.px()))
}
5 changes: 3 additions & 2 deletions examples/widget-gallery/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod buttons;
pub mod checkbox;
pub mod context_menu;
pub mod form;
pub mod images;
pub mod inputs;
pub mod labels;
pub mod lists;
Expand All @@ -23,7 +24,7 @@ use floem::{

fn app_view() -> impl View {
let tabs: im::Vector<&str> = vec![
"Label", "Button", "Checkbox", "Input", "List", "Menu", "RichText",
"Label", "Button", "Checkbox", "Input", "List", "Menu", "RichText", "Image",
]
.into_iter()
.collect();
Expand Down Expand Up @@ -127,6 +128,7 @@ fn app_view() -> impl View {
"List" => container_box(lists::virt_list_view()),
"Menu" => container_box(context_menu::menu_view()),
"RichText" => container_box(rich_text::rich_text_view()),
"Image" => container_box(images::img_view()),
_ => container_box(label(|| "Not implemented".to_owned())),
},
)
Expand All @@ -146,5 +148,4 @@ fn app_view() -> impl View {

fn main() {
floem::launch(app_view);
println!("Hello, world!")
}
1 change: 1 addition & 0 deletions renderer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ license.workspace = true

[dependencies]
resvg = "0.33.0"
image = { version = "0.24", features = ["jpeg", "png"] }
peniko = { git = "https://github.com/linebender/peniko", rev = "cafdac9a211a0fb2fec5656bd663d1ac770bcc81" }
cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "23555c6abf596c9a7fb1d4e604bf2711b0e58ed8" }
# cosmic-text = { path = "../../cosmic-text" }
7 changes: 7 additions & 0 deletions renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ pub struct Svg<'a> {
pub hash: &'a [u8],
}

pub struct Img<'a> {
pub data: &'a [u8],
pub hash: &'a [u8],
}

pub trait Renderer {
fn begin(&mut self);

Expand Down Expand Up @@ -40,5 +45,7 @@ pub trait Renderer {

fn draw_svg<'b>(&mut self, svg: Svg<'b>, rect: Rect, brush: Option<impl Into<BrushRef<'b>>>);

fn draw_img(&mut self, img: Img<'_>, width: u32, height: u32, rect: Rect);

fn finish(&mut self);
}
9 changes: 9 additions & 0 deletions src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
//! - Only one view can be focused at a time.
//!
use crate::cosmic_text::TextLayout;
use floem_renderer::Img;
use floem_vger::VgerRenderer;
use kurbo::{Affine, Rect, Shape, Size};
use peniko::BrushRef;
Expand Down Expand Up @@ -133,6 +134,14 @@ impl floem_renderer::Renderer for Renderer {
}
}

fn draw_img(&mut self, img: Img<'_>, width: u32, height: u32, rect: Rect) {
match self {
Renderer::Vger(v) => {
v.draw_img(img, width, height, rect);
}
}
}

fn draw_svg<'b>(
&mut self,
svg: floem_renderer::Svg<'b>,
Expand Down
Loading

0 comments on commit 8d8e7a3

Please sign in to comment.