use std::any::Any;
use super::{Element, ElementPtr, ViewLimits, FocusRequest, share};
use super::context::{BasicContext, Context};
use super::composite::{Storage, CompositeBase, Composite};
use crate::support::point::Point;
use crate::support::rect::Rect;
use crate::view::{MouseButton, KeyInfo, TextInfo};
pub struct Layer {
inner: Composite,
}
impl Layer {
pub fn new() -> Self {
Self {
inner: Composite::new(),
}
}
pub fn from_vec(children: Vec<ElementPtr>) -> Self {
Self {
inner: Composite::from_vec(children),
}
}
pub fn push(&mut self, element: ElementPtr) {
self.inner.push(element);
}
pub fn pop(&mut self) -> Option<ElementPtr> {
self.inner.pop()
}
pub fn clear(&mut self) {
self.inner.clear();
}
pub fn count(&self) -> usize {
self.inner.len()
}
}
impl Default for Layer {
fn default() -> Self {
Self::new()
}
}
impl Storage for Layer {
fn len(&self) -> usize {
self.inner.len()
}
fn at(&self, index: usize) -> Option<&dyn Element> {
self.inner.at(index)
}
fn at_mut(&mut self, index: usize) -> Option<&mut dyn Element> {
self.inner.at_mut(index)
}
}
impl CompositeBase for Layer {
fn bounds_of(&self, ctx: &Context, index: usize) -> Rect {
ctx.bounds
}
fn reverse_index(&self) -> bool {
true }
}
impl Element for Layer {
fn limits(&self, ctx: &BasicContext) -> ViewLimits {
let mut limits = ViewLimits::new(
Point::new(0.0, 0.0),
Point::new(super::FULL_EXTENT, super::FULL_EXTENT),
);
for i in 0..self.inner.len() {
if let Some(child) = self.inner.at(i) {
let child_limits = child.limits(ctx);
limits.min.x = limits.min.x.max(child_limits.min.x);
limits.min.y = limits.min.y.max(child_limits.min.y);
limits.max.x = limits.max.x.min(child_limits.max.x);
limits.max.y = limits.max.y.min(child_limits.max.y);
}
}
limits.max.x = limits.max.x.max(limits.min.x);
limits.max.y = limits.max.y.max(limits.min.y);
limits
}
fn draw(&self, ctx: &Context) {
for i in 0..self.inner.len() {
if let Some(child) = self.inner.at(i) {
child.draw(ctx);
}
}
}
fn layout(&mut self, ctx: &Context) {
}
fn hit_test(&self, ctx: &Context, p: Point, leaf: bool, control: bool) -> Option<&dyn Element> {
if !ctx.bounds.contains(p) {
return None;
}
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if let Some(hit) = child.hit_test(ctx, p, leaf, control) {
return Some(hit);
}
}
}
if leaf { None } else { Some(self) }
}
fn wants_control(&self) -> bool {
self.inner.wants_control()
}
fn click(&mut self, ctx: &Context, btn: MouseButton) -> bool {
false
}
fn handle_click(&self, ctx: &Context, btn: MouseButton) -> bool {
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if child.handle_click(ctx, btn) {
return true;
}
}
}
false
}
fn handle_drag(&self, ctx: &Context, btn: MouseButton) {
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if child.hit_test(ctx, btn.pos, false, false).is_some() {
child.handle_drag(ctx, btn);
return;
}
}
}
}
fn handle_key(&self, ctx: &Context, k: KeyInfo) -> bool {
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if child.handle_key(ctx, k) {
return true;
}
}
}
false
}
fn handle_text(&self, ctx: &Context, info: TextInfo) -> bool {
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if child.handle_text(ctx, info) {
return true;
}
}
}
false
}
fn handle_scroll(&self, ctx: &Context, dir: Point, p: Point) -> bool {
for i in (0..self.inner.len()).rev() {
if let Some(child) = self.inner.at(i) {
if child.handle_scroll(ctx, dir, p) {
return true;
}
}
}
false
}
fn is_enabled(&self) -> bool {
self.inner.is_enabled()
}
fn enable(&mut self, state: bool) {
self.inner.enable(state);
}
fn wants_focus(&self) -> bool {
self.inner.wants_focus()
}
fn begin_focus(&mut self, req: FocusRequest) {
self.inner.begin_focus(req);
}
fn end_focus(&mut self) -> bool {
self.inner.end_focus()
}
fn focus(&self) -> Option<&dyn Element> {
self.inner.focus()
}
fn clear_focus(&self) {
for i in 0..self.inner.len() {
if let Some(child) = self.inner.at(i) {
child.clear_focus();
}
}
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
pub fn layer<E: Element + 'static>(elements: Vec<E>) -> Layer {
let ptrs: Vec<ElementPtr> = elements.into_iter().map(|e| share(e)).collect();
Layer::from_vec(ptrs)
}
#[macro_export]
macro_rules! layer {
($($elem:expr),* $(,)?) => {{
let mut l = $crate::element::layer::Layer::new();
$(
l.push($crate::element::share($elem));
)*
l
}};
}
pub struct Deck {
inner: Composite,
active_index: usize,
}
impl Deck {
pub fn new() -> Self {
Self {
inner: Composite::new(),
active_index: 0,
}
}
pub fn from_vec(children: Vec<ElementPtr>) -> Self {
Self {
inner: Composite::from_vec(children),
active_index: 0,
}
}
pub fn push(&mut self, element: ElementPtr) {
self.inner.push(element);
}
pub fn active_index(&self) -> usize {
self.active_index
}
pub fn set_active(&mut self, index: usize) {
if index < self.inner.len() {
self.active_index = index;
}
}
pub fn active(&self) -> Option<&dyn Element> {
self.inner.at(self.active_index)
}
pub fn count(&self) -> usize {
self.inner.len()
}
}
impl Default for Deck {
fn default() -> Self {
Self::new()
}
}
impl Element for Deck {
fn limits(&self, ctx: &BasicContext) -> ViewLimits {
if let Some(child) = self.inner.at(self.active_index) {
child.limits(ctx)
} else {
ViewLimits::full()
}
}
fn draw(&self, ctx: &Context) {
if let Some(child) = self.inner.at(self.active_index) {
child.draw(ctx);
}
}
fn hit_test(&self, ctx: &Context, p: Point, leaf: bool, control: bool) -> Option<&dyn Element> {
if let Some(child) = self.inner.at(self.active_index) {
child.hit_test(ctx, p, leaf, control)
} else {
None
}
}
fn wants_control(&self) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.wants_control()
} else {
false
}
}
fn handle_click(&self, ctx: &Context, btn: MouseButton) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.handle_click(ctx, btn)
} else {
false
}
}
fn handle_drag(&self, ctx: &Context, btn: MouseButton) {
if let Some(child) = self.inner.at(self.active_index) {
child.handle_drag(ctx, btn);
}
}
fn handle_key(&self, ctx: &Context, k: KeyInfo) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.handle_key(ctx, k)
} else {
false
}
}
fn handle_text(&self, ctx: &Context, info: TextInfo) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.handle_text(ctx, info)
} else {
false
}
}
fn handle_scroll(&self, ctx: &Context, dir: Point, p: Point) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.handle_scroll(ctx, dir, p)
} else {
false
}
}
fn is_enabled(&self) -> bool {
self.inner.is_enabled()
}
fn enable(&mut self, state: bool) {
self.inner.enable(state);
}
fn wants_focus(&self) -> bool {
if let Some(child) = self.inner.at(self.active_index) {
child.wants_focus()
} else {
false
}
}
fn clear_focus(&self) {
for i in 0..self.inner.len() {
if let Some(child) = self.inner.at(i) {
child.clear_focus();
}
}
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}