@@ -13,7 +13,7 @@ use std::rc::Rc;
1313
1414use spring_native:: {
1515 prelude:: { Error , NativeInterfaceRef } ,
16- RmlDataTextRows ,
16+ RmlDataModel , RmlDataTextRows , RmlDataVariable ,
1717} ;
1818
1919use crate :: sbc:: vfs:: { join_entry, leaf, normalize_extensions, vfs_files} ;
@@ -59,6 +59,10 @@ pub(crate) struct GridView {
5959 clicks : ClickQueue ,
6060 item_size : u32 ,
6161 navigation : Option < GridNavigation > ,
62+ /// The navigation breadcrumb belongs to the surrounding screen's model.
63+ /// Unlike the grid rows, it exists in markup parsed before this grid has a
64+ /// chance to create its own item model.
65+ navigation_path : Option < RmlDataVariable < ' static , String > > ,
6266 /// Engine-owned text collection backing the static `data-for` scaffold.
6367 /// It becomes invalid with its document, so `render` recreates it after a
6468 /// panel reload.
@@ -80,6 +84,7 @@ impl GridView {
8084 clicks : Rc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ,
8185 item_size,
8286 navigation : None ,
87+ navigation_path : None ,
8388 rows : None ,
8489 model_context : None ,
8590 bound_document : None ,
@@ -199,11 +204,16 @@ impl GridView {
199204
200205 pub ( crate ) fn container_rml ( & self ) -> String {
201206 if self . navigation . is_some ( ) {
207+ let path = self
208+ . navigation_path
209+ . as_ref ( )
210+ . map ( |_| format ! ( "{{{{ {} }}}}" , self . navigation_path_name( ) ) )
211+ . unwrap_or_default ( ) ;
202212 return format ! (
203213 r#"<div id="{id}-picker" class="grid-picker">
204214 <div class="grid-navigation">
205215 <button id="{id}-up" class="dialog-button">Up</button>
206- <span id="{id}-path" class="asset-path"></span>
216+ <span id="{id}-path" class="asset-path">{path} </span>
207217 </div>
208218 <div id="{id}" class="grid-container"></div>
209219 </div>"# ,
@@ -221,8 +231,24 @@ impl GridView {
221231 self . items_dirty = true ;
222232 }
223233
234+ /// Bind the breadcrumb before its containing markup is parsed. The item
235+ /// rows intentionally keep their own short-lived model because their
236+ /// scaffold is inserted only after the grid knows its document context.
237+ pub ( crate ) fn prepare_data_model (
238+ & mut self ,
239+ model : & RmlDataModel < ' static > ,
240+ ) -> Result < ( ) , Error > {
241+ let Some ( navigation) = & self . navigation else {
242+ return Ok ( ( ) ) ;
243+ } ;
244+ self . navigation_path =
245+ Some ( model. bind ( & self . navigation_path_name ( ) , navigation. dir . clone ( ) ) ?) ;
246+ Ok ( ( ) )
247+ }
248+
224249 /// Drop document-owned bindings after its panel has been rebuilt.
225250 pub ( crate ) fn forget_bindings ( & mut self ) {
251+ self . navigation_path = None ;
226252 self . rows = None ;
227253 self . model_context = None ;
228254 self . bound_document = None ;
@@ -242,6 +268,10 @@ impl GridView {
242268 self . forget_bindings ( ) ;
243269 Ok ( ( ) )
244270 }
271+
272+ fn navigation_path_name ( & self ) -> String {
273+ format ! ( "{}_path" , self . model_name( ) )
274+ }
245275}
246276
247277/// VFS listing for the asset picker: directories first, then files, both sorted.
0 commit comments