use crate::app::init::CURRENT_FRAME;
use crate::enums::{Color, FrameType, Mode};
use crate::prelude::*;
use crate::utils::FlString;
use fltk_sys::fl;
use std::{ffi::CString, mem, os::raw, sync::atomic::Ordering};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Scheme {
Base,
Plastic,
Gtk,
Gleam,
Oxy,
}
pub fn set_scheme(scheme: Scheme) {
let name_str = match scheme {
Scheme::Base => "base",
Scheme::Gtk => "gtk+",
Scheme::Gleam => "gleam",
Scheme::Plastic => "plastic",
Scheme::Oxy => "oxy",
};
let name_str = CString::safe_new(name_str);
unsafe {
fl::Fl_set_scheme(name_str.as_ptr());
}
}
pub fn scheme() -> Scheme {
unsafe {
use Scheme::{Base, Gleam, Gtk, Oxy, Plastic};
match fl::Fl_scheme() {
0 => Base,
1 => Gtk,
2 => Gleam,
3 => Plastic,
4 => Oxy,
_ => unreachable!(),
}
}
}
pub type AppScheme = Scheme;
pub fn set_scrollbar_size(sz: i32) {
unsafe { fl::Fl_set_scrollbar_size(sz) }
}
pub fn scrollbar_size() -> i32 {
unsafe { fl::Fl_scrollbar_size() }
}
pub fn visible_focus() -> bool {
unsafe { fl::Fl_visible_focus() != 0 }
}
pub fn set_visible_focus(flag: bool) {
unsafe { fl::Fl_set_visible_focus(flag as i32) }
}
pub fn set_frame_type(new_frame: FrameType) {
unsafe {
let new_frame = new_frame.as_i32();
let curr = CURRENT_FRAME.load(Ordering::Relaxed);
fl::Fl_set_box_type(curr, new_frame);
CURRENT_FRAME.store(new_frame, Ordering::Relaxed);
}
}
pub fn set_frame_type2(old_frame: FrameType, new_frame: FrameType) {
unsafe {
fl::Fl_set_box_type(old_frame.as_i32(), new_frame.as_i32());
}
}
pub fn set_frame_type_cb(
old_frame: FrameType,
cb: fn(x: i32, y: i32, w: i32, h: i32, c: Color),
x: i32,
y: i32,
w: i32,
h: i32,
) {
unsafe {
fl::Fl_set_box_type_cb(old_frame.as_i32(), Some(mem::transmute(cb)), x, y, w, h);
}
}
pub fn frame_type() -> FrameType {
let curr = CURRENT_FRAME.load(Ordering::Relaxed);
FrameType::by_index(curr as _)
}
pub fn swap_frame_type(new_frame: FrameType) {
unsafe {
let new_frame = new_frame.as_i32();
let curr = CURRENT_FRAME.load(Ordering::Relaxed);
fl::Fl_set_box_type(56, curr);
fl::Fl_set_box_type(curr, new_frame);
fl::Fl_set_box_type(new_frame, 56);
CURRENT_FRAME.store(new_frame, Ordering::Relaxed);
}
}
pub fn frame_shadow_width() -> i32 {
unsafe { fl::Fl_box_shadow_width() }
}
pub fn set_frame_shadow_width(width: i32) {
unsafe { fl::Fl_set_box_shadow_width(width) }
}
pub fn frame_border_radius_max() -> i32 {
unsafe { fl::Fl_box_border_radius_max() }
}
pub fn set_frame_border_radius_max(radius: i32) {
unsafe { fl::Fl_set_box_border_radius_max(radius) }
}
pub fn own_colormap() {
unsafe { fl::Fl_own_colormap() }
}
pub fn foreground(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_foreground(r, g, b) }
}
pub fn background(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_background(r, g, b) }
}
pub fn background2(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_background2(r, g, b) }
}
pub fn set_foreground_color(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_foreground(r, g, b) }
}
pub fn set_background_color(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_background(r, g, b) }
}
pub fn set_background2_color(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_background2(r, g, b) }
}
pub fn set_selection_color(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_selection_color(r, g, b) }
}
pub fn set_inactive_color(r: u8, g: u8, b: u8) {
unsafe { fl::Fl_inactive_color(r, g, b) }
}
pub fn set_color(old: Color, r: u8, g: u8, b: u8) {
unsafe { fl::Fl_set_color(old.bits(), r, g, b) }
}
#[cfg(any(feature = "enable-glwindow", feature = "cairoext"))]
pub fn set_color_with_alpha(old: Color, r: u8, g: u8, b: u8, a: u8) {
unsafe { fl::Fl_set_color_with_alpha(old.bits() as u32, r, g, b, a) }
}
pub fn get_system_colors() {
unsafe { fl::Fl_get_system_colors() }
}
pub fn reload_scheme() -> Result<(), FltkError> {
unsafe {
match fl::Fl_reload_scheme() {
1 => Ok(()),
_ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
}
}
}
pub fn menu_linespacing() -> i32 {
unsafe { fl::Fl_menu_linespacing() }
}
pub fn set_menu_linespacing(val: i32) {
unsafe { fl::Fl_set_menu_linespacing(val) }
}
pub fn set_visual(mode: Mode) -> Result<(), FltkError> {
unsafe {
match fl::Fl_visual(mode.bits()) {
0 => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
_ => Ok(()),
}
}
}
#[cfg(feature = "enable-glwindow")]
pub fn set_gl_visual(mode: Mode) -> Result<(), FltkError> {
unsafe {
match fl::Fl_gl_visual(mode.bits() as i32) {
0 => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
_ => Ok(()),
}
}
}
pub type GraphicsContext = *mut raw::c_void;
pub fn graphics_context() -> GraphicsContext {
unsafe {
let ctx = fltk_sys::window::Fl_gc();
assert!(!ctx.is_null());
ctx
}
}
pub fn cairo_gc() -> *mut raw::c_void {
unsafe {
let ctx = fltk_sys::window::Fl_cairo_gc();
assert!(!ctx.is_null());
ctx
}
}
pub type Display = *mut raw::c_void;
pub fn display() -> Display {
unsafe {
let disp = fltk_sys::window::Fl_display();
assert!(!disp.is_null());
disp
}
}
pub fn flush() {
assert!(crate::app::is_ui_thread());
unsafe { fl::Fl_flush() }
}
pub fn redraw() {
unsafe { fl::Fl_redraw() }
}
pub unsafe fn open_display() {
fl::Fl_open_display()
}
pub unsafe fn close_display() {
fl::Fl_close_display()
}
pub fn draw_frame_active() -> bool {
unsafe { fl::Fl_draw_box_active() != 0 }
}
pub fn frame_color(col: Color) -> Color {
unsafe { mem::transmute(fl::Fl_box_color(col.bits())) }
}
pub fn set_frame_color(col: Color) {
unsafe { fl::Fl_set_box_color(col.bits()) }
}
pub fn add_symbol(label: &str, scalable: bool, draw_cb: fn(Color)) -> Result<(), FltkError> {
unsafe {
let label = CString::safe_new(label);
let ret = fltk_sys::draw::Fl_add_symbol(
label.into_raw() as _,
mem::transmute(Some(draw_cb)),
scalable as _,
);
if ret == 0 {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
} else {
Ok(())
}
}
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ContrastMode {
None = 0,
Legacy,
Cielab,
Custom,
}
pub fn set_contrast_level(level: i32) {
unsafe { fl::Fl_set_contrast_level(level) }
}
pub fn contrast_level() -> i32 {
unsafe { fl::Fl_contrast_level() }
}
pub fn set_contrast_mode(mode: ContrastMode) {
unsafe { fl::Fl_set_contrast_mode(mode as i32) }
}
pub fn contrast_mode() -> ContrastMode {
unsafe { mem::transmute(fl::Fl_contrast_mode()) }
}
pub fn set_contrast_function(f: fn(fg: Color, bg: Color, fontsize: i32, ctx: i32) -> Color) {
unsafe { fl::Fl_set_contrast_function(mem::transmute(f)) }
}
#[allow(dead_code)]
pub(crate) fn using_wayland() -> bool {
unsafe { fl::Fl_using_wayland() != 0 }
}