use bitflags::bitflags;
use rs_math3d::Vec2i;
#[derive(Debug, Copy, Clone)]
pub enum InputButtonState {
None,
Pressed(f32),
Released,
Scroll(f32),
}
#[derive(Debug, Copy, Clone)]
pub enum MouseEvent {
None,
Click(Vec2i),
Drag {
prev_pos: Vec2i,
curr_pos: Vec2i,
},
Move(Vec2i),
}
#[derive(PartialEq, Copy, Clone)]
#[repr(u32)]
pub enum Clip {
None = 0,
Part = 1,
All = 2,
}
#[derive(PartialEq, Copy, Clone)]
#[repr(u32)]
pub enum ControlColor {
Max = 14,
ScrollThumb = 13,
ScrollBase = 12,
BaseFocus = 11,
BaseHover = 10,
Base = 9,
ButtonFocus = 8,
ButtonHover = 7,
Button = 6,
PanelBG = 5,
TitleText = 4,
TitleBG = 3,
WindowBG = 2,
Border = 1,
Text = 0,
}
impl ControlColor {
pub fn hover(&mut self) {
*self = match self {
Self::Base => Self::BaseHover,
Self::Button => Self::ButtonHover,
_ => *self,
}
}
pub fn focus(&mut self) {
*self = match self {
Self::Base => Self::BaseFocus,
Self::Button => Self::ButtonFocus,
Self::BaseHover => Self::BaseFocus,
Self::ButtonHover => Self::ButtonFocus,
_ => *self,
}
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
pub struct ResourceState : u32 {
const CHANGE = 4;
const SUBMIT = 2;
const ACTIVE = 1;
const NONE = 0;
}
}
impl ResourceState {
pub fn is_changed(&self) -> bool {
self.intersects(Self::CHANGE)
}
pub fn is_submitted(&self) -> bool {
self.intersects(Self::SUBMIT)
}
pub fn is_active(&self) -> bool {
self.intersects(Self::ACTIVE)
}
pub fn is_none(&self) -> bool {
self.bits() == 0
}
}
bitflags! {
#[derive(Copy, Clone)]
pub struct ContainerOption : u32 {
const AUTO_SIZE = 512;
const NO_TITLE = 128;
const NO_CLOSE = 64;
const NO_RESIZE = 16;
const NO_FRAME = 8;
const NO_INTERACT = 4;
const NONE = 0;
}
#[derive(Copy, Clone)]
pub struct WidgetOption : u32 {
const HOLD_FOCUS = 256;
const NO_FRAME = 128;
const NO_INTERACT = 4;
const ALIGN_RIGHT = 2;
const ALIGN_CENTER = 1;
const NONE = 0;
}
#[derive(Copy, Clone)]
pub struct WidgetFillOption : u32 {
const NORMAL = 1;
const HOVER = 2;
const CLICK = 4;
const ALL = Self::NORMAL.bits() | Self::HOVER.bits() | Self::CLICK.bits();
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum WidgetBehaviourOption {
None,
GrabScroll,
NoScroll,
}
impl WidgetBehaviourOption {
pub const NONE: Self = Self::None;
pub const GRAB_SCROLL: Self = Self::GrabScroll;
pub const NO_SCROLL: Self = Self::NoScroll;
pub fn is_grab_scroll(self) -> bool {
matches!(self, Self::GrabScroll)
}
pub fn is_no_scroll(self) -> bool {
matches!(self, Self::NoScroll)
}
}
#[derive(Copy, Clone, Default, Debug)]
pub struct ControlState {
pub hovered: bool,
pub focused: bool,
pub clicked: bool,
pub active: bool,
pub scroll_delta: Option<Vec2i>,
}
#[derive(Clone, Debug)]
pub struct InputSnapshot {
pub mouse_pos: Vec2i,
pub mouse_delta: Vec2i,
pub mouse_down: MouseButton,
pub mouse_pressed: MouseButton,
pub key_mods: KeyMode,
pub key_pressed: KeyMode,
pub key_codes: KeyCode,
pub key_code_pressed: KeyCode,
pub text_input: String,
}
impl Default for InputSnapshot {
fn default() -> Self {
Self {
mouse_pos: Vec2i::default(),
mouse_delta: Vec2i::default(),
mouse_down: MouseButton::NONE,
mouse_pressed: MouseButton::NONE,
key_mods: KeyMode::NONE,
key_pressed: KeyMode::NONE,
key_codes: KeyCode::NONE,
key_code_pressed: KeyCode::NONE,
text_input: String::new(),
}
}
}
impl ContainerOption {
pub fn is_auto_sizing(&self) -> bool {
self.intersects(Self::AUTO_SIZE)
}
pub fn has_no_title(&self) -> bool {
self.intersects(Self::NO_TITLE)
}
pub fn has_no_close(&self) -> bool {
self.intersects(Self::NO_CLOSE)
}
pub fn is_fixed(&self) -> bool {
self.intersects(Self::NO_RESIZE)
}
pub fn has_no_frame(&self) -> bool {
self.intersects(Self::NO_FRAME)
}
}
impl WidgetOption {
pub fn is_holding_focus(&self) -> bool {
self.intersects(WidgetOption::HOLD_FOCUS)
}
pub fn has_no_frame(&self) -> bool {
self.intersects(WidgetOption::NO_FRAME)
}
pub fn is_not_interactive(&self) -> bool {
self.intersects(WidgetOption::NO_INTERACT)
}
pub fn is_aligned_right(&self) -> bool {
self.intersects(WidgetOption::ALIGN_RIGHT)
}
pub fn is_aligned_center(&self) -> bool {
self.intersects(WidgetOption::ALIGN_CENTER)
}
pub fn is_none(&self) -> bool {
self.bits() == 0
}
}
impl WidgetFillOption {
pub fn fill_normal(&self) -> bool {
self.intersects(Self::NORMAL)
}
pub fn fill_hover(&self) -> bool {
self.intersects(Self::HOVER)
}
pub fn fill_click(&self) -> bool {
self.intersects(Self::CLICK)
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
pub struct MouseButton : u32 {
const MIDDLE = 4;
const RIGHT = 2;
const LEFT = 1;
const NONE = 0;
}
}
impl MouseButton {
pub fn is_middle(&self) -> bool {
self.intersects(Self::MIDDLE)
}
pub fn is_right(&self) -> bool {
self.intersects(Self::RIGHT)
}
pub fn is_left(&self) -> bool {
self.intersects(Self::LEFT)
}
pub fn is_none(&self) -> bool {
self.bits() == 0
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
pub struct KeyMode : u32 {
const DELETE = 32;
const RETURN = 16;
const BACKSPACE = 8;
const ALT = 4;
const CTRL = 2;
const SHIFT = 1;
const NONE = 0;
}
}
impl KeyMode {
pub fn is_none(&self) -> bool {
self.bits() == 0
}
pub fn is_delete(&self) -> bool {
self.intersects(Self::DELETE)
}
pub fn is_return(&self) -> bool {
self.intersects(Self::RETURN)
}
pub fn is_backspace(&self) -> bool {
self.intersects(Self::BACKSPACE)
}
pub fn is_alt(&self) -> bool {
self.intersects(Self::ALT)
}
pub fn is_ctrl(&self) -> bool {
self.intersects(Self::CTRL)
}
pub fn is_shift(&self) -> bool {
self.intersects(Self::SHIFT)
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
pub struct KeyCode : u32 {
const DELETE = 32;
const END = 16;
const RIGHT = 8;
const LEFT = 4;
const DOWN = 2;
const UP = 1;
const NONE = 0;
}
}
impl KeyCode {
pub fn is_none(&self) -> bool {
self.bits() == 0
}
pub fn is_delete(&self) -> bool {
self.intersects(Self::DELETE)
}
pub fn is_end(&self) -> bool {
self.intersects(Self::END)
}
pub fn is_up(&self) -> bool {
self.intersects(Self::UP)
}
pub fn is_down(&self) -> bool {
self.intersects(Self::DOWN)
}
pub fn is_left(&self) -> bool {
self.intersects(Self::LEFT)
}
pub fn is_right(&self) -> bool {
self.intersects(Self::RIGHT)
}
}
#[derive(Clone, Debug)]
pub struct Input {
pub(crate) mouse_pos: Vec2i,
pub(crate) last_mouse_pos: Vec2i,
pub(crate) mouse_delta: Vec2i,
pub(crate) scroll_delta: Vec2i,
pub(crate) rel_mouse_pos: Vec2i,
pub(crate) mouse_down: MouseButton,
pub(crate) mouse_pressed: MouseButton,
pub(crate) key_down: KeyMode,
pub(crate) key_pressed: KeyMode,
pub(crate) key_code_down: KeyCode,
pub(crate) key_code_pressed: KeyCode,
pub(crate) input_text: String,
}
impl Default for Input {
fn default() -> Self {
Self {
mouse_pos: Vec2i::default(),
last_mouse_pos: Vec2i::default(),
mouse_delta: Vec2i::default(),
rel_mouse_pos: Vec2i::default(),
scroll_delta: Vec2i::default(),
mouse_down: MouseButton::NONE,
mouse_pressed: MouseButton::NONE,
key_down: KeyMode::NONE,
key_pressed: KeyMode::NONE,
key_code_down: KeyCode::NONE,
key_code_pressed: KeyCode::NONE,
input_text: String::default(),
}
}
}
impl Input {
pub fn rel_mouse_pos(&self) -> Vec2i {
self.rel_mouse_pos
}
pub fn key_state(&self) -> KeyMode {
self.key_down
}
pub fn key_codes(&self) -> KeyCode {
self.key_code_down
}
pub fn text_input(&self) -> &str {
&self.input_text
}
pub fn mousemove(&mut self, x: i32, y: i32) {
self.mouse_pos = Vec2i::new(x, y);
}
pub fn get_mouse_buttons(&self) -> MouseButton {
self.mouse_down
}
pub fn mousedown(&mut self, x: i32, y: i32, btn: MouseButton) {
self.mousemove(x, y);
self.mouse_down |= btn;
self.mouse_pressed |= btn;
}
pub fn mouseup(&mut self, x: i32, y: i32, btn: MouseButton) {
self.mousemove(x, y);
self.mouse_down &= !btn;
}
pub fn scroll(&mut self, x: i32, y: i32) {
self.scroll_delta.x += x;
self.scroll_delta.y += y;
}
pub fn keydown(&mut self, key: KeyMode) {
self.key_pressed |= key;
self.key_down |= key;
}
pub fn keyup(&mut self, key: KeyMode) {
self.key_down &= !key;
}
pub fn keydown_code(&mut self, code: KeyCode) {
self.key_code_pressed |= code;
self.key_code_down |= code;
}
pub fn keyup_code(&mut self, code: KeyCode) {
self.key_code_down &= !code;
}
pub fn text(&mut self, text: &str) {
self.input_text.push_str(text);
}
pub(crate) fn prelude(&mut self) {
self.mouse_delta.x = self.mouse_pos.x - self.last_mouse_pos.x;
self.mouse_delta.y = self.mouse_pos.y - self.last_mouse_pos.y;
}
pub(crate) fn epilogue(&mut self) {
self.key_pressed = KeyMode::NONE;
self.key_code_pressed = KeyCode::NONE;
self.input_text.clear();
self.mouse_pressed = MouseButton::NONE;
self.scroll_delta = Vec2i::new(0, 0);
self.last_mouse_pos = self.mouse_pos;
}
}