chargrid_common/control_flow/
unboxed.rs

1pub use crate::control_flow::{
2    ClickOut, Close, Escape, EscapeOrClickOut, EscapeOrStart, LoopControl, OrClickOut,
3    OrEscapeOrClickOut,
4};
5use crate::{
6    add_offset::AddOffset,
7    align::{Align, Alignment},
8    border::{Border, BorderStyle},
9    bound_size::{BoundHeight, BoundSize, BoundWidth},
10    control_flow::{boxed, Lens, LensState, OrClose, OrEscape, OrEscapeOrStart},
11    fill::Fill,
12    pad_by::{PadBy, Padding},
13    pad_to::PadTo,
14    set_size::{SetHeight, SetSize, SetWidth},
15    text::StyledString,
16};
17use chargrid_core::{
18    app, ctx_tint, input, Component, Coord, Ctx, Event, FrameBuffer, Rgba32, Size, Style, Tint,
19    TintIdentity,
20};
21use std::marker::PhantomData;
22use std::time::Duration;
23
24pub struct CF<C: Component>(C);
25pub fn cf<C: Component>(component: C) -> CF<C> {
26    CF(component)
27}
28
29impl<C: Component> Component for CF<C> {
30    type Output = C::Output;
31    type State = C::State;
32    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
33        self.0.render(state, ctx, fb);
34    }
35    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
36        self.0.update(state, ctx, event)
37    }
38    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
39        self.0.size(state, ctx)
40    }
41}
42
43impl<C: Component> CF<C> {
44    pub fn lens_state<S, L>(self, lens: L) -> CF<LensState<S, L, C>>
45    where
46        L: Lens<Input = S, Output = C::State>,
47    {
48        cf(LensState {
49            state: PhantomData,
50            lens,
51            component: self.0,
52        })
53    }
54
55    pub fn some(self) -> CF<Some_<C>> {
56        cf(Some_(self.0))
57    }
58
59    pub fn none(self) -> CF<None_<C>> {
60        cf(None_(self.0))
61    }
62
63    pub fn clear_each_frame(self) -> CF<ClearEachFrame<C>> {
64        cf(ClearEachFrame(self.0))
65    }
66
67    pub fn overlay_tint<D: Component<State = C::State>, T: Tint>(
68        self,
69        background: D,
70        tint: T,
71        depth_delta: i8,
72    ) -> CF<OverlayTint<C, D, T>> {
73        cf(OverlayTint {
74            foreground: self.0,
75            background,
76            tint,
77            depth_delta,
78        })
79    }
80
81    pub fn overlay<D: Component<State = C::State>>(
82        self,
83        background: D,
84        depth_delta: i8,
85    ) -> CF<OverlayTint<C, D, TintIdentity>> {
86        cf(OverlayTint {
87            foreground: self.0,
88            background,
89            tint: TintIdentity,
90            depth_delta,
91        })
92    }
93
94    pub fn fill(self, background: Rgba32) -> CF<Fill<C>> {
95        cf(Fill {
96            component: self.0,
97            background,
98        })
99    }
100
101    pub fn border(self, style: BorderStyle) -> CF<Border<C>> {
102        cf(Border {
103            component: self.0,
104            style,
105        })
106    }
107
108    pub fn pad_to(self, size: Size) -> CF<PadTo<C>> {
109        cf(PadTo {
110            component: self.0,
111            size,
112        })
113    }
114
115    pub fn pad_by(self, padding: Padding) -> CF<PadBy<C>> {
116        cf(PadBy {
117            component: self.0,
118            padding,
119        })
120    }
121
122    pub fn align(self, alignment: Alignment) -> CF<Align<C>> {
123        cf(Align {
124            component: self.0,
125            alignment,
126        })
127    }
128
129    pub fn centre(self) -> CF<Align<C>> {
130        self.align(Alignment::centre())
131    }
132
133    pub fn add_offset(self, offset: Coord) -> CF<AddOffset<C>> {
134        cf(AddOffset {
135            component: self.0,
136            offset,
137        })
138    }
139
140    pub fn add_x(self, x: i32) -> CF<AddOffset<C>> {
141        cf(AddOffset {
142            component: self.0,
143            offset: Coord { x, y: 0 },
144        })
145    }
146
147    pub fn add_y(self, y: i32) -> CF<AddOffset<C>> {
148        cf(AddOffset {
149            component: self.0,
150            offset: Coord { x: 0, y },
151        })
152    }
153
154    pub fn set_size(self, size: Size) -> CF<SetSize<C>> {
155        cf(SetSize {
156            component: self.0,
157            size,
158        })
159    }
160
161    pub fn set_width(self, width: u32) -> CF<SetWidth<C>> {
162        cf(SetWidth {
163            component: self.0,
164            width,
165        })
166    }
167
168    pub fn set_height(self, height: u32) -> CF<SetHeight<C>> {
169        cf(SetHeight {
170            component: self.0,
171            height,
172        })
173    }
174
175    pub fn bound_size(self, size: Size) -> CF<BoundSize<C>> {
176        cf(BoundSize {
177            component: self.0,
178            size,
179        })
180    }
181
182    pub fn bound_width(self, width: u32) -> CF<BoundWidth<C>> {
183        cf(BoundWidth {
184            component: self.0,
185            width,
186        })
187    }
188
189    pub fn bound_height(self, height: u32) -> CF<BoundHeight<C>> {
190        cf(BoundHeight {
191            component: self.0,
192            height,
193        })
194    }
195
196    pub fn with_title_vertical<T: Component<State = C::State>>(
197        self,
198        title: T,
199        padding: i32,
200    ) -> CF<WithTitleVertical<T, C>> {
201        cf(WithTitleVertical {
202            title,
203            component: self.0,
204            padding,
205        })
206    }
207
208    pub fn with_title_horizontal<T: Component<State = C::State>>(
209        self,
210        title: T,
211        padding: i32,
212    ) -> CF<WithTitleHorizontal<T, C>> {
213        cf(WithTitleHorizontal {
214            title,
215            component: self.0,
216            padding,
217        })
218    }
219}
220
221impl<C: Component> CF<C>
222where
223    C::State: Sized,
224{
225    pub fn with_state(self, state: C::State) -> CF<WithState<C>> {
226        cf(WithState {
227            component: self.0,
228            state,
229        })
230    }
231}
232
233impl<C: Component<Output = ()>> CF<C> {
234    pub fn delay(self, duration: Duration) -> CF<Delay<C>> {
235        cf(Delay {
236            component: self.0,
237            remaining: duration,
238        })
239    }
240
241    pub fn press_any_key(self) -> CF<PressAnyKey<C>> {
242        cf(PressAnyKey(self.0))
243    }
244}
245
246impl<T, C: Component<Output = Option<T>>> CF<C> {
247    pub fn and_then_persistent<U, D, F>(self, f: F) -> CF<AndThenPersistent<C, D, F>>
248    where
249        D: Component<Output = Option<U>, State = C::State>,
250        F: FnOnce(C, T) -> D,
251    {
252        cf(AndThenPersistent(AndThenPersistentPriv::First(Some(
253            AndThenPersistentFirst {
254                component: self.0,
255                f,
256            },
257        ))))
258    }
259
260    pub fn and_then<U, D, F>(self, f: F) -> CF<AndThen<C, D, F>>
261    where
262        D: Component<Output = Option<U>, State = C::State>,
263        F: FnOnce(T) -> D,
264    {
265        cf(AndThen::First {
266            component: self.0,
267            f: Some(f),
268        })
269    }
270
271    pub fn and_then_side_effect<U, D, F>(self, f: F) -> CF<AndThenSideEffect<C, D, F>>
272    where
273        D: Component<Output = Option<U>, State = C::State>,
274        F: FnOnce(T, &mut C::State) -> D,
275    {
276        cf(AndThenSideEffect::First {
277            component: self.0,
278            f: Some(f),
279        })
280    }
281
282    pub fn then<U, D, F>(self, f: F) -> CF<Then<C, D, F>>
283    where
284        D: Component<Output = Option<U>, State = C::State>,
285        F: FnOnce() -> D,
286    {
287        cf(Then::First {
288            component: self.0,
289            f: Some(f),
290        })
291    }
292
293    pub fn then_side_effect<U, D, F>(self, f: F) -> CF<ThenSideEffect<C, D, F>>
294    where
295        D: Component<Output = Option<U>, State = C::State>,
296        F: FnOnce(&mut C::State) -> D,
297    {
298        cf(ThenSideEffect::First {
299            component: self.0,
300            f: Some(f),
301        })
302    }
303
304    pub fn side_effect<F>(self, f: F) -> CF<SideEffect<C, F>>
305    where
306        F: FnOnce(&mut C::State),
307    {
308        cf(SideEffect {
309            component: self.0,
310            f: Some(f),
311        })
312    }
313
314    pub fn map<U, F>(self, f: F) -> CF<Map<C, F>>
315    where
316        F: FnOnce(T) -> U,
317    {
318        cf(Map {
319            component: self.0,
320            f: Some(f),
321        })
322    }
323
324    pub fn map_val<U, F>(self, f: F) -> CF<MapVal<C, F>>
325    where
326        F: FnOnce() -> U,
327    {
328        cf(MapVal {
329            component: self.0,
330            f: Some(f),
331        })
332    }
333
334    pub fn map_side_effect<U, F>(self, f: F) -> CF<MapSideEffect<C, F>>
335    where
336        F: FnOnce(T, &mut C::State) -> U,
337    {
338        cf(MapSideEffect {
339            component: self.0,
340            f: Some(f),
341        })
342    }
343
344    pub fn catch_escape(self) -> CF<CatchEscape<C>> {
345        cf(CatchEscape(self.0))
346    }
347
348    pub fn catch_escape_or_start(self) -> CF<CatchEscapeOrStart<C>> {
349        cf(CatchEscapeOrStart(self.0))
350    }
351
352    pub fn catch_click_out(self) -> CF<CatchClickOut<C>> {
353        cf(CatchClickOut(self.0))
354    }
355
356    pub fn catch_escape_or_click_out(self) -> CF<CatchEscapeOrClickOut<C>> {
357        cf(CatchEscapeOrClickOut(self.0))
358    }
359
360    pub fn menu_harness(self) -> CF<MenuHarness<C>> {
361        cf(MenuHarness(self.0))
362    }
363
364    pub fn no_peek(self) -> CF<NoPeek<C>> {
365        cf(NoPeek(self.0))
366    }
367
368    pub fn continue_<Br>(self) -> CF<Continue<C, Br>> {
369        cf(Continue {
370            component: self.0,
371            br: PhantomData,
372        })
373    }
374
375    pub fn break_<Co>(self) -> CF<Break<C, Co>> {
376        cf(Break {
377            component: self.0,
378            co: PhantomData,
379        })
380    }
381
382    pub fn continue_with<Br, U>(self, value: U) -> CF<Continue<Replace<C, U>, Br>> {
383        self.replace(value).continue_()
384    }
385
386    pub fn break_with<Co, U>(self, value: U) -> CF<Break<Replace<C, U>, Co>> {
387        self.replace(value).break_()
388    }
389
390    pub fn replace<U>(self, value: U) -> CF<Replace<C, U>> {
391        cf(Replace {
392            component: self.0,
393            value: Some(value),
394        })
395    }
396
397    pub fn pause(self) -> CF<Pause<C>> {
398        cf(Pause(self.0))
399    }
400
401    pub fn on_each_tick<F: FnMut()>(self, f: F) -> CF<OnEachTick<C, F>> {
402        cf(OnEachTick {
403            component: self.0,
404            f,
405        })
406    }
407
408    pub fn on_each_tick_with_state<F: FnMut(&mut C::State)>(
409        self,
410        f: F,
411    ) -> CF<OnEachTickWithState<C, F>> {
412        cf(OnEachTickWithState {
413            component: self.0,
414            f,
415        })
416    }
417
418    pub fn on_exit_with_state<F: FnMut(&mut C::State)>(self, f: F) -> CF<OnExitWithState<C, F>> {
419        cf(OnExitWithState {
420            component: self.0,
421            f,
422        })
423    }
424}
425
426impl<C: Component<State = ()>> CF<C> {
427    pub fn ignore_state<S>(self) -> CF<IgnoreState<S, C>> {
428        cf(IgnoreState {
429            state: PhantomData,
430            component: self.0,
431        })
432    }
433}
434
435impl<C: Component<Output = ()>> CF<C> {
436    pub fn ignore_output<O>(self) -> CF<IgnoreOutput<O, C>> {
437        cf(IgnoreOutput {
438            output: PhantomData,
439            component: self.0,
440        })
441    }
442}
443
444impl<C: Component<Output = app::Output>> CF<C> {
445    pub fn exit_on_close(self) -> CF<ExitOnClose<C>> {
446        cf(ExitOnClose(self.0))
447    }
448}
449
450impl<C: 'static + Component> CF<C>
451where
452    C::State: Sized,
453{
454    pub fn boxed(self) -> boxed::CF<C::Output, C::State> {
455        boxed::cf(self.0)
456    }
457}
458
459pub struct Val<T: Clone>(pub T);
460pub fn val<S, T: Clone>(t: T) -> CF<IgnoreState<S, Val<T>>> {
461    cf(Val(t)).ignore_state()
462}
463impl<T: Clone> Component for Val<T> {
464    type Output = Option<T>;
465    type State = ();
466    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
467    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
468        Some(self.0.clone())
469    }
470    fn size(&self, _state: &Self::State, _ctx: Ctx) -> Size {
471        Size::new_u16(0, 0)
472    }
473}
474
475pub struct ValOnce<T>(Option<T>);
476impl<T> ValOnce<T> {
477    pub fn new(t: T) -> Self {
478        Self(Some(t))
479    }
480}
481pub fn val_once<S, T>(t: T) -> CF<IgnoreState<S, ValOnce<T>>> {
482    cf(ValOnce::new(t)).ignore_state()
483}
484impl<T> Component for ValOnce<T> {
485    type Output = Option<T>;
486    type State = ();
487    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
488    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
489        self.0.take()
490    }
491    fn size(&self, _state: &Self::State, _ctx: Ctx) -> Size {
492        Size::new_u16(0, 0)
493    }
494}
495
496pub struct Never<T> {
497    t: PhantomData<T>,
498}
499impl<T> Never<T> {
500    pub fn new() -> Self {
501        Self { t: PhantomData }
502    }
503}
504pub fn never<S, T>() -> CF<IgnoreState<S, Never<T>>> {
505    cf(Never::new()).ignore_state()
506}
507impl<T> Component for Never<T> {
508    type Output = Option<T>;
509    type State = ();
510    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
511    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
512        None
513    }
514    fn size(&self, _state: &Self::State, _ctx: Ctx) -> Size {
515        Size::new_u16(0, 0)
516    }
517}
518
519/// Component decorator that creates an environment with a given state for its child,
520/// and presents a state of `()` to its parent
521pub struct WithState<C: Component> {
522    component: C,
523    state: C::State,
524}
525impl<C> Component for WithState<C>
526where
527    C: Component,
528{
529    type Output = C::Output;
530    type State = ();
531    fn render(&self, _state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
532        self.component.render(&self.state, ctx, fb);
533    }
534    fn update(&mut self, _state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
535        self.component.update(&mut self.state, ctx, event)
536    }
537    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
538        self.component.size(&self.state, ctx)
539    }
540}
541
542/// Component decorator intended for use within `loop_`, which wraps yielded values
543/// in `LoopControl::Continue`
544pub struct Continue<C: Component, Br> {
545    component: C,
546    br: PhantomData<Br>,
547}
548impl<C, Co, Br> Component for Continue<C, Br>
549where
550    C: Component<Output = Option<Co>>,
551{
552    type Output = Option<LoopControl<Co, Br>>;
553    type State = C::State;
554    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
555        self.component.render(&state, ctx, fb);
556    }
557    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
558        self.component
559            .update(state, ctx, event)
560            .map(LoopControl::Continue)
561    }
562    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
563        self.component.size(&state, ctx)
564    }
565}
566
567/// Component decorator intended for use within `loop_`, which wraps yielded values
568/// in `LoopControl::Break`
569pub struct Break<C: Component, Co> {
570    component: C,
571    co: PhantomData<Co>,
572}
573impl<C, Co, Br> Component for Break<C, Co>
574where
575    C: Component<Output = Option<Br>>,
576{
577    type Output = Option<LoopControl<Co, Br>>;
578    type State = C::State;
579    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
580        self.component.render(&state, ctx, fb);
581    }
582    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
583        self.component
584            .update(state, ctx, event)
585            .map(LoopControl::Break)
586    }
587    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
588        self.component.size(&state, ctx)
589    }
590}
591
592pub struct LoopState<S, C, F> {
593    state: S,
594    component: C,
595    f: F,
596}
597pub fn loop_state<S, Co, Br, C, F>(state: S, init: Co, mut f: F) -> CF<LoopState<S, C, F>>
598where
599    C: Component<Output = Option<LoopControl<Co, Br>>, State = S>,
600    F: FnMut(Co) -> C,
601{
602    cf(LoopState {
603        component: f(init),
604        state,
605        f,
606    })
607}
608impl<S, Co, Br, C, F> Component for LoopState<S, C, F>
609where
610    C: Component<Output = Option<LoopControl<Co, Br>>, State = S>,
611    F: FnMut(Co) -> C,
612{
613    type Output = Option<Br>;
614    type State = ();
615    fn render(&self, _state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
616        self.component.render(&self.state, ctx, fb);
617    }
618    fn update(&mut self, _state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
619        if let Some(control) = self.component.update(&mut self.state, ctx, event) {
620            match control {
621                LoopControl::Continue(co) => {
622                    self.component = (self.f)(co);
623                    while let Some(control) =
624                        self.component.update(&mut self.state, ctx, Event::Peek)
625                    {
626                        match control {
627                            LoopControl::Continue(co) => {
628                                self.component = (self.f)(co);
629                            }
630                            LoopControl::Break(br) => {
631                                return Some(br);
632                            }
633                        }
634                    }
635                    None
636                }
637                LoopControl::Break(br) => Some(br),
638            }
639        } else {
640            None
641        }
642    }
643    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
644        self.component.size(&self.state, ctx)
645    }
646}
647
648pub struct Loop<C, F> {
649    component: C,
650    f: F,
651}
652pub fn loop_<Co, Br, C, F>(init: Co, mut f: F) -> CF<Loop<C, F>>
653where
654    C: Component<Output = Option<LoopControl<Co, Br>>>,
655    F: FnMut(Co) -> C,
656{
657    cf(Loop {
658        component: f(init),
659        f,
660    })
661}
662impl<Co, Br, C, F> Component for Loop<C, F>
663where
664    C: Component<Output = Option<LoopControl<Co, Br>>>,
665    F: FnMut(Co) -> C,
666{
667    type Output = Option<Br>;
668    type State = C::State;
669    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
670        self.component.render(state, ctx, fb);
671    }
672    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
673        if let Some(control) = self.component.update(state, ctx, event) {
674            match control {
675                LoopControl::Continue(co) => {
676                    self.component = (self.f)(co);
677                    while let Some(control) = self.component.update(state, ctx, Event::Peek) {
678                        match control {
679                            LoopControl::Continue(co) => {
680                                self.component = (self.f)(co);
681                            }
682                            LoopControl::Break(br) => {
683                                return Some(br);
684                            }
685                        }
686                    }
687                    None
688                }
689                LoopControl::Break(br) => Some(br),
690            }
691        } else {
692            None
693        }
694    }
695    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
696        self.component.size(state, ctx)
697    }
698}
699
700pub struct LoopUnit<C, F> {
701    component: C,
702    f: F,
703}
704pub fn loop_unit<Br, C, F>(mut f: F) -> CF<LoopUnit<C, F>>
705where
706    C: Component<Output = Option<LoopControl<(), Br>>>,
707    F: FnMut() -> C,
708{
709    cf(LoopUnit { component: f(), f })
710}
711impl<Br, C, F> Component for LoopUnit<C, F>
712where
713    C: Component<Output = Option<LoopControl<(), Br>>>,
714    F: FnMut() -> C,
715{
716    type Output = Option<Br>;
717    type State = C::State;
718    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
719        self.component.render(state, ctx, fb);
720    }
721    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
722        if let Some(control) = self.component.update(state, ctx, event) {
723            match control {
724                LoopControl::Continue(()) => {
725                    self.component = (self.f)();
726                    while let Some(control) = self.component.update(state, ctx, Event::Peek) {
727                        match control {
728                            LoopControl::Continue(()) => {
729                                self.component = (self.f)();
730                            }
731                            LoopControl::Break(br) => {
732                                return Some(br);
733                            }
734                        }
735                    }
736                    None
737                }
738                LoopControl::Break(br) => Some(br),
739            }
740        } else {
741            None
742        }
743    }
744    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
745        self.component.size(state, ctx)
746    }
747}
748
749pub struct LoopMut<T, C, F> {
750    value: T,
751    component: C,
752    f: F,
753}
754pub fn loop_mut<Co, Br, T, C, F>(init: Co, mut value: T, mut f: F) -> CF<LoopMut<T, C, F>>
755where
756    C: Component<Output = Option<LoopControl<Co, Br>>>,
757    F: FnMut(Co, &mut T) -> C,
758{
759    cf(LoopMut {
760        component: f(init, &mut value),
761        value,
762        f,
763    })
764}
765impl<Co, Br, T, C, F> Component for LoopMut<T, C, F>
766where
767    C: Component<Output = Option<LoopControl<Co, Br>>>,
768    F: FnMut(Co, &mut T) -> C,
769{
770    type Output = Option<Br>;
771    type State = C::State;
772    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
773        self.component.render(state, ctx, fb);
774    }
775    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
776        if let Some(control) = self.component.update(state, ctx, event) {
777            match control {
778                LoopControl::Continue(co) => {
779                    self.component = (self.f)(co, &mut self.value);
780                    while let Some(control) = self.component.update(state, ctx, Event::Peek) {
781                        match control {
782                            LoopControl::Continue(co) => {
783                                self.component = (self.f)(co, &mut self.value);
784                            }
785                            LoopControl::Break(br) => {
786                                return Some(br);
787                            }
788                        }
789                    }
790
791                    None
792                }
793                LoopControl::Break(br) => Some(br),
794            }
795        } else {
796            None
797        }
798    }
799    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
800        self.component.size(state, ctx)
801    }
802}
803
804/// Call a function on the current state returning a value which is yielded by
805/// this component
806pub struct OnState<S, T, F> {
807    state: PhantomData<S>,
808    output: PhantomData<T>,
809    f: Option<F>,
810}
811pub fn on_state<S, T, F>(f: F) -> CF<OnState<S, T, F>>
812where
813    F: FnOnce(&mut S) -> T,
814{
815    cf(OnState {
816        state: PhantomData,
817        output: PhantomData,
818        f: Some(f),
819    })
820}
821impl<S, T, F> Component for OnState<S, T, F>
822where
823    F: FnOnce(&mut S) -> T,
824{
825    type Output = Option<T>;
826    type State = S;
827
828    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {
829        panic!("this component should not live long enough to be rendered");
830    }
831    fn update(&mut self, state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
832        Some((self
833            .f
834            .take()
835            .expect("this component should only be updated once"))(
836            state
837        ))
838    }
839    fn size(&self, _state: &Self::State, _ctx: Ctx) -> Size {
840        panic!("nothing should be checking the size of this component")
841    }
842}
843
844/// Call a function on the current state returning a component.
845/// This component then acts like the returned component.
846pub enum OnStateThen<C: Component, F> {
847    Component(C),
848    F(Option<F>),
849}
850pub fn on_state_then<C, F>(f: F) -> CF<OnStateThen<C, F>>
851where
852    C: Component,
853    F: FnOnce(&mut C::State) -> C,
854{
855    cf(OnStateThen::F(Some(f)))
856}
857impl<C, F> Component for OnStateThen<C, F>
858where
859    C: Component,
860    F: FnOnce(&mut C::State) -> C,
861{
862    type Output = C::Output;
863    type State = C::State;
864    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
865        match self {
866            Self::F(_) => (),
867            Self::Component(component) => component.render(state, ctx, fb),
868        }
869    }
870    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
871        match self {
872            Self::F(f) => {
873                let mut component = (f.take().unwrap())(state);
874                let result = component.update(state, ctx, event);
875                *self = Self::Component(component);
876                result
877            }
878            Self::Component(component) => component.update(state, ctx, event),
879        }
880    }
881    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
882        match self {
883            Self::F(_) => ctx.bounding_box.size(),
884            Self::Component(component) => component.size(state, ctx),
885        }
886    }
887}
888
889pub struct Render<F: Fn(Ctx, &mut FrameBuffer)> {
890    f: F,
891}
892pub fn render<F: Fn(Ctx, &mut FrameBuffer)>(f: F) -> CF<Render<F>> {
893    cf(Render { f })
894}
895impl<F> Component for Render<F>
896where
897    F: Fn(Ctx, &mut FrameBuffer),
898{
899    type Output = ();
900    type State = ();
901    fn render(&self, _state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
902        (self.f)(ctx, fb);
903    }
904    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {}
905    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
906        ctx.bounding_box.size()
907    }
908}
909
910pub struct RenderState<S, F: Fn(&S, Ctx, &mut FrameBuffer)> {
911    state: PhantomData<S>,
912    f: F,
913}
914pub fn render_state<S, F: Fn(&S, Ctx, &mut FrameBuffer)>(f: F) -> CF<RenderState<S, F>> {
915    cf(RenderState {
916        state: PhantomData,
917        f,
918    })
919}
920impl<S, F> Component for RenderState<S, F>
921where
922    F: Fn(&S, Ctx, &mut FrameBuffer),
923{
924    type Output = ();
925    type State = S;
926    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
927        (self.f)(state, ctx, fb);
928    }
929    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {}
930    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
931        ctx.bounding_box.size()
932    }
933}
934
935pub struct IgnoreState<S, C: Component<State = ()>> {
936    state: PhantomData<S>,
937    component: C,
938}
939
940impl<S, C> Component for IgnoreState<S, C>
941where
942    C: Component<State = ()>,
943{
944    type Output = C::Output;
945    type State = S;
946
947    fn render(&self, _state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
948        self.component.render(&(), ctx, fb);
949    }
950    fn update(&mut self, _state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
951        self.component.update(&mut (), ctx, event)
952    }
953    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
954        self.component.size(&(), ctx)
955    }
956}
957
958pub struct IgnoreOutput<O, C: Component<Output = ()>> {
959    output: PhantomData<O>,
960    component: C,
961}
962
963impl<O, C> Component for IgnoreOutput<O, C>
964where
965    C: Component<Output = ()>,
966{
967    type Output = Option<O>;
968    type State = C::State;
969
970    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
971        self.component.render(state, ctx, fb);
972    }
973    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
974        self.component.update(state, ctx, event);
975        None
976    }
977    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
978        self.component.size(state, ctx)
979    }
980}
981
982struct AndThenPersistentFirst<C, F> {
983    component: C,
984    f: F,
985}
986enum AndThenPersistentPriv<C, D, F> {
987    // First is an option because when it is called, the compiler doesn't know that we're about to
988    // destroy it
989    First(Option<AndThenPersistentFirst<C, F>>),
990    Second { component: D },
991}
992pub struct AndThenPersistent<C, D, F>(AndThenPersistentPriv<C, D, F>);
993
994impl<T, U, C, D, F> Component for AndThenPersistent<C, D, F>
995where
996    C: Component<Output = Option<T>>,
997    D: Component<Output = Option<U>, State = C::State>,
998    F: FnOnce(C, T) -> D,
999{
1000    type Output = Option<U>;
1001    type State = C::State;
1002    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1003        match &self.0 {
1004            AndThenPersistentPriv::First(first) => {
1005                first.as_ref().unwrap().component.render(state, ctx, fb)
1006            }
1007            AndThenPersistentPriv::Second { component, .. } => component.render(state, ctx, fb),
1008        }
1009    }
1010    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1011        match &mut self.0 {
1012            AndThenPersistentPriv::First(first) => {
1013                match first.as_mut().unwrap().component.update(state, ctx, event) {
1014                    None => None,
1015                    Some(t) => {
1016                        let first = first.take().unwrap();
1017                        let mut second_component = (first.f)(first.component, t);
1018                        let peek_result = second_component.update(state, ctx, Event::Peek);
1019                        self.0 = AndThenPersistentPriv::Second {
1020                            component: second_component,
1021                        };
1022                        peek_result
1023                    }
1024                }
1025            }
1026            AndThenPersistentPriv::Second { component, .. } => component.update(state, ctx, event),
1027        }
1028    }
1029    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1030        match &self.0 {
1031            AndThenPersistentPriv::First(first) => {
1032                first.as_ref().unwrap().component.size(state, ctx)
1033            }
1034            AndThenPersistentPriv::Second { component, .. } => component.size(state, ctx),
1035        }
1036    }
1037}
1038
1039pub enum AndThen<C, D, F> {
1040    // f is an option because when it is called, the compiler doesn't know that we're about to
1041    // destroy it
1042    First { component: C, f: Option<F> },
1043    Second(D),
1044}
1045
1046impl<T, U, C, D, F> Component for AndThen<C, D, F>
1047where
1048    C: Component<Output = Option<T>>,
1049    D: Component<Output = Option<U>, State = C::State>,
1050    F: FnOnce(T) -> D,
1051{
1052    type Output = Option<U>;
1053    type State = C::State;
1054    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1055        match self {
1056            Self::First { component, .. } => component.render(state, ctx, fb),
1057            Self::Second(component) => component.render(state, ctx, fb),
1058        }
1059    }
1060    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1061        match self {
1062            Self::First { component, f } => match component.update(state, ctx, event) {
1063                None => None,
1064                Some(t) => {
1065                    let mut d = (f.take().unwrap())(t);
1066                    let peek_result = d.update(state, ctx, Event::Peek);
1067                    *self = Self::Second(d);
1068                    peek_result
1069                }
1070            },
1071            Self::Second(component) => component.update(state, ctx, event),
1072        }
1073    }
1074    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1075        match self {
1076            Self::First { component, .. } => component.size(state, ctx),
1077            Self::Second(component) => component.size(state, ctx),
1078        }
1079    }
1080}
1081
1082pub enum AndThenSideEffect<C, D, F> {
1083    // f is an option because when it is called, the compiler doesn't know that we're about to
1084    // destroy it
1085    First { component: C, f: Option<F> },
1086    Second(D),
1087}
1088
1089impl<T, U, C, D, F> Component for AndThenSideEffect<C, D, F>
1090where
1091    C: Component<Output = Option<T>>,
1092    D: Component<Output = Option<U>, State = C::State>,
1093    F: FnOnce(T, &mut C::State) -> D,
1094{
1095    type Output = Option<U>;
1096    type State = C::State;
1097    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1098        match self {
1099            Self::First { component, .. } => component.render(state, ctx, fb),
1100            Self::Second(component) => component.render(state, ctx, fb),
1101        }
1102    }
1103    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1104        match self {
1105            Self::First { component, f } => match component.update(state, ctx, event) {
1106                None => None,
1107                Some(t) => {
1108                    let mut d = (f.take().unwrap())(t, state);
1109                    let peek_result = d.update(state, ctx, Event::Peek);
1110                    *self = Self::Second(d);
1111                    peek_result
1112                }
1113            },
1114            Self::Second(component) => component.update(state, ctx, event),
1115        }
1116    }
1117    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1118        match self {
1119            Self::First { component, .. } => component.size(state, ctx),
1120            Self::Second(component) => component.size(state, ctx),
1121        }
1122    }
1123}
1124
1125/// Similar to AndThen but the output of the component is ignored
1126pub enum Then<C, D, F> {
1127    // f is an option because when it is called, the compiler doesn't know that we're about to
1128    // destroy it
1129    First { component: C, f: Option<F> },
1130    Second(D),
1131}
1132
1133impl<T, U, C, D, F> Component for Then<C, D, F>
1134where
1135    C: Component<Output = Option<T>>,
1136    D: Component<Output = Option<U>, State = C::State>,
1137    F: FnOnce() -> D,
1138{
1139    type Output = Option<U>;
1140    type State = C::State;
1141    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1142        match self {
1143            Self::First { component, .. } => component.render(state, ctx, fb),
1144            Self::Second(component) => component.render(state, ctx, fb),
1145        }
1146    }
1147    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1148        match self {
1149            Self::First { component, f } => match component.update(state, ctx, event) {
1150                None => None,
1151                Some(_) => {
1152                    let mut d = (f.take().unwrap())();
1153                    let peek_result = d.update(state, ctx, Event::Peek);
1154                    *self = Self::Second(d);
1155                    peek_result
1156                }
1157            },
1158            Self::Second(component) => component.update(state, ctx, event),
1159        }
1160    }
1161    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1162        match self {
1163            Self::First { component, .. } => component.size(state, ctx),
1164            Self::Second(component) => component.size(state, ctx),
1165        }
1166    }
1167}
1168
1169pub enum ThenSideEffect<C, D, F> {
1170    // f is an option because when it is called, the compiler doesn't know that we're about to
1171    // destroy it
1172    First { component: C, f: Option<F> },
1173    Second(D),
1174}
1175
1176impl<T, U, C, D, F> Component for ThenSideEffect<C, D, F>
1177where
1178    C: Component<Output = Option<T>>,
1179    D: Component<Output = Option<U>, State = C::State>,
1180    F: FnOnce(&mut C::State) -> D,
1181{
1182    type Output = Option<U>;
1183    type State = C::State;
1184    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1185        match self {
1186            Self::First { component, .. } => component.render(state, ctx, fb),
1187            Self::Second(component) => component.render(state, ctx, fb),
1188        }
1189    }
1190    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1191        match self {
1192            Self::First { component, f } => match component.update(state, ctx, event) {
1193                None => None,
1194                Some(_) => {
1195                    let mut d = (f.take().unwrap())(state);
1196                    let peek_result = d.update(state, ctx, Event::Peek);
1197                    *self = Self::Second(d);
1198                    peek_result
1199                }
1200            },
1201            Self::Second(component) => component.update(state, ctx, event),
1202        }
1203    }
1204    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1205        match self {
1206            Self::First { component, .. } => component.size(state, ctx),
1207            Self::Second(component) => component.size(state, ctx),
1208        }
1209    }
1210}
1211
1212pub struct SideEffect<C, F> {
1213    component: C,
1214    // f is an option because when it is called, the compiler doesn't know that we're about to
1215    // destroy it
1216    f: Option<F>,
1217}
1218
1219impl<T, C, F> Component for SideEffect<C, F>
1220where
1221    C: Component<Output = Option<T>>,
1222    F: FnOnce(&mut C::State),
1223{
1224    type Output = Option<T>;
1225    type State = C::State;
1226    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1227        self.component.render(state, ctx, fb);
1228    }
1229    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1230        match self.component.update(state, ctx, event) {
1231            None => None,
1232            Some(t) => {
1233                (self.f.take().expect("component yielded multiple times"))(state);
1234                Some(t)
1235            }
1236        }
1237    }
1238    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1239        self.component.size(state, ctx)
1240    }
1241}
1242
1243pub struct Map<C, F> {
1244    component: C,
1245    f: Option<F>,
1246}
1247impl<T, U, C, F> Component for Map<C, F>
1248where
1249    C: Component<Output = Option<T>>,
1250    F: FnOnce(T) -> U,
1251{
1252    type Output = Option<U>;
1253    type State = C::State;
1254    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1255        self.component.render(state, ctx, fb);
1256    }
1257    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1258        match self.component.update(state, ctx, event) {
1259            None => None,
1260            Some(t) => Some((self.f.take().expect("component yielded multiple times"))(
1261                t,
1262            )),
1263        }
1264    }
1265    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1266        self.component.size(state, ctx)
1267    }
1268}
1269
1270pub struct MapVal<C, F> {
1271    component: C,
1272    f: Option<F>,
1273}
1274impl<T, U, C, F> Component for MapVal<C, F>
1275where
1276    C: Component<Output = Option<T>>,
1277    F: FnOnce() -> U,
1278{
1279    type Output = Option<U>;
1280    type State = C::State;
1281    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1282        self.component.render(state, ctx, fb);
1283    }
1284    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1285        match self.component.update(state, ctx, event) {
1286            None => None,
1287            Some(_) => Some((self.f.take().expect("component yielded multiple times"))()),
1288        }
1289    }
1290    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1291        self.component.size(state, ctx)
1292    }
1293}
1294
1295pub struct MapSideEffect<C, F> {
1296    component: C,
1297    f: Option<F>,
1298}
1299impl<T, U, C, F> Component for MapSideEffect<C, F>
1300where
1301    C: Component<Output = Option<T>>,
1302    F: FnOnce(T, &mut C::State) -> U,
1303{
1304    type Output = Option<U>;
1305    type State = C::State;
1306    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1307        self.component.render(state, ctx, fb);
1308    }
1309    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1310        match self.component.update(state, ctx, event) {
1311            None => None,
1312            Some(t) => Some((self.f.take().expect("component yielded multiple times"))(
1313                t, state,
1314            )),
1315        }
1316    }
1317    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1318        self.component.size(state, ctx)
1319    }
1320}
1321
1322pub struct Replace<C, T> {
1323    component: C,
1324    value: Option<T>,
1325}
1326impl<C, T, U> Component for Replace<C, T>
1327where
1328    C: Component<Output = Option<U>>,
1329{
1330    type Output = Option<T>;
1331    type State = C::State;
1332    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1333        self.component.render(state, ctx, fb);
1334    }
1335    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1336        self.component
1337            .update(state, ctx, event)
1338            .and_then(|_| self.value.take())
1339    }
1340    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1341        self.component.size(state, ctx)
1342    }
1343}
1344
1345/// Component decorator that clears the frame buffer before rendering
1346pub struct ClearEachFrame<C: Component>(pub C);
1347
1348impl<C> Component for ClearEachFrame<C>
1349where
1350    C: Component,
1351{
1352    type Output = C::Output;
1353    type State = C::State;
1354    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1355        fb.clear();
1356        self.0.render(state, ctx, fb);
1357    }
1358    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1359        self.0.update(state, ctx, event)
1360    }
1361    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1362        self.0.size(state, ctx)
1363    }
1364}
1365
1366/// Component decorator that yields `app::Exit` in response to a window close event,
1367/// and passes all other input to its child
1368pub struct ExitOnClose<C: Component<Output = app::Output>>(pub C);
1369
1370impl<C> Component for ExitOnClose<C>
1371where
1372    C: Component<Output = app::Output>,
1373{
1374    type Output = app::Output;
1375    type State = C::State;
1376    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1377        self.0.render(state, ctx, fb);
1378    }
1379    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1380        let output_unless_close = self.0.update(state, ctx, event);
1381        if let Event::Input(input::Input::Keyboard(input::keys::ETX)) = event {
1382            return Some(app::Exit);
1383        }
1384        output_unless_close
1385    }
1386    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1387        self.0.size(state, ctx)
1388    }
1389}
1390
1391pub struct OnExitWithState<C: Component, F: FnMut(&mut C::State)> {
1392    component: C,
1393    f: F,
1394}
1395
1396impl<C: Component, F: FnMut(&mut C::State)> Component for OnExitWithState<C, F> {
1397    type Output = C::Output;
1398    type State = C::State;
1399    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1400        self.component.render(state, ctx, fb);
1401    }
1402    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1403        if let Event::Input(input::Input::Keyboard(input::keys::ETX)) = event {
1404            (self.f)(state);
1405        }
1406        self.component.update(state, ctx, event)
1407    }
1408    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1409        self.component.size(state, ctx)
1410    }
1411}
1412
1413/// Component decorator that yields `Err(Escape)` when the escape key is pressed
1414/// rather than passing the escape key event to its child
1415pub struct CatchEscape<C: Component>(pub C);
1416
1417impl<T, C> Component for CatchEscape<C>
1418where
1419    C: Component<Output = Option<T>>,
1420{
1421    type Output = Option<OrEscape<T>>;
1422    type State = C::State;
1423    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1424        self.0.render(state, ctx, fb);
1425    }
1426    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1427        if let Event::Input(input::Input::Keyboard(input::keys::ESCAPE)) = event {
1428            return Some(Err(Escape));
1429        }
1430        self.0.update(state, ctx, event).map(Ok)
1431    }
1432    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1433        self.0.size(state, ctx)
1434    }
1435}
1436
1437pub struct CatchEscapeOrStart<C: Component>(pub C);
1438
1439impl<T, C> Component for CatchEscapeOrStart<C>
1440where
1441    C: Component<Output = Option<T>>,
1442{
1443    type Output = Option<OrEscapeOrStart<T>>;
1444    type State = C::State;
1445    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1446        self.0.render(state, ctx, fb);
1447    }
1448    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1449        match event {
1450            Event::Input(input::Input::Keyboard(input::keys::ESCAPE)) => {
1451                Some(Err(EscapeOrStart::Escape))
1452            }
1453            #[cfg(feature = "gamepad")]
1454            Event::Input(input::Input::Gamepad(input::GamepadInput {
1455                button: input::GamepadButton::Start,
1456                ..
1457            })) => Some(Err(EscapeOrStart::Start)),
1458            _ => self.0.update(state, ctx, event).map(Ok),
1459        }
1460    }
1461    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1462        self.0.size(state, ctx)
1463    }
1464}
1465
1466pub struct CatchClickOut<C: Component>(pub C);
1467
1468impl<T, C> Component for CatchClickOut<C>
1469where
1470    C: Component<Output = Option<T>>,
1471{
1472    type Output = Option<OrClickOut<T>>;
1473    type State = C::State;
1474    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1475        self.0.render(state, ctx, fb);
1476    }
1477    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1478        let is_click_out = match event {
1479            Event::Input(input::Input::Mouse(input::MouseInput::MousePress { coord, .. })) => {
1480                let size = self.size(state, ctx);
1481                !ctx.bounding_box.set_size(size).contains_coord(coord)
1482            }
1483            _ => false,
1484        };
1485        if is_click_out {
1486            Some(Err(ClickOut))
1487        } else {
1488            self.0.update(state, ctx, event).map(Ok)
1489        }
1490    }
1491    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1492        self.0.size(state, ctx)
1493    }
1494}
1495
1496pub struct CatchEscapeOrClickOut<C: Component>(pub C);
1497
1498impl<T, C> Component for CatchEscapeOrClickOut<C>
1499where
1500    C: Component<Output = Option<T>>,
1501{
1502    type Output = Option<OrEscapeOrClickOut<T>>;
1503    type State = C::State;
1504    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1505        self.0.render(state, ctx, fb);
1506    }
1507    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1508        let escape_or_click_out = match event {
1509            Event::Input(input::Input::Keyboard(input::keys::ESCAPE)) => {
1510                Some(EscapeOrClickOut::Escape)
1511            }
1512            Event::Input(input::Input::Mouse(input::MouseInput::MousePress { coord, .. })) => {
1513                let size = self.size(state, ctx);
1514                if ctx.bounding_box.set_size(size).contains_coord(coord) {
1515                    None
1516                } else {
1517                    Some(EscapeOrClickOut::ClickOut)
1518                }
1519            }
1520            _ => None,
1521        };
1522        if let Some(escape_or_click_out) = escape_or_click_out {
1523            Some(Err(escape_or_click_out))
1524        } else {
1525            self.0.update(state, ctx, event).map(Ok)
1526        }
1527    }
1528    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1529        self.0.size(state, ctx)
1530    }
1531}
1532
1533pub struct MenuHarness<C: Component>(pub C);
1534impl<T, C> Component for MenuHarness<C>
1535where
1536    C: Component<Output = Option<T>>,
1537{
1538    type Output = Option<OrClose<T>>;
1539    type State = C::State;
1540    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1541        self.0.render(state, ctx, fb);
1542    }
1543    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1544        match event {
1545            Event::Input(input::Input::Keyboard(input::keys::ESCAPE)) => Some(Err(Close)),
1546            #[cfg(feature = "gamepad")]
1547            Event::Input(input::Input::Gamepad(input::GamepadInput {
1548                button: input::GamepadButton::East,
1549                ..
1550            })) => Some(Err(Close)),
1551            #[cfg(feature = "gamepad")]
1552            Event::Input(input::Input::Gamepad(input::GamepadInput {
1553                button: input::GamepadButton::Start,
1554                ..
1555            })) => self
1556                .0
1557                .update(
1558                    state,
1559                    ctx,
1560                    Event::Input(input::Input::Keyboard(input::keys::RETURN)),
1561                )
1562                .map(Ok),
1563            _ => self.0.update(state, ctx, event).map(Ok),
1564        }
1565    }
1566    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1567        self.0.size(state, ctx)
1568    }
1569}
1570
1571pub struct NoPeek<C>(C);
1572impl<T, C: Component<Output = Option<T>>> Component for NoPeek<C> {
1573    type Output = C::Output;
1574    type State = C::State;
1575    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1576        self.0.render(state, ctx, fb);
1577    }
1578    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1579        if let Event::Peek = event {
1580            return None;
1581        }
1582        self.0.update(state, ctx, event)
1583    }
1584    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1585        self.0.size(state, ctx)
1586    }
1587}
1588
1589pub struct Delay<C: Component<Output = ()>> {
1590    component: C,
1591    remaining: Duration,
1592}
1593impl<C> Component for Delay<C>
1594where
1595    C: Component<Output = ()>,
1596{
1597    type Output = Option<()>;
1598    type State = C::State;
1599    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1600        self.component.render(state, ctx, fb);
1601    }
1602    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1603        self.component.update(state, ctx, event);
1604        if let Event::Tick(duration) = event {
1605            if let Some(remaining) = self.remaining.checked_sub(duration) {
1606                self.remaining = remaining;
1607            } else {
1608                self.remaining = Duration::from_millis(0);
1609                return Some(());
1610            }
1611        }
1612        None
1613    }
1614    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1615        self.component.size(state, ctx)
1616    }
1617}
1618
1619pub struct PressAnyKey<C: Component<Output = ()>>(C);
1620impl<C> Component for PressAnyKey<C>
1621where
1622    C: Component<Output = ()>,
1623{
1624    type Output = Option<()>;
1625    type State = C::State;
1626    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1627        self.0.render(state, ctx, fb);
1628    }
1629    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1630        self.0.update(state, ctx, event);
1631        match event {
1632            Event::Input(input::Input::Keyboard(_))
1633            | Event::Input(input::Input::Mouse(input::MouseInput::MousePress { .. })) => Some(()),
1634            #[cfg(feature = "gamepad")]
1635            Event::Input(input::Input::Gamepad(_)) => Some(()),
1636            _ => None,
1637        }
1638    }
1639    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1640        self.0.size(state, ctx)
1641    }
1642}
1643
1644pub struct OverlayTint<C: Component, D: Component, T: Tint> {
1645    pub foreground: C,
1646    pub background: D,
1647    pub tint: T,
1648    pub depth_delta: i8,
1649}
1650
1651impl<C, D, T> Component for OverlayTint<C, D, T>
1652where
1653    C: Component,
1654    D: Component<State = C::State>,
1655    T: Tint,
1656{
1657    type Output = C::Output;
1658    type State = C::State;
1659    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1660        self.background.render(
1661            state,
1662            ctx_tint!(ctx, self.tint).add_depth(-self.depth_delta),
1663            fb,
1664        );
1665        self.foreground.render(state, ctx, fb);
1666    }
1667    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1668        self.background.update(state, ctx, event);
1669        self.foreground.update(state, ctx, event)
1670    }
1671    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1672        self.foreground.size(state, ctx)
1673    }
1674}
1675
1676pub struct Pause<C: Component>(C);
1677
1678impl<T, C> Component for Pause<C>
1679where
1680    C: Component<Output = Option<T>>,
1681{
1682    type Output = C::Output;
1683    type State = C::State;
1684    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1685        self.0.render(state, ctx, fb);
1686    }
1687    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
1688        None
1689    }
1690    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1691        self.0.size(state, ctx)
1692    }
1693}
1694
1695pub struct Some_<C: Component>(pub C);
1696impl<C: Component> Component for Some_<C> {
1697    type Output = Option<C::Output>;
1698    type State = C::State;
1699    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1700        self.0.render(state, ctx, fb)
1701    }
1702    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1703        Some(self.0.update(state, ctx, event))
1704    }
1705    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1706        self.0.size(state, ctx)
1707    }
1708}
1709
1710pub struct None_<C: Component>(pub C);
1711impl<C: Component> Component for None_<C> {
1712    type Output = Option<C::Output>;
1713    type State = C::State;
1714    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1715        self.0.render(state, ctx, fb)
1716    }
1717    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1718        self.0.update(state, ctx, event);
1719        None
1720    }
1721    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1722        self.0.size(state, ctx)
1723    }
1724}
1725
1726pub struct Unit<S> {
1727    state: PhantomData<S>,
1728}
1729pub fn unit<S>() -> CF<Unit<S>> {
1730    cf(Unit { state: PhantomData })
1731}
1732impl<S> Component for Unit<S> {
1733    type Output = ();
1734    type State = S;
1735    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
1736    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, _event: Event) -> Self::Output {
1737        ()
1738    }
1739    fn size(&self, _state: &Self::State, _ctx: Ctx) -> Size {
1740        Size::new_u16(0, 0)
1741    }
1742}
1743
1744pub struct Many<I, S> {
1745    iterable: I,
1746    state: PhantomData<S>,
1747}
1748
1749impl<I, S, C> Component for Many<I, S>
1750where
1751    C: Component<State = S>,
1752    for<'a> &'a I: IntoIterator<Item = &'a C>,
1753    for<'a> &'a mut I: IntoIterator<Item = &'a mut C>,
1754{
1755    type Output = ();
1756    type State = S;
1757    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1758        for component in &self.iterable {
1759            component.render(state, ctx, fb);
1760        }
1761    }
1762    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1763        for component in &mut self.iterable {
1764            component.update(state, ctx, event);
1765        }
1766    }
1767    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1768        let mut size = Size::new_u16(0, 0);
1769        for component in &self.iterable {
1770            size = size.pairwise_max(component.size(state, ctx));
1771        }
1772        size
1773    }
1774}
1775
1776pub fn many<I, S, C>(iterable: I) -> CF<Many<I, S>>
1777where
1778    C: Component<State = S>,
1779    for<'a> &'a I: IntoIterator<Item = &'a C>,
1780    for<'a> &'a mut I: IntoIterator<Item = &'a mut C>,
1781{
1782    cf(Many {
1783        iterable,
1784        state: PhantomData,
1785    })
1786}
1787
1788pub fn styled_string<S>(string: String, style: Style) -> CF<IgnoreState<S, StyledString>> {
1789    cf(StyledString { string, style }).ignore_state()
1790}
1791
1792pub struct OnInput<F, S> {
1793    f: F,
1794    state: PhantomData<S>,
1795}
1796impl<F, T, S> Component for OnInput<F, S>
1797where
1798    F: FnMut(input::Input) -> Option<T>,
1799{
1800    type Output = Option<T>;
1801    type State = S;
1802    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
1803    fn update(&mut self, _state: &mut Self::State, _ctx: Ctx, event: Event) -> Self::Output {
1804        if let Event::Input(input) = event {
1805            if let Some(output) = (self.f)(input) {
1806                return Some(output);
1807            }
1808        }
1809        None
1810    }
1811    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
1812        ctx.bounding_box.size()
1813    }
1814}
1815pub fn on_input<F, T, S>(f: F) -> CF<OnInput<F, S>>
1816where
1817    F: FnMut(input::Input) -> Option<T>,
1818{
1819    cf(OnInput {
1820        f,
1821        state: PhantomData,
1822    })
1823}
1824
1825pub struct OnInputState<F, S> {
1826    f: F,
1827    state: PhantomData<S>,
1828}
1829impl<F, T, S> Component for OnInputState<F, S>
1830where
1831    F: FnMut(input::Input, &mut S) -> Option<T>,
1832{
1833    type Output = Option<T>;
1834    type State = S;
1835    fn render(&self, _state: &Self::State, _ctx: Ctx, _fb: &mut FrameBuffer) {}
1836    fn update(&mut self, state: &mut Self::State, _ctx: Ctx, event: Event) -> Self::Output {
1837        if let Event::Input(input) = event {
1838            if let Some(output) = (self.f)(input, state) {
1839                return Some(output);
1840            }
1841        }
1842        None
1843    }
1844    fn size(&self, _state: &Self::State, ctx: Ctx) -> Size {
1845        ctx.bounding_box.size()
1846    }
1847}
1848pub fn on_input_state<F, T, S>(f: F) -> CF<OnInputState<F, S>>
1849where
1850    F: FnMut(input::Input, &mut S) -> Option<T>,
1851{
1852    cf(OnInputState {
1853        f,
1854        state: PhantomData,
1855    })
1856}
1857
1858pub struct WithTitleVertical<T, C>
1859where
1860    T: Component,
1861    C: Component<State = T::State>,
1862{
1863    pub title: T,
1864    pub component: C,
1865    pub padding: i32,
1866}
1867
1868impl<T, C> WithTitleVertical<T, C>
1869where
1870    T: Component,
1871    C: Component<State = T::State>,
1872{
1873    fn component_ctx<'a>(&self, state: &T::State, ctx: Ctx<'a>) -> Ctx<'a> {
1874        ctx.add_y(self.padding + self.title.size(state, ctx).height() as i32)
1875    }
1876}
1877
1878impl<T, C> Component for WithTitleVertical<T, C>
1879where
1880    T: Component,
1881    C: Component<State = T::State>,
1882{
1883    type Output = C::Output;
1884    type State = C::State;
1885
1886    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1887        self.title.render(state, ctx, fb);
1888        self.component
1889            .render(state, self.component_ctx(state, ctx), fb);
1890    }
1891
1892    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1893        self.title.update(state, ctx, event);
1894        self.component
1895            .update(state, self.component_ctx(state, ctx), event)
1896    }
1897
1898    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1899        let title_size = self.title.size(state, ctx);
1900        let component_size = self.component.size(state, self.component_ctx(state, ctx));
1901        let width = title_size.width().max(component_size.width());
1902        let height =
1903            (title_size.height() as i32 + component_size.height() as i32 + self.padding) as u32;
1904        Size::new(width, height)
1905    }
1906}
1907
1908pub struct WithTitleHorizontal<T, C>
1909where
1910    T: Component,
1911    C: Component<State = T::State>,
1912{
1913    pub title: T,
1914    pub component: C,
1915    pub padding: i32,
1916}
1917
1918impl<T, C> WithTitleHorizontal<T, C>
1919where
1920    T: Component,
1921    C: Component<State = T::State>,
1922{
1923    fn component_ctx<'a>(&self, state: &T::State, ctx: Ctx<'a>) -> Ctx<'a> {
1924        ctx.add_x(self.padding + self.title.size(state, ctx).width() as i32)
1925    }
1926}
1927
1928impl<T, C> Component for WithTitleHorizontal<T, C>
1929where
1930    T: Component,
1931    C: Component<State = T::State>,
1932{
1933    type Output = C::Output;
1934    type State = C::State;
1935
1936    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1937        self.title.render(state, ctx, fb);
1938        self.component
1939            .render(state, self.component_ctx(state, ctx), fb);
1940    }
1941
1942    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1943        self.title.update(state, ctx, event);
1944        self.component
1945            .update(state, self.component_ctx(state, ctx), event)
1946    }
1947
1948    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1949        let title_size = self.title.size(state, ctx);
1950        let component_size = self.component.size(state, self.component_ctx(state, ctx));
1951        let width =
1952            (title_size.width() as i32 + component_size.width() as i32 + self.padding) as u32;
1953        let height = title_size.height().max(component_size.height());
1954        Size::new(width, height)
1955    }
1956}
1957
1958pub struct OnEachTick<C: Component, F: FnMut()> {
1959    component: C,
1960    f: F,
1961}
1962impl<C: Component, F: FnMut()> Component for OnEachTick<C, F> {
1963    type Output = C::Output;
1964    type State = C::State;
1965    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1966        self.component.render(state, ctx, fb);
1967    }
1968    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1969        (self.f)();
1970        self.component.update(state, ctx, event)
1971    }
1972    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1973        self.component.size(state, ctx)
1974    }
1975}
1976
1977pub struct OnEachTickWithState<C: Component, F: FnMut(&mut C::State)> {
1978    component: C,
1979    f: F,
1980}
1981impl<C: Component, F: FnMut(&mut C::State)> Component for OnEachTickWithState<C, F> {
1982    type Output = C::Output;
1983    type State = C::State;
1984    fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
1985        self.component.render(state, ctx, fb);
1986    }
1987    fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
1988        (self.f)(state);
1989        self.component.update(state, ctx, event)
1990    }
1991    fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
1992        self.component.size(state, ctx)
1993    }
1994}