1mod utils;
4use utils::*;
5
6use bevy::prelude::*;
7use haalka::prelude::*;
8
9fn main() {
10 App::new()
11 .add_plugins(examples_plugin)
12 .add_systems(
13 Startup,
14 (
15 |world: &mut World| {
16 ui_root().spawn(world);
17 },
18 camera,
19 ),
20 )
21 .add_systems(Update, shifter)
22 .run();
23}
24
25const LETTER_SIZE: f32 = 54.167; const COMPUTED_SIZE: f32 = 66.; static SHIFTED: LazyLock<Mutable<bool>> = LazyLock::new(default);
29
30fn letter(letter: String, color: Color) -> impl Element {
31 El::<Text>::new()
32 .text_font(TextFont::from_font_size(LETTER_SIZE))
33 .text_color(TextColor(color))
34 .text(Text::new(letter))
35}
36
37fn letter_column(rotate: usize, color: Color) -> impl Element {
38 let hovered = Mutable::new(false);
39 Column::<Node>::new()
40 .with_node(|mut node| node.height = Val::Px(5. * COMPUTED_SIZE))
41 .mutable_viewport(haalka::prelude::Axis::Vertical)
42 .on_scroll_with_system_disableable_signal(
43 BasicScrollHandler::new()
44 .direction(ScrollDirection::Vertical)
45 .pixels(COMPUTED_SIZE)
46 .into_system(),
47 signal::or(signal::not(hovered.signal()), SHIFTED.signal()),
48 )
49 .with_scroll_position(move |mut scroll_position| scroll_position.offset_y = COMPUTED_SIZE * rotate as f32)
50 .hovered_sync(hovered)
51 .items(
52 "abcdefghijklmnopqrstuvwxyz"
53 .chars()
54 .map(move |c| letter(c.to_string(), color)),
55 )
56}
57
58fn ui_root() -> impl Element {
59 let hovered = Mutable::new(false);
60 El::<Node>::new()
61 .with_node(|mut node| {
62 node.width = Val::Percent(100.);
63 node.height = Val::Percent(100.);
64 })
65 .align_content(Align::center())
66 .child(
67 Row::<Node>::new()
68 .with_node(|mut node| {
69 node.width = Val::Px(300.);
70 node.column_gap = Val::Px(30.);
71 node.padding = UiRect::horizontal(Val::Px(7.5));
72 })
73 .mutable_viewport(haalka::prelude::Axis::Horizontal)
74 .on_scroll_with_system_disableable_signal(
75 BasicScrollHandler::new()
76 .direction(ScrollDirection::Horizontal)
77 .pixels(63.)
79 .into_system(),
80 signal::not(signal::and(hovered.signal(), SHIFTED.signal())),
81 )
82 .hovered_sync(hovered)
83 .items(
84 [
85 bevy::color::palettes::css::RED,
86 bevy::color::palettes::css::ORANGE,
87 bevy::color::palettes::css::YELLOW,
88 bevy::color::palettes::css::GREEN,
89 bevy::color::palettes::css::BLUE,
90 bevy::color::palettes::css::INDIGO,
91 bevy::color::palettes::css::VIOLET,
92 ]
93 .into_iter()
94 .enumerate()
95 .map(|(i, color)| letter_column(i, color.into())),
96 ),
97 )
98}
99
100fn shifter(keys: Res<ButtonInput<KeyCode>>) {
101 if keys.just_pressed(KeyCode::ShiftLeft) || keys.just_pressed(KeyCode::ShiftRight) {
102 SHIFTED.set_neq(true);
103 } else if keys.just_released(KeyCode::ShiftLeft) || keys.just_released(KeyCode::ShiftRight) {
104 SHIFTED.set_neq(false);
105 }
106}
107
108fn camera(mut commands: Commands) {
109 commands.spawn(Camera2d);
110}