use crate::app::{font_index, FONTS};
use crate::prelude::{FltkError, FltkErrorKind};
use crate::utils::{self, FlString};
use fltk_sys::fl;
use std::{
ffi::{CStr, CString},
mem, path,
};
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum LabelType {
Normal = 0,
None,
Shadow,
Engraved,
Embossed,
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ColorDepth {
L8 = 1,
La8 = 2,
Rgb8 = 3,
Rgba8 = 4,
}
impl ColorDepth {
pub fn from_u8(val: u8) -> Result<ColorDepth, FltkError> {
if !(1..=4).contains(&val) {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
} else {
Ok(unsafe { mem::transmute(val) })
}
}
}
#[doc(hidden)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct UnmappedFrameType {
bits: i32,
}
impl UnmappedFrameType {
#[doc(hidden)]
pub const unsafe fn from_i32(val: i32) -> Self {
Self { bits: val }
}
}
#[repr(i32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FrameType {
NoBox,
FlatBox,
UpBox,
DownBox,
UpFrame,
DownFrame,
ThinUpBox,
ThinDownBox,
ThinUpFrame,
ThinDownFrame,
EngravedBox,
EmbossedBox,
EngravedFrame,
EmbossedFrame,
BorderBox,
ShadowBox,
BorderFrame,
ShadowFrame,
RoundedBox,
RShadowBox,
RoundedFrame,
RFlatBox,
RoundUpBox,
RoundDownBox,
DiamondUpBox,
DiamondDownBox,
OvalBox,
OShadowBox,
OvalFrame,
OFlatFrame,
PlasticUpBox,
PlasticDownBox,
PlasticUpFrame,
PlasticDownFrame,
PlasticThinUpBox,
PlasticThinDownBox,
PlasticRoundUpBox,
PlasticRoundDownBox,
GtkUpBox,
GtkDownBox,
GtkUpFrame,
GtkDownFrame,
GtkThinUpBox,
GtkThinDownBox,
GtkThinUpFrame,
GtkThinDownFrame,
GtkRoundUpFrame,
GtkRoundDownFrame,
GleamUpBox,
GleamDownBox,
GleamUpFrame,
GleamDownFrame,
GleamThinUpBox,
GleamThinDownBox,
GleamRoundUpBox,
GleamRoundDownBox,
FreeBoxType,
UserFrameType(UnmappedFrameType),
}
impl FrameType {
pub const OFlatBox: FrameType = FrameType::OFlatFrame;
pub const GtkRoundDownBox: FrameType = FrameType::GtkRoundDownFrame;
pub fn as_i32(&self) -> i32 {
match *self {
FrameType::UserFrameType(v) => v.bits,
_ => self.discriminant(),
}
}
#[doc(hidden)]
pub unsafe fn from_i32(v: i32) -> FrameType {
if (0..=56).contains(&v) {
*(&v as *const i32 as *const FrameType)
} else {
FrameType::UserFrameType(UnmappedFrameType::from_i32(v))
}
}
#[doc(hidden)]
fn discriminant(&self) -> i32 {
unsafe { *(self as *const Self as *const i32) }
}
pub fn by_index(idx: usize) -> FrameType {
let idx = if idx > 56 { 56 } else { idx };
unsafe { FrameType::from_i32(idx as i32) }
}
pub fn dx(self) -> i32 {
unsafe { fl::Fl_box_dx(self.as_i32()) }
}
pub fn dy(self) -> i32 {
unsafe { fl::Fl_box_dy(self.as_i32()) }
}
pub fn dw(self) -> i32 {
unsafe { fl::Fl_box_dw(self.as_i32()) }
}
pub fn dh(self) -> i32 {
unsafe { fl::Fl_box_dh(self.as_i32()) }
}
pub fn swap_frames(old_frame: FrameType, new_frame: FrameType) {
unsafe {
let new_frame = new_frame.as_i32();
let old_frame = old_frame.as_i32();
fl::Fl_set_box_type(old_frame, new_frame);
}
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Align: i32 {
const Center = 0x0000;
const Top = 0x0001;
const Bottom = 0x0002;
const Left = 0x0004;
const Right = 0x0008;
const Inside = 0x0010;
const TextOverImage = 0x0020;
const Clip = 0x0040;
const Wrap = 0x0080;
const ImageNextToText = 0x0100;
const TextNextToImage = 0x0120;
const ImageBackdrop = 0x0200;
const TopLeft = 0x0001 | 0x0004;
const TopRight = 0x0001 | 0x0008;
const BottomLeft = 0x0002 | 0x0004;
const BottomRight = 0x0002 | 0x0008;
const LeftTop = 0x0007;
const RightTop = 0x000B;
const LeftBottom = 0x000D;
const RightBottom = 0x000E;
const PositionMask = 0x000F;
const ImageMask = 0x0320;
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Font {
bits: i32,
}
impl Font {
pub const Helvetica: Font = Font { bits: 0 };
pub const HelveticaBold: Font = Font { bits: 1 };
pub const HelveticaItalic: Font = Font { bits: 2 };
pub const HelveticaBoldItalic: Font = Font { bits: 3 };
pub const Courier: Font = Font { bits: 4 };
pub const CourierBold: Font = Font { bits: 5 };
pub const CourierItalic: Font = Font { bits: 6 };
pub const CourierBoldItalic: Font = Font { bits: 7 };
pub const Times: Font = Font { bits: 8 };
pub const TimesBold: Font = Font { bits: 9 };
pub const TimesItalic: Font = Font { bits: 10 };
pub const TimesBoldItalic: Font = Font { bits: 11 };
pub const Symbol: Font = Font { bits: 12 };
pub const Screen: Font = Font { bits: 13 };
pub const ScreenBold: Font = Font { bits: 14 };
pub const Zapfdingbats: Font = Font { bits: 15 };
pub const fn bits(&self) -> i32 {
self.bits
}
pub fn by_index(idx: usize) -> Font {
if idx < (FONTS.lock().unwrap()).len() {
unsafe { mem::transmute(idx as i32) }
} else {
Font::Helvetica
}
}
pub fn by_name(name: &str) -> Font {
match font_index(name) {
Some(val) => Font::by_index(val),
None => Font::Helvetica,
}
}
pub fn set_font(old: Font, new: &str) {
let new = CString::safe_new(new);
unsafe {
fl::Fl_set_font2(old.bits(), new.into_raw() as _);
}
}
pub fn load_font<P: AsRef<path::Path>>(path: P) -> Result<String, FltkError> {
Font::load_font_(path.as_ref())
}
fn load_font_(path: &path::Path) -> Result<String, FltkError> {
unsafe {
if !path.exists() {
return Err::<String, FltkError>(FltkError::Internal(
FltkErrorKind::ResourceNotFound,
));
}
if let Some(p) = path.to_str() {
let font_data = std::fs::read(path)?;
let face = match ttf_parser::Face::parse(&font_data, 0) {
Ok(f) => f,
Err(_) => {
return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
}
};
let family_name = face
.names()
.into_iter()
.find(|name| {
name.name_id == ttf_parser::name_id::FULL_NAME && name.is_unicode()
})
.and_then(|name| name.to_string());
let path = CString::safe_new(p);
let ret = fl::Fl_load_font(path.as_ptr());
if let Some(family_name) = family_name {
if ret > 0 {
Ok(family_name)
} else {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
}
} else {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
}
} else {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
}
}
}
pub fn get_name(&self) -> String {
unsafe {
CStr::from_ptr(fl::Fl_get_font_name(self.bits()))
.to_string_lossy()
.to_string()
}
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Debug for Font {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
Font::Helvetica => write!(f, "Font::Helvetica"),
Font::HelveticaBold => write!(f, "Font::HelveticaBold"),
Font::HelveticaItalic => write!(f, "Font::HelveticaItalic"),
Font::HelveticaBoldItalic => write!(f, "Font::HelveticaBoldItalic"),
Font::Courier => write!(f, "Font::Courier"),
Font::CourierBold => write!(f, "Font::CourierBold"),
Font::CourierItalic => write!(f, "Font::CourierItalic"),
Font::CourierBoldItalic => write!(f, "Font::CourierBoldItalic"),
Font::Times => write!(f, "Font::Times"),
Font::TimesBold => write!(f, "Font::TimesBold"),
Font::TimesItalic => write!(f, "Font::TimesItalic"),
Font::TimesBoldItalic => write!(f, "Font::TimesBoldItalic"),
Font::Symbol => write!(f, "Font::Symbol"),
Font::Screen => write!(f, "Font::Screen"),
Font::ScreenBold => write!(f, "Font::ScreenBold"),
Font::Zapfdingbats => write!(f, "Font::Zapfdingbats"),
_ => {
write!(f, "Font::from_i32({})", self.bits())
}
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Color {
bits: u32,
}
impl Color {
pub const ForeGround: Color = Color { bits: 0 };
pub const Foreground: Color = Color { bits: 0 };
pub const BackGround2: Color = Color { bits: 7 };
pub const Background2: Color = Color { bits: 7 };
pub const Inactive: Color = Color { bits: 8 };
pub const Selection: Color = Color { bits: 15 };
pub const Free: Color = Color { bits: 16 };
pub const Gray0: Color = Color { bits: 32 };
pub const GrayRamp: Color = Color { bits: 32 };
pub const Dark3: Color = Color { bits: 39 };
pub const Dark2: Color = Color { bits: 45 };
pub const Dark1: Color = Color { bits: 47 };
pub const FrameDefault: Color = Color { bits: 49 };
pub const BackGround: Color = Color { bits: 49 };
pub const Background: Color = Color { bits: 49 };
pub const Light1: Color = Color { bits: 50 };
pub const Light2: Color = Color { bits: 52 };
pub const Light3: Color = Color { bits: 54 };
pub const Black: Color = Color { bits: 56 };
pub const Red: Color = Color { bits: 88 };
pub const Green: Color = Color { bits: 63 };
pub const Yellow: Color = Color { bits: 95 };
pub const Blue: Color = Color { bits: 216 };
pub const Magenta: Color = Color { bits: 248 };
pub const Cyan: Color = Color { bits: 223 };
pub const DarkRed: Color = Color { bits: 72 };
pub const DarkGreen: Color = Color { bits: 60 };
pub const DarkYellow: Color = Color { bits: 76 };
pub const DarkBlue: Color = Color { bits: 136 };
pub const DarkMagenta: Color = Color { bits: 152 };
pub const DarkCyan: Color = Color { bits: 140 };
pub const White: Color = Color { bits: 255 };
pub const fn bits(&self) -> u32 {
self.bits
}
pub const fn from_rgb(r: u8, g: u8, b: u8) -> Color {
let r = r as u32;
let g = g as u32;
let b = b as u32;
let val: u32 = ((r & 0xff) << 24) + ((g & 0xff) << 16) + ((b & 0xff) << 8);
Color::from_rgbi(val)
}
#[cfg(feature = "enable-glwindow")]
pub const fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Color {
let r = r as u32;
let g = g as u32;
let b = b as u32;
let a = a as u32;
let val: u32 = ((r & 0xff) << 24) + ((g & 0xff) << 16) + ((b & 0xff) << 8) + (a & 0xff);
Color::from_rgbi(val)
}
pub const fn from_rgbi(val: u32) -> Color {
Color { bits: val }
}
pub fn from_rgba_tuple(tup: (u8, u8, u8, u8)) -> Color {
if tup.3 != 255 {
let bg_col = if let Some(grp) = crate::group::Group::try_current() {
use crate::prelude::WidgetExt;
grp.color()
} else {
Color::BackGround
};
let bg_col = bg_col.to_rgb();
let alpha = tup.3 as f32 / 255.0;
let r = alpha * tup.0 as f32 + (1.0 - alpha) * bg_col.0 as f32;
let r = r as u8;
let g = alpha * tup.1 as f32 + (1.0 - alpha) * bg_col.1 as f32;
let g = g as u8;
let b = alpha * tup.2 as f32 + (1.0 - alpha) * bg_col.2 as f32;
let b = b as u8;
Color::from_rgb(r, g, b)
} else {
Color::from_rgb(tup.0, tup.1, tup.2)
}
}
pub const fn from_u32(val: u32) -> Color {
#[cfg(feature = "enable-glwindow")]
{
let (r, g, b, a) = utils::hex2rgba(val);
Color::from_rgba(r, g, b, a)
}
#[cfg(not(feature = "enable-glwindow"))]
{
let (r, g, b) = utils::hex2rgb(val);
Color::from_rgb(r, g, b)
}
}
pub const fn from_hex(val: u32) -> Color {
Color::from_u32(val)
}
pub fn from_hex_str(col: &str) -> Result<Color, FltkError> {
if !col.starts_with('#') || col.len() < 7 {
return Err(FltkError::Internal(FltkErrorKind::InvalidColor));
}
let color: Color;
#[cfg(not(feature = "enable-glwindow"))]
{
color = Color::from_hex(u32::from_str_radix(&col[1..7], 16)?);
}
#[cfg(feature = "enable-glwindow")]
{
color = Color::from_hex(u32::from_str_radix(&col[1..9], 16)?);
}
Ok(color)
}
pub fn to_hex_str(&self) -> String {
#[cfg(not(feature = "enable-glwindow"))]
{
let (r, g, b) = self.to_rgb();
format!("#{:02x}{:02x}{:02x}", r, g, b)
}
#[cfg(feature = "enable-glwindow")]
{
let (r, g, b, a) = self.to_rgba();
format!("#{:02x}{:02x}{:02x}{:02x}", r, g, b, a)
}
}
pub fn by_index(idx: u8) -> Color {
unsafe { mem::transmute(idx as u32) }
}
pub fn inactive(&self) -> Color {
unsafe { mem::transmute(fl::Fl_inactive(self.bits())) }
}
pub fn darker(&self) -> Color {
unsafe { mem::transmute(fl::Fl_darker(self.bits())) }
}
pub fn lighter(&self) -> Color {
unsafe { mem::transmute(fl::Fl_lighter(self.bits())) }
}
pub fn gray_ramp(val: i32) -> Color {
unsafe { mem::transmute(fl::Fl_gray_ramp(val)) }
}
pub fn color_average(c1: Color, c2: Color, weight: f32) -> Color {
unsafe { mem::transmute(fl::Fl_color_average(c1.bits(), c2.bits(), weight)) }
}
pub fn contrast(fg: Color, bg: Color) -> Color {
unsafe { mem::transmute(fl::Fl_contrast(fg.bits(), bg.bits())) }
}
pub fn gray_scale(g: u8) -> Color {
unsafe { mem::transmute(fl::Fl_rgb_color2(g)) }
}
pub fn rgb_color(r: u8, g: u8, b: u8) -> Color {
unsafe { mem::transmute(fl::Fl_rgb_color(r, g, b)) }
}
pub fn to_rgb(&self) -> (u8, u8, u8) {
unsafe {
let val = self.bits();
let r = ((val >> 24) & 0xff) as u8;
let g = ((val >> 16) & 0xff) as u8;
let b = ((val >> 8) & 0xff) as u8;
let i = (val & 0xff) as u8;
if i == 0 {
(r, g, b)
} else {
let val = fl::Fl_cmap(val);
let r = ((val >> 24) & 0xff) as u8;
let g = ((val >> 16) & 0xff) as u8;
let b = ((val >> 8) & 0xff) as u8;
(r, g, b)
}
}
}
#[cfg(feature = "enable-glwindow")]
pub fn to_rgba(&self) -> (u8, u8, u8, u8) {
let val = self.bits();
let r = ((val >> 24) & 0xff) as u8;
let g = ((val >> 16) & 0xff) as u8;
let b = ((val >> 8) & 0xff) as u8;
let a = (val & 0xff) as u8;
(r, g, b, a)
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
Color::ForeGround => write!(f, "Color::ForeGround"),
Color::BackGround => write!(f, "Color::BackGround"),
Color::BackGround2 => write!(f, "Color::BackGround2"),
Color::Foreground => write!(f, "Color::Foreground"),
Color::Background => write!(f, "Color::Background"),
Color::Background2 => write!(f, "Color::Background2"),
Color::Inactive => write!(f, "Color::Inactive"),
Color::Selection => write!(f, "Color::Selection"),
Color::Gray0 => write!(f, "Color::Gray0"),
Color::Dark3 => write!(f, "Color::Dark3"),
Color::Dark2 => write!(f, "Color::Dark2"),
Color::Dark1 => write!(f, "Color::Dark1"),
Color::FrameDefault => write!(f, "Color::FrameDefault"),
Color::Light1 => write!(f, "Color::Light1"),
Color::Light2 => write!(f, "Color::Light2"),
Color::Light3 => write!(f, "Color::Light3"),
Color::Black => write!(f, "Color::Black"),
Color::Red => write!(f, "Color::Red"),
Color::Green => write!(f, "Color::Green"),
Color::Yellow => write!(f, "Color::Yellow"),
Color::Blue => write!(f, "Color::Blue"),
Color::Magenta => write!(f, "Color::Magenta"),
Color::Cyan => write!(f, "Color::Cyan"),
Color::DarkRed => write!(f, "Color::DarkRed"),
Color::DarkGreen => write!(f, "Color::DarkGreen"),
Color::DarkYellow => write!(f, "Color::DarkYellow"),
Color::DarkBlue => write!(f, "Color::DarkBlue"),
Color::DarkMagenta => write!(f, "Color::DarkMagenta"),
Color::DarkCyan => write!(f, "Color::DarkCyan"),
Color::White => write!(f, "Color::White"),
_ => {
let temp = format!("{:08x}", self.bits());
write!(f, "Color::from_hex(0x{})", &temp[0..6])
}
}
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Debug for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", *self)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Event {
bits: i32,
}
impl Event {
pub const NoEvent: Event = Event { bits: 0 };
pub const Push: Event = Event { bits: 1 };
pub const Released: Event = Event { bits: 2 };
pub const Enter: Event = Event { bits: 3 };
pub const Leave: Event = Event { bits: 4 };
pub const Drag: Event = Event { bits: 5 };
pub const Focus: Event = Event { bits: 6 };
pub const Unfocus: Event = Event { bits: 7 };
pub const KeyDown: Event = Event { bits: 8 };
pub const KeyUp: Event = Event { bits: 9 };
pub const Close: Event = Event { bits: 10 };
pub const Move: Event = Event { bits: 11 };
pub const Shortcut: Event = Event { bits: 12 };
pub const Deactivate: Event = Event { bits: 13 };
pub const Activate: Event = Event { bits: 14 };
pub const Hide: Event = Event { bits: 15 };
pub const Show: Event = Event { bits: 16 };
pub const Paste: Event = Event { bits: 17 };
pub const SelectionClear: Event = Event { bits: 18 };
pub const MouseWheel: Event = Event { bits: 19 };
pub const DndEnter: Event = Event { bits: 20 };
pub const DndDrag: Event = Event { bits: 21 };
pub const DndLeave: Event = Event { bits: 22 };
pub const DndRelease: Event = Event { bits: 23 };
pub const ScreenConfigChanged: Event = Event { bits: 24 };
pub const Fullscreen: Event = Event { bits: 25 };
pub const ZoomGesture: Event = Event { bits: 26 };
pub const ZoomEvent: Event = Event { bits: 27 };
pub const Resize: Event = Event { bits: 28 };
pub const fn bits(&self) -> i32 {
self.bits
}
pub const fn from_i32(val: i32) -> Event {
Event { bits: val }
}
}
impl From<i32> for Event {
fn from(val: i32) -> Event {
Event::from_i32(val)
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Debug for Event {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", *self)
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Display for Event {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
Event::NoEvent => write!(f, "Event::NoEvent"),
Event::Push => write!(f, "Event::Push"),
Event::Released => write!(f, "Event::Released"),
Event::Enter => write!(f, "Event::Enter"),
Event::Leave => write!(f, "Event::Leave"),
Event::Drag => write!(f, "Event::Drag"),
Event::Focus => write!(f, "Event::Focus"),
Event::Unfocus => write!(f, "Event::Unfocus"),
Event::KeyDown => write!(f, "Event::KeyDown"),
Event::KeyUp => write!(f, "Event::KeyUp"),
Event::Close => write!(f, "Event::Close"),
Event::Move => write!(f, "Event::Move"),
Event::Shortcut => write!(f, "Event::Shortcut"),
Event::Deactivate => write!(f, "Event::Deactivate"),
Event::Activate => write!(f, "Event::Activate"),
Event::Hide => write!(f, "Event::Hide"),
Event::Show => write!(f, "Event::Show"),
Event::Paste => write!(f, "Event::Paste"),
Event::SelectionClear => write!(f, "Event::SelectionClear"),
Event::MouseWheel => write!(f, "Event::MouseWheel"),
Event::DndEnter => write!(f, "Event::DndEnter"),
Event::DndDrag => write!(f, "Event::DndDrag"),
Event::DndLeave => write!(f, "Event::DndLeave"),
Event::DndRelease => write!(f, "Event::DndRelease"),
Event::ScreenConfigChanged => write!(f, "Event::ScreenConfigChanged"),
Event::Fullscreen => write!(f, "Event::Fullscreen"),
Event::ZoomGesture => write!(f, "Event::ZoomGesture"),
Event::ZoomEvent => write!(f, "Event::ZoomEvent"),
Event::Resize => write!(f, "Event::Resize"),
_ => {
write!(f, "Event::from_i32({})", self.bits())
}
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key {
bits: i32,
}
impl Key {
pub const None: Key = Key { bits: 0 };
pub const Button: Key = Key { bits: 0xfee8 };
pub const BackSpace: Key = Key { bits: 0xff08 };
pub const Tab: Key = Key { bits: 0xff09 };
pub const IsoKey: Key = Key { bits: 0xff0c };
pub const Enter: Key = Key { bits: 0xff0d };
pub const Pause: Key = Key { bits: 0xff13 };
pub const ScrollLock: Key = Key { bits: 0xff14 };
pub const Escape: Key = Key { bits: 0xff1b };
pub const Kana: Key = Key { bits: 0xff2e };
pub const Eisu: Key = Key { bits: 0xff2f };
pub const Yen: Key = Key { bits: 0xff30 };
pub const JISUnderscore: Key = Key { bits: 0xff31 };
pub const Home: Key = Key { bits: 0xff50 };
pub const Left: Key = Key { bits: 0xff51 };
pub const Up: Key = Key { bits: 0xff52 };
pub const Right: Key = Key { bits: 0xff53 };
pub const Down: Key = Key { bits: 0xff54 };
pub const PageUp: Key = Key { bits: 0xff55 };
pub const PageDown: Key = Key { bits: 0xff56 };
pub const End: Key = Key { bits: 0xff57 };
pub const Print: Key = Key { bits: 0xff61 };
pub const Insert: Key = Key { bits: 0xff63 };
pub const Menu: Key = Key { bits: 0xff67 };
pub const Help: Key = Key { bits: 0xff68 };
pub const NumLock: Key = Key { bits: 0xff7f };
pub const KP: Key = Key { bits: 0xff80 };
pub const KPEnter: Key = Key { bits: 0xff8d };
pub const KPLast: Key = Key { bits: 0xffbd };
pub const F1: Key = Key { bits: 0xffbd + 1 };
pub const F2: Key = Key { bits: 0xffbd + 2 };
pub const F3: Key = Key { bits: 0xffbd + 3 };
pub const F4: Key = Key { bits: 0xffbd + 4 };
pub const F5: Key = Key { bits: 0xffbd + 5 };
pub const F6: Key = Key { bits: 0xffbd + 6 };
pub const F7: Key = Key { bits: 0xffbd + 7 };
pub const F8: Key = Key { bits: 0xffbd + 8 };
pub const F9: Key = Key { bits: 0xffbd + 9 };
pub const F10: Key = Key { bits: 0xffbd + 10 };
pub const F11: Key = Key { bits: 0xffbd + 11 };
pub const F12: Key = Key { bits: 0xffbd + 12 };
pub const FLast: Key = Key { bits: 0xffe0 };
pub const ShiftL: Key = Key { bits: 0xffe1 };
pub const ShiftR: Key = Key { bits: 0xffe2 };
pub const ControlL: Key = Key { bits: 0xffe3 };
pub const ControlR: Key = Key { bits: 0xffe4 };
pub const CapsLock: Key = Key { bits: 0xffe5 };
pub const MetaL: Key = Key { bits: 0xffe7 };
pub const MetaR: Key = Key { bits: 0xffe8 };
pub const AltL: Key = Key { bits: 0xffe9 };
pub const AltR: Key = Key { bits: 0xffea };
pub const Delete: Key = Key { bits: 0xffff };
pub const fn bits(&self) -> i32 {
self.bits
}
pub const fn from_i32(val: i32) -> Key {
Key { bits: val }
}
pub const fn from_char(val: char) -> Key {
Key { bits: val as i32 }
}
pub const fn to_char(&self) -> Option<char> {
let bits = self.bits();
if bits >= 0xD800 && bits <= 0xDFFF {
None
} else {
Some(bits as u8 as char)
}
}
pub const fn is_fn_key(key: Key) -> bool {
key.bits() >= Key::F1.bits() && key.bits() < Key::FLast.bits()
}
pub const fn fn_key(val: i32) -> Key {
Key::from_i32(Key::F1.bits() - 1 + val)
}
}
#[allow(unreachable_patterns)]
impl std::fmt::Debug for Key {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
Key::None => write!(f, "Key::None"),
Key::Button => write!(f, "Key::Button"),
Key::BackSpace => write!(f, "Key::BackSpace"),
Key::Tab => write!(f, "Key::Tab"),
Key::IsoKey => write!(f, "Key::IsoKey"),
Key::Enter => write!(f, "Key::Enter"),
Key::Pause => write!(f, "Key::Pause"),
Key::ScrollLock => write!(f, "Key::ScrollLock"),
Key::Escape => write!(f, "Key::Escape"),
Key::Kana => write!(f, "Key::Kana"),
Key::Eisu => write!(f, "Key::Eisu"),
Key::Yen => write!(f, "Key::Yen"),
Key::JISUnderscore => write!(f, "Key::JISUnderscore"),
Key::Home => write!(f, "Key::Home"),
Key::Left => write!(f, "Key::Left"),
Key::Up => write!(f, "Key::Up"),
Key::Right => write!(f, "Key::Right"),
Key::Down => write!(f, "Key::Down"),
Key::PageUp => write!(f, "Key::PageUp"),
Key::PageDown => write!(f, "Key::PageDown"),
Key::End => write!(f, "Key::End"),
Key::Print => write!(f, "Key::Print"),
Key::Insert => write!(f, "Key::Insert"),
Key::Menu => write!(f, "Key::Menu"),
Key::Help => write!(f, "Key::Help"),
Key::NumLock => write!(f, "Key::NumLock"),
Key::KP => write!(f, "Key::KP"),
Key::KPEnter => write!(f, "Key::KPEnter"),
Key::KPLast => write!(f, "Key::KPLast"),
Key::F1 => write!(f, "Key::F1"),
Key::F2 => write!(f, "Key::F2"),
Key::F3 => write!(f, "Key::F3"),
Key::F4 => write!(f, "Key::F4"),
Key::F5 => write!(f, "Key::F5"),
Key::F6 => write!(f, "Key::F6"),
Key::F7 => write!(f, "Key::F7"),
Key::F8 => write!(f, "Key::F8"),
Key::F9 => write!(f, "Key::F9"),
Key::F10 => write!(f, "Key::F10"),
Key::F11 => write!(f, "Key::F11"),
Key::F12 => write!(f, "Key::F12"),
Key::FLast => write!(f, "Key::FLast"),
Key::ShiftL => write!(f, "Key::ShiftL"),
Key::ShiftR => write!(f, "Key::ShiftR"),
Key::ControlL => write!(f, "Key::ControlL"),
Key::ControlR => write!(f, "Key::ControlR"),
Key::CapsLock => write!(f, "Key::CapsLock"),
Key::MetaL => write!(f, "Key::MetaL"),
Key::MetaR => write!(f, "Key::MetaR"),
Key::AltL => write!(f, "Key::AltL"),
Key::AltR => write!(f, "Key::AltR"),
Key::Delete => write!(f, "Key::Delete"),
_ => {
write!(f, "Key::from_i32({})", self.bits())
}
}
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Shortcut: i32 {
const None = 0;
const Shift = 0x0001_0000;
const CapsLock = 0x0002_0000;
const Ctrl = 0x0004_0000;
const Alt = 0x0008_0000;
const Meta = 0x0040_0000;
const Command = if cfg!(target_os = "macos") {
Shortcut::Meta.bits()
} else {
Shortcut::Ctrl.bits()
};
const Control = if cfg!(target_os = "macos") {
Shortcut::Ctrl.bits()
} else {
Shortcut::Meta.bits()
};
const Button1 = 0x0100_0000;
const Button2 = 0x0200_0000;
const Button3 = 0x0400_0000;
const Buttons = 0x7f00_0000;
}
}
pub type EventState = Shortcut;
impl Shortcut {
pub const fn from_char(c: char) -> Shortcut {
Shortcut::from_bits_retain(c as _)
}
pub const fn from_key(k: Key) -> Shortcut {
Shortcut::from_bits_retain(k.bits())
}
pub const fn from_i32(v: i32) -> Shortcut {
Shortcut::from_bits_retain(v)
}
pub const fn key(&self) -> Key {
let mut temp = self.bits();
temp &= 0x0000_ffff;
Key::from_i32(temp)
}
pub const fn button(button_num: i32) -> Shortcut {
Shortcut::from_bits_retain(0x0080_0000 << button_num)
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CallbackTrigger: i32 {
const Never = 0;
const Changed = 1;
const NotChanged = 2;
const Release = 4;
const ReleaseAlways = 6;
const EnterKey = 8;
const EnterKeyAlways = 10;
const EnterKeyChanged = 11;
const Closed = 16;
}
}
#[repr(i32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CallbackReason {
Unknown,
Selected,
Deselected,
Reselected,
Opened,
Closed,
Dragged,
Cancelled,
Changed,
GotFocus,
LostFocus,
Released,
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Cursor {
Default = 0,
Arrow = 35,
Cross = 66,
Wait = 76,
Insert = 77,
Hand = 31,
Help = 47,
Move = 27,
NS = 78,
WE = 79,
NWSE = 80,
NESW = 81,
N = 70,
NE = 69,
E = 49,
SE = 8,
S = 9,
SW = 7,
W = 36,
NW = 68,
None = 255,
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Mode: i32 {
const Rgb = 0;
const Single = 0;
const Index = 1;
const Double = 2;
const Accum = 4;
const Alpha = 8;
const Depth = 16;
const Stencil = 32;
const Rgb8 = 64;
const MultiSample = 128;
const Stereo = 256;
const FakeSingle = 512; const Opengl3 = 1024;
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Damage: u8 {
const None = 0x00;
const Child = 0x01;
const Expose = 0x02;
const Scroll = 0x04;
const Overlay = 0x08;
const User1 = 0x10;
const User2 = 0x20;
const All = 0x80;
}
}
impl std::ops::BitOr<char> for Shortcut {
type Output = Shortcut;
fn bitor(self, other: char) -> Self::Output {
unsafe { mem::transmute(self.bits() | other as i32) }
}
}
impl std::ops::BitOr<Key> for Shortcut {
type Output = Shortcut;
fn bitor(self, other: Key) -> Self::Output {
unsafe { mem::transmute(self.bits() | other.bits()) }
}
}
impl std::ops::BitOr<i32> for Align {
type Output = Align;
fn bitor(self, rhs: i32) -> Self::Output {
unsafe { mem::transmute(self.bits() | rhs) }
}
}