use crate::app::*;
use crate::image::Image;
pub use crate::prelude::*;
use crate::widget::*;
use fltk_sys::window::*;
use raw_window_handle::*;
use std::{
ffi::{CStr, CString},
mem,
ops::{Deref, DerefMut},
os::raw,
};
#[cfg(any(
target_os = "windows",
target_os = "macos",
target_os = "ios",
target_os = "android"
))]
pub type RawHandle = *mut raw::c_void;
#[cfg(all(
not(any(
target_os = "windows",
target_os = "macos",
target_os = "ios",
target_os = "android"
)),
any(
target_arch = "arm",
target_arch = "mips",
target_arch = "powerpc",
target_arch = "sparc",
target_arch = "wasm32",
target_arch = "x86",
)
))]
pub type RawHandle = u32;
#[cfg(all(
not(any(
target_os = "windows",
target_os = "macos",
target_os = "ios",
target_os = "android"
)),
any(
target_arch = "aarch64",
target_arch = "mips64",
target_arch = "powerpc64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "x86_64",
)
))]
pub type RawHandle = u64;
pub type Window = DoubleWindow;
#[repr(i32)]
#[derive(WidgetType, Debug, Copy, Clone, PartialEq)]
pub enum WindowType {
Normal = 240,
Double = 241,
}
#[derive(WidgetBase, WidgetExt, GroupExt, WindowExt, Debug)]
pub struct SingleWindow {
_inner: *mut Fl_Single_Window,
_tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
}
impl SingleWindow {
pub fn default() -> SingleWindow {
let mut win = <SingleWindow as Default>::default();
win.free_position();
win
}
pub unsafe fn find_by_handle(handle: RawHandle) -> Option<impl WindowExt> {
let ptr = Fl_Window_find_by_handle(mem::transmute(&handle));
if ptr.is_null() {
None
} else {
Some(Window::from_widget_ptr(
ptr as *mut fltk_sys::widget::Fl_Widget,
))
}
}
pub fn show_with_env_args(&mut self) {
assert!(!self.was_deleted());
unsafe {
let args: Vec<String> = std::env::args().collect();
let len = args.len() as i32;
let mut v: Vec<*mut raw::c_char> = vec![];
for arg in args {
let c = CString::safe_new(arg.as_str());
v.push(c.into_raw() as *mut raw::c_char);
}
let mut v = mem::ManuallyDrop::new(v);
Fl_Window_show_with_args(self._inner as *mut Fl_Window, len, v.as_mut_ptr())
}
}
pub fn show_with_args(&mut self, args: &[&str]) {
assert!(!self.was_deleted());
unsafe {
let mut temp = vec![""];
temp.extend(args);
let len = temp.len() as i32;
let mut v: Vec<*mut raw::c_char> = vec![];
for arg in temp {
let c = CString::safe_new(arg);
v.push(c.into_raw() as *mut raw::c_char);
}
let mut v = mem::ManuallyDrop::new(v);
Fl_Window_show_with_args(self._inner as *mut Fl_Window, len, v.as_mut_ptr())
}
}
}
#[derive(WidgetBase, WidgetExt, GroupExt, WindowExt, Debug)]
pub struct DoubleWindow {
_inner: *mut Fl_Double_Window,
_tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
}
impl DoubleWindow {
pub fn default() -> DoubleWindow {
let mut win = <DoubleWindow as Default>::default();
win.free_position();
win
}
pub unsafe fn find_by_handle(handle: RawHandle) -> Option<impl WindowExt> {
let ptr = Fl_Window_find_by_handle(mem::transmute(&handle));
if ptr.is_null() {
None
} else {
Some(Window::from_widget_ptr(
ptr as *mut fltk_sys::widget::Fl_Widget,
))
}
}
pub fn show_with_env_args(&mut self) {
assert!(!self.was_deleted());
unsafe {
let args: Vec<String> = std::env::args().collect();
let len = args.len() as i32;
let mut v: Vec<*mut raw::c_char> = vec![];
for arg in args {
let c = CString::safe_new(arg.as_str());
v.push(c.into_raw() as *mut raw::c_char);
}
let mut v = mem::ManuallyDrop::new(v);
Fl_Window_show_with_args(self._inner as *mut Fl_Window, len, v.as_mut_ptr())
}
}
pub fn show_with_args(&mut self, args: &[&str]) {
assert!(!self.was_deleted());
unsafe {
let mut temp = vec![""];
temp.extend(args);
let len = temp.len() as i32;
let mut v: Vec<*mut raw::c_char> = vec![];
for arg in temp {
let c = CString::safe_new(arg);
v.push(c.into_raw() as *mut raw::c_char);
}
let mut v = mem::ManuallyDrop::new(v);
Fl_Window_show_with_args(self._inner as *mut Fl_Window, len, v.as_mut_ptr())
}
}
pub fn flush(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Double_Window_flush(self._inner) }
}
}
#[derive(WidgetBase, WidgetExt, GroupExt, WindowExt, Debug)]
pub struct MenuWindow {
_inner: *mut Fl_Menu_Window,
_tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
}
impl MenuWindow {
pub fn default() -> MenuWindow {
let mut win = <MenuWindow as Default>::default();
win.free_position();
win
}
}
pub type GlContext = *mut raw::c_void;
#[cfg(feature = "enable-glwindow")]
#[derive(WidgetBase, WidgetExt, GroupExt, WindowExt, Debug)]
pub struct GlWindow {
_inner: *mut Fl_Gl_Window,
_tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
}
#[cfg(feature = "enable-glwindow")]
impl GlWindow {
pub fn default() -> GlWindow {
let mut win = <GlWindow as Default>::default();
win.free_position();
win
}
pub fn get_proc_address(&self, s: &'static str) -> *const raw::c_void {
gl_loader::get_proc_address(s) as *const _
}
pub fn flush(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_flush(self._inner) }
}
pub fn valid(&self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_valid(self._inner) != 0 }
}
pub fn set_valid(&mut self, v: bool) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_set_valid(self._inner, v as raw::c_char) }
}
pub fn context_valid(&self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_context_valid(self._inner) != 0 }
}
pub fn set_context_valid(&mut self, v: bool) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_set_context_valid(self._inner, v as raw::c_char) }
}
pub fn context(&self) -> Option<GlContext> {
assert!(!self.was_deleted());
unsafe {
let ctx = Fl_Gl_Window_context(self._inner);
if ctx.is_null() {
None
} else {
Some(ctx)
}
}
}
pub fn set_context(&mut self, ctx: GlContext, destroy_flag: bool) {
assert!(!self.was_deleted());
assert!(!ctx.is_null());
unsafe { Fl_Gl_Window_set_context(self._inner, ctx, destroy_flag as i32) }
}
pub fn swap_buffers(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_swap_buffers(self._inner) }
}
pub fn ortho(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_ortho(self._inner) }
}
pub fn can_do_overlay(&mut self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_can_do_overlay(self._inner) != 0 }
}
pub fn redraw_overlay(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_redraw_overlay(self._inner) }
}
pub fn hide_overlay(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_hide_overlay(self._inner) }
}
pub fn make_overlay_current(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_make_overlay_current(self._inner) }
}
pub fn pixels_per_unit(&mut self) -> f32 {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_pixels_per_unit(self._inner) }
}
pub fn pixel_w(&mut self) -> i32 {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_pixel_w(self._inner) }
}
pub fn pixel_h(&mut self) -> i32 {
assert!(!self.was_deleted());
unsafe { Fl_Gl_Window_pixel_h(self._inner) }
}
pub fn mode(&self) -> Mode {
assert!(!self.was_deleted());
unsafe { mem::transmute(Fl_Gl_Window_mode(self._inner)) }
}
pub fn set_mode(&mut self, mode: Mode) {
assert!(!self.was_deleted());
unsafe {
Fl_Gl_Window_set_mode(self._inner, mode.bits());
}
}
}
#[cfg(feature = "enable-glwindow")]
#[derive(WidgetBase, WidgetExt, GroupExt, WindowExt, Debug)]
pub struct GlutWindow {
_inner: *mut Fl_Glut_Window,
_tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
}
#[cfg(feature = "enable-glwindow")]
impl GlutWindow {
pub fn default() -> GlutWindow {
let mut win = <GlutWindow as Default>::default();
win.free_position();
win
}
pub fn get_proc_address(&self, s: &'static str) -> *const raw::c_void {
let ret = gl_loader::get_proc_address(s);
if !ret.is_null() {
ret as *const _
} else {
let s = CString::safe_new(s);
unsafe { Fl_Glut_Window_get_proc_address(self._inner, s.as_ptr()) as *const _ }
}
}
pub fn flush(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_flush(self._inner) }
}
pub fn valid(&self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_valid(self._inner) != 0 }
}
pub fn set_valid(&mut self, v: bool) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_set_valid(self._inner, v as raw::c_char) }
}
pub fn context_valid(&self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_context_valid(self._inner) != 0 }
}
pub fn set_context_valid(&mut self, v: bool) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_set_context_valid(self._inner, v as raw::c_char) }
}
pub fn context(&self) -> Option<GlContext> {
assert!(!self.was_deleted());
unsafe {
let ctx = Fl_Glut_Window_context(self._inner);
if ctx.is_null() {
None
} else {
Some(ctx)
}
}
}
pub fn set_context(&mut self, ctx: GlContext, destroy_flag: bool) {
assert!(!self.was_deleted());
assert!(!ctx.is_null());
unsafe { Fl_Glut_Window_set_context(self._inner, ctx, destroy_flag as i32) }
}
pub fn swap_buffers(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_swap_buffers(self._inner) }
}
pub fn ortho(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_ortho(self._inner) }
}
pub fn can_do_overlay(&mut self) -> bool {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_can_do_overlay(self._inner) != 0 }
}
pub fn redraw_overlay(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_redraw_overlay(self._inner) }
}
pub fn hide_overlay(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_hide_overlay(self._inner) }
}
pub fn make_overlay_current(&mut self) {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_make_overlay_current(self._inner) }
}
pub fn pixels_per_unit(&mut self) -> f32 {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_pixels_per_unit(self._inner) }
}
pub fn pixel_w(&mut self) -> i32 {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_pixel_w(self._inner) }
}
pub fn pixel_h(&mut self) -> i32 {
assert!(!self.was_deleted());
unsafe { Fl_Glut_Window_pixel_h(self._inner) }
}
pub fn mode(&self) -> Mode {
assert!(!self.was_deleted());
unsafe { mem::transmute(Fl_Glut_Window_mode(self._inner)) }
}
pub fn set_mode(&mut self, mode: Mode) {
assert!(!self.was_deleted());
unsafe {
Fl_Glut_Window_set_mode(self._inner, mode.bits());
}
}
}
pub struct AndroidWindow {
win: Window,
}
impl AndroidWindow {
pub fn default() -> Self {
let (w, h) = screen_size();
let mut w = AndroidWindow {
win: Window::new(0, 30, w as i32, h as i32 - 30, ""),
};
w.win.set_color(Color::White);
w
}
}
impl Deref for AndroidWindow {
type Target = Window;
fn deref(&self) -> &Self::Target {
&self.win
}
}
impl DerefMut for AndroidWindow {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.win
}
}