z_mirror/BlueprintTools
git clone https://git.raiguard.me/z_mirror/BlueprintTools
00b37f1
trunk
1-- FIXME: Use flib gui-lite 2 3--- @diagnostic disable 4 5local mod_name =script . mod_name 6local gui_event_defines ={} 7 8local event_id_to_string_mapping ={} 9for name , id in pairs ( defines . events ) do 10if string . find ( name , "^on_gui" ) then 11gui_event_defines [ name ] =id 12event_id_to_string_mapping [ id ] =string . gsub ( name , "^on_gui" , "on" ) 13end 14end 15 16local flib_gui ={} 17 18function flib_gui . hook_events ( callback ) 19local on_event =script . on_event 20for _ , id in pairs ( gui_event_defines ) do 21on_event ( id , callback ) 22end 23end 24 25function flib_gui . read_action ( event_data ) 26local elem =event_data . element 27if not elem or not elem . valid then 28return 29end 30 31local mod_tags =elem . tags [ mod_name ] 32if not mod_tags then 33return 34end 35 36local elem_actions =mod_tags . flib 37if not elem_actions then 38return 39end 40 41local event_name =event_id_to_string_mapping [ event_data . name ] 42local msg =elem_actions [ event_name ] 43 44return msg 45end 46 47local function recursive_build ( parent , structure , refs ) 48-- If the structure has no type, just ignore it 49-- This is to make it possible to pass unit types `{}` to represent "no element" without breaking things 50if not structure . type then 51return 52end 53 54-- Prepare tags 55local original_tags =structure . tags 56local tags =original_tags or {} 57local actions =structure . actions 58local tags_flib =tags . flib 59tags . flib =actions 60structure . tags ={ [ mod_name ] =tags } 61 62-- Make the game not convert these into a property tree for no reason 63structure . actions =nil 64-- Substructures can be defined in special tables or as the array portion of this structure 65local substructures 66local substructures_len =# structure 67if substructures_len > 0 then 68if structure . children or structure . tabs then 69error ( "Children or tab-and-content pairs must ALL be in the array portion, or a subtable. Not both at once!" ) 70end 71substructures ={} 72for i =1 , substructures_len do 73substructures [ i ] =structure [ i ] 74structure [ i ] =nil 75end 76else 77substructures =structure . children or structure . tabs 78structure . children =nil 79structure . tabs =nil 80end 81 82-- Create element 83local elem =parent . add ( structure ) 84 85-- Restore structure 86structure . tags =original_tags 87structure . actions =actions 88tags . flib =tags_flib 89 90local style_mods =structure . style_mods 91if style_mods then 92for k , v in pairs ( style_mods ) do 93elem . style [ k ] =v 94end 95end 96 97local elem_mods =structure . elem_mods 98if elem_mods then 99for k , v in pairs ( elem_mods ) do 100elem [ k ] =v 101end 102end 103 104local ref =structure . ref 105if ref then 106-- Recursively create tables as needed 107local prev =refs 108local ref_length =# ref 109for i =1 , ref_length - 1 do 110local current_key =ref [ i ] 111local current =prev [ current_key ] 112if not current then 113current ={} 114prev [ current_key ] =current 115end 116prev =current 117end 118prev [ ref [ ref_length ]] =elem 119end 120 121-- Substructures 122if substructures then 123if structure . type == "tabbed-pane" then 124local add_tab =elem . add_tab 125for i =1 , # substructures do 126local tab_and_content =substructures [ i ] 127if not ( tab_and_content . tab and tab_and_content . content ) then 128error ( "TabAndContent must have `tab` and `content` fields" ) 129end 130local tab =recursive_build ( elem , tab_and_content . tab , refs ) 131local content =recursive_build ( elem , tab_and_content . content , refs ) 132add_tab ( tab , content ) 133end 134else 135for i =1 , # substructures do 136recursive_build ( elem , substructures [ i ], refs ) 137end 138end 139end 140 141return elem 142end 143 144function flib_gui . build ( parent , structures ) 145local refs ={} 146for i =1 , # structures do 147recursive_build ( parent , structures [ i ], refs ) 148end 149return refs 150end 151 152function flib_gui . add ( parent , structure ) 153-- Just in case they had a ref in the structure already, extract it 154local previous_ref =structure . ref 155-- Put in a known ref that we can use later 156structure . ref ={ "FLIB_ADD_ROOT" } 157-- Build the element 158local refs ={} 159recursive_build ( parent , structure , refs ) 160-- Restore the previous ref 161structure . ref =previous_ref 162-- Return the element 163return refs . FLIB_ADD_ROOT 164end 165 166local function recursive_update ( elem , updates ) 167if updates . cb then 168updates . cb ( elem ) 169end 170 171if updates . style then 172elem . style =updates . style 173end 174 175if updates . style_mods then 176for key , value in pairs ( updates . style_mods ) do 177elem . style [ key ] =value 178end 179end 180 181if updates . elem_mods then 182for key , value in pairs ( updates . elem_mods ) do 183elem [ key ] =value 184end 185end 186 187if updates . tags then 188flib_gui . update_tags ( elem , updates . tags ) 189end 190 191-- TODO: This could be a lot better 192if updates . actions then 193for event_name , payload in pairs ( updates . actions ) do 194flib_gui . set_action ( elem , event_name , payload ) 195end 196end 197 198local substructures 199local substructures_len =# updates 200if substructures_len > 0 then 201if updates . children or updates . tabs then 202error ( "Children or tab-and-content pairs must ALL be in the array portion, or a subtable. Not both at once!" ) 203end 204substructures ={} 205for i =1 , substructures_len do 206substructures [ i ] =updates [ i ] 207updates [ i ] =nil 208end 209else 210substructures =updates . children or updates . tabs 211updates . children =nil 212updates . tabs =nil 213end 214local subelements 215if elem . type == "tabbed-pane" then 216subelements =elem . tabs 217else 218subelements =elem . children 219end 220 221if substructures then 222for i , substructure in pairs ( substructures ) do 223if substructure . tab or substructure . content then 224local elem_tab_and_content =subelements [ i ] 225if elem_tab_and_content then 226local tab =elem_tab_and_content . tab 227local tab_updates =substructures . tab 228if tab and tab_updates then 229recursive_update ( tab , tab_updates ) 230end 231local content =elem_tab_and_content . content 232local content_updates =substructures . content 233if content and content_updates then 234recursive_update ( content , content_updates ) 235end 236end 237elseif subelements [ i ] then 238recursive_update ( subelements [ i ], substructure ) 239end 240end 241end 242end 243 244function flib_gui . update ( elem , updates ) 245recursive_update ( elem , updates ) 246end 247 248function flib_gui . get_tags ( elem ) 249return elem . tags [ mod_name ] or {} 250end 251 252function flib_gui . set_tags ( elem , tags ) 253local elem_tags =elem . tags 254elem_tags [ mod_name ] =tags 255elem . tags =elem_tags 256end 257 258function flib_gui . delete_tags ( elem ) 259local elem_tags =elem . tags 260elem_tags [ mod_name ] =nil 261elem . tags =elem_tags 262end 263 264function flib_gui . update_tags ( elem , updates ) 265local elem_tags =elem . tags 266local existing =elem_tags [ mod_name ] 267 268if not existing then 269existing ={} 270elem_tags [ mod_name ] =existing 271end 272 273for k , v in pairs ( updates ) do 274existing [ k ] =v 275end 276 277elem . tags =elem_tags 278end 279 280function flib_gui . set_action ( elem , event_name , msg ) 281local elem_tags =elem . tags 282local existing =elem_tags [ mod_name ] 283 284if not existing then 285existing ={} 286elem_tags [ mod_name ] =existing 287end 288 289local actions =existing . flib 290if not actions then 291actions ={} 292existing . flib =actions 293end 294 295actions [ event_name ] =msg or nil 296 297elem . tags =elem_tags 298end 299 300function flib_gui . get_action ( elem , event_name ) 301local elem_tags =elem . tags 302local existing =elem_tags [ mod_name ] 303 304if not existing then 305return 306end 307 308local actions =existing . flib 309if not actions then 310return 311end 312 313return actions [ event_name ] 314end 315 316return flib_gui