Skip to main content

danceinterpreter_rs/ui/
song_window.rs

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