danceinterpreter_rs/ui/
song_window.rs1use 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}