Skip to content

Commit 7a5bdf6

Browse files
committed
Revise make_widget class spec
1 parent e46fea6 commit 7a5bdf6

File tree

6 files changed

+47
-34
lines changed

6 files changed

+47
-34
lines changed

kas-gtk/examples/calculator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ enum Key {
3131

3232
fn main() -> Result<(), kas_gtk::Error> {
3333
let buttons = make_widget!{
34-
grid => Key;
34+
container(grid) => Key;
3535
struct {
3636
#[widget(col = 0, row = 0)] _ = TextButton::new("clear", || Key::Clear),
3737
#[widget(col = 1, row = 0)] _ = TextButton::new("÷", || Key::Divide),
@@ -53,7 +53,7 @@ fn main() -> Result<(), kas_gtk::Error> {
5353
}
5454
};
5555
let content = make_widget!{
56-
vertical => NoResponse;
56+
container(vertical) => NoResponse;
5757
struct {
5858
// #[widget] state: Text = Text::from("0"),
5959
// #[widget] buf: Text = Text::new() ,

kas-gtk/examples/clock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use kas::{SimpleWindow, Toolkit, TkWidget};
2020

2121
fn main() -> Result<(), kas_gtk::Error> {
2222
let mut window = SimpleWindow::new(make_widget! {
23-
vertical => NoResponse;
23+
container(vertical) => NoResponse;
2424
struct {
2525
#[widget] date: Text = Text::new(),
2626
#[widget] time: Text = Text::new()

kas-gtk/examples/counter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ enum Message {
2323

2424
fn main() -> Result<(), kas_gtk::Error> {
2525
let buttons = make_widget!(
26-
horizontal => Message;
26+
container(horizontal) => Message;
2727
struct {
2828
#[widget] _ = TextButton::new("−", || Message::Decr),
2929
#[widget] _ = TextButton::new("+", || Message::Incr),
3030
}
3131
);
3232
let window = SimpleWindow::new(make_widget!(
33-
vertical => NoResponse;
33+
container(vertical) => NoResponse;
3434
struct {
3535
#[widget] display: Text = Text::from("0"),
3636
#[widget(handler = handle_button)] buttons -> Message = buttons,

kas-gtk/examples/stopwatch.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use kas::display::Text;
1717
use kas::event::{NoResponse};
1818
use kas::macros::{NoResponse, make_widget};
1919
use kas::HasText;
20-
use kas::{Class, SimpleWindow, Toolkit, TkWidget, Window};
20+
use kas::{SimpleWindow, Toolkit, TkWidget, Window};
2121

2222
#[derive(Debug, NoResponse)]
2323
enum Control {
@@ -34,11 +34,10 @@ fn make_window() -> Rc<RefCell<Window>> {
3434
}
3535

3636
let stopwatch = make_widget! {
37-
horizontal => NoResponse;
37+
container(horizontal) => NoResponse;
3838
struct {
3939
#[widget] display: impl SetText = make_widget!{
40-
single => NoResponse;
41-
class = Class::Frame;
40+
frame => NoResponse;
4241
struct {
4342
#[widget] display: Text = Text::from("0.000"),
4443
}

kas-macros/src/args.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use proc_macro2::{Punct, Spacing, Span, TokenStream, TokenTree};
77
use quote::{quote, TokenStreamExt, ToTokens};
8-
use syn::{Data, DeriveInput, Expr, Fields, FieldsNamed, FieldsUnnamed, Generics, Ident, Index, Lit, Member, Path, TypeTraitObject, Type, TypePath, ImplItemMethod};
8+
use syn::{Data, DeriveInput, Expr, Fields, FieldsNamed, FieldsUnnamed, Generics, Ident, Index, Lit, Member, TypeTraitObject, Type, TypePath, ImplItemMethod};
99
use syn::{parse_quote, braced, bracketed, parenthesized};
1010
use syn::parse::{Error, Parse, ParseStream, Result};
1111
use syn::token::{Brace, Colon, Comma, Eq, FatArrow, Impl, Paren, Pound, RArrow, Semi, Struct, Underscore, Where};
@@ -355,6 +355,11 @@ impl Parse for HandlerArgs {
355355
}
356356
}
357357

358+
pub enum Class {
359+
Container(Ident),
360+
Frame,
361+
}
362+
358363
pub enum ChildType {
359364
Fixed(Type), // fixed type
360365
// Generic, optionally with specified handler response type,
@@ -370,10 +375,8 @@ pub struct WidgetField {
370375
}
371376

372377
pub struct MakeWidget {
373-
// layout direction
374-
pub layout: Ident,
375378
// widget class
376-
pub class: Option<Path>,
379+
pub class: Class,
377380
// response type
378381
pub response: Type,
379382
// child widgets and data fields
@@ -384,23 +387,23 @@ pub struct MakeWidget {
384387

385388
impl Parse for MakeWidget {
386389
fn parse(input: ParseStream) -> Result<Self> {
387-
let layout: Ident = input.parse()?;
388-
let _: FatArrow = input.parse()?;
390+
let class_name: Ident = input.parse()?;
391+
let class = if class_name == "container" {
392+
let content;
393+
let _ = parenthesized!(content in input);
394+
let layout: Ident = content.parse()?;
395+
Class::Container(layout)
396+
} else if class_name == "frame" {
397+
Class::Frame
398+
} else {
399+
return Err(Error::new(class_name.span(),
400+
"make_widget only supports the following classes: container, frame"));
401+
};
389402

403+
let _: FatArrow = input.parse()?;
390404
let response: Type = input.parse()?;
391405
let _: Semi = input.parse()?;
392406

393-
// TODO: revise attributes?
394-
let class = if input.peek(kw::class) {
395-
let _: kw::class = input.parse()?;
396-
let _: Eq = input.parse()?;
397-
let class: Path = input.parse()?;
398-
let _: Semi = input.parse()?;
399-
Some(class)
400-
} else {
401-
None
402-
};
403-
404407
let _: Struct = input.parse()?;
405408
let content;
406409
let _ = braced!(content in input);
@@ -436,7 +439,7 @@ impl Parse for MakeWidget {
436439
impls.push((target, methods));
437440
}
438441

439-
Ok(MakeWidget { layout, class, response, fields, impls })
442+
Ok(MakeWidget { class, response, fields, impls })
440443
}
441444
}
442445

kas-macros/src/lib.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use syn::{parse_quote, parse_macro_input};
2020
use syn::token::Comma;
2121
use syn::punctuated::Punctuated;
2222

23-
use self::args::ChildType;
23+
use self::args::{Class, ChildType};
2424

2525
#[cfg(not(feature = "cassowary"))] mod layout_extern;
2626
#[cfg(not(feature = "cassowary"))] use self::layout_extern as layout;
@@ -304,6 +304,11 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
304304

305305
/// Macro to create a widget with anonymous type
306306
///
307+
/// This macro supports widgets of the following classes:
308+
///
309+
/// - Container
310+
/// - Frame
311+
///
307312
/// This exists purely to save you some typing. You could instead make your own
308313
/// struct, derive `Widget` (with attributes to enable Core, Layout and Widget
309314
/// implementation), manually implement `event::Handler`, and instantiate an
@@ -312,10 +317,10 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
312317
/// Syntax should match the following Backus-Naur Form:
313318
///
314319
/// ```bnf
315-
/// <input> ::= <layout> "=>" <response> ";" <class_spec> <fields> ";" <funcs>
320+
/// <input> ::= <class> "=>" <response> ";" <fields> ";" <funcs>
321+
/// <class> ::= "container" "(" <layout> ")" | "frame"
316322
/// <layout> ::= "single" | "horizontal" | "vertical" | "grid"
317323
/// <response> ::= <type>
318-
/// <class_spec> ::= "" | "class" "=" <path> ";"
319324
/// <fields> ::= "" | <field> | <field> "," <fields>
320325
/// <field> ::= <w_attr> <opt_ident> <field_ty> = <expr>
321326
/// <opt_ident> ::= "_" | <ident>
@@ -454,9 +459,17 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
454459
let mut handler_extra = Punctuated::<_, Comma>::new();
455460
let mut handler_clauses = Punctuated::<_, Comma>::new();
456461

457-
let layout = &args.layout;
458462
let response = &args.response;
459463

464+
let widget_args = match args.class {
465+
Class::Container(layout) => quote!{
466+
class = #c::Class::Container, layout = #layout
467+
},
468+
Class::Frame => quote!{
469+
class = #c::Class::Frame
470+
},
471+
};
472+
460473
for (index, field) in args.fields.drain(..).enumerate() {
461474
let attr = &field.widget_attr;
462475

@@ -545,12 +558,10 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
545558
});
546559
};
547560

548-
let class = args.class.unwrap_or_else(|| parse_quote!{ #c::Class::Container });
549-
550561
// TODO: we should probably not rely on recursive macro expansion here!
551562
// (I.e. use direct code generation for Widget derivation, instead of derive.)
552563
let toks = (quote!{ {
553-
#[widget(class = #class, layout = #layout)]
564+
#[widget(#widget_args)]
554565
#[handler(response = #response, generics = < #handler_extra > #handler_where)]
555566
#[derive(Clone, Debug, #c::macros::Widget)]
556567
struct AnonWidget<#gen_ptrs> {

0 commit comments

Comments
 (0)