#![allow(unused)]
pub use crate::camera::camera2d::Camera2D;
use crate::camera::render_target::RenderTarget;
use crate::draw_state::shapes::Shape;
pub use crate::draw_state::shapes::color::*;
pub use crate::end_frame;
use crate::global::{PENDING_CONFIG, STATE, ctx};
pub use crate::misc::flake_image::Image;
use crate::misc::font::Font;
pub use crate::misc::math::*;
pub use crate::misc::rect::Rect;
use crate::misc::span::RichtextSection;
pub use crate::misc::span::Span;
pub use crate::misc::timer::Timer;
pub use crate::misc::*;
use crate::model::instance::Instance;
pub use crate::model::texture::DrawTextureParams;
pub use crate::model::texture::FilterType;
use crate::model::texture::{GpuTexture, Texture};
pub use crate::runtime::next_frame::next_frame;
pub use crate::{FlakeResult, flake};
use image::{DynamicImage, GenericImageView, ImageBuffer, Rgb, Rgba};
use std::borrow::Borrow;
use std::sync::Arc;
pub use winit::event::MouseButton;
pub use winit::keyboard::KeyCode;
use winit::platform::windows::WindowExtWindows;
use winit::window::Window;
pub use winit::window::{WindowButtons, WindowLevel};
pub fn flake_quit() {
ctx(|s| s.exit())
}
pub fn flake_sleep(seconds: f32) {
std::thread::sleep(std::time::Duration::from_secs_f32(seconds));
}
pub fn add_timer(timer: Timer) -> Timer {
if STATE.get().is_some() {
return ctx(|s| {
if !s.timers.contains(&timer) {
s.add_timer(timer.clone());
}
timer
});
}
PENDING_CONFIG.with_borrow_mut(|s| {
if !s.timers.contains(&timer) {
s.timers.push(timer.clone())
}
});
timer
}
pub fn get_window() -> Arc<Window> {
ctx(|s| s.get_window())
}
pub fn set_window_passthrough(passthrough: bool) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_passthrough(passthrough));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_passthrough = Some(passthrough));
}
pub fn set_window_level(level: WindowLevel) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_level(level));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_level = Some(level));
}
pub fn set_window_enabled_buttons(window_buttons: WindowButtons) {
ctx(|s| s.get_window().set_enabled_buttons(window_buttons));
}
pub fn set_skip_taskbar(skip: bool) {
if STATE.get().is_some() {
return ctx(|s| s.window.set_skip_taskbar(skip));
}
PENDING_CONFIG.with_borrow_mut(|s| s.skip_taskbar = Some(skip));
}
pub fn set_window_transparent(transparent: bool) {
if STATE.get().is_some() {
return get_window().set_transparent(transparent);
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_transparent = Some(transparent));
}
pub fn set_window_decorations(enabled: bool) {
if STATE.get().is_some() {
return get_window().set_decorations(enabled);
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_decorations = Some(enabled));
}
pub fn set_window_title(title: &str) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_title(title));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_title = Some(title.into()));
}
pub fn set_window_visible(visible: bool) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_visible(visible));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_visible = Some(visible));
}
pub fn set_window_icon(path: &str) {
let img = image::open(path)
.expect("image icon does not exist at path")
.into_rgba8();
let (width, height) = img.dimensions();
let rgba = img.into_raw();
if STATE.get().is_some() {
return ctx(|s| s.set_window_icon(rgba, width, height));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
}
pub fn set_window_icon_bytes(bytes: &[u8]) {
let img = image::load_from_memory(bytes)
.expect("image icon does not exist at path")
.into_rgba8();
let (width, height) = img.dimensions();
let rgba = img.into_raw();
if STATE.get().is_some() {
return ctx(|s| s.set_window_icon(rgba, width, height));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
}
pub fn set_window_x(x: i32) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_x(x));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_x = Some(x));
}
pub fn set_window_y(y: i32) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_y(y));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_y = Some(y));
}
pub fn set_window_position(x: i32, y: i32) {
set_window_x(x);
set_window_y(y);
}
pub fn window_width() -> f32 {
ctx(|s| s.window_width())
}
pub fn window_height() -> f32 {
ctx(|s| s.window_height())
}
pub fn window_size() -> Vector2 {
ctx(|s| Vector2::new(s.window_width(), s.window_height()))
}
pub fn window_position() -> (f32, f32) {
ctx(|s| s.window_position())
}
pub fn window_position_vec2() -> Vector2 {
ctx(|s| s.window_position().into())
}
pub fn window_x() -> f32 {
ctx(|s| s.window_x())
}
pub fn window_y() -> f32 {
ctx(|s| s.window_y())
}
pub fn set_window_width(w: u32) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_w(w));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_width = Some(w));
}
pub fn set_window_height(h: u32) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_h(h));
}
PENDING_CONFIG.with_borrow_mut(|s| s.window_height = Some(h));
}
pub fn set_window_size(w: u32, h: u32) {
if STATE.get().is_some() {
return ctx(|s| s.set_window_size(w, h));
}
PENDING_CONFIG.with_borrow_mut(|s| {
s.window_width = Some(w);
s.window_height = Some(h);
});
}
pub fn set_window_resizable(resizeable: bool) {
ctx(|s| s.window.set_resizable(resizeable));
}
pub fn get_fps() -> f32 {
ctx(|s| s.get_fps())
}
pub fn set_target_fps(fps: usize) {
if STATE.get().is_some() {
return ctx(|s| s.set_target_fps(fps));
}
PENDING_CONFIG.with_borrow_mut(|s| s.target_fps = Some(fps));
}
pub fn set_fps_capped(capped: bool) {
if STATE.get().is_some() {
return ctx(|s| s.set_fps_capped(capped));
}
PENDING_CONFIG.with_borrow_mut(|s| s.fps_capped = Some(capped));
}
pub fn get_frame_time() -> f32 {
ctx(|s| s.get_frame_time())
}
pub fn get_frames() -> usize {
ctx(|s| s.get_frames())
}
pub fn mouse_position() -> (f32, f32) {
ctx(|s| s.mouse_state.get_position().into())
}
pub fn mouse_position_vec2() -> Vector2 {
ctx(|s| s.mouse_state.get_position())
}
pub fn mouse_screen_position_vec2() -> Vector2 {
ctx(|s| s.mouse_state.get_screen_position())
}
pub fn mouse_screen_position() -> (f32, f32) {
ctx(|s| s.mouse_state.get_screen_position().into())
}
pub fn mouse_wheel() -> Vector2 {
ctx(|s| s.mouse_state.get_mouse_wheel())
}
pub fn focus_window() {
get_window().focus_window();
}
pub fn is_mouse_button_down(btn: MouseButton) -> bool {
ctx(|s| s.mouse_state.is_button_down(btn))
}
pub fn is_mouse_button_pressed(btn: MouseButton) -> bool {
ctx(|s| s.mouse_state.is_button_pressed(btn))
}
pub fn is_mouse_button_released(btn: MouseButton) -> bool {
ctx(|s| s.mouse_state.is_button_released(btn))
}
pub fn is_key_down(key: KeyCode) -> bool {
ctx(|s| s.keyboard_state.is_key_down(key))
}
pub fn is_key_pressed(key: KeyCode) -> bool {
ctx(|s| s.keyboard_state.is_key_pressed(key))
}
pub fn is_key_released(key: KeyCode) -> bool {
ctx(|s| s.keyboard_state.is_key_released(key))
}
pub fn get_axis(left: KeyCode, right: KeyCode) -> f32 {
ctx(|s| match (is_key_down(left), is_key_down(right)) {
(true, false) => -1.0,
(false, true) => 1.0,
_ => 0.0,
})
}
pub fn get_vector(left: KeyCode, right: KeyCode, up: KeyCode, down: KeyCode) -> Vector2 {
ctx(|s| {
Vector2::new(
match (is_key_down(left), is_key_down(right)) {
(true, false) => -1.0,
(false, true) => 1.0,
_ => 0.0,
},
match (is_key_down(up), is_key_down(down)) {
(true, false) => -1.0,
(false, true) => 1.0,
_ => 0.0,
},
)
})
}
pub fn clear_background(color: Color) {
if STATE.get().is_some() {
return ctx(|s| {
s.clear_color = Some(color);
s.draw_state.clear();
});
}
PENDING_CONFIG.with_borrow_mut(|c| c.window_clear_color = Some(color));
}
pub fn draw_rectangle(x: f32, y: f32, w: f32, h: f32, color: Color) {
draw_rectangle_rounded(x, y, w, h, 0.0, color);
}
pub fn draw_rectangle_rounded(x: f32, y: f32, w: f32, h: f32, radius: f32, color: Color) {
draw_rectangle_rounded_ex(x, y, w, h, radius, radius, radius, radius, color)
}
pub fn draw_rectangle_rounded_ex(
x: f32,
y: f32,
w: f32,
h: f32,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
color: Color,
) {
ctx(|s| {
s.draw_state.draw_rectangle(
x,
y,
w,
h,
top_left,
top_right,
bottom_left,
bottom_right,
color,
)
});
}
pub fn draw_rectangle_from_rect(rect: Rect, color: Color) {
draw_rectangle(rect.x, rect.y, rect.w, rect.h, color);
}
pub fn draw_rectangle_rounded_from_rect(rect: Rect, radius: f32, color: Color) {
draw_rectangle_rounded(rect.x, rect.y, rect.w, rect.h, radius, color);
}
pub fn draw_rectangle_lines_rounded_from_rect(
rect: Rect,
radius: f32,
thickness: f32,
color: Color,
) {
draw_rectangle_lines_rounded(rect.x, rect.y, rect.w, rect.h, radius, thickness, color);
}
pub fn draw_rectangle_lines_rounded_from_rect_ex(
rect: Rect,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
thickness: f32,
color: Color,
) {
draw_rectangle_lines_rounded_ex(
rect.x,
rect.y,
rect.w,
rect.h,
top_left,
top_right,
bottom_left,
bottom_right,
thickness,
color,
);
}
pub fn draw_rectangle_rounded_from_rect_ex(
rect: Rect,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
color: Color,
) {
draw_rectangle_rounded_ex(
rect.x,
rect.y,
rect.w,
rect.h,
top_left,
top_right,
bottom_left,
bottom_right,
color,
);
}
pub fn draw_rectangle_lines(x: f32, y: f32, w: f32, h: f32, thickness: f32, color: Color) {
draw_rectangle_lines_rounded(x, y, w, h, 0.0, thickness, color)
}
pub fn draw_rectangle_lines_from_rect(rect: Rect, thickness: f32, color: Color) {
draw_rectangle_lines(rect.x, rect.y, rect.w, rect.h, thickness, color);
}
pub fn draw_rectangle_lines_rounded(
x: f32,
y: f32,
w: f32,
h: f32,
radius: f32,
thickness: f32,
color: Color,
) {
draw_rectangle_lines_rounded_ex(x, y, w, h, radius, radius, radius, radius, thickness, color);
}
pub fn draw_rectangle_lines_rounded_ex(
x: f32,
y: f32,
w: f32,
h: f32,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
thickness: f32,
color: Color,
) {
ctx(|s| {
s.draw_state.draw_rectangle_lines(
x,
y,
w,
h,
top_left,
top_right,
bottom_left,
bottom_right,
thickness,
color,
)
});
}
pub fn draw_rectangle_rotated(x: f32, y: f32, w: f32, h: f32, rotation: f32, color: Color) {
ctx(|s| {
s.draw_state
.draw_rectangle_rotated(x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, color)
});
}
pub fn draw_rectangle_lines_rotated(
x: f32,
y: f32,
w: f32,
h: f32,
rotation: f32,
thickness: f32,
color: Color,
) {
ctx(|s| {
s.draw_state.draw_rectangle_lines_rotated(
x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, thickness, color,
)
});
}
pub fn draw_rectangle_rounded_rotated(
x: f32,
y: f32,
w: f32,
h: f32,
rotation: f32,
radius: f32,
color: Color,
) {
draw_rectangle_rounded_rotated_ex(x, y, w, h, rotation, radius, radius, radius, radius, color);
}
pub fn draw_rectangle_rounded_rotated_ex(
x: f32,
y: f32,
w: f32,
h: f32,
rotation: f32,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
color: Color,
) {
ctx(|s| {
s.draw_state.draw_rectangle_rotated(
x,
y,
w,
h,
rotation,
top_left,
top_right,
bottom_left,
bottom_right,
color,
)
});
}
pub fn draw_rectangle_lines_rounded_rotated(
x: f32,
y: f32,
w: f32,
h: f32,
rotation: f32,
radius: f32,
thickness: f32,
color: Color,
) {
draw_rectangle_lines_rounded_rotated_ex(
x, y, w, h, rotation, radius, radius, radius, radius, thickness, color,
);
}
pub fn draw_rectangle_lines_rounded_rotated_ex(
x: f32,
y: f32,
w: f32,
h: f32,
rotation: f32,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
thickness: f32,
color: Color,
) {
ctx(|s| {
s.draw_state.draw_rectangle_lines_rotated(
x,
y,
w,
h,
rotation,
top_left,
top_right,
bottom_left,
bottom_right,
thickness,
color,
)
});
}
pub fn draw_circle(x: f32, y: f32, r: f32, color: Color) {
ctx(|s| s.draw_state.draw_circle(x, y, r, color));
}
pub fn draw_circle_lines(x: f32, y: f32, r: f32, thickness: f32, color: Color) {
ctx(|s| s.draw_state.draw_circle_lines(x, y, r, thickness, color));
}
pub fn draw_triangle(x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32, color: Color) {
ctx(|s| s.draw_state.draw_triangle(x1, y1, x2, y2, x3, y3, color));
}
pub fn draw_triangle_lines(
x1: f32,
y1: f32,
x2: f32,
y2: f32,
x3: f32,
y3: f32,
thickness: f32,
color: Color,
) {
ctx(|s| {
s.draw_state
.draw_triangle_lines(x1, y1, x2, y2, x3, y3, thickness, color)
});
}
pub fn draw_line(x1: f32, y1: f32, x2: f32, y2: f32, thickness: f32, color: Color) {
ctx(|s| s.draw_state.draw_line(x1, y1, x2, y2, thickness, color))
}
pub fn draw_poly_line(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
ctx(|s| {
s.draw_state
.draw_poly_line_miter(points, thickness, color, closed)
})
}
pub fn draw_poly_line_rounded(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
ctx(|s| {
s.draw_state
.draw_poly_line(points, thickness, color, closed, true)
})
}
pub fn draw_polygon(points: &[Vector2], color: Color) {
ctx(|s| s.draw_state.draw_polygon(points, color))
}
pub fn draw_polygon_concave(points: &[Vector2], color: Color) {
ctx(|s| s.draw_state.draw_polygon_concave(points, color))
}
pub fn draw_text(t: &str, x: f32, y: f32, size: f32, font: Option<&Font>, color: Color) {
ctx(|s| s.draw_state.draw_text(&s.fonts, t, x, y, size, font, color));
}
pub fn draw_rich_text<'a, I>(position: Vector2, size: f32, font: Option<&Font>, color: Color, spans: I)
where
I: IntoIterator,
I::Item: Borrow<Span<'a>>,
{
ctx(|s| s.draw_state.draw_richtext(position, size, font, color, spans))
}
pub fn load_font_from_path(path: &str) -> Font {
if STATE.get().is_some() {
return ctx(|s| {
s.load_font_from_path(path);
s.fonts[s.fonts.len() - 1].clone()
});
}
PENDING_CONFIG.with_borrow_mut(|s| {
let font = Font::from_path(s.fonts.len() + 1, path);
s.fonts.push(font.clone());
font
})
}
pub fn load_font_from_bytes(bytes: &[u8]) -> Font {
if STATE.get().is_some() {
return ctx(|s| {
s.load_font_from_bytes(bytes);
s.fonts[s.fonts.len() - 1].clone()
});
}
PENDING_CONFIG.with_borrow_mut(|s| {
let font = Font::from_bytes(s.fonts.len() + 1, bytes);
s.fonts.push(font.clone());
font
})
}
pub fn measure_text(t: &str, size: f32, font: Option<&Font>) -> Vector2 {
let (w, h) = ctx(|s| s.measure_text(t, size, font));
Vector2::new(w, h)
}
pub fn draw_arrow(
x1: f32,
y1: f32,
x2: f32,
y2: f32,
thickness: f32,
head_size: f32,
color: Color,
) {
ctx(|s| {
s.draw_state
.draw_arrow(x1, y1, x2, y2, thickness, head_size, color)
});
}
pub fn screen_size() -> Vector2 {
let win = get_window();
match win.current_monitor() {
Some(m) => {
let s = m.size();
Vector2::new(s.width as f32, s.height as f32)
}
None => window_size(),
}
}
pub fn screen_width() -> f32 {
screen_size().x
}
pub fn screen_height() -> f32 {
screen_size().y
}
pub fn create_empty_texture(width: u32, height: u32, filter_type: FilterType) -> Texture {
ctx(|s| {
let gpu = GpuTexture::empty(
&s.device,
width,
height,
filter_type,
wgpu::TextureFormat::Rgba8UnormSrgb,
)
.expect("Couldn't create empty GpuTexture");
Texture {
id: s.add_gpu_texture(gpu),
width,
height,
}
})
}
pub fn load_texture(path: &str) -> Texture {
ctx(|s| {
let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
let width = image.width();
let height = image.height();
Texture {
id: s.add_texture(image, FilterType::Linear),
width,
height,
}
})
}
pub fn load_texture_with_filter_type(path: &str, filter_type: FilterType) -> Texture {
ctx(|s| {
let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
let width = image.width();
let height = image.height();
Texture {
id: s.add_texture(image, filter_type),
width,
height,
}
})
}
pub fn load_texture_from_bytes(bytes: &[u8]) -> Texture {
ctx(|s| {
let image = image::load_from_memory(bytes).unwrap();
let (width, height) = image.dimensions();
Texture {
id: s.add_texture(image, FilterType::Linear),
width,
height,
}
})
}
pub fn load_texture_from_bytes_with_filter_type(bytes: &[u8], filter_type: FilterType) -> Texture {
ctx(|s| {
let image = image::load_from_memory(bytes).unwrap();
let (width, height) = image.dimensions();
Texture {
id: s.add_texture(image, filter_type),
width,
height,
}
})
}
pub fn load_texture_from_data(width: u32, height: u32, data: &[f32]) -> Texture {
ctx(|s| {
let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
.expect("Buffer size mismatch");
let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
Texture {
id: s.add_texture(dynamic_img, FilterType::Linear),
width,
height,
}
})
}
pub fn load_texture_from_data_with_filter_type(
width: u32,
height: u32,
data: &[f32],
filter_type: FilterType,
) -> Texture {
ctx(|s| {
let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
.expect("Buffer size mismatch");
let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
Texture {
id: s.add_texture(dynamic_img, filter_type),
width,
height,
}
})
}
pub fn load_texture_from_image(image: &Image) -> Texture {
let tex = create_empty_texture(image.width, image.height, image.filter_type);
update_texture(tex, image);
tex
}
pub fn draw_texture(texture: Texture, x: f32, y: f32, w: f32, h: f32, tint: Color) {
ctx(|s| s.draw_state.draw_texture(texture, x, y, w, h, tint))
}
pub fn draw_texture_ex(texture: Texture, x: f32, y: f32, p: DrawTextureParams) {
ctx(|s| s.draw_state.draw_texture_ex(texture, x, y, p))
}
pub fn update_texture(texture: Texture, image: &Image) {
ctx(|s| s.update_texture(texture.id, image))
}
pub fn render_target(width: u32, height: u32, filter_type: FilterType) -> RenderTarget {
ctx(|s| s.create_render_target(width, height, filter_type))
}
pub fn set_camera(cam: &Camera2D) {
ctx(|s| s.set_camera(cam))
}
pub fn set_default_camera() {
ctx(|s| s.set_default_camera())
}