55![ Calculator] ( screenshots/calculator.png )
66
77``` rust
8- # extern crate kas;
98use std :: num :: ParseFloatError ;
109use std :: str :: FromStr ;
1110
1211use kas :: event :: NamedKey ;
1312use kas :: prelude :: * ;
14- use kas :: widgets :: {AccessLabel , Adapt , Button , EditBox , column, grid};
13+ use kas :: theme :: FrameStyle ;
14+ use kas :: widgets :: {AccessLabel , Adapt , Button , EditBox , Frame , column, grid};
1515
1616type Key = kas :: event :: Key <kas :: event :: SmolStr >;
1717
1818fn key_button (label : & str ) -> Button <AccessLabel > {
1919 let string = AccessString :: from (label );
20- let key = string . key (). unwrap (). clone ();
20+ let key = string . key (). unwrap (). 0. clone ();
2121 Button :: label_msg (string , key )
2222}
2323fn key_button_with (label : & str , key : Key ) -> Button <AccessLabel > {
@@ -29,7 +29,8 @@ fn calc_ui() -> Window<()> {
2929 let display = EditBox :: string (| calc : & Calculator | calc . display ())
3030 . with_multi_line (true )
3131 . with_lines (3.0 , 3.0 )
32- . with_width_em (5.0 , 10.0 );
32+ . with_width_em (5.0 , 10.0 )
33+ . with_margin_style (kas :: theme :: MarginStyle :: None );
3334
3435 let buttons = grid! {
3536 // Key bindings: C, Del
@@ -44,18 +45,19 @@ fn calc_ui() -> Window<()> {
4445 (0 , 1 ) => key_button (" &7" ),
4546 (1 , 1 ) => key_button (" &8" ),
4647 (2 , 1 ) => key_button (" &9" ),
47- (3 , 1 .. 3 ) => key_button (" &+" ),
48+ (3 , 1 ..= 2 ) => key_button (" &+" ),
4849 (0 , 2 ) => key_button (" &4" ),
4950 (1 , 2 ) => key_button (" &5" ),
5051 (2 , 2 ) => key_button (" &6" ),
5152 (0 , 3 ) => key_button (" &1" ),
5253 (1 , 3 ) => key_button (" &2" ),
5354 (2 , 3 ) => key_button (" &3" ),
54- (3 , 3 .. 5 ) => key_button_with (" &=" , NamedKey :: Enter . into ()),
55- (0 .. 2 , 4 ) => key_button (" &0" ),
55+ (3 , 3 ..= 4 ) => key_button_with (" &=" , NamedKey :: Enter . into ()),
56+ (0 ..= 1 , 4 ) => key_button (" &0" ),
5657 (2 , 4 ) => key_button (" &." ),
57- }
58- . map_any ();
58+ };
59+ // We use map_any to avoid passing input data (not wanted by buttons):
60+ let buttons = Frame :: new (buttons ). with_style (FrameStyle :: None ). map_any ();
5961
6062 let ui = Adapt :: new (column! [display , buttons ], Calculator :: new ())
6163 . on_message (| _ , calc , key | calc . handle (key ));
@@ -123,7 +125,6 @@ To make the calculator keyboard-accessible, we'll use *access keys* (see more on
123125
124126To make constructing buttons easier, we define some helper functions. (These facilitate defining the button * message* more than they do the * access keys* .)
125127``` rust
126- # extern crate kas;
127128# use kas :: text :: AccessString ;
128129# use kas :: widgets :: {AccessLabel , Button };
129130# type Key = kas :: event :: Key <kas :: event :: SmolStr >;
@@ -141,7 +142,6 @@ fn key_button_with(label: &str, key: Key) -> Button<AccessLabel> {
141142
142143Normally, access keys are only active while holding <kbd >Alt</kbd >. To avoid this requirement we call [ ` with_alt_bypass ` ] . Further, we disable <kbd >Tab</kbd > key navigation with [ ` without_nav_focus ` ] and ensure that the window can be closed with the <kbd >Esc</kbd > key.
143144``` rust
144- # extern crate kas;
145145# use kas :: {Widget , widgets :: {Label , Adapt }, window :: Window };
146146# #[derive(Debug )]
147147# struct Calculator ;
@@ -163,10 +163,10 @@ Normally, access keys are only active while holding <kbd>Alt</kbd>. To avoid thi
163163
164164We already saw column and row layouts. This time, we'll use [ ` grid! ` ] for layout.
165165``` rust
166- # extern crate kas;
167166# use kas :: event :: NamedKey ;
168167# use kas :: prelude :: * ;
169- # use kas :: widgets :: {AccessLabel , Button , grid};
168+ # use kas :: widgets :: {AccessLabel , Button , Frame , grid};
169+ # use kas :: theme :: FrameStyle ;
170170# type Key = kas :: event :: Key <kas :: event :: SmolStr >;
171171# fn key_button (label : & str ) -> Button <AccessLabel > {
172172# let string = AccessString :: from (label );
@@ -190,18 +190,19 @@ We already saw column and row layouts. This time, we'll use [`grid!`] for layout
190190 (0 , 1 ) => key_button (" &7" ),
191191 (1 , 1 ) => key_button (" &8" ),
192192 (2 , 1 ) => key_button (" &9" ),
193- (3 , 1 .. 3 ) => key_button (" &+" ),
193+ (3 , 1 ..= 2 ) => key_button (" &+" ),
194194 (0 , 2 ) => key_button (" &4" ),
195195 (1 , 2 ) => key_button (" &5" ),
196196 (2 , 2 ) => key_button (" &6" ),
197197 (0 , 3 ) => key_button (" &1" ),
198198 (1 , 3 ) => key_button (" &2" ),
199199 (2 , 3 ) => key_button (" &3" ),
200- (3 , 3 .. 5 ) => key_button_with (" &=" , NamedKey :: Enter . into ()),
201- (0 .. 2 , 4 ) => key_button (" &0" ),
200+ (3 , 3 ..= 4 ) => key_button_with (" &=" , NamedKey :: Enter . into ()),
201+ (0 ..= 1 , 4 ) => key_button (" &0" ),
202202 (2 , 4 ) => key_button (" &." ),
203- }
204- . map_any ();
203+ };
204+ // We use map_any to avoid passing input data (not wanted by buttons):
205+ let buttons = Frame :: new (buttons ). with_style (FrameStyle :: None ). map_any ();
205206# buttons
206207# }
207208```
0 commit comments