1- use spring_native:: prelude:: { Error , NativeInterfaceRef } ;
1+ use spring_native:: {
2+ prelude:: { Error , NativeInterfaceRef } ,
3+ RmlDataModel , RmlDataVariable ,
4+ } ;
25
36use crate :: sbc:: panels:: field:: {
47 element_by_id, escape_rml, on_blur, on_enter, on_pointer, ChangeQueue , Field , FieldValue ,
@@ -16,6 +19,7 @@ pub(crate) struct StringField {
1619 display_elem : Option < u64 > ,
1720 edit_elem : Option < u64 > ,
1821 editing : bool ,
22+ display_value : Option < RmlDataVariable < ' static , String > > ,
1923}
2024
2125impl StringField {
@@ -29,6 +33,7 @@ impl StringField {
2933 display_elem : None ,
3034 edit_elem : None ,
3135 editing : false ,
36+ display_value : None ,
3237 }
3338 }
3439
@@ -37,14 +42,34 @@ impl StringField {
3742 self
3843 }
3944
40- fn button_rml ( & self ) -> String {
45+ fn binding_name ( & self ) -> String {
4146 format ! (
42- r#"<span class="field-button-title">{title}:</span><span class="field-button-value">{value}</span>"# ,
43- title = escape_rml( self . title. trim_end_matches( ':' ) ) ,
44- value = escape_rml( & self . value) ,
47+ "field_{}_display" ,
48+ self . name
49+ . chars( )
50+ . map( |character| if character. is_ascii_alphanumeric( ) {
51+ character
52+ } else {
53+ '_'
54+ } )
55+ . collect:: <String >( ) ,
4556 )
4657 }
4758
59+ fn display_markup ( & self ) -> String {
60+ self . display_value
61+ . as_ref ( )
62+ . map ( |_| format ! ( "{{{{ {} }}}}" , self . binding_name( ) ) )
63+ . unwrap_or_else ( || escape_rml ( & self . value ) )
64+ }
65+
66+ fn sync_display_value ( & self ) -> Result < ( ) , Error > {
67+ if let Some ( value) = & self . display_value {
68+ value. set ( self . value . clone ( ) ) ?;
69+ }
70+ Ok ( ( ) )
71+ }
72+
4873 fn show_edit ( & mut self , interface : & NativeInterfaceRef ) {
4974 self . editing = true ;
5075 let rml = interface. rml_ui ( ) ;
@@ -61,11 +86,10 @@ impl StringField {
6186
6287 fn show_display ( & mut self , interface : & NativeInterfaceRef ) {
6388 self . editing = false ;
64- let markup = self . button_rml ( ) ;
6589 let rml = interface. rml_ui ( ) ;
6690 if let Some ( element) = self . display_elem {
6791 let _ = rml. element_set_class ( element, "hidden" , false ) ;
68- let _ = rml . element_set_inner_rml ( element , & markup ) ;
92+ let _ = self . sync_display_value ( ) ;
6993 }
7094 if let Some ( element) = self . edit_elem {
7195 let _ = rml. element_set_class ( element, "hidden" , true ) ;
@@ -82,18 +106,24 @@ impl Field for StringField {
82106 self . tooltip . as_deref ( )
83107 }
84108
109+ fn prepare_data_model ( & mut self , model : & RmlDataModel < ' static > ) -> Result < ( ) , Error > {
110+ self . display_value = Some ( model. bind ( & self . binding_name ( ) , self . value . clone ( ) ) ?) ;
111+ Ok ( ( ) )
112+ }
113+
85114 fn generate_rml ( & self ) -> String {
86115 format ! (
87116 concat!(
88117 r#"<div class="field-row">"# ,
89- r#"<button id="field-{n}" class="field-composite-button field-string-button" style="width: {width}px;">{ button} </button>"# ,
90- r#"<input type="text" id="field-{n}-input" class="field-input field-string-input hidden" style="width: {width}px;" value="{value }"/>"# ,
118+ r#"<button id="field-{n}" class="field-composite-button field-string-button" style="width: {width}px;"><span class="field-button-title">{title}:</span><span class="field- button-value">{value}</span> </button>"# ,
119+ r#"<input type="text" id="field-{n}-input" class="field-input field-string-input hidden" style="width: {width}px;" value="{input_value }"/>"# ,
91120 r#"</div>"# ,
92121 ) ,
93122 n = self . name,
94123 width = self . width,
95- button = self . button_rml( ) ,
96- value = escape_rml( & self . value) ,
124+ title = escape_rml( self . title. trim_end_matches( ':' ) ) ,
125+ value = self . display_markup( ) ,
126+ input_value = escape_rml( & self . value) ,
97127 )
98128 }
99129
@@ -128,10 +158,8 @@ impl Field for StringField {
128158 }
129159
130160 fn write_to_dom ( & self , interface : & NativeInterfaceRef ) -> Result < ( ) , Error > {
131- if let Some ( element) = self . display_elem {
132- interface
133- . rml_ui ( )
134- . element_set_inner_rml ( element, & self . button_rml ( ) ) ?;
161+ if self . display_elem . is_some ( ) {
162+ self . sync_display_value ( ) ?;
135163 }
136164 if let Some ( element) = self . edit_elem {
137165 interface
0 commit comments