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