klondike_lib/display/stack/
mod.rs1use std::fmt;
2
3use crate::model::stack::{Orientation, Stack};
4
5use super::{card::CardWidget, geometry, selector::SelectorWidget, Widget};
6
7use self::common::Offsets;
8
9mod common;
10mod horizontal;
11mod vertical;
12
13#[derive(Debug)]
14pub struct StackWidget<'a> {
15 pub bounds: geometry::Rect<u16>,
16 pub stack: &'a Stack<'a>,
17}
18
19impl<'a> Widget for StackWidget<'a> {
20 fn bounds(&self) -> geometry::Rect<u16> {
21 let offsets = self.offsets();
22
23 let mut bounds = geometry::Rect::new(self.bounds.origin, geometry::Size2D::zero());
24
25 for card_widget in self.card_widget_iter(&offsets) {
26 bounds = bounds.union(&card_widget.bounds());
27 }
28
29 if let Some(selector_widget) = self.selector_widget(&offsets) {
30 bounds = bounds.union(&selector_widget.bounds());
31 }
32
33 bounds
34 }
35}
36
37impl<'a> fmt::Display for StackWidget<'a> {
38 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
39 let offsets = self.offsets();
40
41 for card_widget in self.card_widget_iter(&offsets) {
42 write!(fmt, "{}", card_widget)?;
43 }
44
45 if let Some(selector_widget) = self.selector_widget(&offsets) {
46 write!(fmt, "{}", selector_widget)?;
47 }
48
49 Ok(())
50 }
51}
52
53impl<'a> StackWidget<'a> {
54 fn offsets(&self) -> Offsets {
55 match self.stack.details.orientation {
56 Orientation::Horizontal => horizontal::offsets(self),
57 Orientation::Vertical => vertical::offsets(self),
58 }
59 }
60
61 fn card_widget_iter(&'a self, offsets: &'a Offsets) -> impl Iterator<Item = CardWidget<'a>> {
62 let mut horizontal_iter = None;
66 let mut vertical_iter = None;
67
68 match self.stack.details.orientation {
69 Orientation::Horizontal => {
70 horizontal_iter = Some(horizontal::card_widget_iter(self, offsets))
71 }
72 Orientation::Vertical => {
73 vertical_iter = Some(vertical::card_widget_iter(self, offsets))
74 }
75 }
76
77 let horizontal_iter = horizontal_iter.into_iter().flatten();
79 let vertical_iter = vertical_iter.into_iter().flatten();
80
81 horizontal_iter.chain(vertical_iter)
82 }
83
84 fn selector_widget(&self, offsets: &Offsets) -> Option<SelectorWidget> {
85 match self.stack.details.orientation {
86 Orientation::Horizontal => horizontal::selector_widget(self, offsets),
87 Orientation::Vertical => vertical::selector_widget(self, offsets),
88 }
89 }
90}