File tree Expand file tree Collapse file tree 4 files changed +121
-6
lines changed Expand file tree Collapse file tree 4 files changed +121
-6
lines changed Original file line number Diff line number Diff line change @@ -17,12 +17,28 @@ use crate::{attribute_parser::*, util::*};
17
17
18
18
fn gen_set_template ( source : & TemplateSource , crate_ident : & proc_macro2:: Ident ) -> TokenStream {
19
19
match source {
20
- TemplateSource :: File ( file) => quote ! {
21
- #crate_ident:: subclass:: widget:: WidgetClassSubclassExt :: set_template_static(
22
- klass,
23
- include_bytes!( #file) ,
24
- ) ;
25
- } ,
20
+ TemplateSource :: File ( file) => {
21
+ let template = if file. ends_with ( ".blp" ) {
22
+ if cfg ! ( feature = "blueprint" ) {
23
+ quote ! {
24
+ #crate_ident:: gtk4_macros:: include_blueprint!( #file) . as_bytes( )
25
+ }
26
+ } else {
27
+ panic ! ( "blueprint feature is disabled" )
28
+ }
29
+ } else {
30
+ quote ! {
31
+ include_bytes!( #file)
32
+ }
33
+ } ;
34
+
35
+ quote ! {
36
+ #crate_ident:: subclass:: widget:: WidgetClassSubclassExt :: set_template_static(
37
+ klass,
38
+ #template,
39
+ ) ;
40
+ }
41
+ }
26
42
TemplateSource :: Resource ( resource) => quote ! {
27
43
#crate_ident:: subclass:: widget:: WidgetClassSubclassExt :: set_template_from_resource(
28
44
klass,
Original file line number Diff line number Diff line change @@ -15,6 +15,49 @@ use proc_macro::TokenStream;
15
15
use proc_macro_error:: proc_macro_error;
16
16
use syn:: { parse_macro_input, DeriveInput } ;
17
17
18
+ /// That macro includes and compiles blueprint file by path relative to project rood
19
+ ///
20
+ /// It expected to run inside composite_template_derive, not by users
21
+ #[ cfg( feature = "blueprint" ) ]
22
+ #[ proc_macro]
23
+ pub fn include_blueprint ( input : TokenStream ) -> TokenStream {
24
+ use quote:: quote;
25
+
26
+ let tokens: Vec < _ > = input. into_iter ( ) . collect ( ) ;
27
+
28
+ if tokens. len ( ) != 1 {
29
+ panic ! ( "File name not found" ) ;
30
+ }
31
+
32
+ let root = std:: env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap_or_else ( |_| "." . into ( ) ) ;
33
+
34
+ let file_name = tokens[ 0 ] . to_string ( ) ;
35
+ let file_name = file_name. trim ( ) ;
36
+ let file_name = & file_name[ 1 ..file_name. len ( ) - 1 ] ;
37
+
38
+ let path = std:: path:: Path :: new ( & root) . join ( file_name) ;
39
+
40
+ if !path. exists ( ) {
41
+ panic ! ( "{path:?} not found" ) ;
42
+ }
43
+
44
+ let path = path. to_string_lossy ( ) . to_string ( ) ;
45
+
46
+ let template = blueprint:: compile_blueprint (
47
+ std:: fs:: read_to_string ( & path)
48
+ . unwrap_or_else ( |err| panic ! ( "{err}" ) )
49
+ . as_bytes ( ) ,
50
+ )
51
+ . unwrap ( ) ;
52
+
53
+ quote ! ( {
54
+ // Compiler reruns macro if file changed
55
+ _ = include_str!( #path) ;
56
+ #template
57
+ } )
58
+ . into ( )
59
+ }
60
+
18
61
/// Derive macro for using a composite template in a widget.
19
62
///
20
63
/// The `template` attribute specifies where the template should be loaded
Original file line number Diff line number Diff line change
1
+ template MyWidget5 {
2
+ Label label {
3
+ label: 'foobar';
4
+ }
5
+
6
+ Label my_label2 {
7
+ label: 'foobaz';
8
+ }
9
+ }
Original file line number Diff line number Diff line change @@ -256,3 +256,50 @@ glib::wrapper! {
256
256
fn blueprint_template ( ) {
257
257
let _: MyWidget4 = glib:: Object :: new ( ) ;
258
258
}
259
+
260
+ #[ cfg( feature = "blueprint" ) ]
261
+ mod imp5 {
262
+ use super :: * ;
263
+
264
+ #[ derive( Debug , Default , CompositeTemplate ) ]
265
+ #[ template( file = "tests/my_widget.blp" ) ]
266
+ pub struct MyWidget5 {
267
+ #[ template_child]
268
+ pub label : TemplateChild < gtk:: Label > ,
269
+ #[ template_child( id = "my_label2" ) ]
270
+ pub label2 : gtk:: TemplateChild < gtk:: Label > ,
271
+ }
272
+
273
+ #[ glib:: object_subclass]
274
+ impl ObjectSubclass for MyWidget5 {
275
+ const NAME : & ' static str = "MyWidget5" ;
276
+ type Type = super :: MyWidget5 ;
277
+ type ParentType = gtk:: Widget ;
278
+ fn class_init ( klass : & mut Self :: Class ) {
279
+ klass. bind_template ( ) ;
280
+ }
281
+ fn instance_init ( obj : & glib:: subclass:: InitializingObject < Self > ) {
282
+ obj. init_template ( ) ;
283
+ }
284
+ }
285
+
286
+ impl ObjectImpl for MyWidget5 {
287
+ fn dispose ( & self ) {
288
+ while let Some ( child) = self . obj ( ) . first_child ( ) {
289
+ child. unparent ( ) ;
290
+ }
291
+ }
292
+ }
293
+ impl WidgetImpl for MyWidget5 { }
294
+ }
295
+
296
+ #[ cfg( feature = "blueprint" ) ]
297
+ glib:: wrapper! {
298
+ pub struct MyWidget5 ( ObjectSubclass <imp5:: MyWidget5 >) @extends gtk:: Widget ;
299
+ }
300
+
301
+ #[ gtk:: test]
302
+ #[ cfg( feature = "blueprint" ) ]
303
+ fn blueprint_file ( ) {
304
+ let _: MyWidget5 = glib:: Object :: new ( ) ;
305
+ }
You can’t perform that action at this time.
0 commit comments