14
14
15
15
//! A toggle switch widget.
16
16
17
- use crate :: kurbo:: { Circle , Point , Rect , RoundedRect , Size } ;
17
+ use crate :: kurbo:: { Circle , Point , Rect , RoundedRect , Shape , Size } ;
18
18
use crate :: piet:: { FontBuilder , Text , TextLayout , TextLayoutBuilder } ;
19
19
use crate :: piet:: { LinearGradient , RenderContext , UnitPoint } ;
20
20
use crate :: theme;
21
21
use crate :: widget:: Align ;
22
22
use crate :: {
23
- BaseState , BoxConstraints , Env , Event , EventCtx , LayoutCtx , PaintCtx , UpdateCtx , Widget ,
23
+ BaseState , BoxConstraints , Env , Event , EventCtx , LayoutCtx , LocalizedString , PaintCtx ,
24
+ UpdateCtx , Widget ,
24
25
} ;
25
26
26
- #[ derive( Debug , Clone ) ]
27
- pub struct Switch ;
28
-
29
- impl Switch {
30
- pub fn new ( ) -> impl Widget < bool > {
31
- Align :: vertical ( UnitPoint :: CENTER , SwitchRaw :: default ( ) )
32
- }
33
- }
34
-
27
+ /// A switch that toggles a boolean.
35
28
#[ derive( Debug , Clone , Default ) ]
36
- pub struct SwitchRaw {
29
+ pub struct Switch {
37
30
knob_pos : Point ,
38
31
knob_hovered : bool ,
39
32
}
40
33
41
- impl SwitchRaw {
34
+ impl Switch {
35
+ pub fn new ( ) -> impl Widget < bool > {
36
+ Align :: vertical ( UnitPoint :: CENTER , Self :: default ( ) )
37
+ }
38
+
42
39
fn knob_hit_test ( & self , knob_width : f64 , mouse_pos : Point ) -> bool {
43
40
let knob_circle = Circle :: new ( self . knob_pos , knob_width / 2. ) ;
44
- if mouse_pos. distance ( knob_circle. center ) < knob_circle. radius {
45
- return true ;
46
- }
47
- false
41
+ knob_circle. winding ( mouse_pos) > 0
48
42
}
49
43
50
44
fn paint_label (
@@ -58,8 +52,14 @@ impl SwitchRaw {
58
52
) {
59
53
let font_name = env. get ( theme:: FONT_NAME ) ;
60
54
let font_size = env. get ( theme:: TEXT_SIZE_NORMAL ) ;
55
+ let switch_height = env. get ( theme:: BORDERED_WIDGET_HEIGHT ) ;
61
56
62
- let label = if * data { "ON" } else { "OFF" } ;
57
+ let label: LocalizedString < & str > = if * data {
58
+ LocalizedString :: new ( "On" )
59
+ } else {
60
+ LocalizedString :: new ( "Off" )
61
+ } ;
62
+ let localized_label = label. localized_str ( ) . to_uppercase ( ) ;
63
63
64
64
let font = paint_ctx
65
65
. text ( )
@@ -70,7 +70,7 @@ impl SwitchRaw {
70
70
71
71
let text_layout = paint_ctx
72
72
. text ( )
73
- . new_text_layout ( & font, label )
73
+ . new_text_layout ( & font, & localized_label )
74
74
. unwrap ( )
75
75
. build ( )
76
76
. unwrap ( ) ;
@@ -79,12 +79,12 @@ impl SwitchRaw {
79
79
Point :: ORIGIN ,
80
80
Size :: new (
81
81
( base_state. size ( ) . width - text_layout. width ( ) ) . max ( 0.0 ) ,
82
- base_state . size ( ) . height + ( font_size * 1.2 ) / 2. ,
82
+ switch_height + ( font_size * 1.2 ) / 2. ,
83
83
) ,
84
84
) ) ;
85
85
86
86
// adjust label position
87
- origin. y = origin. y . min ( base_state . size ( ) . height ) ;
87
+ origin. y = origin. y . min ( switch_height ) ;
88
88
89
89
if * data {
90
90
origin. x = switch_padding * 2.
@@ -96,7 +96,7 @@ impl SwitchRaw {
96
96
}
97
97
}
98
98
99
- impl Widget < bool > for SwitchRaw {
99
+ impl Widget < bool > for Switch {
100
100
fn paint ( & mut self , paint_ctx : & mut PaintCtx , base_state : & BaseState , data : & bool , env : & Env ) {
101
101
let switch_padding = 3. ;
102
102
let switch_height = env. get ( theme:: BORDERED_WIDGET_HEIGHT ) ;
@@ -110,6 +110,7 @@ impl Widget<bool> for SwitchRaw {
110
110
) ;
111
111
112
112
// paint different background for on and off state
113
+ // todo: make color configurable
113
114
let background_gradient = if * data {
114
115
LinearGradient :: new (
115
116
UnitPoint :: TOP ,
@@ -210,11 +211,7 @@ impl Widget<bool> for SwitchRaw {
210
211
if ctx. is_active ( ) {
211
212
ctx. set_active ( false ) ;
212
213
if ctx. is_hot ( ) {
213
- if * data {
214
- * data = false ;
215
- } else {
216
- * data = true ;
217
- }
214
+ * data = !* data
218
215
}
219
216
ctx. invalidate ( ) ;
220
217
}
@@ -224,11 +221,7 @@ impl Widget<bool> for SwitchRaw {
224
221
// todo: animate dragging of knob
225
222
}
226
223
if ctx. is_hot ( ) {
227
- if self . knob_hit_test ( knob_size, mouse. pos ) {
228
- self . knob_hovered = true
229
- } else {
230
- self . knob_hovered = false
231
- }
224
+ self . knob_hovered = self . knob_hit_test ( knob_size, mouse. pos )
232
225
}
233
226
ctx. invalidate ( ) ;
234
227
}
0 commit comments