use crate::{
gui::state::UiState,
prelude::*,
renderer::{Renderer, RendererSettings, Rendering, WindowRenderer},
texture::TextureRenderer,
};
use environment::Environment;
use settings::Settings;
use std::{collections::HashSet, mem, time::Instant};
pub mod environment;
pub mod settings;
#[non_exhaustive]
#[derive(Debug)]
pub struct PixState {
pub(crate) renderer: Renderer,
pub(crate) env: Environment,
pub(crate) ui: UiState,
pub(crate) settings: Settings,
pub(crate) setting_stack: Vec<Settings>,
pub(crate) theme: Theme,
}
impl PixState {
#[inline]
#[must_use]
pub fn title(&self) -> &str {
self.renderer.title()
}
#[inline]
pub fn set_title<S: AsRef<str>>(&mut self, title: S) -> PixResult<()> {
self.renderer.set_title(title.as_ref())
}
#[inline]
pub fn mouse_pos(&self) -> Point<i32> {
self.ui.mouse_pos()
}
#[inline]
pub fn pmouse_pos(&self) -> Point<i32> {
self.ui.pmouse_pos()
}
#[inline]
#[must_use]
pub fn mouse_pressed(&self) -> bool {
self.ui.mouse_pressed()
}
#[inline]
#[must_use]
pub fn mouse_clicked(&self, btn: Mouse) -> bool {
self.ui.mouse_clicked(btn)
}
#[inline]
#[must_use]
pub fn mouse_dbl_clicked(&self, btn: Mouse) -> bool {
self.ui.mouse_dbl_clicked(btn)
}
#[inline]
#[must_use]
pub fn mouse_down(&self, btn: Mouse) -> bool {
self.ui.mouse_down(btn)
}
#[inline]
#[must_use]
pub const fn mouse_buttons(&self) -> &HashSet<Mouse> {
self.ui.mouse_buttons()
}
#[inline]
#[must_use]
pub fn key_pressed(&self) -> bool {
self.ui.key_pressed()
}
#[inline]
#[must_use]
pub fn key_down(&self, key: Key) -> bool {
self.ui.key_down(key)
}
#[inline]
#[must_use]
pub const fn keys(&self) -> &HashSet<Key> {
self.ui.keys()
}
#[inline]
#[must_use]
pub const fn keymod_down(&self, keymod: KeyMod) -> bool {
self.ui.keymod_down(keymod)
}
#[inline]
pub const fn keymod(&self) -> &KeyMod {
self.ui.keymod()
}
}
impl PixState {
#[inline]
pub(crate) fn new(settings: RendererSettings, theme: Theme) -> PixResult<Self> {
let show_frame_rate = settings.show_frame_rate;
let target_frame_rate = settings.target_frame_rate;
let renderer = Renderer::new(settings)?;
let mut state = Self {
renderer,
env: Environment::default(),
ui: UiState::default(),
settings: Settings::default(),
setting_stack: Vec::new(),
theme: theme.clone(),
};
state.background(theme.colors.background);
state.fill(theme.colors.on_background());
state.show_frame_rate(show_frame_rate);
state.frame_rate(target_frame_rate);
state.font_size(theme.font_size)?;
state.font_style(theme.styles.body);
state.font_family(theme.fonts.body)?;
Ok(state)
}
#[inline]
pub(crate) fn pre_update(&mut self) {
let _ignore_result = self.renderer.cursor(self.settings.cursor.as_ref());
self.ui.pre_update(&self.theme);
}
#[inline]
pub(crate) fn on_update(&mut self) -> PixResult<()> {
for texture in self.ui.textures.iter_mut().filter(|t| t.visible) {
self.renderer
.texture(texture.id, texture.src, texture.dst, 0.0, None, None, None)?;
}
Ok(())
}
#[inline]
pub(crate) fn post_update(&mut self) {
self.ui.post_update();
}
#[inline]
pub(crate) fn get_rect<R>(&self, rect: R) -> Rect<i32>
where
R: Into<Rect<i32>>,
{
let mut rect = rect.into();
if self.settings.rect_mode == RectMode::Center {
rect.center_on(rect.top_left());
}
rect
}
#[inline]
pub(crate) fn get_ellipse<E>(&self, ellipse: E) -> Ellipse<i32>
where
E: Into<Ellipse<i32>>,
{
let mut ellipse = ellipse.into();
if self.settings.ellipse_mode == RectMode::Corner {
ellipse.center_on(ellipse.bottom_right());
}
ellipse
}
#[inline]
pub(crate) fn on_mouse_motion(&mut self, pos: Point<i32>) {
self.ui.pmouse.pos = self.ui.mouse.pos;
self.ui.mouse.pos = pos;
}
#[inline]
pub(crate) fn on_mouse_click(&mut self, btn: Mouse, time: Instant) {
self.ui.pmouse.clicked = mem::take(&mut self.ui.mouse.clicked);
self.ui.pmouse.last_clicked = mem::take(&mut self.ui.mouse.last_clicked);
self.ui.mouse.click(btn, time);
}
#[inline]
pub(crate) fn on_mouse_dbl_click(&mut self, btn: Mouse, time: Instant) {
self.ui.pmouse.last_dbl_clicked = mem::take(&mut self.ui.mouse.last_dbl_clicked);
self.ui.mouse.dbl_click(btn, time);
}
#[inline]
pub(crate) fn on_mouse_pressed(&mut self, btn: Mouse) {
self.ui.pmouse.pressed = mem::take(&mut self.ui.mouse.pressed);
self.ui.mouse.press(btn);
}
#[inline]
pub(crate) fn on_mouse_released(&mut self, btn: Mouse) {
self.ui.pmouse.pressed = mem::take(&mut self.ui.mouse.pressed);
self.ui.mouse.release(btn);
}
#[inline]
pub(crate) fn on_mouse_wheel(&mut self, x: i32, y: i32) {
self.ui.pmouse.xrel = self.ui.mouse.xrel;
self.ui.pmouse.yrel = self.ui.mouse.yrel;
self.ui.mouse.wheel(x, y);
}
#[inline]
pub fn poll_event(&mut self) -> Option<Event> {
self.renderer.poll_event()
}
#[inline]
pub fn open_controller(&mut self, id: ControllerId) -> PixResult<()> {
self.renderer.open_controller(id)
}
#[inline]
pub fn close_controller(&mut self, id: ControllerId) {
self.renderer.close_controller(id);
}
}