use crate::draw_context::{DrawContext, FontStyle, FontType};
use fltk::{draw as fltk_draw, enums::*, prelude::*};
pub struct FltkDrawContext {
has_focus: bool,
is_active: bool,
}
impl FltkDrawContext {
pub fn new(has_focus: bool, is_active: bool) -> Self {
FltkDrawContext {
has_focus,
is_active,
}
}
pub fn from_widget_ptr<T: WidgetExt>(widget: &T) -> Self {
let has_focus = fltk::app::focus().map(|f| f.as_base_widget()).as_ref()
== Some(&widget.as_base_widget());
Self::new(has_focus, widget.active())
}
}
impl FltkDrawContext {
fn inner_set_font(&self, font: FontType, style: FontStyle, size: u8) {
fltk_draw::set_font(
match font {
FontType::Content => match style {
FontStyle::Regular => Font::Helvetica,
FontStyle::Bold => Font::HelveticaBold,
FontStyle::Italic => Font::HelveticaItalic,
FontStyle::BoldItalic => Font::HelveticaBoldItalic,
},
FontType::Code => match style {
FontStyle::Regular => Font::Courier,
FontStyle::Bold => Font::CourierBold,
FontStyle::Italic => Font::CourierItalic,
FontStyle::BoldItalic => Font::CourierBoldItalic,
},
FontType::Heading => match style {
FontStyle::Regular => Font::Helvetica,
FontStyle::Bold => Font::HelveticaBold,
FontStyle::Italic => Font::HelveticaItalic,
FontStyle::BoldItalic => Font::HelveticaBoldItalic,
},
},
size as i32,
);
}
}
impl DrawContext for FltkDrawContext {
fn set_color(&mut self, color: u32) {
let r = ((color >> 24) & 0xFF) as u8;
let g = ((color >> 16) & 0xFF) as u8;
let b = ((color >> 8) & 0xFF) as u8;
fltk_draw::set_draw_color(Color::from_rgb(r, g, b));
}
fn set_font(&mut self, font: FontType, style: FontStyle, size: u8) {
self.inner_set_font(font, style, size);
}
fn draw_text(&mut self, text: &str, x: i32, y: i32) {
fltk_draw::draw_text(text, x, y);
}
fn draw_rect_filled(&mut self, x: i32, y: i32, w: i32, h: i32) {
fltk_draw::draw_rectf(x, y, w, h);
}
fn draw_line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) {
fltk_draw::draw_line(x1, y1, x2, y2);
}
fn text_width(&mut self, text: &str, font: FontType, style: FontStyle, size: u8) -> f64 {
self.set_font(font, style, size);
fltk_draw::width(text)
}
fn text_height(&self, font: FontType, style: FontStyle, size: u8) -> i32 {
self.inner_set_font(font, style, size);
fltk_draw::height()
}
fn text_descent(&self, font: FontType, style: FontStyle, size: u8) -> i32 {
self.inner_set_font(font, style, size);
fltk_draw::descent()
}
fn push_clip(&mut self, x: i32, y: i32, w: i32, h: i32) {
fltk_draw::push_clip(x, y, w, h);
}
fn pop_clip(&mut self) {
fltk_draw::pop_clip();
}
fn color_average(&self, c1: u32, c2: u32, weight: f32) -> u32 {
let r1 = ((c1 >> 24) & 0xFF) as f32;
let g1 = ((c1 >> 16) & 0xFF) as f32;
let b1 = ((c1 >> 8) & 0xFF) as f32;
let r2 = ((c2 >> 24) & 0xFF) as f32;
let g2 = ((c2 >> 16) & 0xFF) as f32;
let b2 = ((c2 >> 8) & 0xFF) as f32;
let r = (r1 * (1.0 - weight) + r2 * weight) as u32;
let g = (g1 * (1.0 - weight) + g2 * weight) as u32;
let b = (b1 * (1.0 - weight) + b2 * weight) as u32;
(r << 24) | (g << 16) | (b << 8) | 0xFF
}
fn color_contrast(&self, _fg: u32, bg: u32) -> u32 {
let r = ((bg >> 24) & 0xFF) as f32;
let g = ((bg >> 16) & 0xFF) as f32;
let b = ((bg >> 8) & 0xFF) as f32;
let brightness = (r * 0.299 + g * 0.587 + b * 0.114) / 255.0;
if brightness > 0.5 {
0x000000FF } else {
0xFFFFFFFF }
}
fn color_inactive(&self, c: u32) -> u32 {
let r = ((c >> 24) & 0xFF) as f32;
let g = ((c >> 16) & 0xFF) as f32;
let b = ((c >> 8) & 0xFF) as f32;
let gray = (r + g + b) / 3.0;
let r = (r * 0.5 + gray * 0.5) as u32;
let g = (g * 0.5 + gray * 0.5) as u32;
let b = (b * 0.5 + gray * 0.5) as u32;
(r << 24) | (g << 16) | (b << 8) | 0xFF
}
fn has_focus(&self) -> bool {
self.has_focus
}
fn is_active(&self) -> bool {
self.is_active
}
}