Implement button::Renderer
in ggez
example
This commit is contained in:
parent
b4eb0df5a0
commit
ccb87b12da
@ -2,26 +2,33 @@ mod renderer;
|
||||
mod widget;
|
||||
|
||||
use renderer::Renderer;
|
||||
use widget::Text;
|
||||
use widget::{button, Button, Column, Text};
|
||||
|
||||
use ggez;
|
||||
use ggez::event;
|
||||
use ggez::graphics;
|
||||
use ggez::input::mouse;
|
||||
|
||||
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()?;
|
||||
let state = &mut Game::new(ctx)?;
|
||||
event::run(ctx, event_loop, state)
|
||||
}
|
||||
|
||||
struct Game {}
|
||||
struct Game {
|
||||
spritesheet: graphics::Image,
|
||||
button: button::State,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new() -> ggez::GameResult<Game> {
|
||||
Ok(Game {})
|
||||
fn new(context: &mut ggez::Context) -> ggez::GameResult<Game> {
|
||||
Ok(Game {
|
||||
spritesheet: graphics::Image::new(context, "/ui.png").unwrap(),
|
||||
button: button::State::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,17 +40,50 @@ impl event::EventHandler for Game {
|
||||
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 screen = graphics::screen_coordinates(context);
|
||||
|
||||
let mouse_cursor = ui.draw(renderer, iced::Point::new(0.0, 0.0));
|
||||
let cursor = {
|
||||
let hello = Text::new("Hello, iced!")
|
||||
.horizontal_alignment(iced::text::HorizontalAlignment::Center);
|
||||
|
||||
let button = Button::new(&mut self.button, "Press me!").width(200);
|
||||
|
||||
let content = Column::new()
|
||||
.width(screen.w as u32)
|
||||
.height(screen.h as u32)
|
||||
.align_items(iced::Align::Center)
|
||||
.justify_content(iced::Justify::Center)
|
||||
.spacing(20)
|
||||
.push(hello)
|
||||
.push(button);
|
||||
|
||||
let renderer =
|
||||
&mut Renderer::new(context, self.spritesheet.clone());
|
||||
|
||||
let ui: Interface<(), Renderer> =
|
||||
Interface::compute(content.into(), renderer);
|
||||
|
||||
let cursor = ui.draw(renderer, iced::Point::new(0.0, 0.0));
|
||||
|
||||
renderer.flush();
|
||||
}
|
||||
|
||||
cursor
|
||||
};
|
||||
|
||||
mouse::set_cursor_type(context, into_cursor_type(cursor));
|
||||
|
||||
graphics::present(context)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn into_cursor_type(cursor: iced::MouseCursor) -> mouse::MouseCursor {
|
||||
match cursor {
|
||||
iced::MouseCursor::OutOfBounds => mouse::MouseCursor::Default,
|
||||
iced::MouseCursor::Idle => mouse::MouseCursor::Default,
|
||||
iced::MouseCursor::Pointer => mouse::MouseCursor::Hand,
|
||||
iced::MouseCursor::Working => mouse::MouseCursor::Progress,
|
||||
iced::MouseCursor::Grab => mouse::MouseCursor::Grab,
|
||||
iced::MouseCursor::Grabbing => mouse::MouseCursor::Grabbing,
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,31 @@
|
||||
mod button;
|
||||
mod text;
|
||||
|
||||
use ggez::graphics::{self, Color};
|
||||
use ggez::graphics::{self, spritebatch::SpriteBatch, Color, Image};
|
||||
use ggez::Context;
|
||||
|
||||
pub struct Renderer<'a> {
|
||||
pub context: &'a mut Context,
|
||||
pub sprites: SpriteBatch,
|
||||
pub spritesheet: Image,
|
||||
}
|
||||
|
||||
impl Renderer<'_> {
|
||||
pub fn new(context: &mut Context, spritesheet: Image) -> Renderer {
|
||||
Renderer {
|
||||
context,
|
||||
sprites: SpriteBatch::new(spritesheet.clone()),
|
||||
spritesheet,
|
||||
}
|
||||
}
|
||||
pub fn flush(&mut self) {
|
||||
graphics::draw(
|
||||
self.context,
|
||||
&self.sprites,
|
||||
graphics::DrawParam::default(),
|
||||
)
|
||||
.expect("Draw sprites");
|
||||
|
||||
graphics::draw_queued_text(
|
||||
self.context,
|
||||
graphics::DrawParam::default(),
|
||||
|
144
examples/ggez/renderer/button.rs
Normal file
144
examples/ggez/renderer/button.rs
Normal file
@ -0,0 +1,144 @@
|
||||
use super::Renderer;
|
||||
use ggez::graphics::{
|
||||
self, Align, Color, DrawParam, Rect, Scale, Text, TextFragment, WHITE,
|
||||
};
|
||||
use iced::{button, MouseCursor};
|
||||
|
||||
const LEFT: Rect = Rect {
|
||||
x: 0.0,
|
||||
y: 34.0,
|
||||
w: 6.0,
|
||||
h: 49.0,
|
||||
};
|
||||
|
||||
const BACKGROUND: Rect = Rect {
|
||||
x: LEFT.w,
|
||||
y: LEFT.y,
|
||||
w: 1.0,
|
||||
h: LEFT.h,
|
||||
};
|
||||
|
||||
const RIGHT: Rect = Rect {
|
||||
x: LEFT.h - LEFT.w,
|
||||
y: LEFT.y,
|
||||
w: LEFT.w,
|
||||
h: LEFT.h,
|
||||
};
|
||||
|
||||
impl button::Renderer for Renderer<'_> {
|
||||
fn draw(
|
||||
&mut self,
|
||||
cursor_position: iced::Point,
|
||||
mut bounds: iced::Rectangle<f32>,
|
||||
state: &button::State,
|
||||
label: &str,
|
||||
class: button::Class,
|
||||
) -> MouseCursor {
|
||||
let mouse_over = bounds.contains(cursor_position);
|
||||
|
||||
let mut state_offset = 0.0;
|
||||
|
||||
if mouse_over {
|
||||
if state.is_pressed() {
|
||||
bounds.y += 4.0;
|
||||
state_offset = RIGHT.x + RIGHT.w;
|
||||
} else {
|
||||
bounds.y -= 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
let class_index = match class {
|
||||
button::Class::Primary => 0,
|
||||
button::Class::Secondary => 1,
|
||||
button::Class::Positive => 2,
|
||||
};
|
||||
|
||||
let width = self.spritesheet.width() as f32;
|
||||
let height = self.spritesheet.height() as f32;
|
||||
|
||||
self.sprites.add(DrawParam {
|
||||
src: Rect {
|
||||
x: (LEFT.x + state_offset) / width,
|
||||
y: (LEFT.y + class_index as f32 * LEFT.h) / height,
|
||||
w: LEFT.w / width,
|
||||
h: LEFT.h / height,
|
||||
},
|
||||
dest: ggez::mint::Point2 {
|
||||
x: bounds.x,
|
||||
y: bounds.y,
|
||||
},
|
||||
..DrawParam::default()
|
||||
});
|
||||
|
||||
self.sprites.add(DrawParam {
|
||||
src: Rect {
|
||||
x: (BACKGROUND.x + state_offset) / width,
|
||||
y: (BACKGROUND.y + class_index as f32 * BACKGROUND.h) / height,
|
||||
w: BACKGROUND.w / width,
|
||||
h: BACKGROUND.h / height,
|
||||
},
|
||||
dest: ggez::mint::Point2 {
|
||||
x: bounds.x + LEFT.w,
|
||||
y: bounds.y,
|
||||
},
|
||||
scale: ggez::mint::Vector2 {
|
||||
x: bounds.width - LEFT.w - RIGHT.w,
|
||||
y: 1.0,
|
||||
},
|
||||
..DrawParam::default()
|
||||
});
|
||||
|
||||
self.sprites.add(DrawParam {
|
||||
src: Rect {
|
||||
x: (RIGHT.x + state_offset) / width,
|
||||
y: (RIGHT.y + class_index as f32 * RIGHT.h) / height,
|
||||
w: RIGHT.w / width,
|
||||
h: RIGHT.h / height,
|
||||
},
|
||||
dest: ggez::mint::Point2 {
|
||||
x: bounds.x + bounds.width - RIGHT.w,
|
||||
y: bounds.y,
|
||||
},
|
||||
..DrawParam::default()
|
||||
});
|
||||
|
||||
let mut text = Text::new(TextFragment {
|
||||
text: String::from(label),
|
||||
scale: Some(Scale { x: 20.0, y: 20.0 }),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
text.set_bounds(
|
||||
ggez::mint::Point2 {
|
||||
x: bounds.width,
|
||||
y: bounds.height,
|
||||
},
|
||||
Align::Center,
|
||||
);
|
||||
|
||||
graphics::queue_text(
|
||||
self.context,
|
||||
&text,
|
||||
ggez::mint::Point2 {
|
||||
x: bounds.x,
|
||||
y: bounds.y + BACKGROUND.h / 4.0,
|
||||
},
|
||||
Some(if mouse_over {
|
||||
WHITE
|
||||
} else {
|
||||
Color {
|
||||
r: 0.9,
|
||||
g: 0.9,
|
||||
b: 0.9,
|
||||
a: 1.0,
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
if mouse_over {
|
||||
MouseCursor::Pointer
|
||||
} else {
|
||||
MouseCursor::OutOfBounds
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
use ggez::graphics::Color;
|
||||
|
||||
pub use iced::{button, Button, Column, Row};
|
||||
|
||||
pub type Text = iced::Text<Color>;
|
||||
|
BIN
resources/ui.png
Normal file
BIN
resources/ui.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in New Issue
Block a user