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::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}