Start implementing ggez example

This commit is contained in:
Héctor Ramón Jiménez 2019-07-21 12:35:25 +02:00
parent 2b7ad3d50e
commit 0eaffff422
5 changed files with 188 additions and 0 deletions

View File

@ -15,3 +15,6 @@ categories = ["gui"]
stretch = "0.2"
nalgebra = "0.18"
twox-hash = "1.3"
[dev-dependencies]
ggez = { version = "0.5", git = "https://github.com/hecrj/ggez" }

49
examples/ggez/main.rs Normal file
View File

@ -0,0 +1,49 @@
mod renderer;
mod widget;
use renderer::Renderer;
use widget::Text;
use ggez;
use ggez::event;
use ggez::graphics;
use iced::Interface;
pub fn main() -> ggez::GameResult {
let cb = ggez::ContextBuilder::new("iced", "ggez");
let (ctx, event_loop) = &mut cb.build()?;
let state = &mut Game::new()?;
event::run(ctx, event_loop, state)
}
struct Game {}
impl Game {
fn new() -> ggez::GameResult<Game> {
Ok(Game {})
}
}
impl event::EventHandler for Game {
fn update(&mut self, _ctx: &mut ggez::Context) -> ggez::GameResult {
Ok(())
}
fn draw(&mut self, context: &mut ggez::Context) -> ggez::GameResult {
graphics::clear(context, [0.1, 0.2, 0.3, 1.0].into());
{
let renderer = &mut Renderer { context };
let ui: Interface<(), Renderer> =
Interface::compute(Text::new("Hello, iced!").into(), renderer);
let mouse_cursor = ui.draw(renderer, iced::Point::new(0.0, 0.0));
renderer.flush();
}
graphics::present(context)?;
Ok(())
}
}

26
examples/ggez/renderer.rs Normal file
View File

@ -0,0 +1,26 @@
mod text;
use ggez::graphics::{self, Color};
use ggez::Context;
pub struct Renderer<'a> {
pub context: &'a mut Context,
}
impl Renderer<'_> {
pub fn flush(&mut self) {
graphics::draw_queued_text(
self.context,
graphics::DrawParam::default(),
Default::default(),
graphics::FilterMode::Linear,
)
.expect("Draw text");
}
}
impl iced::Renderer for Renderer<'_> {
type Color = Color;
fn explain(&mut self, layout: &iced::Layout<'_>, color: Color) {}
}

View File

@ -0,0 +1,107 @@
use super::Renderer;
use ggez::graphics::{self, mint, Align, Color, Scale, Text, TextFragment};
use iced::text;
use std::cell::RefCell;
use std::f32;
impl text::Renderer<Color> for Renderer<'_> {
fn node(&self, style: iced::Style, content: &str, size: f32) -> iced::Node {
let font_cache = graphics::font_cache(self.context);
let content = String::from(content);
let measure = RefCell::new(None);
iced::Node::with_measure(style, move |bounds| {
// TODO: Investigate why stretch tries to measure this MANY times
// with every ancestor's bounds.
// Bug? Using the library wrong? I should probably open an issue on
// the stretch repository.
// I noticed that the first measure is the one that matters in
// practice. Here, we use a RefCell to store the cached
// measurement.
let mut measure = measure.borrow_mut();
if measure.is_none() {
let bounds = (
match bounds.width {
iced::Number::Undefined => f32::INFINITY,
iced::Number::Defined(w) => w,
},
match bounds.height {
iced::Number::Undefined => f32::INFINITY,
iced::Number::Defined(h) => h,
},
);
let mut text = Text::new(TextFragment {
text: content.clone(),
scale: Some(Scale { x: size, y: size }),
..Default::default()
});
text.set_bounds(
mint::Point2 {
x: bounds.0,
y: bounds.1,
},
Align::Left,
);
let (width, height) = text.dimensions(&font_cache);
let size = iced::Size {
width: width as f32,
height: height as f32,
};
// If the text has no width boundary we avoid caching as the
// layout engine may just be measuring text in a row.
if bounds.0 == f32::INFINITY {
return size;
} else {
*measure = Some(size);
}
}
measure.unwrap()
})
}
fn draw(
&mut self,
bounds: iced::Rectangle<f32>,
content: &str,
size: f32,
color: Color,
horizontal_alignment: text::HorizontalAlignment,
_vertical_alignment: text::VerticalAlignment,
) {
let mut text = Text::new(TextFragment {
text: String::from(content),
scale: Some(Scale { x: size, y: size }),
..Default::default()
});
text.set_bounds(
mint::Point2 {
x: bounds.width,
y: bounds.height,
},
match horizontal_alignment {
text::HorizontalAlignment::Left => graphics::Align::Left,
text::HorizontalAlignment::Center => graphics::Align::Center,
text::HorizontalAlignment::Right => graphics::Align::Right,
},
);
graphics::queue_text(
self.context,
&text,
mint::Point2 {
x: bounds.x,
y: bounds.y,
},
Some(color),
);
}
}

3
examples/ggez/widget.rs Normal file
View File

@ -0,0 +1,3 @@
use ggez::graphics::Color;
pub type Text = iced::Text<Color>;