z_mirror/TaskList
git clone https://git.raiguard.me/z_mirror/TaskList
fa77a7d
task-details-gui
1local gui =require ( "__flib__.gui" ) 2 3local constants =require ( "constants" ) 4 5local templates =require ( "scripts.gui.templates" ) 6local util =require ( "scripts.util" ) 7 8local actions =require ( "actions" ) 9 10-- GUI 11 12--- @class TasksGuiRefs 13--- @field window LuaGuiElement 14--- @field titlebar_flow LuaGuiElement 15--- @field pin_button LuaGuiElement 16--- @field visibility_switch LuaGuiElement 17--- @field scroll_pane LuaGuiElement 18--- @field force_flow LuaGuiElement 19--- @field private_flow LuaGuiElement 20 21--- @class TasksGui 22local TasksGui ={} 23 24TasksGui . actions =actions 25 26function TasksGui : destroy () 27local window =self . refs . window 28if window and window . valid then 29self . refs . window . destroy () 30end 31 32self . player_table . guis . tasks =nil 33end 34 35function TasksGui : open () 36self . refs . window . bring_to_front () 37self . refs . window . visible =true 38self . state . visible =true 39 40if not self . state . pinned then 41self . player . opened =self . refs . window 42end 43 44self . player . set_shortcut_toggled ( "tlst-toggle-gui" , true ) 45end 46 47function TasksGui : close () 48if self . state . ignore_close then 49self . state . ignore_close =false 50return 51end 52 53self . refs . window . visible =false 54self . state . visible =false 55 56if self . player . opened == self . refs . window then 57self . player . opened =nil 58end 59 60self . player . set_shortcut_toggled ( "tlst-toggle-gui" , false ) 61end 62 63function TasksGui : toggle () 64if self . state . visible then 65self : close () 66else 67self : open () 68end 69end 70 71function TasksGui : dispatch ( msg , e ) 72local transform =msg . transform 73if transform then 74if transform == "handle_titlebar_click" and e . button == defines . mouse_button_type . middle then 75msg . action ="recenter" 76elseif transform == "handle_expand_click" then 77if e . button == defines . mouse_button_type . middle then 78msg . action ="open_task_gui" 79else 80if e . shift then 81msg . action ="move_task" 82msg . delta =- 1 83elseif e . control then 84msg . action ="move_task" 85msg . delta =1 86else 87msg . action ="expand_task" 88end 89end 90end 91end 92 93if msg . action then 94local handler =self . actions [ msg . action ] 95if handler then 96handler ( self , msg , e ) 97end 98end 99end 100 101--- Get the parent flow for the given task 102--- @param Task Task 103function TasksGui : get_parent_flow ( Task ) 104local route ={} 105 106local owner =Task . owner 107while owner . object_name == "Task" do 108table . insert ( route , 1 , owner ) 109owner =owner . owner 110end 111 112-- At this point, the owner will be a LuaForce or LuaPlayer 113local flow =owner . object_name == "LuaForce" and self . refs . force_flow or self . refs . private_flow 114for _ , owner in pairs ( route ) do 115local subflow =owner . completed and flow . completed or flow . incompleted 116local row =subflow [ tostring ( owner . id )] 117if row then 118flow =row . details_flow . subtasks_flow 119end 120end 121 122return flow 123end 124 125--- @param Task Task 126--- @param index number 127function TasksGui : add_task ( Task , index , completed ) 128if completed == nil then 129completed =Task . completed 130end 131local flow =self : get_parent_flow ( Task ) 132--- @type LuaGuiElement 133local flow =completed and flow . completed or flow . incompleted 134 135gui . add ( flow , templates . task_item ( Task , "tasks" , index , completed )) 136 137if # flow . children > 0 and ( not completed or self . state . show_completed ) then 138flow . visible =true 139else 140flow . visible =false 141end 142 143-- Add subtasks 144for _ , subtasks in pairs ( { Task . completed_tasks , Task . tasks } ) do 145for _ , subtask_id in pairs ( subtasks ) do 146local subtask =global . tasks [ subtask_id ] 147if subtask then 148self : add_task ( subtask ) 149end 150end 151end 152end 153 154--- @param Task Task 155function TasksGui : update_task ( Task ) 156local flow =self : get_parent_flow ( Task ) 157--- @type LuaGuiElement 158local flow =Task . completed and flow . completed or flow . incompleted 159 160local row =flow [ tostring ( Task . id )] 161if row then 162local status_info =constants . task_status [ Task . status ] 163local assignee_name =Task . assignee and Task . assignee . name or nil 164gui . update ( row , { 165{ 166{ elem_mods ={ caption =Task . title } } , 167{ elem_mods ={ caption =assignee_name , visible =assignee_name and true or false } } , 168{ 169elem_mods ={ 170sprite ="flib_indicator_" .. status_info . color , 171tooltip =status_info . label , 172} , 173} , 174} , 175{ 176{ elem_mods ={ caption =Task . description , visible =# Task . description > 0 } } , 177} , 178} ) 179end 180end 181 182--- @param Task Task 183function TasksGui : delete_task ( Task , completed ) 184if completed == nil then 185completed =Task . completed 186end 187local flow =self : get_parent_flow ( Task ) 188--- @type LuaGuiElement 189local flow =completed and flow . completed or flow . incompleted 190 191local row =flow [ tostring ( Task . id )] 192if row then 193row . destroy () 194end 195 196if # flow . children > 0 and ( not completed or self . state . show_completed ) then 197flow . visible =true 198else 199flow . visible =false 200end 201end 202 203--- @param Task Task 204--- @param delta number 205function TasksGui : move_task ( Task , delta ) 206local flow =self : get_parent_flow ( Task ) 207--- @type LuaGuiElement 208local flow =Task . completed and flow . completed or flow . incompleted 209local row =flow [ tostring ( Task . id )] 210if row then 211flow . swap_children ( row . get_index_in_parent (), row . get_index_in_parent () + delta ) 212end 213end 214 215function TasksGui : update_show_completed () 216local show_completed =self . state . show_completed 217 218util . recursive_show_completed ( self . refs . force_flow , show_completed ) 219util . recursive_show_completed ( self . refs . private_flow , show_completed ) 220end 221 222-- BOOTSTRAP 223 224local index ={} 225 226--- @param player LuaPlayer 227--- @param player_table PlayerTable 228function index . new ( player , player_table ) 229--- @type TasksGuiRefs 230local refs =gui . build ( player . gui . screen , { 231{ 232type ="frame" , 233style_mods ={ width =500 } , 234direction ="vertical" , 235ref ={ "window" } , 236visible =false , 237actions ={ 238on_closed ={ gui ="tasks" , action ="close" } , 239} , 240{ 241type ="flow" , 242style ="flib_titlebar_flow" , 243ref ={ "titlebar_flow" } , 244actions ={ 245on_click ={ gui ="tasks" , transform ="handle_titlebar_click" } , 246} , 247{ type ="label" , style ="frame_title" , caption ={ "gui.tlst-tasks" } , ignored_by_interaction =true } , 248{ type ="empty-widget" , style ="flib_titlebar_drag_handle" , ignored_by_interaction =true } , 249templates . frame_action_button ( 250"flib_pin" , 251{ "gui.flib-keep-open" } , 252{ gui ="tasks" , action ="pin" } , 253{ "pin_button" } 254), 255templates . frame_action_button ( "utility/close" , { "gui.close-instruction" } , { 256gui ="tasks" , 257action ="close" , 258} ), 259} , 260{ 261type ="frame" , 262style ="inside_shallow_frame" , 263direction ="vertical" , 264{ 265type ="frame" , 266style ="subheader_frame" , 267{ 268type ="checkbox" , 269style_mods ={ left_margin =8 } , 270caption ={ "gui.tlst-show-completed" } , 271state =false , 272actions ={ 273on_checked_state_changed ={ gui ="tasks" , action ="toggle_show_completed" } , 274} , 275} , 276{ type ="empty-widget" , style ="flib_horizontal_pusher" } , 277{ 278type ="switch" , 279left_label_caption ={ "gui.tlst-force" } , 280left_label_tooltip ={ "gui.tlst-force-switch-description" } , 281right_label_caption ={ "gui.tlst-private" } , 282right_label_tooltip ={ "gui.tlst-private-switch-description" } , 283switch_state ="left" , 284ref ={ "visibility_switch" } , 285actions ={ 286on_switch_state_changed ={ gui ="tasks" , action ="toggle_tasks_mode" } , 287} , 288} , 289{ type ="empty-widget" , style_mods ={ width =20 } } , 290{ 291type ="sprite-button" , 292style ="flib_tool_button_light_green" , 293sprite ="utility/add" , 294tooltip ={ "gui.tlst-new-task" } , 295actions ={ 296on_click ={ gui ="tasks" , action ="edit_task" } , 297} , 298} , 299} , 300{ 301type ="scroll-pane" , 302style ="flib_naked_scroll_pane" , 303ref ={ "scroll_pane" } , 304templates . checkboxes_flow ( "force" ), 305templates . checkboxes_flow ( "private" , false ), 306} , 307} , 308} , 309} ) 310 311refs . window . force_auto_center () 312refs . titlebar_flow . drag_target =refs . window 313 314--- @type TasksGui 315local self ={ 316player =player , 317player_table =player_table , 318refs =refs , 319--- @class TasksGuiState 320state ={ 321ignore_close =false , 322pinned =false , 323show_completed =false , 324visible =false , 325} , 326} 327 328setmetatable ( self , { __index =TasksGui } ) 329 330player_table . guis . tasks =self 331 332-- Add existing tasks 333local force_table =global . forces [ player . force . index ] 334for _ , tasks in pairs ( { 335force_table . completed_tasks , 336force_table . tasks , 337player_table . completed_tasks , 338player_table . tasks , 339} ) do 340for _ , task_id in pairs ( tasks ) do 341local Task =global . tasks [ task_id ] 342if Task then 343self : add_task ( Task ) 344end 345end 346end 347end 348 349--- @param Gui TasksGui 350function index . load ( Gui ) 351setmetatable ( Gui , { __index =TasksGui } ) 352end 353 354return index