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
519pub 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
542pub 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
567pub 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
804pub 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
844pub 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(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 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 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
1125pub enum Then<C, D, F> {
1127 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 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: 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
1345pub 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
1366pub 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
1413pub 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}