use std::any::Any;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::mem;
use std::sync::{Arc, Mutex};
use glutin;
use glutin::{ScanCode, VirtualKeyCode};
use webrender::api::*;
use winit;
use crate::gui::font;
use crate::gui::properties;
#[derive(Debug, Clone)]
pub enum PrimitiveEvent {
Exit,
CursorEntered,
CursorLeft,
CursorMoved(properties::Position),
Button(
properties::Position,
properties::Button,
properties::ButtonState,
properties::Modifiers,
),
Char(char),
KeyInput(
Option<VirtualKeyCode>,
ScanCode,
properties::ButtonState,
properties::Modifiers,
),
SetFocus(bool),
Resized(glutin::dpi::LogicalSize),
DPI(f64),
HoverBegin(Vec<ItemTag>),
HoverEnd(Vec<ItemTag>),
}
#[derive(Debug, Clone, Eq)]
pub enum ElementEvent {
Clicked,
FocusChange,
HoverBegin,
HoverEnd,
}
impl Hash for ElementEvent {
fn hash<H: Hasher>(&self, state: &mut H) {
mem::discriminant(self).hash(state)
}
}
impl PartialEq for ElementEvent {
fn eq(&self, other: &ElementEvent) -> bool {
mem::discriminant(self) == mem::discriminant(other)
}
}
pub type EventClosure = FnMut(&mut Element, &Any) -> bool;
#[derive(Clone)]
pub struct EventFn(Arc<Mutex<EventClosure>>);
unsafe impl Send for EventFn {}
unsafe impl Sync for EventFn {}
use std::ops::DerefMut;
impl EventFn {
pub fn new(f: Arc<Mutex<EventClosure>>) -> EventFn {
EventFn(f)
}
pub fn call(&mut self, _e: &mut Element, _d: &Any) -> bool {
if let Ok(mut f) = self.0.lock() {
let x = f.deref_mut();
x(_e, _d)
} else {
false
}
}
}
pub type EventHandlers = HashMap<ElementEvent, EventFn>;
pub trait Element: Send + Sync {
fn get_ext_id(&self) -> u64;
fn set(&mut self, prop: properties::Property);
fn get_properties(&self) -> properties::Properties;
fn render(
&mut self,
api: &RenderApi,
builder: &mut DisplayListBuilder,
extent: properties::Extent,
font_store: &mut font::FontStore,
props: Option<Arc<properties::Properties>>,
id: &mut properties::IdGenerator
);
fn get_bounds(&self) -> properties::Extent;
#[allow(unused)]
fn on_primitive_event(&mut self, item_tag: &[ItemTag], e: PrimitiveEvent) -> bool;
#[allow(unused)]
fn set_handler(&mut self, e: ElementEvent, f: EventFn) {}
#[allow(unused)]
fn exec_handler(&mut self, e: ElementEvent, d: &Any) -> bool {
false
}
fn as_any(&self) -> &Any;
fn as_any_mut(&mut self) -> &mut Any;
#[allow(unused)]
fn on_event(
&mut self,
event: winit::WindowEvent,
api: &RenderApi,
document_id: DocumentId,
) -> bool {
false
}
}
pub type ElementObj = Arc<Mutex<Element>>;
pub trait HasChildren: Element {
#[allow(unused)]
fn get_child(&self, i: u32) -> Option<Arc<Mutex<Element>>> {
None
}
#[allow(unused)]
fn append(&mut self, e: Arc<Mutex<Element>>) -> Option<Arc<Mutex<Element>>> {
None
}
}
pub trait CanDisable: Element {
fn set_enabled(&mut self, _: bool);
fn get_enabled(&self) -> bool;
}