danceinterpreter_rs/ui/
song_window.rs

1use crate::Window;
2use crate::{DanceInterpreter, Message};
3use iced::advanced::text::Shaping;
4use iced::alignment::{Horizontal, Vertical};
5use iced::widget::text::LineHeight;
6use iced::widget::{column, horizontal_space, image, row, stack, Text};
7use iced::Size;
8use iced::{window, Element, Length};
9
10pub struct SongWindow {
11    pub id: Option<window::Id>,
12    pub size: Size,
13
14    pub enable_image: bool,
15    pub enable_next_dance: bool,
16}
17
18impl Window for SongWindow {
19    fn on_create(&mut self, id: window::Id) {
20        self.id = Some(id);
21    }
22
23    fn on_resize(&mut self, size: Size) {
24        self.size = size;
25    }
26}
27
28impl Default for SongWindow {
29    fn default() -> Self {
30        Self {
31            id: None,
32            size: Size::new(1.0, 1.0),
33            enable_image: true,
34            enable_next_dance: true,
35        }
36    }
37}
38
39impl SongWindow {
40    pub fn view<'a>(&self, state: &'a DanceInterpreter) -> Element<'a, Message> {
41        let Some(song_info) = state.data_provider.get_current_song_info() else {
42            return horizontal_space().into();
43        };
44
45        let dance_size = self.size.height / 8.0;
46        let title_size = self.size.height / 20.0;
47        let artist_size = self.size.height / 25.0;
48        let next_dance_size = self.size.height / 25.0;
49        let next_dance_label_size = self.size.height / 30.0;
50
51        let dance_spacing = self.size.height / 35.0;
52        let song_spacing = self.size.height / 150.0;
53
54        let cover_height = LineHeight::default().to_absolute(title_size.into())
55            + song_spacing
56            + LineHeight::default().to_absolute(artist_size.into());
57
58        let text_dance = Text::new(&song_info.dance)
59            .size(dance_size)
60            .height(Length::Fill)
61            .align_y(Vertical::Bottom)
62            .shaping(Shaping::Advanced);
63
64        let column_title_artist = column![
65            Text::new(&song_info.title)
66                .size(title_size)
67                .shaping(Shaping::Advanced),
68            Text::new(&song_info.artist)
69                .size(artist_size)
70                .shaping(Shaping::Advanced),
71        ]
72        .spacing(song_spacing);
73
74        let row_bottom = (if self.enable_image {
75            if let Some(image_handle) = song_info.album_art.as_ref() {
76                row![
77                    image(image_handle).height(cover_height),
78                    column_title_artist
79                ]
80            } else {
81                row![column_title_artist]
82            }
83        } else {
84            row![column_title_artist]
85        })
86        .height(Length::Fill)
87        .align_y(Vertical::Top)
88        .spacing(song_spacing);
89
90        let column_center = column![text_dance, row_bottom]
91            .width(Length::Fill)
92            .height(Length::Fill)
93            .align_x(Horizontal::Center)
94            .spacing(dance_spacing);
95
96        (if self.enable_next_dance {
97            if let Some(next_song_info) = state.data_provider.get_next_song_info() {
98                stack![
99                    column_center,
100                    row![
101                        horizontal_space(),
102                        column![
103                            Text::new("Nächster Tanz")
104                                .size(next_dance_label_size)
105                                .height(Length::Fill)
106                                .align_x(Horizontal::Right)
107                                .align_y(Vertical::Bottom)
108                                .shaping(Shaping::Advanced),
109                            Text::new(&next_song_info.dance)
110                                .size(next_dance_size)
111                                .align_x(Horizontal::Right)
112                                .align_y(Vertical::Bottom)
113                                .shaping(Shaping::Advanced)
114                        ]
115                        .width(Length::Shrink)
116                        .spacing(dance_spacing / 3.0)
117                    ]
118                ]
119            } else {
120                stack![column_center]
121            }
122        } else {
123            stack![column_center]
124        })
125        .width(Length::Fill)
126        .height(Length::Fill)
127        .into()
128    }
129}