@@ -13,13 +13,10 @@ use super::{
13
13
constant, theme,
14
14
} ;
15
15
16
- const BUTTON_EXPAND_BORDER : i16 = 32 ;
17
-
18
16
/// Component for the header of a screen. Eckhart UI shows the title (can be two
19
17
/// lines), optional icon button on the left, and optional icon button
20
18
/// (typically for menu) on the right.
21
19
pub struct Header {
22
- area : Rect ,
23
20
title : Label < ' static > ,
24
21
/// button in the top-right corner
25
22
right_button : Option < Button > ,
@@ -30,6 +27,7 @@ pub struct Header {
30
27
/// icon in the top-left corner (used instead of left button)
31
28
icon : Option < Icon > ,
32
29
icon_color : Option < Color > ,
30
+ icon_area : Rect ,
33
31
/// Battery status indicator
34
32
fuel_gauge : Option < FuelGauge > ,
35
33
}
@@ -43,19 +41,18 @@ pub enum HeaderMsg {
43
41
44
42
impl Header {
45
43
pub const HEADER_HEIGHT : i16 = theme:: HEADER_HEIGHT ; // [px]
46
- pub const HEADER_BUTTON_WIDTH : i16 = 56 ; // [px]
47
- pub const HEADER_INSETS : Insets = Insets :: sides ( 24 ) ; // [px]
44
+ const BUTTON_TOUCH_EXPAND : Insets = Insets :: sides ( 32 ) ; // [px]
48
45
49
46
pub const fn new ( title : TString < ' static > ) -> Self {
50
47
Self {
51
- area : Rect :: zero ( ) ,
52
48
title : Label :: left_aligned ( title, theme:: label_title_main ( ) ) . vertically_centered ( ) ,
53
49
right_button : None ,
54
50
left_button : None ,
55
51
right_button_msg : HeaderMsg :: Cancelled ,
56
52
left_button_msg : HeaderMsg :: Cancelled ,
57
53
icon : None ,
58
54
icon_color : None ,
55
+ icon_area : Rect :: zero ( ) ,
59
56
fuel_gauge : Some ( FuelGauge :: on_charging_change ( ) ) ,
60
57
}
61
58
}
@@ -69,9 +66,12 @@ impl Header {
69
66
#[ inline( never) ]
70
67
pub fn with_right_button ( self , button : Button , msg : HeaderMsg ) -> Self {
71
68
debug_assert ! ( matches!( button. content( ) , ButtonContent :: Icon ( _) ) ) ;
72
- let touch_area = Insets :: uniform ( BUTTON_EXPAND_BORDER ) ;
73
69
Self {
74
- right_button : Some ( button. with_expanded_touch_area ( touch_area) ) ,
70
+ right_button : Some (
71
+ button
72
+ . with_expanded_touch_area ( Self :: BUTTON_TOUCH_EXPAND )
73
+ . with_radius ( 12 ) ,
74
+ ) ,
75
75
right_button_msg : msg,
76
76
..self
77
77
}
@@ -80,10 +80,13 @@ impl Header {
80
80
#[ inline( never) ]
81
81
pub fn with_left_button ( self , button : Button , msg : HeaderMsg ) -> Self {
82
82
debug_assert ! ( matches!( button. content( ) , ButtonContent :: Icon ( _) ) ) ;
83
- let touch_area = Insets :: uniform ( BUTTON_EXPAND_BORDER ) ;
84
83
Self {
85
84
icon : None ,
86
- left_button : Some ( button. with_expanded_touch_area ( touch_area) ) ,
85
+ left_button : Some (
86
+ button
87
+ . with_expanded_touch_area ( Self :: BUTTON_TOUCH_EXPAND )
88
+ . with_radius ( 12 ) ,
89
+ ) ,
87
90
left_button_msg : msg,
88
91
..self
89
92
}
@@ -126,20 +129,35 @@ impl Header {
126
129
ctx. request_paint ( ) ;
127
130
}
128
131
132
+ /// Calculates the width needed for the right button
133
+ fn right_button_width ( & self ) -> i16 {
134
+ if let Some ( b) = & self . right_button {
135
+ match b. content ( ) {
136
+ ButtonContent :: Icon ( icon) => icon. toif . width ( ) + 2 * theme:: PADDING ,
137
+ // We do not expect any other ButtonContent as the right button of the Header
138
+ _ => unreachable ! ( ) ,
139
+ }
140
+ } else {
141
+ // Title must have a default padding from the right side
142
+ theme:: PADDING
143
+ }
144
+ }
145
+
129
146
/// Calculates the width needed for the left icon, be it a button with icon
130
147
/// or just icon
131
- fn left_icon_width ( & self ) -> i16 {
132
- let margin_right : i16 = 16 ; // [px]
148
+ fn left_object_width ( & self ) -> i16 {
149
+ const ICON_MARGIN_RIGHT : i16 = 16 ; // [px]
133
150
if let Some ( b) = & self . left_button {
134
151
match b. content ( ) {
135
- ButtonContent :: Icon ( icon) => icon. toif . width ( ) + margin_right ,
152
+ ButtonContent :: Icon ( icon) => icon. toif . width ( ) + 2 * theme :: PADDING ,
136
153
// We do not expect any other ButtonContent as the left button of the Header
137
154
_ => unreachable ! ( ) ,
138
155
}
139
156
} else if let Some ( icon) = self . icon {
140
- icon. toif . width ( ) + margin_right
157
+ theme :: PADDING + icon. toif . width ( ) + ICON_MARGIN_RIGHT
141
158
} else {
142
- 0
159
+ // Title must have a default padding from the left side
160
+ theme:: PADDING
143
161
}
144
162
}
145
163
}
@@ -148,31 +166,24 @@ impl Component for Header {
148
166
type Msg = HeaderMsg ;
149
167
150
168
fn place ( & mut self , bounds : Rect ) -> Rect {
151
- debug_assert_eq ! ( bounds. width( ) , constant:: screen ( ) . width( ) ) ;
169
+ debug_assert_eq ! ( bounds. width( ) , constant:: SCREEN . width( ) ) ;
152
170
debug_assert_eq ! ( bounds. height( ) , Self :: HEADER_HEIGHT ) ;
153
171
154
- let bounds = bounds. inset ( Self :: HEADER_INSETS ) ;
155
- let rest = if let Some ( b) = & mut self . right_button {
156
- let ( rest, right_button_area) = bounds. split_right ( Self :: HEADER_BUTTON_WIDTH ) ;
157
- b. place ( right_button_area) ;
158
- rest
159
- } else {
160
- bounds
161
- } ;
162
-
163
- let icon_width = self . left_icon_width ( ) ;
164
- let ( left_button_area, title_area) = rest. split_left ( icon_width) ;
172
+ let ( rest, right_button_area) = bounds. split_right ( self . right_button_width ( ) ) ;
173
+ self . icon_area = rest. inset ( Insets :: left ( theme:: PADDING ) ) ;
174
+ let ( left_object_area, title_area) = rest. split_left ( self . left_object_width ( ) ) ;
165
175
166
- self . left_button . place ( left_button_area ) ;
176
+ self . left_button . place ( left_object_area ) ;
167
177
self . title . place ( title_area) ;
168
- self . fuel_gauge . place ( title_area. union ( left_button_area) ) ;
178
+ self . fuel_gauge . place ( self . icon_area ) ;
179
+ self . right_button . place ( right_button_area) ;
180
+
169
181
if let Some ( fuel_gauge) = & mut self . fuel_gauge {
170
182
// Force update the fuel gauge state, so it is up-to-date
171
183
// necessary e.g. for the first DeviceMenu Submenu re-entry
172
184
fuel_gauge. update_pm_state ( ) ;
173
185
}
174
186
175
- self . area = bounds;
176
187
bounds
177
188
}
178
189
@@ -200,7 +211,7 @@ impl Component for Header {
200
211
} else {
201
212
self . left_button . render ( target) ;
202
213
if let Some ( icon) = self . icon {
203
- shape:: ToifImage :: new ( self . area . left_center ( ) , icon. toif )
214
+ shape:: ToifImage :: new ( self . icon_area . left_center ( ) , icon. toif )
204
215
. with_fg ( self . icon_color . unwrap_or ( theme:: GREY_LIGHT ) )
205
216
. with_align ( Alignment2D :: CENTER_LEFT )
206
217
. render ( target) ;
0 commit comments