返回 CodeWhale
habitat.rs
1 //! Authored marine poses and their composition with the existing whale.
2 //! Elapsed time and the resting whale state are illustrative caller inputs.
3
4 use std::time::Duration;
5
6 use ratatui::{buffer::Buffer, layout::Rect};
7
8 use super::Entry;
9 use crate::{
10 BubbleField, Caps, FishSchool, Habitat, HabitatDensity, Heading, Jellyfish, Message,
11 MotionMode, Paint, Theme, Whale, WhaleState,
12 };
13
14 fn fish(area: Rect, buf: &mut Buffer, theme: &Theme) {
15 FishSchool::new(Duration::from_millis(2_400), MotionMode::Full)
16 .density(HabitatDensity::Rich)
17 .paint(area, buf, theme);
18 }
19
20 fn jelly(area: Rect, buf: &mut Buffer, theme: &Theme) {
21 Jellyfish::new(Duration::from_millis(1_800), MotionMode::Full).paint(area, buf, theme);
22 }
23
24 fn bubbles(area: Rect, buf: &mut Buffer, theme: &Theme) {
25 BubbleField::new(Duration::from_millis(1_200), MotionMode::Full)
26 .density(HabitatDensity::Rich)
27 .paint(area, buf, theme);
28 }
29
30 fn scene_with(area: Rect, buf: &mut Buffer, theme: &Theme, motion: MotionMode) {
31 let area = area.intersection(buf.area);
32 if area.is_empty() {
33 return;
34 }
35 Heading::new("Codewhale / clear water")
36 .meta(if motion.animates() {
37 "Native habitat"
38 } else {
39 "Reduced motion"
40 })
41 .paint(Rect { height: 1, ..area }, buf, theme);
42 let words = Rect {
43 x: area.x.saturating_add(2),
44 y: area.y.saturating_add(4),
45 width: area.width.min(32).saturating_sub(2),
46 height: area.height.saturating_sub(4).min(7),
47 }
48 .intersection(area);
49 Message::new(
50 "One ocean",
51 "A small school.\nOne visiting jellyfish.\nBubbles in the deep water.",
52 )
53 .paint(words, buf, theme);
54 let whale = Rect {
55 x: area.x.saturating_add(area.width.saturating_sub(32) / 2),
56 y: area.y.saturating_add(3),
57 width: area.width.min(32),
58 height: area.height.saturating_sub(3).min(18),
59 }
60 .intersection(area);
61 Whale::new(WhaleState::Rest).paint(whale, buf, theme);
62 Habitat::new(Duration::from_millis(1_500), motion)
63 .density(HabitatDensity::Rich)
64 .hold_jellyfish_visit(true)
65 .paint(area, buf, theme);
66 }
67
68 fn scene(area: Rect, buf: &mut Buffer, theme: &Theme) {
69 scene_with(area, buf, theme, MotionMode::Full);
70 }
71
72 fn ascii(area: Rect, buf: &mut Buffer, theme: &Theme) {
73 let ascii = Theme::new(Caps {
74 ascii: true,
75 ..theme.caps()
76 })
77 .ground(theme.ground_kind());
78 scene_with(area, buf, &ascii, MotionMode::Full);
79 }
80
81 fn reduced(area: Rect, buf: &mut Buffer, theme: &Theme) {
82 scene_with(area, buf, theme, MotionMode::Reduced);
83 }
84
85 pub(crate) fn entries() -> Vec<Entry> {
86 vec![
87 Entry {
88 name: "fish-school",
89 width: 72,
90 height: 8,
91 draw: fish,
92 },
93 Entry {
94 name: "jellyfish",
95 width: 40,
96 height: 9,
97 draw: jelly,
98 },
99 Entry {
100 name: "bubble-field",
101 width: 72,
102 height: 9,
103 draw: bubbles,
104 },
105 Entry {
106 name: "habitat-scene",
107 width: 112,
108 height: 30,
109 draw: scene,
110 },
111 Entry {
112 name: "habitat-ascii",
113 width: 84,
114 height: 24,
115 draw: ascii,
116 },
117 Entry {
118 name: "habitat-reduced",
119 width: 112,
120 height: 30,
121 draw: reduced,
122 },
123 ]
124 }
125
125 lines RUST