From 886fb2c22690608fcead73eaea6e28c8a573ce1f Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 21 Oct 2019 22:17:59 +0100 Subject: [PATCH 01/21] Added main gui file --- config/_file_loader.lua | 15 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 2 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 2 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 11143 ++-------------- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 2 +- docs/guis/Warps-List.html | 2 +- docs/index.html | 7 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 29 +- expcore/gui.lua | 659 +- expcore/gui/concepts/center.lua | 198 - expcore/gui/concepts/left.lua | 322 - expcore/gui/concepts/popups.lua | 230 - expcore/gui/concepts/toolbar.lua | 114 - expcore/gui/core.lua | 368 - expcore/gui/elements/buttons.lua | 128 - expcore/gui/elements/checkbox.lua | 247 - expcore/gui/elements/dropdown.lua | 184 - expcore/gui/elements/elem-button.lua | 96 - expcore/gui/elements/progress-bar.lua | 387 - expcore/gui/elements/slider.lua | 173 - expcore/gui/elements/text.lua | 145 - expcore/gui/instances.lua | 235 - expcore/gui/prototype.lua | 300 - expcore/gui/test.lua | 663 - 109 files changed, 1652 insertions(+), 14169 deletions(-) delete mode 100644 expcore/gui/concepts/center.lua delete mode 100644 expcore/gui/concepts/left.lua delete mode 100644 expcore/gui/concepts/popups.lua delete mode 100644 expcore/gui/concepts/toolbar.lua delete mode 100644 expcore/gui/core.lua delete mode 100644 expcore/gui/elements/buttons.lua delete mode 100644 expcore/gui/elements/checkbox.lua delete mode 100644 expcore/gui/elements/dropdown.lua delete mode 100644 expcore/gui/elements/elem-button.lua delete mode 100644 expcore/gui/elements/progress-bar.lua delete mode 100644 expcore/gui/elements/slider.lua delete mode 100644 expcore/gui/elements/text.lua delete mode 100644 expcore/gui/instances.lua delete mode 100644 expcore/gui/prototype.lua delete mode 100644 expcore/gui/test.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index c4a5bba6..44f73644 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -39,17 +39,18 @@ return { 'modules.addons.discord-alerts', 'modules.addons.chat-reply', -- GUI - 'modules.gui.rocket-info', - 'modules.gui.science-info', - 'modules.gui.warp-list', - 'modules.gui.task-list', - 'modules.gui.player-list', - 'modules.commands.debug', + --'modules.gui.rocket-info', + --'modules.gui.science-info', + --'modules.gui.warp-list', + --'modules.gui.task-list', + --'modules.gui.player-list', + --'modules.commands.debug', + 'expcore.gui', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config 'config.expcore-commands.auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups 'config.roles', -- loads some predefined roles - 'expcore.gui.test' -- loads multiple gui defines to test the gui system + --'expcore.gui.test' -- loads multiple gui defines to test the gui system } \ No newline at end of file diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 8fc6a44a..4871b8c9 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index c9ea0f82..3efd7ce5 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index d6eda160..c5d3cfc4 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 4fafcaa9..57a4a065 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index a445fe5a..f42f7dee 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index faadc765..6f540b7d 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e0ecba4b..e9f689ac 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 8a60609c..06a8e29a 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 46baddb7..806b86fd 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index c4f4487d..bcfab620 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 6b3002a3..7f9b0c0a 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 04b6b9fe..0a936c4e 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index 3786a596..e7e42cdd 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 81523c11..53b422c3 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index a250f390..17ef4f9d 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 0af8bb1c..880bb18e 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index 0f1ae48d..f8d25958 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index 024c376f..b7d54d80 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index d4881527..d279fe65 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index eeaf7d3d..8458181f 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 67d43bef..214140d6 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index 967cb7e1..421f28a9 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index fbba050f..a31f9a45 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index f30d335d..439294a8 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 361a22d7..98e6942b 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index f94af164..1957df69 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index 3bc1f04d..0f9bc8b1 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index 257da669..f72dbee2 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 63606adc..60783e88 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 472651ba..353738fe 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index a62c9b8e..d33d1547 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 02b2965a..94b0896f 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 2e3966d2..e7bb072a 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 727827bc..ee1e2dd2 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index fd824730..157b0311 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 4f49a827..59a9ed26 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index 9aacac5f..b299522c 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 64d71e20..42155a89 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 574f8aa4..8128d402 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 98043b31..0932f52e 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 859cf7d9..1e635943 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 4139d6e6..7214429c 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 8aa4661f..21a5ee90 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 305e744d..1ab7621e 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 2c9fc83f..bd67fe6b 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 64d7f6f0..d775b006 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index 114b8348..02436326 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 824291f5..2d2a05a7 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index e61920c5..5141d747 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index 929fbf4c..f011e724 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index 5c7aabf3..e435071a 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index c9c7fd1c..bea29f94 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index 3c038550..f271bf65 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 4395fc07..a1a68698 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 1bd48171..e4f9760a 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 78291b18..751529ef 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index c8a87917..3840e9b9 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -684,7 +684,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 46633de1..8ed47a2e 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index ea5291cb..2cac6422 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 4470dca7..16391654 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index ea2c7aae..831e5343 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 41068882..c68201ec 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index abec17b0..ff7f7802 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index ebb0dfb5..7791b32f 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 07dfce01..075e5bb8 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index 4206d114..caba804c 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 09dee1fe..74601e95 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -42,21 +42,12 @@

Sections

@@ -217,21 +208,12 @@

Jump to Section

@@ -252,10 +234,7 @@

Gui core

Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started

+- Used to define new gui elements and gui event handlers

@@ -263,6 +242,42 @@ +

Usage

+
-- Defining a button that prints the player's name
+local example_button =
+Gui.new_element{
+    type = 'button',
+    caption = 'Example Button'
+}
+:on_click(function(event)
+    local player = event.player
+    player.print(player.name)
+end)
+
-- Defining using a custom function
+local example_flow_with_button =
+Gui.new_element(function(event_trigger,parent)
+    local flow =
+    parent.add{
+        name = 'example_flow',
+        type = 'flow'
+    }
+
+    local element =
+    flow.add{
+        name = event_trigger,
+        type = 'button',
+        caption = 'Example Button'
+    }
+
+    return element
+end)
+:on_click(function(event)
+    local player = event.player
+    player.print(player.name)
+end)
+
-- Drawing an element
+local exmple_button_element = example_button(parent)
+local example_flow_with_button = example_flow_with_button(parent)
@@ -275,840 +290,178 @@ - expcore.gui.core - - - expcore.gui.instances - - - expcore.gui.elements.buttons - - - expcore.gui.elements.checkbox - - - expcore.gui.elements.dropdown - - - expcore.gui.elements.slider - - - expcore.gui.elements.text - - - expcore.gui.elements.elem-button - - - expcore.gui.elements.progress-bar - - - expcore.gui.concepts.toolbar - - - expcore.gui.concepts.left - - - expcore.gui.concepts.center - - - expcore.gui.concepts.popups - - - - - -

Center Guis

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
expcore.gui.concepts.toolbar
utils.game
CenterFrames.get_flow(player)Gets the center flow for a player
CenterFrames.clear_flow(player)Clears the center flow for a player
CenterFrames.draw_frame(player, name)Draws the center frame for a player, if already open then will do nothing
CenterFrames.redraw_frame(player, name)Draws the center frame for a player, if already open then will destroy it and redraw
CenterFrames.toggle_frame(player, name[, state])Toggles if the frame is currently open or not, will open if closed and close if open
CenterFrames.new_frame(permission_name)Creates a new center frame define
CenterFrames._prototype:set_auto_focus([state=true])Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:draw_frame(player)Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)
CenterFrames._prototype:redraw_frame(player)Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)
CenterFrames._prototype:toggle_frame(player)Toggles if the frame is open, if open it will close it and if closed it will open it
CenterFrames._prototype:event_handler([action=update])Creates an event handler that will trigger one of its functions, use with Event.add
- - -

Left Guis

- - - - - - - - - - - - - - + + +
expcore.gui.core
expcore.gui.prototype
expcore.gui.concepts.toolbar
expcore.gui.elements.buttonsutils.event
mod-gui
+ + +

Tables

+ + + - + + - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
utils.gametop_elementsContains the uids of the elements that will show on the top flow and the auth function
utils.eventleft_elementsContains the uids of the elements that will show on the left flow and the open on join function
LeftFrames.get_flow(player)Gets the left frame flow for a playerdefinesTable of all the elements which have been registed with the draw function and event handlers
LeftFrames.get_frame(name, player)Gets one frame from the left flow by its namefile_pathsAn index used for debuging to find the file where different elements where registered
LeftFrames.get_open(player)Gets all open frames for a player, if non are open it will remove the close all button_prototype_elementThe element prototype which is returned from Gui.new_element
LeftFrames.toggle_frame(name, player[, state])Toggles the visibility of a left frame, or sets its visibility state
LeftFrames.new_frame(permission_name)Creates a new left frame define
LeftFrames._prototype:set_open_by_default([state=true])Sets if the frame is visible when a player joins, can also be a function to return a boolean
LeftFrames._prototype:set_direction(direction)Sets the direction of the frame, either vertical or horizontal
LeftFrames._prototype:_internal_draw(player)Creates the gui for the first time, used internally
LeftFrames._prototype:get_frame(player)Gets the frame for this define from the left frame flow
LeftFrames._prototype:is_open(player)Returns if the player currently has this define visible
LeftFrames._prototype:toggle(player)Toggles the visibility of the left frame
LeftFrames._prototype:update(player)Updates the contents of the left frame, first tries update callback, other wise will clear and redraw
LeftFrames._prototype:update_all([update_offline=false])Updates the frame for all players, see update
LeftFrames._prototype:redraw(player)Redraws the frame by calling on_draw, will always clear the frame
LeftFrames._prototype:redraw_all([update_offline=false])Redraws the frame for all players, see redraw
LeftFrames._prototype:event_handler([action=update])Creates an event handler that will trigger one of its functions, use with Event.add_mt_elementThe prototype metatable applied to new element defines
-

Popups

+

Fields

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
expcore.gui.core
expcore.gui.prototype
utils.game
utils.event
expcore.gui.elements.progress-bar
expcore.gui.elements.buttons
mod-gui
resources.color_presets
utils.global
PopupFrames.get_flow(player)Gets the left flow that contains the popup frames
PopupFrames.open(define_name, player[, open_time], ...)Opens a popup for the player, can give the amount of time it is open as well as params for the draw function
PopupFrames.close_progressProgress bar which when depleted will close the popup frame
PopupFrames.close_buttonA button which can be used to close the gui before the timer runs out
PopupFrames.new_popup([name])Creates a new popup frame define
PopupFrames._prototype:set_default_open_time(amount)Sets the default open time for the popup, will be used if non is provided with open
PopupFrames._prototype:open(player[, open_time], ...)Opens this define for a player, can be given open time and any other params for the draw functionuidThe current highest uid that is being used, will not increase during runtime
-

Toolbar

+

Element Define

- + + - + + - - - - - - - - - - - - - - - - - - - - - - + +
expcore.gui.corenew_element(element_define)Base function used to define new elements, can be used with a table or with a function
expcore.gui.elements.buttonsGui._prototype_element:add_to_top_flow([authenticator])Adds an element to be drawn to the top flow when a player joins
expcore.roles
utils.event
utils.game
mod-gui
Toolbar.new_button([name])Adds a new button to the toolbar
Toolbar.add_button(button)Adds an existing buttton to the toolbar
Toolbar.update(player)Updates the player's toolbar with an new buttons or expected change in auth returnGui._prototype_element:add_to_left_flow([open_on_join])Adds an element to be drawn to the left flow when a player joins
-

Core

+

Element Events

- + + - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - + +
utils.guiGui._prototype_element.on_openedCalled when the player opens a GUI.
utils.gameGui._prototype_element.on_closedCalled when the player closes the GUI they have open.
new_define(prototype[, debug_name])Used to create new element defines from a class prototype, please use the own given by the classGui._prototype_element.on_clickCalled when LuaGuiElement is clicked.
get_define(name[, internal])Gets an element define give the uid, debug name or a copy of the element defineGui._prototype_element.on_confirmedCalled when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
categorize_by_player(element)A categorize function to be used with add_store, each player has their own valueGui._prototype_element.on_checked_changedCalled when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
categorize_by_force(element)A categorize function to be used with add_store, each force has its own valueGui._prototype_element.on_elem_changedCalled when LuaGuiElement element value is changed (related to choose element buttons).
categorize_by_surface(element)A categorize function to be used with add_store, each surface has its own valueGui._prototype_element.on_location_changedCalled when LuaGuiElement element location is changed (related to frames in player.gui.screen).
draw(name, element)Draws a copy of the element define to the parent element, see draw_toGui._prototype_element.on_tab_changedCalled when LuaGuiElement selected tab is changed (related to tabbed-panes).
toggle_enabled(element)Will toggle the enabled state of an elementGui._prototype_element.on_selection_changedCalled when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
toggle_visible(element)Will toggle the visiblity of an elementGui._prototype_element.on_switch_changedCalled when LuaGuiElement switch state is changed (related to switches).
set_padding(element[, up=0][, down=0][, left=0][, right=0])Sets the padding for a gui elementGui._prototype_element.on_text_changeCalled when LuaGuiElement text is changed by the player.
set_padding_style(style[, up=0][, down=0][, left=0][, right=0])Sets the padding for a gui style
create_alignment(element[, name][, horizontal_align='right'][, vertical_align='center'])Allows the creation of an alignment flow to place elements into
destroy_if_valid(element)Destroies an element but tests for it being present and valid first
create_scroll_table(element, table_size, maximal_height[, name='scroll'])Creates a scroll area with a table inside, table can be any size
create_header(element, caption[, tooltip][, right_align][, name='header'])Creates a header section with a label and button areaGui._prototype_element.on_value_changedCalled when LuaGuiElement slider value is changed (related to the slider element).
-

Buttons

+

Top Flow

- + + - + + - + + - - - - - - - - - - - - - - + +
mod-guitoggle_top_flowButton which toggles the top flow elements
expcore.gui.coreget_top_flow(player)Gets the flow which contains the elements for the top flow
expcore.gui.prototypeupdate_top_flow(player)Updates the visible states of all the elements on a players top flow
Button.new_button([name])Creates a new button element define
Button._prototype:set_sprites(sprite[, hovered_sprite][, clicked_sprite])Adds sprites to a button making it a sprite button
Button._prototype:set_click_filter(filter[, ...])Adds a click / mouse button filter to the button
Button._prototype:set_key_filter(filter[, ...])Adds a control key filter to the buttontoggle_top_flow(player[, state])Toggles the visible states of all the elements on a players top flow
-

Checkboxs

+

Left Flow

- + + - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.corehide_left_flowButton which hides the elements in the left flow
expcore.gui.prototypeget_left_flow(player)Gets the flow which contains the elements for the left flow
expcore.storehide_left_flow(player)Hides all left elements for a player
utils.game
Checkbox.new_checkbox([name])Creates a new checkbox element define
Checkbox.new_radiobutton([name])Creates a new radiobutton element define, has all functions checkbox has
Checkbox._prototype_radiobutton:add_as_option(option_set, option_name)Adds this radiobutton to be an option in the given option set (only one can be true at a time)
Checkbox._prototype_radiobutton:get_store(category, internal)Gets the stored value of the radiobutton or the option set if present
Checkbox._prototype_radiobutton:set_store(category, value, internal)Sets the stored value of the radiobutton or the option set if present
Checkbox.new_option_set(callback, categorize)Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
Checkbox.draw_option_set(name, element)Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)
Checkbox.reset_radiobuttons(element[, exclude][, recursive=false])Sets all radiobutton in a element to false (unless excluded) and can act recursively
- - -

Dropdowns

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
Dropdown.new_dropdown([name])Creates a new dropdown element define
Dropdown.new_list_box([name])Creates a new list box element define
Dropdown._prototype:new_static_options(options[, ...], the)Adds new static options to the dropdown which will trigger the general callback
Dropdown._prototype:new_dynamic_options(callback)Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)
Dropdown._prototype:add_option_callback(option, callback)Adds a case specific callback which will only run when that option is selected (general case still triggered)
Dropdown.select_value(element, value)Selects the option from a dropdown or list box given the value rather than key
Dropdown.get_selected_value(element)Returns the currently selected value rather than index
- - -

Elem Buttons

- - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
ElemButton.new_elem_button([name])Creates a new elem button element define
ElemButton._prototype.set_typeSets the type of the elem button, the type is required so this must be called at least once
ElemButton._prototype:set_default(value)Sets the default value for the elem button, this may be a function or a string
- - -

Progress Bars

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.global
utils.game
ProgressBar.set_maximum(element, amount)Sets the maximum value that represents the end value of the progress bar
ProgressBar.increment(element[, amount=1])Increases the value of the progressbar, if a define is given all of its instances have incremented
ProgressBar.decrement(element[, amount=1])Decreases the value of the progressbar, if a define is given all of its instances have decremented
ProgressBar.new_progressbar([name])Creates a new progressbar element define
ProgressBar._prototype:set_default_maximum(amount)Sets the maximum value that represents the end value of the progress bar
ProgressBar._prototype:use_count_down([state=true])Will set the progress bar to start at 1 and trigger when it hits 0
ProgressBar._prototype:increment([amount=1][, category])Increases the value of the progressbar
ProgressBar._prototype:increment_filtered([amount=1], filter)Increases the value of the progressbar, if the filter condition is met, does not work with store
ProgressBar._prototype:decrement([amount=1][, category])Decreases the value of the progressbar
ProgressBar._prototype:decrement_filtered([amount=1], filter)Decreases the value of the progressbar, if the filter condition is met, does not work with store
ProgressBar._prototype:add_element(element[, maximum])Adds an element into the list of instances that will are waiting to complete, does not work with store - note use store if you want persistent data, this only stores the elements not the values which they have
ProgressBar._prototype:reset_element(element)Resets an element, or its store, to be back at the start, either 1 or 0
ProgressBar._prototype:event_counter([filter])Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented
ProgressBar._prototype:event_countdown([filter])Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented
- - -

Sliders

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
expcore.gui.instances
utils.game
Slider.new_slider([name])Creates a new slider element define
Slider._prototype:set_range([min][, max])Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element)Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label([state=true])Enables auto draw of the label, the label will share the same parent element as the slider
- - -

Text

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
Text.new_text_field([name])Creates a new text field element define
Text.new_text_box([name])Creates a new text box element define
Text._prototype_box:set_selectable([state=true])Sets the text box to be selectable
Text._prototype_box:set_word_wrap([state=true])Sets the text box to have word wrap
Text._prototype_box:set_read_only([state=true])Sets the text box to be read only
- - -

Instances

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
utils.global
Instances.has_categories(name)Returns if a instance group has a serializer function; must be registered
Instances.is_registered(name)Returns if the given name is a registered instance group
Instances.register(name[, serializer])Registers the name of an instance group to allow for storing element instances
Instances.add_element(name, element)Adds an element to the instance group under the correct category; must be registered
Instances.get_elements_raw(name[, category])Gets all element instances without first removing any invalid ones; used internally and must be registered
Instances.get_valid_elements(name[, category][, callback])Gets all valid element instances and has the option of running a callback on those that are valid
Instances.unregistered_add_element(name, category, element)A version of add_element that does not require the group to be registered
Instances.unregistered_get_elements(name, category[, callback])A version of get_elements that does not require the group to be registered
- - -

Prototype

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
utils.game
expcore.store
expcore.gui.instances
Constructor.event(event_name)Creates a new function to add functions to an event handler
Constructor.extend(new_prototype)Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(callback)Creates a new function which adds a store to a gui define
Constructor.setter(value_type, key[, second_key])Creates a setter function that checks the type when a value is set
Prototype:uid()Gets the uid for the element define
Prototype.debug_nameSets a debug alias for the define
Prototype.set_captionSets the caption for the element define
Prototype.set_tooltipSets the tooltip for the element define
Prototype.set_pre_authenticatorSets an authenticator that blocks the draw function if check fails
Prototype.set_post_authenticatorSets an authenticator that disables the element if check fails
Prototype.on_drawRegisters a callback to the on_draw event
Prototype.on_style_updateRegisters a callback to the on_style_update event
Prototype:set_style(style[, callback])Sets the style for the element define
Prototype:set_embedded_flow(state)Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:raise_event(event_name, ...)Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element)The main function for defines, when called will draw an instance of this define to the given element - what is drawn is based on the data in draw_data which is set using other functions
Prototype:get_store(category)Gets the value in this elements store, category needed if serializer function used
Prototype:set_store(category, value)Sets the value in this elements store, category needed if serializer function used
Prototype:clear_store([category])Sets the value in this elements store to nil, category needed if serializer function used
- - -

Test

- - - - - - - - - - - - - - - - - + +
expcore.gui
expcore.common
resources.color_presets
utils.event
expcore.storetoggle_left_element(player, element_define[, state])Toggles the visible state of all a left element for a player
@@ -1122,1187 +475,8 @@
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.instances -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.buttons -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.checkbox -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.dropdown -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.slider -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.text -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.elem-button -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.progress-bar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.left -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.center -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.popups -
-
-
-
- - - - - - - - - - - - - - - -
- -

Center Guis

-
-
-
-
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.prototype -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - utils.game -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - CenterFrames.get_flow(player) -
-
-
-
- -

Gets the center flow for a player

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to get the flow for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.clear_flow(player) -
-
-
-
- -

Clears the center flow for a player

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to clear the flow for - -
  • - - -
- - - - - - - - - - - - - -
-
-
-
- # - CenterFrames.draw_frame(player, name) -
-
-
-
- -

Draws the center frame for a player, if already open then will do nothing

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame drawn - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will drawn - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.redraw_frame(player, name) -
-
-
-
- -

Draws the center frame for a player, if already open then will destroy it and redraw

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame drawn - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will drawn - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.toggle_frame(player, name[, state]) -
-
-
-
- -

Toggles if the frame is currently open or not, will open if closed and close if open

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame toggled - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will be toggled - -
  • - - - - - -
  • - - state - - : - - (boolean) - - when set will force a state for the frame - - (optional) -
  • - - -
- - - - - Returns: -
    -
  • - (boolean) - if the frame if no open or closed -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames.new_frame(permission_name) -
-
-
-
- -

Creates a new center frame define

-

- - - Parameters: - -
    - - - - - -
  • - - permission_name - - : - - (string) - - the name that can be used with the permission system - -
  • - - -
- - - - - Returns: -
    -
  • - (table) - the new center frame define -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:set_auto_focus([state=true]) -
-
-
-
- -

Sets the frame to be the current active gui when opened and closes all other frames

-

- - - Parameters: - -
    - - - - - -
  • - - state - - : - - (boolean) - - when true will auto close other frames and set this frame as player.opened - - (default: true) -
  • - - -
- - - - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:draw_frame(player) -
-
-
-
- -

Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:redraw_frame(player) -
-
-
-
- -

Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:toggle_frame(player) -
-
-
-
- -

Toggles if the frame is open, if open it will close it and if closed it will open it

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: -
    -
  • - (boolean) - with the gui frame is now open -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:event_handler([action=update]) -
-
-
-
- -

Creates an event handler that will trigger one of its functions, use with Event.add

-

- - - Parameters: - -
    - - - - - -
  • - - action - - : - - (string) - - the action to take on this event - - (default: update) -
  • - - -
- - - - - - - - - - - - - -
-
-

Left Guis

-
-
-
-
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.prototype -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.buttons + # + utils.event
@@ -2348,16 +522,21 @@
+
+

Tables

+
- # - utils.game + # + top_elements
+

Contains the uids of the elements that will show on the top flow and the auth function

+

@@ -2376,13 +555,15 @@
- # - utils.event + # + left_elements
+

Contains the uids of the elements that will show on the left flow and the open on join function

+

@@ -2401,14 +582,196 @@
- # - LeftFrames.get_flow(player) + # + defines
-

Gets the left frame flow for a player

+

Table of all the elements which have been registed with the draw function and event handlers

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + file_paths +
+
+
+
+ +

An index used for debuging to find the file where different elements where registered

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + _prototype_element +
+
+
+
+ +

The element prototype which is returned from Gui.new_element

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + _mt_element +
+
+
+
+ +

The prototype metatable applied to new element defines

+

+ + + Fields: + +
    + + + + + +
  • + + __call + + + + + +
  • + + +
+ + + + + + + + + + + + + +
+
+

Fields

+
+
+
+
+ # + uid +
+
+
+
+ +

The current highest uid that is being used, will not increase during runtime

+

+ + + +
    + + + + + +
  • + + uid + + + + + +
  • + + +
+ + + + + + + + + + + + + +
+
+

Element Define

+
+
+
+
+ # + new_element(element_define) +
+
+
+
+ +

Base function used to define new elements, can be used with a table or with a function

@@ -2422,143 +785,13 @@
  • - player + element_define : - (LuaPlayer) + (table or function) - the player to get the flow of - -
  • - - - - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames.get_frame(name, player) -
    -
    -
    -
    - -

    Gets one frame from the left flow by its name

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the gui frame to get - -
    • - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame in the left frame flow with that name -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames.get_open(player) -
    -
    -
    -
    - -

    Gets all open frames for a player, if non are open it will remove the close all button

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the flow of + used to define how the element is draw, using a table is the simplist way of doing this
    • @@ -2572,7 +805,7 @@
      • (table) - contains all the open (and registered) frames for the player + the new element define that is used to register events to this element
      @@ -2582,20 +815,45 @@ + Usage: +
      -- Defining an element with a table
      +local example_button =
      +Gui.new_element{
      +    type = 'button',
      +    caption = 'Example Button'
      +}
      +
      -- Defining an element with a function
      +local example_flow_with_button =
      +Gui.new_element(function(event_trigger,parent)
      +    local flow =
      +    parent.add{
      +        name = 'example_flow',
      +        type = 'flow'
      +    }
      +
      +    local element =
      +    flow.add{
      +        name = event_trigger,
      +        type = 'button',
      +        caption = 'Example Button'
      +    }
      +
      +    return element
      +end)
    - # - LeftFrames.toggle_frame(name, player[, state]) + # + Gui._prototype_element:add_to_top_flow([authenticator])
    -

    Toggles the visibility of a left frame, or sets its visibility state

    +

    Adds an element to be drawn to the top flow when a player joins

    @@ -2609,45 +867,13 @@
  • - name + authenticator : - (string) + (function) - the name of the gui frame to toggle - -
  • - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
  • - - - - - -
  • - - state - - : - - (boolean) - - when given will be the state that the visibility is set to + called during toggle or update to decide if the element should be visible (optional)
  • @@ -2658,13 +884,6 @@ - Returns: -
      -
    • - (boolean) - the new state of the visibility -
    • -
    @@ -2672,20 +891,26 @@ + Usage: +
    -- Adding the example button
    +example_button:add_to_top_flow(function(player)
    +    -- example button will only show when game time is less than 1 minute
    +    return player.online_time < 3600
    +end)
    - # - LeftFrames.new_frame(permission_name) + # + Gui._prototype_element:add_to_left_flow([open_on_join])
    -

    Creates a new left frame define

    +

    Adds an element to be drawn to the left flow when a player joins

    @@ -2699,606 +924,15 @@
  • - permission_name - - : - - (string) - - the name that can be used with the permission system - -
  • - - - - - - - - Returns: -
      -
    • - (table) - the new left frame define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:set_open_by_default([state=true]) -
    -
    -
    -
    - -

    Sets if the frame is visible when a player joins, can also be a function to return a boolean

    -

    - - - Parameters: - -
      - - - - - -
    • - - state + open_on_join : (boolean or function) - the default state of the visibility, can be a function - state param - player LuaPlayer - the player that has joined the game - state param - define_name string - the define name for the frame - state return - boolean - false will hide the frame + called during first darw to decide if the element is visible - (default: true) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:set_direction(direction) -
    -
    -
    -
    - -

    Sets the direction of the frame, either vertical or horizontal

    -

    - - - Parameters: - -
      - - - - - -
    • - - direction - - : - - (string) - - the direction to have the elements be added to the frame - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:_internal_draw(player) -
    -
    -
    -
    - -

    Creates the gui for the first time, used internally

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to draw the frame to - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:get_frame(player) -
    -
    -
    -
    - -

    Gets the frame for this define from the left frame flow

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame in the left frame flow for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:is_open(player) -
    -
    -
    -
    - -

    Returns if the player currently has this define visible

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if it is open/visible -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:toggle(player) -
    -
    -
    -
    - -

    Toggles the visibility of the left frame

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to toggle the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state of the visibility -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:update(player) -
    -
    -
    -
    - -

    Updates the contents of the left frame, first tries update callback, other wise will clear and redraw

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the frame of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:update_all([update_offline=false]) -
    -
    -
    -
    - -

    Updates the frame for all players, see update

    -

    - - - Parameters: - -
      - - - - - -
    • - - update_offline - - : - - (boolean) - - when true will update the frame for offline players - - (default: false) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:redraw(player) -
    -
    -
    -
    - -

    Redraws the frame by calling on_draw, will always clear the frame

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the frame of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:redraw_all([update_offline=false]) -
    -
    -
    -
    - -

    Redraws the frame for all players, see redraw

    -

    - - - Parameters: - -
      - - - - - -
    • - - update_offline - - : - - (boolean) - - when true will update the frame for offline players - - (default: false) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:event_handler([action=update]) -
    -
    -
    -
    - -

    Creates an event handler that will trigger one of its functions, use with Event.add

    -

    - - - Parameters: - -
      - - - - - -
    • - - action - - : - - (string) - - the action to take on this event - - (default: update) + (optional)
    • @@ -3314,3911 +948,26 @@ + Usage: +
      -- Adding the example button
      +example_flow_with_button:add_to_left_flow(true)
    -

    Popups

    +

    Element Events

    - # - expcore.gui.core + # + Gui._prototype_element.on_opened
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.progress-bar -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.buttons -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.get_flow(player) -
    -
    -
    -
    - -

    Gets the left flow that contains the popup frames

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the flow for - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the left flow that contains the popup frames -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.open(define_name, player[, open_time], ...) -
    -
    -
    -
    - -

    Opens a popup for the player, can give the amount of time it is open as well as params for the draw function

    -

    - - - Parameters: - -
      - - - - - -
    • - - define_name - - : - - (string) - - the name of the define that you want to open for the player - -
    • - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to open the popup for - -
    • - - - - - -
    • - - open_time - - : - - (number) - - the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default - - (optional) -
    • - - - - - -
    • - - ... - - : - - (any) - - the other params that you want to pass to your on_draw event - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame that was drawn, the inner gui flow which contains the content -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.close_progress -
    -
    -
    -
    - -

    Progress bar which when depleted will close the popup frame

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.close_button -
    -
    -
    -
    - -

    A button which can be used to close the gui before the timer runs out

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.new_popup([name]) -
    -
    -
    -
    - -

    Creates a new popup frame define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new popup frame define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames._prototype:set_default_open_time(amount) -
    -
    -
    -
    - -

    Sets the default open time for the popup, will be used if non is provided with open

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the number of ticks, by default, the popup will be open for - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames._prototype:open(player[, open_time], ...) -
    -
    -
    -
    - -

    Opens this define for a player, can be given open time and any other params for the draw function

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to open the popup for - -
    • - - - - - -
    • - - open_time - - : - - (number) - - the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default - - (optional) -
    • - - - - - -
    • - - ... - - : - - (any) - - the other params that you want to pass to your on_draw event - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame that was drawn, the inner gui flow which contains the content -
    • -
    - - - - - - - - - -
    -
    -

    Toolbar

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.buttons -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.roles -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.new_button([name]) -
    -
    -
    -
    - -

    Adds a new button to the toolbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - when given allows an alias to the button for the permission system - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the button define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.add_button(button) -
    -
    -
    -
    - -

    Adds an existing buttton to the toolbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - button - - : - - (table) - - the button define for the button to be added - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.update(player) -
    -
    -
    -
    - -

    Updates the player's toolbar with an new buttons or expected change in auth return

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the toolbar for - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -

    Core

    -
    -
    -
    -
    - # - utils.gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - new_define(prototype[, debug_name]) -
    -
    -
    -
    - -

    Used to create new element defines from a class prototype, please use the own given by the class

    -

    - - - Parameters: - -
      - - - - - -
    • - - prototype - - : - - (table) - - the class prototype that will be used for the element define - -
    • - - - - - -
    • - - debug_name - - : - - (string) - - the name that you want to see while debuging - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define with all functions accessed via __index metamethod -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - get_define(name[, internal]) -
    -
    -
    -
    - -

    Gets an element define give the uid, debug name or a copy of the element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string or table) - - the uid, debug name or define for the element define to get - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - when true the error trace is one level higher (used internally) - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the element define that was found or an error -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_player(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each player has their own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_force(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each force has its own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's force name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_surface(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each surface has its own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's surface name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - draw(name, element) -
    -
    -
    -
    - -

    Draws a copy of the element define to the parent element, see draw_to

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string or table) - - the uid, debug name or define for the element define to draw - -
    • - - - - - -
    • - - element - - : - - (LuaGuiEelement) - - the parent element that it the define will be drawn to - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - toggle_enabled(element) -
    -
    -
    -
    - -

    Will toggle the enabled state of an element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element to toggle - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state that the element has -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - toggle_visible(element) -
    -
    -
    -
    - -

    Will toggle the visiblity of an element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element to toggle - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state that the element has -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - set_padding(element[, up=0][, down=0][, left=0][, right=0]) -
    -
    -
    -
    - -

    Sets the padding for a gui element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to set the padding for - -
    • - - - - - -
    • - - up - - : - - (number) - - the amount of padding on the top - - (default: 0) -
    • - - - - - -
    • - - down - - : - - (number) - - the amount of padding on the bottom - - (default: 0) -
    • - - - - - -
    • - - left - - : - - (number) - - the amount of padding on the left - - (default: 0) -
    • - - - - - -
    • - - right - - : - - (number) - - the amount of padding on the right - - (default: 0) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - set_padding_style(style[, up=0][, down=0][, left=0][, right=0]) -
    -
    -
    -
    - -

    Sets the padding for a gui style

    -

    - - - Parameters: - -
      - - - - - -
    • - - style - - : - - (LuaStyle) - - the element to set the padding for - -
    • - - - - - -
    • - - up - - : - - (number) - - the amount of padding on the top - - (default: 0) -
    • - - - - - -
    • - - down - - : - - (number) - - the amount of padding on the bottom - - (default: 0) -
    • - - - - - -
    • - - left - - : - - (number) - - the amount of padding on the left - - (default: 0) -
    • - - - - - -
    • - - right - - : - - (number) - - the amount of padding on the right - - (default: 0) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - create_alignment(element[, name][, horizontal_align='right'][, vertical_align='center']) -
    -
    -
    -
    - -

    Allows the creation of an alignment flow to place elements into

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this alignment into - -
    • - - - - - -
    • - - name - - : - - (string) - - the name to use for the alignment - - (optional) -
    • - - - - - -
    • - - horizontal_align - - : - - (string) - - the horizontal alignment of the elements in this flow - - (default: 'right') -
    • - - - - - -
    • - - vertical_align - - : - - (string) - - the vertical alignment of the elements in this flow - - (default: 'center') -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - destroy_if_valid(element) -
    -
    -
    -
    - -

    Destroies an element but tests for it being present and valid first

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to be destroied - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if it was destoried -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - create_scroll_table(element, table_size, maximal_height[, name='scroll']) -
    -
    -
    -
    - -

    Creates a scroll area with a table inside, table can be any size

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this scroll into - -
    • - - - - - -
    • - - table_size - - : - - (number) - - the number of columns in the table - -
    • - - - - - -
    • - - maximal_height - - : - - (number) - - the max hieght of the scroll - -
    • - - - - - -
    • - - name - - : - - (string) - - the name of the scoll element - - (default: 'scroll') -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - create_header(element, caption[, tooltip][, right_align][, name='header']) -
    -
    -
    -
    - -

    Creates a header section with a label and button area

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this header into - -
    • - - - - - -
    • - - caption - - : - - (localeString) - - the caption that is used as the title - -
    • - - - - - -
    • - - tooltip - - : - - (localeString) - - the tooltip that is shown on the caption - - (optional) -
    • - - - - - -
    • - - right_align - - : - - (boolean) - - when true will include the right align area - - (optional) -
    • - - - - - -
    • - - name - - : - - (string) - - the name of the header area - - (default: 'header') -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the header that was made, or the align area if that was created -
    • -
    - - - - - - - - - -
    -
    -

    Buttons

    -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Button.new_button([name]) -
    -
    -
    -
    - -

    Creates a new button element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_sprites(sprite[, hovered_sprite][, clicked_sprite]) -
    -
    -
    -
    - -

    Adds sprites to a button making it a sprite button

    -

    - - - Parameters: - -
      - - - - - -
    • - - sprite - - : - - (SpritePath) - - the sprite path for the default sprite for the button - -
    • - - - - - -
    • - - hovered_sprite - - : - - (SpritePath) - - the sprite path for the sprite when the player hovers over the button - - (optional) -
    • - - - - - -
    • - - clicked_sprite - - : - - (SpritePath) - - the sprite path for the sprite when the player clicks the button - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_click_filter(filter[, ...]) -
    -
    -
    -
    - -

    Adds a click / mouse button filter to the button

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (table) - - ?string|table either a of mouse buttons or the first mouse button to filter, with a table true means allowed - -
    • - - - - - -
    • - - ... - - : - - (table) - - when filter is not a you can add the mouse buttons one after each other - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_key_filter(filter[, ...]) -
    -
    -
    -
    - -

    Adds a control key filter to the button

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (table) - - ?string|table either a of control keys or the first control keys to filter, with a table true means allowed - -
    • - - - - - -
    • - - ... - - : - - (table) - - when filter is not a you can add the control keys one after each other - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -

    Checkboxs

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_checkbox([name]) -
    -
    -
    -
    - -

    Creates a new checkbox element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new checkbox element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_radiobutton([name]) -
    -
    -
    -
    - -

    Creates a new radiobutton element define, has all functions checkbox has

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:add_as_option(option_set, option_name) -
    -
    -
    -
    - -

    Adds this radiobutton to be an option in the given option set (only one can be true at a time)

    -

    - - - Parameters: - -
      - - - - - -
    • - - option_set - - : - - (string) - - the name of the option set to add this element to - -
    • - - - - - -
    • - - option_name - - : - - (string) - - the name of this option that will be used to identify it - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:get_store(category, internal) -
    -
    -
    -
    - -

    Gets the stored value of the radiobutton or the option set if present

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - used to prevent stackover flow - -
    • - - -
    - - - - - Returns: -
      -
    • - (any) - the value that is stored for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:set_store(category, value, internal) -
    -
    -
    -
    - -

    Sets the stored value of the radiobutton or the option set if present

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - value - - : - - (boolean) - - the value to set for this define, must be valid for its type ie for checkbox etc - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - used to prevent stackover flow - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the value was set -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_option_set(callback, categorize) -
    -
    -
    -
    - -

    Registers a new option set that can be linked to radiobuttons (only one can be true at a time)

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the update callback when the value of the option set changes - callback param - value string - the new selected option for this option set - callback param - category string - the category that updated if categorize was used - -
    • - - - - - -
    • - - categorize - - : - - (function) - - the function used to convert an element into a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the name of this option set to be passed to add_as_option -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.draw_option_set(name, element) -
    -
    -
    -
    - -

    Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the option set to draw the radiobuttons of - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the parent element that the radiobuttons will be drawn to - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.reset_radiobuttons(element[, exclude][, recursive=false]) -
    -
    -
    -
    - -

    Sets all radiobutton in a element to false (unless excluded) and can act recursively

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the root gui element to start setting radio buttons from - -
    • - - - - - -
    • - - exclude - - : - - (table) - - ?string|table the name of the radiobutton to exclude or a of radiobuttons where true will set the state true - - (optional) -
    • - - - - - -
    • - - recursive - - : - - (number or boolean) - - if true will recur as much as possible, if a will recur that number of times - - (default: false) -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if successful -
    • -
    - - - - - - - - - -
    -
    -

    Dropdowns

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.new_dropdown([name]) -
    -
    -
    -
    - -

    Creates a new dropdown element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new dropdown element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.new_list_box([name]) -
    -
    -
    -
    - -

    Creates a new list box element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new list box element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:new_static_options(options[, ...], the) -
    -
    -
    -
    - -

    Adds new static options to the dropdown which will trigger the general callback

    -

    - - - Parameters: - -
      - - - - - -
    • - - options - - : - - (table) - - ?string|table either a of option strings or the first option string, with a table values are the options - -
    • - - - - - -
    • - - ... - - : - - (table) - - when options is not a you can add the options one after each other - - (optional) -
    • - - - - - -
    • - - the - - : - - (self) - - define to allow chaining - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:new_dynamic_options(callback) -
    -
    -
    -
    - -

    Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will run to get the options for the dropdown - callback param - player LuaPlayer - the player that the element is being drawn to - callback param - element LuaGuiElement - the element that is being drawn - callback return - table - the values of this table will be appended to the static options of the dropdown - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:add_option_callback(option, callback) -
    -
    -
    -
    - -

    Adds a case specific callback which will only run when that option is selected (general case still triggered)

    -

    - - - Parameters: - -
      - - - - - -
    • - - option - - : - - (string) - - the name of the option to trigger the callback on; if not already added then will be added as an option - -
    • - - - - - -
    • - - callback - - : - - (function) - - the function that will be called when that option is selected - callback param - player LuaPlayer - the player who owns the gui element - callback param - element LuaGuiElement - the element which is being effected - callback param - value string - the new option that has been selected - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.select_value(element, value) -
    -
    -
    -
    - -

    Selects the option from a dropdown or list box given the value rather than key

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that contains the option - -
    • - - - - - -
    • - - value - - : - - (string) - - the option to select from the dropdown - -
    • - - -
    - - - - - Returns: -
      -
    • - (number) - the key where the value was -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.get_selected_value(element) -
    -
    -
    -
    - -

    Returns the currently selected value rather than index

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element that you want to get the value of - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the value that is currently selected -
    • -
    - - - - - - - - - -
    -
    -

    Elem Buttons

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ElemButton.new_elem_button([name]) -
    -
    -
    -
    - -

    Creates a new elem button element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new elem button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ElemButton._prototype.set_type -
    -
    -
    -
    - -

    Sets the type of the elem button, the type is required so this must be called at least once

    +

    Called when the player opens a GUI.

    @@ -7231,13 +980,13 @@
  • - type + handler : - (string) + (function) - the type that this elem button is see factorio api + the event handler which will be called
  • @@ -7260,18 +1009,17 @@
    - # - ElemButton._prototype:set_default(value) + # + Gui._prototype_element.on_closed
    -

    Sets the default value for the elem button, this may be a function or a string

    +

    Called when the player closes the GUI they have open.

    - Parameters:
      @@ -7279,15 +1027,15 @@ -
    • +
    • - value + handler : - (string or function) + (function) - string a will be a static default and a function will be called when drawn to get the default + the event handler which will be called
    • @@ -7297,13 +1045,496 @@ - Returns: + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_click +
    +
    +
    +
    + +

    Called when LuaGuiElement is clicked.

    +

    + + +
      -
    • - (the) - element define to allow for chaining + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called +
    • + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_confirmed +
    +
    +
    +
    + +

    Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_checked_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_elem_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element value is changed (related to choose element buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_location_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_tab_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selected tab is changed (related to tabbed-panes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_selection_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_switch_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement switch state is changed (related to switches).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_text_change +
    +
    +
    +
    + +

    Called when LuaGuiElement text is changed by the player.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_value_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement slider value is changed (related to the slider element).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + @@ -7315,121 +1546,48 @@
    -

    Progress Bars

    +

    Top Flow

    - # - expcore.gui.core + # + toggle_top_flow
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.set_maximum(element, amount) -
    -
    -
    -
    - -

    Sets the maximum value that represents the end value of the progress bar

    +

    Button which toggles the top flow elements

    + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_top_flow(player) +
    +
    +
    +
    + +

    Gets the flow which contains the elements for the top flow

    +

    (player)

    + Parameters: @@ -7441,271 +1599,13 @@
  • - element + player : - (LuaGuiElement or string) + (LuaPlayer) - either a gui element or a registered define - -
  • - - - - - -
  • - - amount - - : - - (number) - - the amount to have set as the maximum - -
  • - - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.increment(element[, amount=1]) -
    -
    -
    -
    - -

    Increases the value of the progressbar, if a define is given all of its instances have incremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement or string) - - either a gui element or a registered define - -
    • - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.decrement(element[, amount=1]) -
    -
    -
    -
    - -

    Decreases the value of the progressbar, if a define is given all of its instances have decremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement or string) - - either a gui element or a registered define - -
    • - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.new_progressbar([name]) -
    -
    -
    -
    - -

    Creates a new progressbar element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new progressbar element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:set_default_maximum(amount) -
    -
    -
    -
    - -

    Sets the maximum value that represents the end value of the progress bar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to have set as the maximum + the player that you want to get the flow for
    • @@ -7718,8 +1618,8 @@ Returns: @@ -7729,20 +1629,23 @@ + Usage: +
      -- Geting your top element flow
      +local top_flow = Gui.get_top_flow(game.player)
    - # - ProgressBar._prototype:use_count_down([state=true]) + # + update_top_flow(player)
    -

    Will set the progress bar to start at 1 and trigger when it hits 0

    +

    Updates the visible states of all the elements on a players top flow

    @@ -7754,6 +1657,75 @@ +
  • + + player + + : + + (LuaPlayer) + + the player that you want to update the flow for + +
  • + + + + + + + + + + + + + + + Usage: +
    -- Update your flow
    +Gui.update_top_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_top_flow(player[, state]) +
    +
    +
    +
    + +

    Toggles the visible states of all the elements on a players top flow

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the flow for + +
    • + + + + +
    • state @@ -7762,453 +1734,7 @@ (boolean) - when true the bar will start filled, to be used with decrease - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:increment([amount=1][, category]) -
    -
    -
    -
    - -

    Increases the value of the progressbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - - - - -
    • - - category - - : - - (string) - - the category that is used with a store - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:increment_filtered([amount=1], filter) -
    -
    -
    -
    - -

    Increases the value of the progressbar, if the filter condition is met, does not work with store

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - - - - -
    • - - filter - - : - - (function) - - the filter to be used - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:decrement([amount=1][, category]) -
    -
    -
    -
    - -

    Decreases the value of the progressbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - - - - -
    • - - category - - : - - (string) - - the category that is used with a store - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:decrement_filtered([amount=1], filter) -
    -
    -
    -
    - -

    Decreases the value of the progressbar, if the filter condition is met, does not work with store

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - - - - -
    • - - filter - - : - - (function) - - the filter to be used - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:add_element(element[, maximum]) -
    -
    -
    -
    - -

    Adds an element into the list of instances that will are waiting to complete, does not work with store - note use store if you want persistent data, this only stores the elements not the values which they have

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that you want to add into the waiting to complete list - -
    • - - - - - -
    • - - maximum - - : - - (number) - - the maximum for this element if not given the default for this define is used - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:reset_element(element) -
    -
    -
    -
    - -

    Resets an element, or its store, to be back at the start, either 1 or 0

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that you want to reset the progress of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:event_counter([filter]) -
    -
    -
    -
    - -

    Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (function) - - when given will use filtered increment + if given then the state will be set to this state (optional)
    • @@ -8222,66 +1748,8 @@ Returns: - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:event_countdown([filter]) -
    -
    -
    -
    - -

    Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (function) - - when given will use filtered decrement - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the event handler + (boolean) + the new visible state of the top flow
    @@ -8291,22 +1759,29 @@ + Usage: +
    -- Toggle your flow
    +Gui.toggle_top_flow(game.player)
    +
    -- Open your top flow
    +Gui.toggle_top_flow(game.player,true)
    -

    Sliders

    +

    Left Flow

    - # - expcore.gui.core + # + hide_left_flow
    +

    Button which hides the elements in the left flow

    +

    @@ -8325,18 +1800,50 @@
    - # - expcore.gui.prototype + # + get_left_flow(player)
    +

    Gets the flow which contains the elements for the left flow

    +

    (player)

    + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the flow for + +
    • + + +
    + + Returns: + @@ -8344,70 +1851,23 @@ + Usage: +
    -- Geting your left element flow
    +local left_flow = Gui.get_left_flow(game.player)
    - # - expcore.gui.instances + # + hide_left_flow(player)
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Slider.new_slider([name]) -
    -
    -
    -
    - -

    Creates a new slider element define

    +

    Hides all left elements for a player

    @@ -8421,15 +1881,14 @@
  • - name + player : - (string) + (LuaPlayer) - the optional debug name that can be added + the player to hide the elements for - (optional)
  • @@ -8438,174 +1897,70 @@ - Returns: + + + + + + + + Usage: +
    -- Hide your left elements
    +Gui.hide_left_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_left_element(player, element_define[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of all a left element for a player

    +

    + + + Parameters: +
      -
    • + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the element for + +
    • + + + + + +
    • + + element_define + + : + (table) - the new slider element define -
    • -
    - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:set_range([min][, max]) -
    -
    -
    -
    - -

    Sets the range of a slider, if not used will use default values for a slider

    -

    - - - Parameters: - -
      - - - - - -
    • - - min - - : - - (number) - - the minimum value that the slider can take - - (optional) -
    • - - - - - -
    • - - max - - : - - (number) - - the maximum value that the slider can take - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:draw_label(element) -
    -
    -
    -
    - -

    Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the parent element that the label will be drawn to + the element that you want to toggle for the player
    • -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the new label element so that styles can be applied -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:enable_auto_draw_label([state=true]) -
    -
    -
    -
    - -

    Enables auto draw of the label, the label will share the same parent element as the slider

    -

    - - - Parameters: - -
      - - @@ -8617,2174 +1972,7 @@ (boolean) - when false will disable the auto draw of the label - - (default: true) - - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -

    Text

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Text.new_text_field([name]) -
    -
    -
    -
    - -

    Creates a new text field element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new text field element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text.new_text_box([name]) -
    -
    -
    -
    - -

    Creates a new text box element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new text box element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_selectable([state=true]) -
    -
    -
    -
    - -

    Sets the text box to be selectable

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_word_wrap([state=true]) -
    -
    -
    -
    - -

    Sets the text box to have word wrap

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_read_only([state=true]) -
    -
    -
    -
    - -

    Sets the text box to be read only

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -

    Instances

    -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.has_categories(name) -
    -
    -
    -
    - -

    Returns if a instance group has a serializer function; must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if there is a serializer function -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.is_registered(name) -
    -
    -
    -
    - -

    Returns if the given name is a registered instance group

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group you are testing - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the name is registered -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.register(name[, serializer]) -
    -
    -
    -
    - -

    Registers the name of an instance group to allow for storing element instances

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group; must to unique - -
    • - - - - - -
    • - - serializer - - : - - (function) - - function used to turn the element into a string - serializer param - element LuaGuiElement - the gui element to be turned into a string - serializer return - string - the category that the element will be added to like the player's name or force's name - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the name that was added so it can be used as a variable -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.add_element(name, element) -
    -
    -
    -
    - -

    Adds an element to the instance group under the correct category; must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to add the element to - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add the the instance group - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.get_elements_raw(name[, category]) -
    -
    -
    -
    - -

    Gets all element instances without first removing any invalid ones; used internally and must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string) - - the category to get the instance from, not needed when no serializer function - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances of which some may be invalid -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.get_valid_elements(name[, category][, callback]) -
    -
    -
    -
    - -

    Gets all valid element instances and has the option of running a callback on those that are valid

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string) - - the category to get the instances of, not needed when no serializer function - - (optional) -
    • - - - - - -
    • - - callback - - : - - (function) - - when given the callback will be ran on all valid elements - callback param - element LuaGuiElement - the current valid element - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances with all invalid ones removed -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.unregistered_add_element(name, category, element) -
    -
    -
    -
    - -

    A version of add_element that does not require the group to be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to add the element to - -
    • - - - - - -
    • - - category - - : - - (string or nil) - - the category to add the element to, can be nil but must still be given - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add to the instance group - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.unregistered_get_elements(name, category[, callback]) -
    -
    -
    -
    - -

    A version of get_elements that does not require the group to be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string or nil) - - the category to get the instances of, can be nil but must still be given - -
    • - - - - - -
    • - - callback - - : - - (function) - - when given will be called on all valid instances - callback param - element LuaGuiElement - the current valid element - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances with all invalid ones removed -
    • -
    - - - - - - - - - -
    -
    -

    Prototype

    -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.instances -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Constructor.event(event_name) -
    -
    -
    -
    - -

    Creates a new function to add functions to an event handler

    -

    - - - Parameters: - -
      - - - - - -
    • - - event_name - - : - - (string) - - the name of the event that callbacks will be added to - -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function used to register handlers -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.extend(new_prototype) -
    -
    -
    -
    - -

    Extents a prototype with the base functions of all gui prototypes, no metatables

    -

    - - - Parameters: - -
      - - - - - -
    • - - new_prototype - - : - - (table) - - the prototype that you want to add the functions to - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the same prototype but with the new functions added -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.store(callback) -
    -
    -
    -
    - -

    Creates a new function which adds a store to a gui define

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the function called when needing to update the value of an element - -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function that will add a store for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.setter(value_type, key[, second_key]) -
    -
    -
    -
    - -

    Creates a setter function that checks the type when a value is set

    -

    - - - Parameters: - -
      - - - - - -
    • - - value_type - - : - - (string) - - the type that the value should be when it is set - -
    • - - - - - -
    • - - key - - : - - (string) - - the key of the define that will be set - -
    • - - - - - -
    • - - second_key - - : - - (string) - - allows for setting of a key in a sub table - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function that will check the type and set the value -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:uid() -
    -
    -
    -
    - -

    Gets the uid for the element define

    -

    - - - - - - Returns: -
      -
    • - (string) - the uid of this element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype.debug_name -
    -
    -
    -
    - -

    Sets a debug alias for the define

    -

    - - - -
      - - - - - -
    • - - name - - : - - (string) - - the debug name for the element define that can be used to get this element define - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_caption -
    -
    -
    -
    - -

    Sets the caption for the element define

    -

    - - - -
      - - - - - -
    • - - caption - - : - - (string) - - the caption that will be drawn with the element - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_tooltip -
    -
    -
    -
    - -

    Sets the tooltip for the element define

    -

    - - - -
      - - - - - -
    • - - tooltip - - : - - (string) - - the tooltip that will be displayed for this element when drawn - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_pre_authenticator -
    -
    -
    -
    - -

    Sets an authenticator that blocks the draw function if check fails

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will be ran to test if the element should be drawn or not - callback param - LuaPlayer player - the player that the element is being drawn to - callback param - string define_name - the name of the define that is being drawn - callback return - boolean - false will stop the element from being drawn - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_post_authenticator -
    -
    -
    -
    - -

    Sets an authenticator that disables the element if check fails

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will be ran to test if the element should be enabled or not - callback param - LuaPlayer player - the player that the element is being drawn to - callback param - string define_name - the name of the define that is being drawn - callback return - boolean - false will disable the element - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.on_draw -
    -
    -
    -
    - -

    Registers a callback to the on_draw event

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - - callback param - LuaPlayer player - the player that the element was drawn to - callback param - LuaGuiElement element - the element that was drawn - callback param - any ... - any other params passed by the draw_to function - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.on_style_update -
    -
    -
    -
    - -

    Registers a callback to the on_style_update event

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - - callback param - LuaStyle style - the style that was changed and/or needs changing - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_style(style[, callback]) -
    -
    -
    -
    - -

    Sets the style for the element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - style - - : - - (string) - - the style that will be used for this element when drawn - -
    • - - - - - -
    • - - callback - - : - - (function) - - function is called when element is drawn to alter its style - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the element define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_embedded_flow(state) -
    -
    -
    -
    - -

    Sets the element to be drawn inside a nameless flow, can be given a name using a function

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean or function) - - when true a padless flow is created to contain the element - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the element define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:raise_event(event_name, ...) -
    -
    -
    -
    - -

    Raises a custom event for this define, any number of params can be given

    -

    - - - Parameters: - -
      - - - - - -
    • - - event_name - - : - - (string) - - the name of the event that you want to raise - -
    • - - - - - -
    • - - ... - - : - - (any) - - any params that you want to pass to the event - -
    • - - -
    - - - - - Returns: -
      -
    • - (number) - the number of handlers that were registered -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:draw_to(element) -
    -
    -
    -
    - -

    The main function for defines, when called will draw an instance of this define to the given element - what is drawn is based on the data in draw_data which is set using other functions

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that the define will draw a instance of its self onto - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - Prototype:get_store(category) -
    -
    -
    -
    - -

    Gets the value in this elements store, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - -
    - - - - - Returns: -
      -
    • - (any) - the value that is stored for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_store(category, value) -
    -
    -
    -
    - -

    Sets the value in this elements store, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - value - - : - - (any) - - the value to set for this define, must be valid for its type ie for checkbox etc - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the value was set -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:clear_store([category]) -
    -
    -
    -
    - -

    Sets the value in this elements store to nil, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - the category to get such as player name or force name + if given then the state will be set to this state (optional)
    • @@ -10799,7 +1987,7 @@
      • (boolean) - true if the value was set + the new visible state of the element
      @@ -10809,134 +1997,11 @@ - - -
    -
    -

    Test

    -
    -
    -
    -
    - # - expcore.gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.common -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - + Usage: +
    -- Toggle your example button
    +Gui.toggle_top_flow(game.player,example_flow_with_button)
    +
    -- Open your example button
    +Gui.toggle_top_flow(game.player,example_flow_with_button,true)
    @@ -10955,7 +2020,7 @@ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index 00b18e72..d684f92e 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 3f2be0c2..2e261b19 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index 1d8ad527..c977f109 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1464,7 +1464,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 23573d85..ea78d5a3 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index da3e4e7f..d1ca6a0e 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index cd01fbd5..21253ddc 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 7a48f8dc..3dc31aa5 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 44170d3b..454a6901 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -632,7 +632,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 196ec539..a4647a51 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -837,7 +837,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index 4601a828..cd8ed91c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -57,10 +57,7 @@ Gui Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started +- Used to define new gui elements and gui event handlers Permissions-Groups @@ -514,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 75103f1b..2b73d7da 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 51092a84..fc152587 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index 31b33120..d3a78a5d 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index 3d92af43..661eb841 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index e54ef510..fff59dbb 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 87ca10a6..663e8dcb 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index e9fcbde4..26e97c55 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index 12045d90..c192045d 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 59d49a86..51c8fb76 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 68e88fea..5708101d 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 5ffe1e8b..2c9404e6 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index cfc96b04..f1a4a0be 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index fcf4b838..c22b2df7 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 1eab766f..6901e6e6 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 46789283..e472eb59 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -228,26 +228,29 @@

    ExpGaming Scenario Repository

    ## Explosive Gaming -

    Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible with in our reset schedule. Although these server tend to the more experienced players our server are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in factorio (ExpGaming S1). +

    Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our Factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible within our reset schedule. Although these servers tend to attract the more experienced players, our servers are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in Factorio (ExpGaming S1, ExpGaming S2, etc.).

    ## Use and Installation

    1) Download this [git repository](https://github.com/explosivegaming/scenario/archive/master.zip) for the stable release. The dev branch can be found [here](https://github.com/explosivegaming/scenario/archive/dev.zip) for those who want the latest features. See [releases](#releases) for other release branches. -

    2) Extract the downloaded zip file from the branch you downloaded into factorio's scenario directory: +

    2) Extract the downloaded zip file from the branch you downloaded into Factorio's scenario directory: * Windows: `%appdata%\Factorio\scenarios` * Linux: `~/.factorio/scenarios`

    3) Within the scenario you can find `./config/_file_loader.lua` which contains a list of all the modules that will be loaded by the scenario; simply comment out (or remove) features you do not want but note that some modules may load other modules as dependencies even when removed from the list.

    4) More advanced users may want to play with the other configs files within `./config` but please be aware that some of the config files will require a basic understanding of lua while others may just be a list of values. -

    5) Once you have made any config changes that you wish to make open factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. -

    6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash so if any features don't work as expected then it may be returning an error in the log, please report these errors to [the issues page](issues). +

    5) Once you have made any config changes that you wish to make open Factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. +

    6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash, so if any features do not work as expected then it may be returning an error in the log. +Please report these errors to [the issues page](issues).

    ## Contributing -

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes:

    * New features should have the branch names: `feature/feature-name` -* New features are merged into `dev` after it has been completed. -* After a number of features have been added a release branch is made: `release/X.Y.0`; this branch should have no new features and only bug fixes or localization. -* A release is merged into `master` on the following friday in time for the the weekly reset. -* Patches may be named `patch/X.Y.Z` and fill be merged into `master` and `dev` when appropriate. +* New features are merged into `dev` after it has been completed, this can be done through a pull request. +* After a number of features have been added a release branch is made: `release/X.Y.0` +* Bug fixes and localization can be made to the release branch with a pull request rather than into dev. +* A release is merged into `master` on the following friday after it is considered stable. +* Patches may be named `patch/X.Y.Z` and will be merged into `dev` and then `master` when appropriate.

    ## Releases

    | Scenario Version* | Version Name | Factorio Version** | |---|---|---| +| [v5.10][s5.10] | Data Store Rewrite | [v0.17.71][f0.17.71] | | [v5.9][s5.9] | Control Modules and Documentation | [v0.17.63][f0.17.63] | | [v5.8][s5.8] | Home and Chat Bot | [v0.17.47][f0.17.49] | | [v5.7][s5.7] | Warp System | [v0.17.47][f0.17.47] | @@ -265,7 +268,8 @@ | [v0.1][s0.1] | First Tracked Version | [v0.14][f0.14] |

    \* Scenario patch versions have been omitted.

    \*\* Factorio versions show the version they were made for, often the minimum requirement. -

    [s5.9]: https://github.com/explosivegaming/scenario/releases/tag/5.9.0 +

    [s5.10]: https://github.com/explosivegaming/scenario/releases/tag/5.10.0 +[s5.9]: https://github.com/explosivegaming/scenario/releases/tag/5.9.0 [s5.8]: https://github.com/explosivegaming/scenario/releases/tag/5.8.0 [s5.7]: https://github.com/explosivegaming/scenario/releases/tag/5.7.0 [s5.6]: https://github.com/explosivegaming/scenario/releases/tag/5.6.0 @@ -280,7 +284,8 @@ [s2.0]: https://github.com/explosivegaming/scenario/releases/tag/v2.0 [s1.0]: https://github.com/explosivegaming/scenario/releases/tag/v1.0 [s0.1]: https://github.com/explosivegaming/scenario/releases/tag/v0.1 -

    [f0.17.63]: https://wiki.factorio.com/Version_history/0.17.0#0.17.63 +

    [f0.17.71]: https://wiki.factorio.com/Version_history/0.17.0#0.17.71 +[f0.17.63]: https://wiki.factorio.com/Version_history/0.17.0#0.17.63 [f0.17.49]: https://wiki.factorio.com/Version_history/0.17.0#0.17.49 [f0.17.47]: https://wiki.factorio.com/Version_history/0.17.0#0.17.47 [f0.17.44]: https://wiki.factorio.com/Version_history/0.17.0#0.17.44 @@ -333,7 +338,7 @@ generated by LDoc

    diff --git a/expcore/gui.lua b/expcore/gui.lua index 82257d43..8e25a7c3 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -1,284 +1,489 @@ --[[-- Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started - @core Gui - @alias Gui +- Used to define new gui elements and gui event handlers +@core Gui +@alias Gui + +@usage-- Defining a button that prints the player's name +local example_button = +Gui.new_element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(event) + local player = event.player + player.print(player.name) +end) + +@usage-- Defining using a custom function +local example_flow_with_button = +Gui.new_element(function(event_trigger,parent) + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } + + return element +end) +:on_click(function(event) + local player = event.player + player.print(player.name) +end) + +@usage-- Drawing an element +local exmple_button_element = example_button(parent) +local example_flow_with_button = example_flow_with_button(parent) + ]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core +local Event = require 'utils.event' --- @dep utils.event +local mod_gui = require 'mod-gui' --- @dep mod-gui ---[[ - Core +local Gui = { + --- The current highest uid that is being used, will not increase during runtime + -- @field uid + uid = 0, + --- Contains the uids of the elements that will show on the top flow and the auth function + -- @table top_elements + top_elements = {}, + --- Contains the uids of the elements that will show on the left flow and the open on join function + -- @table left_elements + left_elements = {}, + --- Table of all the elements which have been registed with the draw function and event handlers + -- @table defines + defines = {}, + --- An index used for debuging to find the file where different elements where registered + -- @table file_paths + file_paths = {}, + --- The element prototype which is returned from Gui.new_element + -- @table _prototype_element + _prototype_element = {}, + --- The prototype metatable applied to new element defines + -- @table _mt_element + _mt_element = { + __call = function(self,parent,...) + return self._draw(self.name,parent,...) + end + } +} - Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype - Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to +Gui._mt_element.__index = Gui._prototype_element - Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value - Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value - Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value +--- Element Define. +-- @section elementDefine - Gui.toggle_enabled(element) --- Will toggle the enabled state of an element - Gui.toggle_visible(element) --- Will toggle the visibility of an element - Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element - Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style - Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into - Gui.destroy_if_valid(element) --- Destroys an element but tests for it being present and valid first - Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size - Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area +--[[-- Base function used to define new elements, can be used with a table or with a function +@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element - Prototype Constructor +@usage-- Defining an element with a table +local example_button = +Gui.new_element{ + type = 'button', + caption = 'Example Button' +} - Constructor.event(event_name) --- Creates a new function to add functions to an event handler - Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables - Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define - Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set +@usage-- Defining an element with a function +local example_flow_with_button = +Gui.new_element(function(event_trigger,parent) + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } - Base Prototype + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } - Prototype:uid() --- Gets the uid for the element define - Prototype:debug_name(value) --- Sets a debug alias for the define - Prototype:set_caption(value) --- Sets the caption for the element define - Prototype:set_tooltip(value) --- Sets the tooltip for the element define - Prototype:set_style(style,callback) --- Sets the style for the element define - Prototype:set_embedded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function + return element +end) - Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails - Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails - - Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given - Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element - - Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used - Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used - Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used ]] +function Gui.new_element(element_define) + -- Set the metatable to allow access to register events + local element = setmetatable({}, Gui._mt_element) -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances -Gui.new_instance_group = Instances.registers -Gui.get_instances = Instances.get_elements -Gui.add_instance = Instances.get_elements -Gui.update_instances = Instances.apply_to_elements -Gui.classes.instances = Instances ---[[ - Instances.has_categories(name) --- Returns if a instance group has a categorise function; must be registered - Instances.is_registered(name) --- Returns if the given name is a registered instance group - Instances.register(name,categorise) --- Registers the name of an instance group to allow for storing element instances + -- Increment the uid counter + local uid = Gui.uid + 1 + Gui.uid = uid + local name = tostring(uid) + element.name = name - Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered - Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered - Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid + -- Add the defination function + if type(element_define) == 'table' then + element_define.name = name + element._draw = function(_,parent) + return parent.add(element_define) + end + else + element._draw = element_define + end + + -- Add the define to the base module + local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) + Gui.file_paths[name] = file_path + Gui.defines[name] = element + + -- Return the element so event handers can be accessed + return element +end + +--[[-- Adds an element to be drawn to the top flow when a player joins +@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible + +@usage-- Adding the example button +example_button:add_to_top_flow(function(player) + -- example button will only show when game time is less than 1 minute + return player.online_time < 3600 +end) - Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered - Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered ]] +function Gui._prototype_element:add_to_top_flow(authenticator) + Gui.top_elements[self.name] = authenticator or true +end -local Button = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -Gui.new_button = Button.new_button -Gui.classes.button = Button ---[[ - Button.new_button(name) --- Creates a new button element define +--[[-- Adds an element to be drawn to the left flow when a player joins +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible - Button._prototype:on_click(player,element) --- Registers a handler for when the button is clicked - Button._prototype:on_left_click(player,element) --- Registers a handler for when the button is clicked with the left mouse button - Button._prototype:on_right_click(player,element) --- Registers a handler for when the button is clicked with the right mouse button +@usage-- Adding the example button +example_flow_with_button:add_to_left_flow(true) - Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) --- Adds sprites to a button making it a sprite button - Button._prototype:set_click_filter(filter,...) --- Adds a click / mouse button filter to the button - Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button ]] +function Gui._prototype_element:add_to_left_flow(open_on_join) + Gui.left_elements[self.name] = open_on_join or false +end -local Checkbox = require 'expcore.gui.elements.checkbox' --- @dep expcore.gui.elements.checkbox -Gui.new_checkbox = Checkbox.new_checkbox -Gui.new_radiobutton = Checkbox.new_radiobutton -Gui.new_radiobutton_option_set = Checkbox.new_option_set -Gui.draw_option_set = Checkbox.draw_option_set -Gui.classes.checkbox = Checkbox ---[[ - Checkbox.new_checkbox(name) --- Creates a new checkbox element define - Checkbox._prototype_checkbox:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_checkbox:on_store_update(callback) --- Registers a handler for when the stored value updates +-- This function is called for event event +local function general_event_handler(event) + -- Check the element is valid + local element = event.element + if not element or not element.valid then + return + end - Checkbox.new_radiobutton(name) --- Creates a new radiobutton element define - Checkbox._prototype_radiobutton:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates - Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time) + -- Get the event handler for this element + local handlers = Gui.defines[element.name] + local handler = handlers and handlers[event.name] + if not handler then + return + end - Checkbox.new_option_set(callback,categorize) --- Registers a new option set that can be linked to radiobuttons (only one can be true at a time) - Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) + -- Get the player for this event + local player = game.players[event.player_index] + if not player or not player.valid then + return + end + event.player = player + + local success, err = pcall(handler,event) + if not success then + error('There as been an error with an event handler for a gui element:\n\t'..err) + end +end + +-- This function returns the event handler adder and registeres the general handler +local function event_handler_factory(event_name) + Event.add(event_name, general_event_handler) + + return function(self,handler) + self[event_name] = handler + return self + end +end + +--- Element Events. +-- @section elementEvents + +--- Called when the player opens a GUI. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) + +--- Called when the player closes the GUI they have open. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) + +--- Called when LuaGuiElement is clicked. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) + +--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) + +--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) + +--- Called when LuaGuiElement element value is changed (related to choose element buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) + +--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) + +--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) + +--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) + +--- Called when LuaGuiElement switch state is changed (related to switches). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) + +--- Called when LuaGuiElement text is changed by the player. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_text_change = event_handler_factory(defines.events.on_gui_text_changed) + +--- Called when LuaGuiElement slider value is changed (related to the slider element). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) + +--- Top Flow. +-- @section topFlow + +--- Button which toggles the top flow elements +-- @element toggle_top_flow +local toggle_top_flow = +Gui.new_element(function(event_trigger,parent) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'button', + style = mod_gui.button_style, + caption = '<', + tooltip = {'gui_util.button_tooltip'} + } + + -- Change its style + local style = element.style + style.width = 18 + style.height = 36 + style.padding = 0 + style.font = 'default-small-bold' + + -- Return the element + return element +end) +:on_click(function(event) + Gui.toggle_top_flow(event.player) +end) + +--[[-- Gets the flow which contains the elements for the top flow +@function Gui.get_top_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the top element flow + +@usage-- Geting your top element flow +local top_flow = Gui.get_top_flow(game.player) - Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobuttons in a element to false (unless excluded) and can act recursively ]] +Gui.get_top_flow = mod_gui.get_button_flow -local Dropdown = require 'expcore.gui.elements.dropdown' --- @dep expcore.gui.elements.dropdown -Gui.new_dropdown = Dropdown.new_dropdown -Gui.new_list_box = Dropdown.new_list_box -Gui.classes.dropdown = Dropdown ---[[ - Dropdown.new_dropdown(name) --- Creates a new dropdown element define - Dropdown.new_list_box(name) --- Creates a new list box element define +--[[-- Updates the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to update the flow for - Dropdown._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Dropdown._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates +@usage-- Update your flow +Gui.update_top_flow(game.player) - Dropdown._prototype:new_static_options(options,...) --- Adds new static options to the dropdown which will trigger the general callback - Dropdown._prototype:new_dynamic_options(callback) --- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) - Dropdown._prototype:add_option_callback(option,callback) --- Adds a case specific callback which will only run when that option is selected (general case still triggered) - - Dropdown.select_value(element,value) --- Selects the option from a dropdown or list box given the value rather than key - Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index ]] +function Gui.update_top_flow(player) + local top_flow = Gui.get_top_flow(player) + local toggle_button = top_flow[toggle_top_flow.name] + local is_visible = toggle_button.caption == '<' -local Slider = require 'expcore.gui.elements.slider' --- @dep expcore.gui.elements.slider -Gui.new_slider = Slider.new_slider -Gui.classes.slider = Slider ---[[ - Slider.new_slider(name) --- Creates a new slider element define + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + -- Ensure the element exists + local element = top_flow[name] + if not element then + element = Gui.defines[name](top_flow) + end - Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates + -- Set the visible state + element.visible = is_visible and authenticator(player) or false + end +end + +--[[-- Toggles the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to toggle the flow for +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the top flow + +@usage-- Toggle your flow +Gui.toggle_top_flow(game.player) + +@usage-- Open your top flow +Gui.toggle_top_flow(game.player,true) - Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider - Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player - Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider ]] +function Gui.toggle_top_flow(player,state) + local top_flow = Gui.get_top_flow(player) + local toggle_button = top_flow[toggle_top_flow.name] + local new_state = state or toggle_button.caption == '>' -local Text = require 'expcore.gui.elements.text' --- @dep expcore.gui.elements.text -Gui.new_text_filed = Text.new_text_field -Gui.new_text_box = Text.new_text_box -Gui.classes.text = Text ---[[ - Text.new_text_field(name) --- Creates a new text field element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + top_flow[name].visible = new_state and authenticator(player) or false + end + + -- Change the style of the toggle button + if new_state then + toggle_button.caption = '<' + toggle_button.style.height = 34 + else + toggle_button.caption = '>' + toggle_button.style.height = 24 + end + + return new_state +end + +--- Left Flow. +-- @section leftFlow + +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.new_element(function(event_trigger,parent) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'button', + style = mod_gui.button_style, + caption = '<', + tooltip = {'expcore-gui.left-button-tooltip'} + } + + -- Change its style + local style = element.style + style.width = 18 + style.height = 36 + style.padding = 0 + style.font = 'default-small-bold' + + -- Return the element + return element +end) +:on_click(function(event) + Gui.hide_left_flow(event.player) +end) + +--[[-- Gets the flow which contains the elements for the left flow +@function Gui.get_left_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the left element flow + +@usage-- Geting your left element flow +local left_flow = Gui.get_left_flow(game.player) - Text.new_text_box(name) --- Creates a new text box element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - Text._prototype_box:set_selectable(state) --- Sets the text box to be selectable - Text._prototype_box:set_word_wrap(state) --- Sets the text box to have word wrap - Text._prototype_box:set_read_only(state) --- Sets the text box to be read only ]] +Gui.get_left_flow = mod_gui.get_frame_flow -local ElemButton = require 'expcore.gui.elements.elem-button' --- @dep expcore.gui.elements.elem-button -Gui.new_elem_button = ElemButton.new_elem_button -Gui.classes.elem_button = ElemButton ---[[ - ElemButton.new_elem_button(name) --- Creates a new elem button element define +--[[-- Hides all left elements for a player +@tparam LuaPlayer player the player to hide the elements for - ElemButton._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - ElemButton._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates +@usage-- Hide your left elements +Gui.hide_left_flow(game.player) - ElemButton._prototype:set_type(type) --- Sets the type of the elem button, the type is required so this must be called at least once - ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string ]] +function Gui.hide_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow[hide_left_flow.name] -local ProgressBar = require 'expcore.gui.elements.progress-bar' --- @dep expcore.gui.elements.progress-bar -Gui.new_progressbar = ProgressBar.new_progressbar -Gui.set_progressbar_maximum = ProgressBar.set_maximum -Gui.increment_progressbar = ProgressBar.increment -Gui.decrement_progressbar = ProgressBar.decrement -Gui.classes.progressbar = ProgressBar ---[[ - ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar.increment(element,amount) --- Increases the value of the progressbar, if a define is given all of its instances are incremented - ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances are decreased + -- Set the visible state of all elements in the flow + hide_button.visible = false + for name,_ in pairs(Gui.left_elements) do + left_flow[name].visible = false + end +end - ProgressBar.new_progressbar(name) --- Creates a new progressbar element define - ProgressBar._prototype:set_maximum(amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar._prototype:use_count_down(state) --- Will set the progress bar to start at 1 and trigger when it hits 0 - ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar - ProgressBar._prototype:increment_filtered(amount,filter) --- Increases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar - ProgressBar._prototype:decrement_filtered(amount,filter) --- Decreases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:add_element(element,maximum) --- Adds an element into the list of instances that will are waiting to complete, does not work with store - ProgressBar._prototype:reset_element(element) --- Resets an element, or its store, to be back at the start, either 1 or 0 +--[[-- Toggles the visible state of all a left element for a player +@tparam LuaPlayer player the player that you want to toggle the element for +@tparam table element_define the element that you want to toggle for the player +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the element + +@usage-- Toggle your example button +Gui.toggle_top_flow(game.player,example_flow_with_button) + +@usage-- Open your example button +Gui.toggle_top_flow(game.player,example_flow_with_button,true) - ProgressBar._prototype:on_complete(callback) --- Triggers when a progress bar element completes (hits 0 or 1) - ProgressBar._prototype:on_complete(callback) --- Triggers when a store value completes (hits 0 or 1) - ProgressBar._prototype:event_counter(filter) --- Event handler factory that counts up by 1 every time the event triggers, can filter which elements are incremented - ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggers, can filter which elements are decremented ]] +function Gui.toggle_left_element(player,element_define,state) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow[hide_left_flow.name] -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -Gui.new_toolbar_button = Toolbar.new_button -Gui.add_button_to_toolbar = Toolbar.add_button -Gui.update_toolbar = Toolbar.update -Gui.classes.toolbar = Toolbar ---[[ - Toolbar.new_button(name) --- Adds a new button to the toolbar - Toolbar.add_button(button) --- Adds an existing buttton to the toolbar - Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return -]] + -- Set the visible state + local element = left_flow[element_define.name] + local new_state = state or not element.visible + element.visible = new_state -local LeftFrames = require 'expcore.gui.concepts.left' --- @dep expcore.gui.concepts.left -Gui.get_left_frame_flow = LeftFrames.get_flow -Gui.toggle_left_frame = LeftFrames.toggle_frame -Gui.new_left_frame = LeftFrames.new_frame -Gui.classes.left_frames = LeftFrames ---[[ - LeftFrames.get_flow(player) --- Gets the left frame flow for a player - LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name - LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.toggle_frame(name,player,state) --- Toggles the visibility of a left frame, or sets its visibility state + -- Check if the hide button should be visible + local show_hide_button = false + for name,_ in pairs(Gui.left_elements) do + if left_flow[name].visible then + show_hide_button = true + break + end + end + hide_button.visible = show_hide_button - LeftFrames.new_frame(permission_name) --- Creates a new left frame define - LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames._prototype:set_direction(direction) --- Sets the direction of the frame, either vertical or horizontal - LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow - LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible - LeftFrames._prototype:toggle(player) --- Toggles the visibility of the left frame + return new_state +end - LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw - LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update - LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame - LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw +-- Draw the two flows when a player joins +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] - LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame - LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it - LeftFrames._prototype:on_player_toggle(player,frame) --- Triggered when the player toggle the left frame - LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] + -- Draw the top flow + local top_flow = Gui.get_top_flow(player) + toggle_top_flow(top_flow) + Gui.update_top_flow(player) -local CenterFrames = require 'expcore.gui.concepts.center' --- @dep expcore.gui.concepts.center -Gui.get_center_flow = CenterFrames.get_flow -Gui.toggle_center_frame = CenterFrames.toggle_frame -Gui.draw_center_frame = CenterFrames.draw_frame -Gui.redraw_center_frame = CenterFrames.redraw_frames -Gui.new_center_frame = CenterFrames.new_frame -Gui.classes.center_frames = CenterFrames ---[[ - CenterFrames.get_flow(player) --- Gets the center flow for a player - CenterFrames.clear_flow(player) --- Clears the center flow for a player - CenterFrames.draw_frame(player,name) --- Draws the center frame for a player, if already open then will do nothing - CenterFrames.redraw_frame(player,name) --- Draws the center frame for a player, if already open then will destroy it and redraw - CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open + -- Draw the left flow + local left_flow = Gui.get_left_flow(player) + local hide_left = hide_left_flow(left_flow) - CenterFrames.new_frame(permission_name) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame - CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) - CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) - CenterFrames._prototype:toggle_frame(player) --- Toggles if the frame is open, if open it will close it and if closed it will open it - CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] + -- Draw the elements on the left flow + local show_hide_left = false + for name,open_on_join in pairs(Gui.left_elements) do + local left_element = Gui.defines[name](left_flow) -local PopupFrames = require 'expcore.gui.concepts.popups' --- @dep expcore.gui.concepts.popups -Gui.get_popup_flow = PopupFrames.get_flow -Gui.open_popup = PopupFrames.open -Gui.new_popup = PopupFrames.new_popup -Gui.classes.popup_frames = PopupFrames ---[[ - PopupFrames.get_flow(player) --- Gets the left flow that contains the popup frames - PopupFrames.open(define_name,player,open_time,...) --- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function + -- Check if the element should be visible + local visible = type(open_on_join) == 'boolean' and open_on_join or false + if type(open_on_join) == 'function' then + local success, err = pcall(open_on_join,player) + if not success then + error('There as been an error with an open on join hander for a gui element:\n\t'..err) + end + visible = err + end - PopupFrames.close_progress --- Progress bar which when depleted will close the popup frame - PopupFrames.close_button --- A button which can be used to close the gui before the timer runs out + left_element.visible = visible + if visible then + show_hide_left = true + end + end - PopupFrames.new_popup(name) --- Creates a new popup frame define - PopupFrames._prototype:set_default_open_time(amount) --- Sets the default open time for the popup, will be used if non is provided with open - PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function -]] + hide_left.visible = show_hide_left +end) return Gui \ No newline at end of file diff --git a/expcore/gui/concepts/center.lua b/expcore/gui/concepts/center.lua deleted file mode 100644 index ffbc3f9f..00000000 --- a/expcore/gui/concepts/center.lua +++ /dev/null @@ -1,198 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Center Guis. --- Gui structure define for center gui frames --- @section center - ---[[ ->>>> Functions - CenterFrames.get_flow(player) --- Gets the center flow for a player - CenterFrames.clear_flow(player) --- Clears the center flow for a player - CenterFrames.draw_frame(player,name) --- Draws the center frame for a player, if already open then will do nothing - CenterFrames.redraw_frame(player,name) --- Draws the center frame for a player, if already open then will destroy it and redraw - CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open - - CenterFrames.new_frame(permission_name) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame - CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) - CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) - CenterFrames._prototype:toggle_frame(player) --- Toggles if the frame is open, if open it will close it and if closed it will open it - CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -local Game = require 'utils.game' --- @dep utils.game - -local CenterFrames = { - _prototype = Prototype.extend{ - on_creation = Prototype.event - } -} - ---- Gets the center flow for a player --- @tparam LuaPlayer player the player to get the flow for --- @treturn LuaGuiElement the center flow -function CenterFrames.get_flow(player) - player = Game.get_player_from_any(player) - return player.gui.center -end - ---- Clears the center flow for a player --- @tparam LuaPlayer player the player to clear the flow for -function CenterFrames.clear_flow(player) - local flow = CenterFrames.get_flow(player) - flow.clear() -end - ---- Draws the center frame for a player, if already open then will do nothing --- @tparam LuaPlayer player the player that will have the frame drawn --- @tparam string name the name of the hui that will drawn --- @treturn LuaGuiElement the new frame that was made -function CenterFrames.draw_frame(player,name) - local define = Gui.get_define(name,true) - if define then - return define:draw_frame(player) - end -end - ---- Draws the center frame for a player, if already open then will destroy it and redraw --- @tparam LuaPlayer player the player that will have the frame drawn --- @tparam string name the name of the hui that will drawn --- @treturn LuaGuiElement the new frame that was made -function CenterFrames.redraw_frame(player,name) - local define = Gui.get_define(name,true) - if define then - return define:draw_frame(player) - end -end - ---- Toggles if the frame is currently open or not, will open if closed and close if open --- @tparam LuaPlayer player the player that will have the frame toggled --- @tparam string name the name of the hui that will be toggled --- @tparam[opt] boolean state when set will force a state for the frame --- @treturn boolean if the frame if no open or closed -function CenterFrames.toggle_frame(player,name,state) - local define = Gui.get_define(name,true) - if define then - if state == true then - define:draw_frame(player) - return true - elseif state == false then - local flow = CenterFrames.get_flow(player) - if flow[define.name..'-frame'] then - flow[define.name..'-frame'].destroy() - end - return false - else - return define:toggle_frame(player) - end - end -end - ---- Creates a new center frame define --- @tparam string permission_name the name that can be used with the permission system --- @treturn table the new center frame define -function CenterFrames.new_frame(permission_name) - local self = Toolbar.new_button(permission_name) - - self:on_click(function(player,element) - self:toggle_frame(player) - end) - - local mt = getmetatable(self) - mt.__index = CenterFrames._prototype - mt.__call = self.event_handler - - Gui.on_custom_close(self.name..'-frame',function(event) - local element = event.element - if element and element.valid then element.destroy() end - end) - - return self -end - ---- Sets the frame to be the current active gui when opened and closes all other frames --- @tparam[opt=true] boolean state when true will auto close other frames and set this frame as player.opened -function CenterFrames._prototype:set_auto_focus(state) - if state == false then - self.auto_focus = false - else - self.auto_focus = true - end -end - ---- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) --- @tparam LuaPlayer player the player to draw the frame for --- @treturn LuaGuiElement the new frame that was drawn -function CenterFrames._prototype:draw_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - return flow[self.name..'-frame'] - end - - if self.auto_focus then - flow.clear() - end - - local frame = flow.add{ - type='frame', - name=self.name..'-frame' - } - - if self.auto_focus then - player.opened = frame - end - - self:raise_event('on_creation',player,frame) - - return frame -end - ---- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) --- @tparam LuaPlayer player the player to draw the frame for --- @treturn LuaGuiElement the new frame that was drawn -function CenterFrames._prototype:redraw_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - flow[self.name..'-frame'].destroy() - end - - return self:draw_frame(player) -end - ---- Toggles if the frame is open, if open it will close it and if closed it will open it --- @tparam LuaPlayer player the player to draw the frame for --- @treturn boolean with the gui frame is now open -function CenterFrames._prototype:toggle_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - flow[self.name..'-frame'].destroy() - return false - else - self:draw_frame(player) - return true - end -end - ---- Creates an event handler that will trigger one of its functions, use with Event.add --- @tparam[opt=update] string action the action to take on this event -function CenterFrames._prototype:event_handler(action) - action = action or 'update' - return function(event) - local player = Game.get_player_by_index(event.player_index) - self[action](self,player) - end -end - -return CenterFrames \ No newline at end of file diff --git a/expcore/gui/concepts/left.lua b/expcore/gui/concepts/left.lua deleted file mode 100644 index e827f36a..00000000 --- a/expcore/gui/concepts/left.lua +++ /dev/null @@ -1,322 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Left Guis. --- Gui structure define for left frames --- @section left - ---[[ ->>>> Example formating - - -- first we add config that relates to the button on the toolbar, all normal button functions are present - local left_frame = - Gui.new_left_frame('test-left-frame') - :set_caption('Test Left Gui') - :set_post_authenticator(function(player,button_name) - return global.show_test_gui - end) - - -- then we add the config for the left frame, on_draw should draw the gui from an empty frame, on_update should take a frame from on_draw on edit it - :set_open_by_default() - :on_draw(function(_player,frame) - for _,player in pairs(game.connected_players) do - frame.add{ - type='label', - caption=player.name - } - end - end) - - -- now we can use the action factory to call events on the gui, actions are: 'update', 'update_all', 'redraw', 'redraw_all' - Event.add(defines.events.on_player_joined_game,left_frame 'update_all') - Event.add(defines.events.on_player_left_game,left_frame 'update_all') - ->>>> Functions - LeftFrames.get_flow(player) --- Gets the left frame flow for a player - LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name - LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.toggle_frame(name,player,state) --- Toggles the visibility of a left frame, or sets its visibility state - - LeftFrames.new_frame(permission_name) --- Creates a new left frame define - LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames._prototype:set_direction(direction) --- Sets the direction of the frame, either vertical or horizontal - LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow - LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible - LeftFrames._prototype:toggle(player) --- Toggles the visibility of the left frame - - LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw - LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update - LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame - LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw - - LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame - LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it - LeftFrames._prototype:on_player_toggle(player,frame) --- Is triggered when the player presses the toggle button - LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -local Buttons = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Game = require 'utils.game' --- @dep utils.game -local Event = require 'utils.event' --- @dep utils.event - -local LeftFrames = { - frames={}, - _prototype=Prototype.extend{ - on_creation = Prototype.event, - on_update = Prototype.event, - on_player_toggle = Prototype.event - } -} -setmetatable(LeftFrames._prototype, { - __index = Buttons._prototype -}) - ---- Gets the left frame flow for a player --- @tparam LuaPlayer player the player to get the flow of --- @treturn LuaGuiElement the left frame flow for the player -function LeftFrames.get_flow(player) - player = Game.get_player_from_any(player) - return mod_gui.get_frame_flow(player) -end - ---- Gets one frame from the left flow by its name --- @tparam string name the name of the gui frame to get --- @tparam LuaPlayer player the player to get the frame of --- @treturn LuaGuiElement the frame in the left frame flow with that name -function LeftFrames.get_frame(name,player) - local define = LeftFrames.frames[name] - if not define then - return error('Left Frame '..name..' is not defined.',2) - end - return define:get_frame(player) -end - ---- Gets all open frames for a player, if non are open it will remove the close all button --- @tparam LuaPlayer player the player to get the flow of --- @treturn table contains all the open (and registered) frames for the player -function LeftFrames.get_open(player) - local open = {} - local flow = LeftFrames.get_flow(player) - - for _,define in pairs(LeftFrames.frames) do - if define:is_open(player) then - table.insert(open,define) - end - end - - flow[LeftFrames.toggle_button.name].visible = #open ~= 0 - - return open -end - ---- Toggles the visibility of a left frame, or sets its visibility state --- @tparam string name the name of the gui frame to toggle --- @tparam LuaPlayer player the player to get the frame of --- @tparam[opt] boolean state when given will be the state that the visibility is set to --- @treturn boolean the new state of the visibility -function LeftFrames.toggle_frame(name,player,state) - local define = LeftFrames.frames[name] - if not define then - return error('Left Frame '..name..' is not defined.',2) - end - - local frame = LeftFrames.get_frame(name,player) - if state ~= nil then - frame.visible = state - else - Gui.toggle_visible(frame) - end - - LeftFrames.get_open(player) - - return frame.visible -end - ---- Creates a new left frame define --- @tparam string permission_name the name that can be used with the permission system --- @treturn table the new left frame define -function LeftFrames.new_frame(permission_name) - local self = Toolbar.new_button(permission_name) - - local mt = getmetatable(self) - mt.__index = LeftFrames._prototype - mt.__call = self.event_handler - - self:on_click(function(player,_element) - local visible = self:toggle(player) - local frame = self:get_frame(player) - self:raise_event('on_player_toggle',player,frame,visible) - end) - - LeftFrames.frames[self.name] = self - - return self -end - ---- Sets if the frame is visible when a player joins, can also be a function to return a boolean --- @tparam[opt=true] ?boolean|function state the default state of the visibility, can be a function --- state param - player LuaPlayer - the player that has joined the game --- state param - define_name string - the define name for the frame --- state return - boolean - false will hide the frame -function LeftFrames._prototype:set_open_by_default(state) - if state == false then - self.open_by_default = false - elseif state == nil then - self.open_by_default = true - else - self.open_by_default = state - end - return self -end - ---- Sets the direction of the frame, either vertical or horizontal --- @tparam string direction the direction to have the elements be added to the frame -function LeftFrames._prototype:set_direction(direction) - self.direction = direction - return self -end - ---- Creates the gui for the first time, used internally --- @tparam LuaPlayer player the player to draw the frame to --- @treturn LuaGuiElement the frame that was made -function LeftFrames._prototype:_internal_draw(player) - local flow = LeftFrames.get_flow(player) - local frame = flow.add{ - type='frame', - name=self.name..'-frame', - direction=self.direction - } - - self:raise_event('on_creation',player,frame) - - if not self.open_by_default then - frame.visible = false - elseif type(self.open_by_default) == 'function' then - if not self.open_by_default(player,self.name) then - frame.visible = false - end - end - - if not Toolbar.allowed(player,self.name) then - frame.visible = false - end - - return frame -end - ---- Gets the frame for this define from the left frame flow --- @tparam LuaPlayer player the player to get the frame of --- @treturn LuaGuiElement the frame in the left frame flow for this define -function LeftFrames._prototype:get_frame(player) - local flow = LeftFrames.get_flow(player) - if flow[self.name..'-frame'] and flow[self.name..'-frame'].valid then - return flow[self.name..'-frame'] - else - return self:_internal_draw(player) - end -end - ---- Returns if the player currently has this define visible --- @tparam LuaPlayer player the player to get the frame of --- @treturn boolean true if it is open/visible -function LeftFrames._prototype:is_open(player) - local frame = self:get_frame(player) - return frame and frame.visible or false -end - ---- Toggles the visibility of the left frame --- @tparam LuaPlayer player the player to toggle the frame of --- @treturn boolean the new state of the visibility -function LeftFrames._prototype:toggle(player) - local frame = self:get_frame(player) - Gui.toggle_visible(frame) - LeftFrames.get_open(player) - return frame.visible -end - ---- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw --- @tparam LuaPlayer player the player to update the frame of -function LeftFrames._prototype:update(player) - local frame = self:get_frame(player) - if self:raise_event('on_update',player,frame) == 0 then - frame.clear() - self:raise_event('on_creation',player,frame) - end -end - ---- Updates the frame for all players, see update --- @tparam[opt=false] boolean update_offline when true will update the frame for offline players -function LeftFrames._prototype:update_all(update_offline) - local players = update_offline == true and game.players or game.connected_players - for _,player in pairs(players) do - self:update(player) - end -end - ---- Redraws the frame by calling on_draw, will always clear the frame --- @tparam LuaPlayer player the player to update the frame of -function LeftFrames._prototype:redraw(player) - local frame = self:get_frame(player) - frame.clear() - self:raise_event('on_creation',player,frame) -end - ---- Redraws the frame for all players, see redraw --- @tparam[opt=false] boolean update_offline when true will update the frame for offline players -function LeftFrames._prototype:redraw_all(update_offline) - local players = update_offline == true and game.players or game.connected_players - for _,player in pairs(players) do - self:redraw(player) - end -end - ---- Creates an event handler that will trigger one of its functions, use with Event.add --- @tparam[opt=update] string action the action to take on this event -function LeftFrames._prototype:event_handler(action) - action = action or 'update' - return function(event) - local player - if event and event.player_index then - player = Game.get_player_by_index(event.player_index) - end - self[action](self,player) - end -end - -LeftFrames.toggle_button = -Buttons.new_button() -:set_tooltip{'expcore-gui.left-button-tooltip'} -:set_caption('<') -:on_click(function(player,element) - for _,define in pairs(LeftFrames.frames) do - local frame = LeftFrames.get_frame(define.name,player) - frame.visible = false - define:raise_event('on_player_toggle',player,frame,false) - end - element.visible = false -end) - -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - local flow = LeftFrames.get_flow(player) - - local close_button = LeftFrames.toggle_button(flow) - Gui.set_padding(close_button) - local style = close_button.style - style.width = 18 - style.height = 36 - style.font = 'default-small-bold' - - for _,define in pairs(LeftFrames.frames) do - define:_internal_draw(player) - end - - LeftFrames.get_open(player) -end) - -return LeftFrames \ No newline at end of file diff --git a/expcore/gui/concepts/popups.lua b/expcore/gui/concepts/popups.lua deleted file mode 100644 index bda932b3..00000000 --- a/expcore/gui/concepts/popups.lua +++ /dev/null @@ -1,230 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Popups. --- Gui structure define for popup gui --- @section popups - ---[[ ->>>> Functions - PopupFrames.get_flow(player) --- Gets the left flow that contains the popup frames - PopupFrames.open(define_name,player,open_time,...) --- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function - - PopupFrames.close_progress --- Progress bar which when depleted will close the popup frame - PopupFrames.close_button --- A button which can be used to close the gui before the timer runs out - - PopupFrames.new_popup(name) --- Creates a new popup frame define - PopupFrames._prototype:set_default_open_time(amount) --- Sets the default open time for the popup, will be used if non is provided with open - PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game -local Event = require 'utils.event' --- @dep utils.event -local ProgressBar = require 'expcore.gui.elements.progress-bar' --- @dep expcore.gui.elements.progress-bar -local Button = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Color = require 'resources.color_presets' --- @dep resources.color_presets -local Global = require 'utils.global' --- @dep utils.global - -local PopupFrames = { - paused_popups={}, - popup_flow_name = Gui.uid_name(), - main_frame_name = Gui.uid_name(), - close_frame_name = Gui.uid_name(), - _prototype = Prototype.extend{ - on_creation = Prototype.event - } -} -Global.register(PopupFrames.paused_popups,function(tbl) - PopupFrames.paused_popups = tbl -end) - ---- Sets the state of the element in the paused list, nil or true --- @tparam LuaGuiElement element the element to set the state of --- @tparam[opt] boolean state the state to set it to, true will pause the the progress bar -local function set_paused_state(element,state) - local name = element.player_index..':'..element.index - PopupFrames.paused_popups[name] = state -end - ---- Gets the state of the element in the paused list, nil or true --- @tparam LuaGuiElement element the element to get the state of -local function get_paused_state(element) - local name = element.player_index..':'..element.index - return PopupFrames.paused_popups[name] -end - ---- Gets the left flow that contains the popup frames --- @tparam LuaPlayer player the player to get the flow for --- @treturn LuaGuiElement the left flow that contains the popup frames -function PopupFrames.get_flow(player) - player = Game.get_player_from_any(player) - local flow = mod_gui.get_frame_flow(player) - return flow[PopupFrames.popup_flow_name] -end - ---- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function --- @tparam string define_name the name of the define that you want to open for the player --- @tparam LuaPlayer player the player to open the popup for --- @tparam[opt] number open_time the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default --- @tparam any ... the other params that you want to pass to your on_draw event --- @treturn LuaGuiElement the frame that was drawn, the inner gui flow which contains the content -function PopupFrames.open(define_name,player,open_time,...) - local define = Gui.get_define(define_name,true) - player = Game.get_player_from_any(player) - return define:open(player,open_time,...) -end - ---- Closes the popup, is called by progress bar and close button --- @tparam LuaGuiElement element either the progress bar or the close button -local function close_popup(element) - local frame = element.parent.parent.parent - if not frame or not frame.valid then return end - set_paused_state(element.parent[PopupFrames.close_progress:uid()]) - frame.destroy() -end - ---- Progress bar which when depleted will close the popup frame -PopupFrames.close_progress = -ProgressBar.new_progressbar() -:use_count_down() -:set_tooltip('Pause/Resume Auto-close') -:on_complete(function(player,element) - close_popup(element) -end) - ---- A button which can be used to close the gui before the timer runs out -PopupFrames.close_button = -Button.new_button() -:set_sprites('utility/close_white') -:set_tooltip('Close Popup') -:on_click(function(player,element) - close_popup(element) -end) - ---- When the progress bar is clicked it will pause its progress, or resume if previously paused -Gui.on_click(PopupFrames.close_progress:uid(),function(event) - local element = event.element - if get_paused_state(element) then - set_paused_state(element) - else - set_paused_state(element,true) - end -end) - ---- When the parent flow of the progress bar is clicked it will pause its progress, or resume if previously paused -Gui.on_click(PopupFrames.close_frame_name,function(event) - local element = event.element[PopupFrames.close_progress:uid()] - if get_paused_state(element) then - set_paused_state(element) - else - set_paused_state(element,true) - end -end) - ---- Creates a new popup frame define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new popup frame define -function PopupFrames.new_popup(name) - local self = Gui.new_define(PopupFrames._prototype,name) - self.draw_data.type = 'flow' - self.draw_data.direction = 'vertical' - - local mt = getmetatable(self) - mt.__call = function(tbl,player,open_time,...) - return tbl:open(player,open_time,...) - end - - self:on_draw(function(player,element,maximum,...) - -- main content frame - local frame = element.add{ - type='flow', - name=PopupFrames.main_frame_name - } - frame.style.horizontally_stretchable = true - - -- flow for progress bar and close button - local close_flow = element.add{ - type='flow', - name=PopupFrames.close_frame_name - } - close_flow.style.horizontally_stretchable = true - - -- progress bar, when 0 then a static full one is drawn - local progress_style - if maximum == 0 then - progress_style = close_flow.add{ - type='progressbar', - tooltip='No Auto-close', - value=1 - }.style - else - progress_style = PopupFrames.close_progress(close_flow,maximum).style - end - progress_style.top_padding = 6 - progress_style.bottom_padding = 3 - progress_style.height = 11 - progress_style.color = Color.grey - - -- close button, will close the popup when clicked - local close_button = PopupFrames.close_button(close_flow) - Gui.set_padding(close_button) - local close_button_style = close_button.style - close_button_style.width = 20 - close_button_style.height = 20 - - -- event trigger to draw the gui content - self:raise_event('on_creation',player,frame,...) - end) - - return self -end - ---- Sets the default open time for the popup, will be used if non is provided with open --- @tparam number amount the number of ticks, by default, the popup will be open for --- @treturn table the define to allow for chaining -function PopupFrames._prototype:set_default_open_time(amount) - self.default_open_time = amount - return self -end - ---- Opens this define for a player, can be given open time and any other params for the draw function --- @tparam LuaPlayer player the player to open the popup for --- @tparam[opt] number open_time the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default --- @tparam any ... the other params that you want to pass to your on_draw event --- @treturn LuaGuiElement the frame that was drawn, the inner gui flow which contains the content -function PopupFrames._prototype:open(player,open_time,...) - open_time = open_time or self.default_open_time or 0 - player = Game.get_player_from_any(player) - - local flow = PopupFrames.get_flow(player) - local frame = flow.add{ - type='frame', - style='blurry_frame' - } - - Gui.set_padding(frame,3,3,4,4) - return self:draw_to(frame,open_time,...)[PopupFrames.main_frame_name] -end - ---- When player is first created the popup flow is added to they left flow -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - local flow = mod_gui.get_frame_flow(player) - - flow.add{ - type='flow', - direction='vertical', - name=PopupFrames.popup_flow_name - } -end) - ---- Every tick any, not paused, progress bars will go down by one tick -Event.add(defines.events.on_tick,PopupFrames.close_progress:event_countdown(function(element) - return not get_paused_state(element) -end)) - -return PopupFrames \ No newline at end of file diff --git a/expcore/gui/concepts/toolbar.lua b/expcore/gui/concepts/toolbar.lua deleted file mode 100644 index 10a8d971..00000000 --- a/expcore/gui/concepts/toolbar.lua +++ /dev/null @@ -1,114 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Toolbar. --- Gui structure for the toolbar (top left) --- @section toolbar - ---[[ ->>>> Example format - -- this is the same as any other button define, this just automatically draws it - -- you can use add_button if you already defined the button - local toolbar_button = - Toolbar.new_button('print-click') - :on_click(function(player,_element) - player.print('You clicked a button!') - end) - ->>>> Functions - Toolbar.new_button(name) --- Adds a new button to the toolbar - Toolbar.add_button(button) --- Adds an existing buttton to the toolbar - Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Buttons = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local Roles = require 'expcore.roles' --- @dep expcore.roles -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game -local mod_gui = require 'mod-gui' --- @dep mod-gui - -local Toolbar = { - permission_names = {}, - buttons = {} -} - -function Toolbar.allowed(player,define_name) - local permission_name = Toolbar.permission_names[define_name] or define_name - return Roles.player_allowed(player,permission_name) -end - -function Toolbar.permission_alias(define_name,permission_name) - Toolbar.permission_names[define_name] = permission_name -end - ---- Adds a new button to the toolbar --- @tparam[opt] string name when given allows an alias to the button for the permission system --- @treturn table the button define -function Toolbar.new_button(name) - local button = - Buttons.new_button() - :set_post_authenticator(Toolbar.allowed) - :set_style(mod_gui.button_style,function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - end) - Toolbar.add_button(button) - Toolbar.permission_alias(button.name,name) - return button -end - ---- Adds an existing buttton to the toolbar --- @tparam table button the button define for the button to be added -function Toolbar.add_button(button) - table.insert(Toolbar.buttons,button) - Gui.allow_player_to_toggle_top_element_visibility(button.name) - Gui.on_player_show_top(button.name,function(event) - if not button.post_authenticator(event.player,button.name) then - event.element.visible = false - end - end) - if not button.post_authenticator then - button:set_post_authenticator(function() return true end) - end -end - ---- Updates the player's toolbar with an new buttons or expected change in auth return --- @tparam LuaPlayer player the player to update the toolbar for -function Toolbar.update(player) - local top = Gui.get_top_element_flow(player) - if not top then return end - local visible = top[Gui.top_toggle_button_name].caption == '<' - for _,button in pairs(Toolbar.buttons) do - local element - if top[button.name] then element = top[button.name] - else element = button:draw_to(top) end - if button.post_authenticator(player,button.name) then - element.visible = visible - element.enabled = true - else - element.visible = false - element.enabled = false - end - end -end - ---- When there is a new player they will have the toolbar update -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - ---- When a player gets a new role they will have the toolbar updated -Event.add(Roles.events.on_role_assigned,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - ---- When a player loses a role they will have the toolbar updated -Event.add(Roles.events.on_role_unassigned,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - -return Toolbar \ No newline at end of file diff --git a/expcore/gui/core.lua b/expcore/gui/core.lua deleted file mode 100644 index 1fd93480..00000000 --- a/expcore/gui/core.lua +++ /dev/null @@ -1,368 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Core. --- Core gui file for making element defines and element classes (use require 'expcore.gui') --- see utils.gui for event handlering --- see expcore.gui.test for examples for element defines --- @section core - ---[[ ->>>> Basic useage with no defines - This module can be igroned if you are only wanting only event handlers as utils.gui adds the following: - - Gui.uid_name() --- Generates a unqiue name to register events to - Gui.on_checked_state_changed(callback) --- Register a handler for the on_gui_checked_state_changed event - Gui.on_click(callback) --- Register a handler for the on_gui_click event - Gui.on_elem_changed(callback) --- Register a handler for the on_gui_elem_changed - Gui.on_selection_state_changed(callback) --- Register a handler for the on_gui_selection_state_changed event - Gui.on_text_changed(callback) --- Register a handler for the on_gui_text_changed event - Gui.on_value_changed(callback) --- Register a handler for the on_gui_value_changed event - - Note that all event handlers will include event.player as a valid player and that if the player or the - element is not valid then the callback will not be run. - ->>>> Basic prototype functions (see expcore.gui.prototype) - Using a class defination you can create a new element dinfation in our examples we will be using the checkbox. - - local checkbox_example = Gui.new_checkbox() - - Although all class definations are stored in Gui.classes the main function used to make new element defination are - made aviable in the top level gui module. All functions which return a new element defination will accept a name argument - which is a name which is used while debuging and is not required to be used (has not been used in examples) - - Every element define will accept a caption and tooltip (although some may not show) and to do this you would use the two - set function provided for the element defines: - - checkbox_example:set_caption('Example Checkbox') - checkbox_example:set_tooltip('Example checkbox') - - Each element define can have event handlers set, for our example checkbox we only have access to on_change which will trigger - when the state of the checkbox changes; if we want to assign handlers using the utils.gui methods then we can get the uid by calling - the uid function on the element define; however, each element can only have one handler (of each event) so it is not possible to use - Gui.on_checked_state_changed and on_change at the same time in our example. - - checkbox_example:on_change(function(player,element,value) - player.print('Example checkbox is now: '..tostring(value)) - end) - - local checkbox_example_uid = checkbox_example:uid() - Gui.on_click(checkbox_example_uid,function(event) - event.player.print('You clicked the example checkbox!') - end) - - Finally you will want to draw your element defines for which you can call deirectly on the deinfe or use Gui.draw to do; when Gui.draw is - used it can be given either the element define, the define's uid or the debug name of the define (if set): - - checkbox_example:draw_to(parent_element) - Gui.draw(checkbox_example_uid,parent_element) - ->>>> Using authenticators with draw - When an element is drawn to its parent it can always be used but if you want to limit who can use it then you can use an authenticator. There - are two types which can be used: post and pre; using a pre authenticator will mean that the draw function is stoped before the element is added - to the parent element while using a post authenticator will draw the element to the parent but will disable the element from interaction. Both may - be used if you have use for such. - - -- unless global.checkbox_example_allow_pre_auth is true then the checkbox will not be drawn - checkbox_example:set_pre_authenticator(function(player,define_name) - player.print('Example checkbox pre auth callback ran') - return global.checkbox_example_allow_pre_auth - end) - - -- unless global.checkbox_example_allow_post_auth is true then the checkbox will be drawn but deactiveated (provided pre auth returns true) - checkbox_example:set_post_authenticator(function(player,define_name) - player.print('Example checkbox pre auth callback ran') - return global.checkbox_example_allow_post_auth - end) - ->>>> Using store (see expcore.gui.prototype and expcore.gui.instances) - A powerful assept of this gui system is allowing an automatic store for the state of a gui element, this means that when a gui is closed and re-opened - the elements which have a store will retain they value even if the element was previously destroied. The store is not limited to only per player and can - be catergorised by any method you want such as one that is shared between all players or by all players on a force. Using a method that is not limited to - one player means that when one player changes the state of the element it will be automaticlly updated for all other player (even if the element is already drawn) - and so this is a powerful and easy way to sync gui elements. - - -- note the example below is the same as checkbox_example:add_store(Gui.categorize_by_player) - checkbox_example:add_store(function(element) - local player = Game.get_player_by_index(element.player_index) - return player.force.name - end) - - Of course this tool is not limited to only player interactions; the current satate of a define can be gotten using a number of methods and the value can - even be updated by the script and have all instances of the element define be updated. When you use a category then we must give a category to the get - and set functions; in our case we used Gui.categorize_by_player which uses the player's name as the category which is why 'Cooldude2606' is given as a argument, - if we did not set a function for add_store then all instances for all players have the same value and so a category is not required. - - checkbox_example:get_store('Cooldude2606') - Gui.get_store(name,'Cooldude2606') - - checkbox_example:set_store('Cooldude2606',true) - Gui.set_store(name,'Cooldude2606',true) - - These methods use the Store module which means that if you have the need to access these sotre location (for example if you want to add a watch function) then - you can get the store location of any define using checkbox_example.store - - Important note about event handlers: when the store is updated it will also trigger the event handlers (such as on_element_update) for that define but only - for the valid instances of the define which means if a player does not have the element drawn on a gui then it will not trigger the events; if you want a - trigger for all updates then you can use on_store_update however you will be required to parse the category which may or may not be a - player name (depends what store categorize function you use) - ->>>> Example formating - - local checkbox_example = - Gui.new_checkbox() - :set_caption('Example Checkbox') - :set_tooltip('Example checkbox') - :add_store(Gui.categorize_by_player) - :on_element_update(function(player,element,value) - player.print('Example checkbox is now: '..tostring(value)) - end) - ->>>> Functions - Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype - Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to - - Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value - Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value - Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value - - Gui.toggle_enabled(element) --- Will toggle the enabled state of an element - Gui.toggle_visible(element) --- Will toggle the visiblity of an element - Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element - Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style - Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into - Gui.destroy_if_valid(element) --- Destroies an element but tests for it being present and valid first - Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size - Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area -]] -local Gui = require 'utils.gui' --- @dep utils.gui -local Game = require 'utils.game' --- @dep utils.game - -Gui.classes = {} -- Stores the class definations used to create element defines -Gui.defines = {} -- Stores the indivdual element definations -Gui.names = {} -- Stores debug names to link to gui uids - ---- Used to create new element defines from a class prototype, please use the own given by the class --- @tparam table prototype the class prototype that will be used for the element define --- @tparam[opt] string debug_name the name that you want to see while debuging --- @treturn table the new element define with all functions accessed via __index metamethod -function Gui.new_define(prototype,debug_name) - local name = Gui.uid_name() - local define = setmetatable({ - debug_name = debug_name, - name = name, - events = {}, - draw_data = { - name = name - } - },{ - __index = prototype, - __call = function(self,...) - return self:draw_to(...) - end - }) - Gui.defines[define.name] = define - return define -end - ---- Gets an element define give the uid, debug name or a copy of the element define --- @tparam ?string|table name the uid, debug name or define for the element define to get --- @tparam[opt] boolean internal when true the error trace is one level higher (used internally) --- @treturn table the element define that was found or an error -function Gui.get_define(name,internal) - if type(name) == 'table' then - if name.name and Gui.defines[name.name] then - return Gui.defines[name.name] - end - end - - local define = Gui.defines[name] - - if not define and Gui.names[name] then - return Gui.defines[Gui.names[name]] - - elseif not define then - return error('Invalid name for element define, name not found.',internal and 3 or 2) or nil - - end - - return define -end - ---- A categorize function to be used with add_store, each player has their own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's name who owns this element -function Gui.categorize_by_player(element) - local player = Game.get_player_by_index(element.player_index) - return player.name -end - ---- A categorize function to be used with add_store, each force has its own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's force name who owns this element -function Gui.categorize_by_force(element) - local player = Game.get_player_by_index(element.player_index) - return player.force.name -end - ---- A categorize function to be used with add_store, each surface has its own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's surface name who owns this element -function Gui.categorize_by_surface(element) - local player = Game.get_player_by_index(element.player_index) - return player.surface.name -end - ---- Draws a copy of the element define to the parent element, see draw_to --- @tparam ?string|table name the uid, debug name or define for the element define to draw --- @tparam LuaGuiEelement element the parent element that it the define will be drawn to --- @treturn LuaGuiElement the new element that was created -function Gui.draw(name,element,...) - local define = Gui.get_define(name,true) - return define:draw_to(element,...) -end - ---- Will toggle the enabled state of an element --- @tparam LuaGuiElement element the gui element to toggle --- @treturn boolean the new state that the element has -function Gui.toggle_enabled(element) - if not element or not element.valid then return end - if not element.enabled then - element.enabled = true - else - element.enabled = false - end - return element.enabled -end - ---- Will toggle the visiblity of an element --- @tparam LuaGuiElement element the gui element to toggle --- @treturn boolean the new state that the element has -function Gui.toggle_visible(element) - if not element or not element.valid then return end - if not element.visible then - element.visible = true - else - element.visible = false - end - return element.visible -end - ---- Sets the padding for a gui element --- @tparam LuaGuiElement element the element to set the padding for --- @tparam[opt=0] number up the amount of padding on the top --- @tparam[opt=0] number down the amount of padding on the bottom --- @tparam[opt=0] number left the amount of padding on the left --- @tparam[opt=0] number right the amount of padding on the right -function Gui.set_padding(element,up,down,left,right) - local style = element.style - style.top_padding = up or 0 - style.bottom_padding = down or 0 - style.left_padding = left or 0 - style.right_padding = right or 0 -end - ---- Sets the padding for a gui style --- @tparam LuaStyle style the element to set the padding for --- @tparam[opt=0] number up the amount of padding on the top --- @tparam[opt=0] number down the amount of padding on the bottom --- @tparam[opt=0] number left the amount of padding on the left --- @tparam[opt=0] number right the amount of padding on the right -function Gui.set_padding_style(style,up,down,left,right) - style.top_padding = up or 0 - style.bottom_padding = down or 0 - style.left_padding = left or 0 - style.right_padding = right or 0 -end - ---- Allows the creation of an alignment flow to place elements into --- @tparam LuaGuiElement element the element to add this alignment into --- @tparam[opt] string name the name to use for the alignment --- @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in this flow --- @tparam[opt='center'] string vertical_align the vertical alignment of the elements in this flow --- @treturn LuaGuiElement the new flow that was created -function Gui.create_alignment(element,name,horizontal_align,vertical_align) - local flow = element.add{name=name,type='flow'} - local style = flow.style - Gui.set_padding(flow,1,1,2,2) - style.horizontal_align = horizontal_align or 'right' - style.vertical_align = vertical_align or 'center' - style.horizontally_stretchable =style.horizontal_align ~= 'center' - style.vertically_stretchable = style.vertical_align ~= 'center' - return flow -end - ---- Destroies an element but tests for it being present and valid first --- @tparam LuaGuiElement element the element to be destroied --- @treturn boolean true if it was destoried -function Gui.destroy_if_valid(element) - if element and element.valid then - element.destroy() - return true - end -end - ---- Creates a scroll area with a table inside, table can be any size --- @tparam LuaGuiElement element the element to add this scroll into --- @tparam number table_size the number of columns in the table --- @tparam number maximal_height the max hieght of the scroll --- @tparam[opt='scroll'] string name the name of the scoll element --- @treturn LuaGuiElement the table that was made -function Gui.create_scroll_table(element,table_size,maximal_height,name) - local list_scroll = - element.add{ - name=name or 'scroll', - type='scroll-pane', - direction='vertical', - horizontal_scroll_policy='never', - vertical_scroll_policy='auto-and-reserve-space' - } - Gui.set_padding(list_scroll,1,1,2,2) - list_scroll.style.horizontally_stretchable = true - list_scroll.style.maximal_height = maximal_height - - local list_table = - list_scroll.add{ - name='table', - type='table', - column_count=table_size - } - Gui.set_padding(list_table) - list_table.style.horizontally_stretchable = true - list_table.style.vertical_align = 'center' - list_table.style.cell_padding = 0 - - return list_table -end - ---- Creates a header section with a label and button area --- @tparam LuaGuiElement element the element to add this header into --- @tparam localeString caption the caption that is used as the title --- @tparam[opt] localeString tooltip the tooltip that is shown on the caption --- @tparam[opt] boolean right_align when true will include the right align area --- @tparam[opt='header'] string name the name of the header area --- @treturn LuaGuiElement the header that was made, or the align area if that was created -function Gui.create_header(element,caption,tooltip,right_align,name) - local header = - element.add{ - name=name or 'header', - type='frame', - style='subheader_frame' - } - Gui.set_padding(header,2,2,4,4) - header.style.horizontally_stretchable = true - header.style.use_header_filler = false - - header.add{ - type='label', - style='heading_1_label', - caption=caption, - tooltip=tooltip - } - - return right_align and Gui.create_alignment(header,'header-align') or header -end - -return Gui \ No newline at end of file diff --git a/expcore/gui/elements/buttons.lua b/expcore/gui/elements/buttons.lua deleted file mode 100644 index aa06f58b..00000000 --- a/expcore/gui/elements/buttons.lua +++ /dev/null @@ -1,128 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Buttons. --- Gui class define for buttons and sprite buttons --- @section Buttons - ---[[ ->>>> Functions - Button.new_button(name) --- Creates a new button element define - - Button._prototype:on_click(player,element) --- Registers a handler for when the button is clicked - Button._prototype:on_left_click(player,element) --- Registers a handler for when the button is clicked with the left mouse button - Button._prototype:on_right_click(player,element) --- Registers a handler for when the button is clicked with the right mouse button - - Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) --- Adds sprites to a button making it a sprite button - Button._prototype:set_click_filter(filter,...) --- Adds a click / mouse button filter to the button - Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button - - Other functions present from expcore.gui.core -]] -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype - -local Button = { - _prototype=Prototype.extend{ - on_raw_click = Prototype.event, - on_click = Prototype.event, - on_left_click = Prototype.event, - on_right_click = Prototype.event, - } -} - ---- Creates a new button element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new button element define -function Button.new_button(name) - - local self = Gui.new_define(Button._prototype,name) - self.draw_data.type = 'button' - self.draw_data.style = mod_gui.button_style - - Gui.on_click(self.name,function(event) - local mouse_button = event.button - local keys = {alt=event.alt,control=event.control,shift=event.shift} - local player,element = event.player,event.element - event.keys = keys - - self:raise_event('on_raw_click',event) - - if self.post_authenticator then - if not self.post_authenticator(event.player,self.name) then return end - end - - if mouse_button == defines.mouse_button_type.left then - self:raise_event('on_left_click',player,element) - elseif mouse_button == defines.mouse_button_type.right and self.events.on_right_click then - self:raise_event('on_right_click',player,element) - end - - if self.mouse_button_filter and not self.mouse_button_filter[mouse_button] then return end - if self.key_button_filter then - for key,state in pairs(self.key_button_filter) do - if state and not keys[key] then return end - end - end - - self:raise_event('on_click',player,element) - end) - - return self -end - ---- Adds sprites to a button making it a sprite button --- @tparam SpritePath sprite the sprite path for the default sprite for the button --- @tparam[opt] SpritePath hovered_sprite the sprite path for the sprite when the player hovers over the button --- @tparam[opt] SpritePath clicked_sprite the sprite path for the sprite when the player clicks the button --- @treturn self returns the button define to allow chaining -function Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) - self.draw_data.type = 'sprite-button' - self.draw_data.sprite = sprite - self.draw_data.hovered_sprite = hovered_sprite - self.draw_data.clicked_sprite = clicked_sprite - return self -end - ---- Adds a click / mouse button filter to the button --- @tparam table filter ?string|table either a of mouse buttons or the first mouse button to filter, with a table true means allowed --- @tparam[opt] table ... when filter is not a you can add the mouse buttons one after each other --- @treturn self returns the button define to allow chaining -function Button._prototype:set_click_filter(filter,...) - if type(filter) == 'string' then - filter = {[filter]=true} - for _,v in pairs({...}) do - filter[v] = true - end - end - - for k,v in pairs(filter) do - if type(v) == 'string' then - filter[k] = defines.mouse_button_type[v] - end - end - - self.mouse_button_filter = filter - return self -end - ---- Adds a control key filter to the button --- @tparam table filter ?string|table either a of control keys or the first control keys to filter, with a table true means allowed --- @tparam[opt] table ... when filter is not a you can add the control keys one after each other --- @treturn self returns the button define to allow chaining -function Button._prototype:set_key_filter(filter,...) - if type(filter) == 'string' then - filter = {[filter]=true} - for _,v in pairs({...}) do - filter[v] = true - end - end - - self.key_button_filter = filter - return self -end - -return Button \ No newline at end of file diff --git a/expcore/gui/elements/checkbox.lua b/expcore/gui/elements/checkbox.lua deleted file mode 100644 index ce9b2a8a..00000000 --- a/expcore/gui/elements/checkbox.lua +++ /dev/null @@ -1,247 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Checkboxs. --- Gui class define for checkbox and radiobuttons --- @section checkboxs - ---[[ ->>>> Using an option set - An option set is a set of radio buttons where only one of them can be active at a time, this means that when one - is clicked all the other ones are set to false, an option set must be defined before hand and will always store - its state but is not limited by how it can categorize the store. - - First you must register the store with a name and a update callback, and an optional function for categorize: - - local example_option_set = - Gui.new_option_set('example-option-set',function(value,category) - game.print('Example options set '..category..' is now: '..tostring(value)) - end,Gui.categorize_by_player) - - Then you must register some radiobutton defines and include them in the option set: - - local example_option_one = - Gui.new_radiobutton() - :set_caption('Option One') - :add_as_option(example_option_set,'One') - - local example_option_two = - Gui.new_radiobutton() - :set_caption('Option Two') - :add_as_option(example_option_set,'Two') - - Note that these radiobuttons can still have on_element_update events but this may result in a double trigger of events as - the option set update is always triggered; also add_store cant be used as the option set acts as the store however get - and set store will still work but will effect the option set rather than the individual radiobuttons. - ->>>> Functions - Checkbox.new_checkbox(name) --- Creates a new checkbox element define - Checkbox._prototype_checkbox:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_checkbox:on_store_update(callback) --- Registers a handler for when the stored value updates - - Checkbox.new_radiobutton(name) --- Creates a new radiobutton element define - Checkbox._prototype_radiobutton:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates - Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time) - - Checkbox.new_option_set(name,callback,categorize) --- Registers a new option set that can be linked to radiobutton (only one can be true at a time) - Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) - - Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobutton in a element to false (unless excluded) and can act recursively - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Store = require 'expcore.store' --- @dep expcore.store -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam boolean value the new state of the checkbox -local function store_update(define,element,value) - element.state = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local Checkbox = { - option_sets={}, - option_categorize={}, - _prototype_checkbox=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - }, - _prototype_radiobutton=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new checkbox element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new checkbox element define -function Checkbox.new_checkbox(name) - - local self = Gui.new_define(Checkbox._prototype_checkbox,name) - self.draw_data.type = 'checkbox' - self.draw_data.state = false - - self:on_draw(function(player,element) - if self.store then - local state = self:get_store(element,true) - if state then element.state = true end - end - end) - - Gui.on_checked_state_changed(self.name,function(event) - local element = event.element - - if self.option_set then - local value = Checkbox.option_sets[self.option_set][element.name] - self:set_store(element,value) - - elseif self.store then - local value = element.state - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,element.state) - - end - end) - - return self -end - ---- Creates a new radiobutton element define, has all functions checkbox has --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new button element define -function Checkbox.new_radiobutton(name) - local self = Checkbox.new_checkbox(name) - self.draw_data.type = 'radiobutton' - - local mt = getmetatable(self) - mt.__index = Checkbox._prototype_radiobutton - - return self -end - ---- Adds this radiobutton to be an option in the given option set (only one can be true at a time) --- @tparam string option_set the name of the option set to add this element to --- @tparam string option_name the name of this option that will be used to identify it --- @treturn self the define to allow chaining -function Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) - self.option_set = option_set - self.option_name = option_name or self.name - - Checkbox.option_sets[option_set][self.option_name] = self.name - Checkbox.option_sets[option_set][self.name] = self.option_name - - self:add_store(Checkbox.option_categorize[option_set]) - - return self -end - ---- Gets the stored value of the radiobutton or the option set if present --- @tparam string category[opt] the category to get such as player name or force name --- @tparam boolean internal used to prevent stackover flow --- @treturn any the value that is stored for this define -function Checkbox._prototype_radiobutton:get_store(category,internal) - if not self.store then return end - local location = not internal and self.option_set or self.store - return Store.get(location,category) -end - ---- Sets the stored value of the radiobutton or the option set if present --- @tparam string category[opt] the category to get such as player name or force name --- @tparam boolean value the value to set for this define, must be valid for its type ie for checkbox etc --- @tparam boolean internal used to prevent stackover flow --- @treturn boolean true if the value was set -function Checkbox._prototype_radiobutton:set_store(category,value,internal) - if not self.store then return end - local location = not internal and self.option_set or self.store - return Store.set(location,category,value) -end - ---- Registers a new option set that can be linked to radiobuttons (only one can be true at a time) --- @tparam function callback the update callback when the value of the option set changes --- callback param - value string - the new selected option for this option set --- callback param - category string - the category that updated if categorize was used --- @tparam function categorize the function used to convert an element into a string --- @treturn string the name of this option set to be passed to add_as_option -function Checkbox.new_option_set(callback,categorize) - local name = Store.register(categorize) - - Store.watch(name,function(value,category) - local options = Checkbox.option_sets[name] - for opt_name,define_name in pairs(options) do - if Gui.defines[define_name] then - local define = Gui.get_define(define_name) - local state = opt_name == value - define:set_store(category,state,true) - end - end - callback(value,category) - end) - - Checkbox.option_categorize[name] = categorize - Checkbox.option_sets[name] = {} - - return name -end - ---- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) --- @tparam string name the name of the option set to draw the radiobuttons of --- @tparam LuaGuiElement element the parent element that the radiobuttons will be drawn to -function Checkbox.draw_option_set(name,element) - if not Checkbox.option_sets[name] then return end - local options = Checkbox.option_sets[name] - - for _,option in pairs(options) do - if Gui.defines[option] then - Gui.defines[option]:draw_to(element) - end - end - -end - ---- Sets all radiobutton in a element to false (unless excluded) and can act recursively --- @tparam LuaGuiElement element the root gui element to start setting radio buttons from --- @tparam[opt] table exclude ?string|table the name of the radiobutton to exclude or a of radiobuttons where true will set the state true --- @tparam[opt=false] ?number|boolean recursive if true will recur as much as possible, if a will recur that number of times --- @treturn boolean true if successful -function Checkbox.reset_radiobuttons(element,exclude,recursive) - if not element or not element.valid then return end - exclude = type(exclude) == 'table' and exclude or exclude ~= nil and {[exclude]=true} or {} - recursive = type(recursive) == 'number' and recursive-1 or recursive - - for _,child in pairs(element.children) do - if child and child.valid and child.type == 'radiobutton' then - local state = exclude[child.name] or false - local define = Gui.defines[child.name] - - if define then - local category = define.categorize and define.categorize(child) or state - define:set_store(category,state) - - else - child.state = state - - end - - elseif child.children and (type(recursive) == 'number' and recursive >= 0 or recursive == true) then - Checkbox.reset_radiobutton(child,exclude,recursive) - - end - end - - return true -end - -return Checkbox \ No newline at end of file diff --git a/expcore/gui/elements/dropdown.lua b/expcore/gui/elements/dropdown.lua deleted file mode 100644 index ae6857c0..00000000 --- a/expcore/gui/elements/dropdown.lua +++ /dev/null @@ -1,184 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Dropdowns. --- Gui class define for dropdowns and list box --- @section dropdowns - ---[[ ->>>> Functions - Dropdown.new_dropdown(name) --- Creates a new dropdown element define - Dropdown.new_list_box(name) --- Creates a new list box element define - - Dropdown._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Dropdown._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - Dropdown._prototype:new_static_options(options,...) --- Adds new static options to the dropdown which will trigger the general callback - Dropdown._prototype:new_dynamic_options(callback) --- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) - Dropdown._prototype:add_option_callback(option,callback) --- Adds a case specific callback which will only run when that option is selected (general case still triggered) - - Dropdown.select_value(element,value) --- Selects the option from a dropdown or list box given the value rather than key - Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - -local select_value ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new option for the dropdown -local function store_update(define,element,value) - select_value(element,value) - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) - - if define.option_callbacks and define.option_callbacks[value] then - define.option_callbacks[value](player,element,value) - end -end - -local Dropdown = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new dropdown element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new dropdown element define -function Dropdown.new_dropdown(name) - - local self = Gui.new_define(Dropdown._prototype,name) - self.draw_data.type = 'drop-down' - - self:on_draw(function(player,element) - if self.dynamic_options then - local dynamic_options = self.dynamic_options(player,element) - local items = element.items - for _,v in pairs(dynamic_options) do - table.insert(items,v) - end - element.items = items - end - - if self.store then - local value = self:get_store(element) - if value then Dropdown.select_value(element,value) end - end - end) - - Gui.on_selection_state_changed(self.name,function(event) - local element = event.element - local value = Dropdown.get_selected_value(element) - - if self.store then - self:set_store(element,value) - - else - local player = event.player - local option_callbacks = self.option_callbacks - self:raise_event('on_element_update',player,element,value) - if option_callbacks and option_callbacks[value] then - option_callbacks[value](player,element,value) - end - - end - - end) - - return self -end - ---- Creates a new list box element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new list box element define -function Dropdown.new_list_box(name) - local self = Dropdown.new_dropdown(name) - self.draw_data.type = 'list-box' - - return self -end - ---- Adds new static options to the dropdown which will trigger the general callback --- @tparam table options ?string|table either a of option strings or the first option string, with a table values are the options --- @tparam[opt] table ... when options is not a you can add the options one after each other --- @tparam self the define to allow chaining -function Dropdown._prototype:new_static_options(options,...) - if type(options) == 'string' then - options = {options} - for _,v in pairs({...}) do - table.insert(options,v) - end - end - - self.options = options - self.draw_data.items = options - return self -end -Dropdown._prototype.add_options = Dropdown._prototype.new_static_options - ---- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) --- @tparam function callback the function that will run to get the options for the dropdown --- callback param - player LuaPlayer - the player that the element is being drawn to --- callback param - element LuaGuiElement - the element that is being drawn --- callback return - table - the values of this table will be appended to the static options of the dropdown --- @treturn self the define to allow chaining -function Dropdown._prototype:new_dynamic_options(callback) - if type(callback) ~= 'function' then - return error('Dynamic options callback must be a function',2) - end - self.dynamic_options = callback - return self -end -Dropdown._prototype.add_dynamic = Dropdown._prototype.new_dynamic_options - ---- Adds a case specific callback which will only run when that option is selected (general case still triggered) --- @tparam string option the name of the option to trigger the callback on; if not already added then will be added as an option --- @tparam function callback the function that will be called when that option is selected --- callback param - player LuaPlayer - the player who owns the gui element --- callback param - element LuaGuiElement - the element which is being effected --- callback param - value string - the new option that has been selected --- @treturn self the define to allow chaining -function Dropdown._prototype:add_option_callback(option,callback) - if not self.option_callbacks then self.option_callbacks = {} end - if not self.options then self.options = {} end - - self.option_callbacks[option] = callback - if not table.contains(self.options,option) then - table.insert(self.options,option) - end - - return self -end - ---- Selects the option from a dropdown or list box given the value rather than key --- @tparam LuaGuiElement element the element that contains the option --- @tparam string value the option to select from the dropdown --- @treturn number the key where the value was -function Dropdown.select_value(element,value) - for k,item in pairs(element.items) do - if item == value then - element.selected_index = k - return k - end - end -end -select_value = Dropdown.select_value - ---- Returns the currently selected value rather than index --- @tparam LuaGuiElement element the gui element that you want to get the value of --- @treturn string the value that is currently selected -function Dropdown.get_selected_value(element) - local index = element.selected_index - return element.items[index] -end - -return Dropdown \ No newline at end of file diff --git a/expcore/gui/elements/elem-button.lua b/expcore/gui/elements/elem-button.lua deleted file mode 100644 index 8b2b2b3c..00000000 --- a/expcore/gui/elements/elem-button.lua +++ /dev/null @@ -1,96 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Elem Buttons. --- Gui class defines for elem buttons --- @section elem-buttons - ---[[ ->>>> Functions - ElemButton.new_elem_button(name) --- Creates a new elem button element define - - ElemButton._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - ElemButton._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - ElemButton._prototype:set_type(type) --- Sets the type of the elem button, the type is required so this must be called at least once - ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new value for the elem button -local function store_update(define,element,value) - element.elem_value = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local ElemButton = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new elem button element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new elem button element define -function ElemButton.new_elem_button(name) - - local self = Gui.new_define(ElemButton._prototype,name) - self.draw_data.type = 'choose-elem-button' - - self:on_draw(function(player,element) - if type(self.default) == 'function' then - element.elem_value = self.default(player,element) - end - - if self.store then - local value = self:get_store(element) - if value then element.elem_value = value end - end - end) - - Gui.on_elem_changed(self.name,function(event) - local element = event.element - local value = element.elem_value - - if self.store then - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,value) - - end - - end) - - return self -end - ---- Sets the type of the elem button, the type is required so this must be called at least once --- @tparam string type the type that this elem button is see factorio api --- @treturn the element define to allow for chaining -ElemButton._prototype.set_type = Prototype.setter('string','draw_data','elem_type') - ---- Sets the default value for the elem button, this may be a function or a string --- @tparam ?string|function value string a will be a static default and a function will be called when drawn to get the default --- @treturn the element define to allow for chaining -function ElemButton._prototype:set_default(value) - self.default = value - if type(value) ~= 'function' then - self.draw_data[self.draw_data.elem_type] = value - end - return self -end - -return ElemButton \ No newline at end of file diff --git a/expcore/gui/elements/progress-bar.lua b/expcore/gui/elements/progress-bar.lua deleted file mode 100644 index 0e096d42..00000000 --- a/expcore/gui/elements/progress-bar.lua +++ /dev/null @@ -1,387 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Progress Bars. --- Gui element define for progress bars --- @section progress-bars - ---[[ ->>>> Functions - ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar.increment(element,amount) --- Increases the value of the progressbar, if a define is given all of its instances have incremented - ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances have decremented - - ProgressBar.new_progressbar(name) --- Creates a new progressbar element define - ProgressBar._prototype:set_maximum(amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar._prototype:use_count_down(state) --- Will set the progress bar to start at 1 and trigger when it hits 0 - ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar - ProgressBar._prototype:increment_filtered(amount,filter) --- Increases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar - ProgressBar._prototype:decrement_filtered(amount,filter) --- Decreases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:add_element(element,maximum) --- Adds an element into the list of instances that will are waiting to complete, does not work with store - ProgressBar._prototype:reset_element(element) --- Resets an element, or its store, to be back at the start, either 1 or 0 - - ProgressBar._prototype:on_complete(callback) --- Triggers when a progress bar element completes (hits 0 or 1) - ProgressBar._prototype:on_complete(callback) --- Triggers when a store value completes (hits 0 or 1) - ProgressBar._prototype:event_counter(filter) --- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented - ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Global = require 'utils.global' --- @dep utils.global -local Game = require 'utils.game' --- @dep utils.game - ---- Event call for when the value is outside the range 0-1 --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event -local function event_call(define,element) - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_complete',player,element,function() - define:add_element(element) - define:reset_element(element) - end) -end - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the progress bar -local function store_update(define,element,value) - if value then - element.value = value - if define.count_down and value <= 0 - or not define.count_down and value >= 1 then - event_call(define,element) - end - end -end - -local ProgressBar = { - unregistered={}, -- elements with no callbacks - independent={}, -- elements with a link to a define - _prototype=Prototype.extend{ - on_complete = Prototype.event, - on_store_complete = Prototype.event, - add_store = Prototype.store(store_update) - } -} - -Global.register({ - unregistered = ProgressBar.unregistered, - independent = ProgressBar.independent -},function(tbl) - ProgressBar.unregistered = tbl.unregistered - ProgressBar.independent = tbl.independent -end) - ---- Gets the define data, cant use Gui.get_define as it would error --- @tparam ?table|string define the define to get --- @treturn table the define or nil -local function get_define(define) - if type(define) == 'table' then - if define.name and Gui.defines[define.name] then - return Gui.defines[define.name] - end - end - - return Gui.defines[define] -end - ---- Gets the element data, used when there is no define --- @tparam LuaGuiElement element the element to get the data of --- @treturn table the element data similar to define -local function get_element(element) - if not element.valid then return end - local name = element.player_index..':'..element.index - - if ProgressBar.unregistered[name] then - return ProgressBar.unregistered[name] - end -end - ---- Sets the maximum value that represents the end value of the progress bar --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam number amount the amount to have set as the maximum -function ProgressBar.set_maximum(element,amount) - amount = amount > 0 and amount or error('amount must be greater than 0') - - local define = get_define(element) - if define then - define:set_default_maximum(amount) - - else - local element_data = get_element(element) - - if element_data then - element_data.maximum = amount - - else - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = { - element=element, - maximum=amount or 1 - } - - end - - end -end - ---- Increases the value of the progressbar, if a define is given all of its instances have incremented --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam[opt=1] number amount the amount to increase the progressbar by -function ProgressBar.increment(element,amount) - amount = type(amount) == 'number' and amount or 1 - - local define = get_define(element) - if define then - define:increment(amount) - - else - local element_data = get_element(element) - - if element_data then - local real_amount = amount/element_data.maximum - element.value = element.value + real_amount - - if element.value >= 1 then - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = nil - return true - end - end - - end -end - ---- Decreases the value of the progressbar, if a define is given all of its instances have decremented --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam[opt=1] number amount the amount to decrease the progressbar by -function ProgressBar.decrement(element,amount) - amount = type(amount) == 'number' and amount or 1 - - local define = get_define(element) - if define then - define:decrement(amount) - - else - local element_data = get_element(element) - - if element_data then - local real_amount = amount/element_data.maximum - element.value = element.value - real_amount - - if element.value <= 0 then - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = nil - return true - end - end - - end -end - ---- Creates a new progressbar element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new progressbar element define -function ProgressBar.new_progressbar(name) - - local self = Gui.new_define(ProgressBar._prototype,name) - self.draw_data.type = 'progressbar' - - self:on_draw(function(player,element,maximum) - if self.store then - local value = self:get_store(element) - if not value then - value = self.count_down and 1 or 0 - self:set_store(element,value) - end - element.value = value - - else - if self.count_down then - element.value = 1 - end - - if not ProgressBar.independent[self.name] then - ProgressBar.independent[self.name] = {} - end - - table.insert(ProgressBar.independent[self.name],{ - element = element, - maximum = maximum - }) - - end - - end) - - return self -end - ---- Sets the maximum value that represents the end value of the progress bar --- @tparam number amount the amount to have set as the maximum --- @treturn table the define to allow chaining -function ProgressBar._prototype:set_default_maximum(amount) - amount = amount > 0 and amount or error('amount must be greater than 0') - self.default_maximum = amount - return self -end - ---- Will set the progress bar to start at 1 and trigger when it hits 0 --- @tparam[opt=true] boolean state when true the bar will start filled, to be used with decrease --- @treturn table the define to allow chaining -function ProgressBar._prototype:use_count_down(state) - if state == false then - self.count_down = false - else - self.count_down = true - end - return self -end - ---- Main logic for changing the value of a progress bar, this only applies when its a registered define --- @tparam table self the define that is being changed --- @tparam number amount the amount which it is being changed by, may be negative --- @tparam[opt] string category the category to use with store --- @tparam[opt] function filter when given the filter must return true for the value of the element to be changed -local function change_value_prototype(self,amount,category,filter) - - local function reset_store() - local value = self.count_down and 1 or 0 - self:set_store(category,value) - end - - if self.store then - local value = self:get_store(category) or self.count_down and 1 or 0 - local maximum = self.default_maximum or 1 - local new_value = value + (amount/maximum) - - self:set_store(category,new_value) - - if self.count_down and new_value <= 0 - or not self.count_down and new_value >= 1 then - self:clear_store(category) - self:raise_event('on_store_complete',category,reset_store) - return - end - - return - end - - if ProgressBar.independent[self.name] then - for key,element_data in pairs(ProgressBar.independent[self.name]) do - local element = element_data.element - if not element or not element.valid then - ProgressBar.independent[self.name][key] = nil - - else - if not filter or filter(element) then - local maximum = element_data.maximum or self.default_maximum or 1 - element.value = element.value + (amount/maximum) - - if self.count_down and element.value <= 0 - or not self.count_down and element.value >= 1 then - ProgressBar.independent[self.name][key] = nil - event_call(self,element) - end - end - - end - end - end - -end - ---- Increases the value of the progressbar --- @tparam[opt=1] number amount the amount to increase the progressbar by --- @tparam[opt] string category the category that is used with a store -function ProgressBar._prototype:increment(amount,category) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,amount,category) -end - ---- Increases the value of the progressbar, if the filter condition is met, does not work with store --- @tparam[opt=1] number amount the amount to increase the progressbar by --- @tparam function filter the filter to be used -function ProgressBar._prototype:increment_filtered(amount,filter) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,amount,nil,filter) -end - ---- Decreases the value of the progressbar --- @tparam[opt=1] number amount the amount to decrease the progressbar by --- @tparam[opt] string category the category that is used with a store -function ProgressBar._prototype:decrement(amount,category) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,-amount,category) -end - ---- Decreases the value of the progressbar, if the filter condition is met, does not work with store --- @tparam[opt=1] number amount the amount to decrease the progressbar by --- @tparam function filter the filter to be used -function ProgressBar._prototype:decrement_filtered(amount,filter) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,-amount,nil,filter) -end - ---- Adds an element into the list of instances that will are waiting to complete, does not work with store --- note use store if you want persistent data, this only stores the elements not the values which they have --- @tparam LuaGuiElement element the element that you want to add into the waiting to complete list --- @tparam[opt] number maximum the maximum for this element if not given the default for this define is used -function ProgressBar._prototype:add_element(element,maximum) - if self.store then return end - if not ProgressBar.independent[self.name] then - ProgressBar.independent[self.name] = {} - end - table.insert(ProgressBar.independent[self.name],{ - element = element, - maximum = maximum - }) -end - ---- Resets an element, or its store, to be back at the start, either 1 or 0 --- @tparam LuaGuiElement element the element that you want to reset the progress of -function ProgressBar._prototype:reset_element(element) - if not element or not element.valid then return end - local value = self.count_down and 1 or 0 - if self.store then - self:set_store(element,value) - else - element.value = value - end -end - ---- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented --- @tparam[opt] function filter when given will use filtered increment --- @treturn function the event handler -function ProgressBar._prototype:event_counter(filter) - if type(filter) == 'function' then - return function() - self:increment_filtered(1,filter) - end - else - return function() - self:increment() - end - end -end - ---- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented --- @tparam[opt] function filter when given will use filtered decrement --- @treturn function the event handler -function ProgressBar._prototype:event_countdown(filter) - if type(filter) == 'function' then - return function() - self:decrement_filtered(1,filter) - end - else - return function() - self:decrement() - end - end -end - -return ProgressBar \ No newline at end of file diff --git a/expcore/gui/elements/slider.lua b/expcore/gui/elements/slider.lua deleted file mode 100644 index e8099b06..00000000 --- a/expcore/gui/elements/slider.lua +++ /dev/null @@ -1,173 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Sliders. --- Gui class define for sliders --- @section sliders - ---[[ ->>>> Functions - Slider.new_slider(name) --- Creates a new slider element define - - Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider - Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player - Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances -local Game = require 'utils.game' --- @dep utils.game - ---- Event call for on_value_changed and store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the slider -local function event_call(define,element,value) - local player = Game.get_player_by_index(element.player_index) - - local min,max = element.get_slider_minimum(),element.get_slider_maximum() - local delta = max-min - local percent = delta == 0 and 0 or (value-min)/delta - - define:raise_event('on_element_update',player,element,value,percent) - - local category = player.name - if define.categorize then - category = define.categorize(element) - end - - Instances.unregistered_get_elements(define.name..'-label',category,function(label) - label.caption = tostring(math.round(value,2)) - end) -end - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the slider -local function store_update(define,element,value) - element.slider_value = value - event_call(define,element,value) -end - -local Slider = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new slider element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new slider element define -function Slider.new_slider(name) - - local self = Gui.new_define(Slider._prototype,name) - self.draw_data.type = 'slider' - - self:on_draw(function(player,element) - local min,max = element.get_slider_minimum(),element.get_slider_maximum() - - if type(self.min) == 'function' then - min = self.min(player,element) - end - - if type(self.max) == 'function' then - max = self.max(player,element) - end - - element.set_slider_minimum_maximum(min,max) - - if self.store then - local value = self:get_store(element) - if value then element.slider_value = value end - end - - if self.auto_label then - self:draw_label(element.parent) - end - end) - - Gui.on_value_changed(self.name,function(event) - local element = event.element - local value = element.slider_value - - if self.store then - self:set_store(element,value) - - else - event_call(self,element,value) - - end - - end) - - return self -end - ---- Sets the range of a slider, if not used will use default values for a slider --- @tparam[opt] number min the minimum value that the slider can take --- @tparam[opt] number max the maximum value that the slider can take --- @treturn self the define to allow chaining -function Slider._prototype:set_range(min,max) - self.min = min - self.max = max - - if type(min) == 'number' then - self.draw_data.minimum_value = min - end - - if type(max) == 'number' then - self.draw_data.maximum_value = max - end - - return self -end - ---- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player --- @tparam LuaGuiElement element the parent element that the label will be drawn to --- @treturn LuaGuiElement the new label element so that styles can be applied -function Slider._prototype:draw_label(element) - local name = self.name..'-label' - if element[name] then return end - - local value = 0 - if self.store then - value = self:get_store(element) or 0 - end - - local new_element = element.add{ - name=name, - type='label', - caption=tostring(math.round(value,2)) - } - - local categorise = self.categorise or Gui.categorize_by_player - local category = categorise(new_element) - - Instances.unregistered_add_element(name,category,new_element) - - return new_element -end - ---- Enables auto draw of the label, the label will share the same parent element as the slider --- @tparam[opt=true] boolean state when false will disable the auto draw of the label --- @treturn self the define to allow chaining -function Slider._prototype:enable_auto_draw_label(state) - if state == false then - self.auto_label = false - else - self.auto_label = true - end - return self -end - -return Slider \ No newline at end of file diff --git a/expcore/gui/elements/text.lua b/expcore/gui/elements/text.lua deleted file mode 100644 index 56709ede..00000000 --- a/expcore/gui/elements/text.lua +++ /dev/null @@ -1,145 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Text. --- Gui class define for text fields and text boxes --- @section text - ---[[ ->>>> Functions - Text.new_text_field(name) --- Creates a new text field element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - - Text.new_text_box(name) --- Creates a new text box element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - Text._prototype_box:set_selectable(state) --- Sets the text box to be selectable - Text._prototype_box:set_word_wrap(state) --- Sets the text box to have word wrap - Text._prototype_box:set_read_only(state) --- Sets the text box to be read only - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new text for the text field -local function store_update(define,element,value) - element.text = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local Text = { - _prototype_field=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - }, - _prototype_box=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new text field element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new text field element define -function Text.new_text_field(name) - - local self = Gui.new_define(Text._prototype_field,name) - self.draw_data.type = 'textfield' - - self:on_draw(function(player,element) - if self.selectable then - element.selectable = true - end - - if self.word_wrap then - element.word_wrap = true - end - - if self.read_only then - element.read_only = true - end - - if self.store then - local value = self:get_store(element) - if value then element.text = value end - end - end) - - Gui.on_text_changed(self.name,function(event) - local element = event.element - local value = element.text - - if self.store then - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,value) - - end - - end) - - return self -end - ---- Creates a new text box element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new text box element define -function Text.new_text_box(name) - local self = Text.new_text_field(name) - self.draw_data.type = 'text-box' - - local mt = getmetatable(self) - mt.__index = Text._prototype_box - - return self -end - ---- Sets the text box to be selectable --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_selectable(state) - if state == false then - self.selectable = false - else - self.selectable = true - end - return self -end - ---- Sets the text box to have word wrap --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_word_wrap(state) - if state == false then - self.word_wrap = false - else - self.word_wrap = true - end - return self -end - ---- Sets the text box to be read only --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_read_only(state) - if state == false then - self.read_only = false - else - self.read_only = true - end - return self -end - -return Text \ No newline at end of file diff --git a/expcore/gui/instances.lua b/expcore/gui/instances.lua deleted file mode 100644 index 2db7273e..00000000 --- a/expcore/gui/instances.lua +++ /dev/null @@ -1,235 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Instances. --- This file is a breakout from core which forcues on instance management of defines --- @section instances - ---[[ ->>>> Using registered instance groups - The main use of this module is to register a group of elements referred here as "instances of an element define" in which - is meant that you define the name of a group of drawn elements that are really just multiple versions of a single element. - For example this might be that you have one label in multiple places (either for one player or many) and you want to update - the caption of all of them at once; this is where this module comes it. - - First you must register the way that the instances are stored and under what name, using Instances.register you will give the - name of the collective group of instances followed by an optional serializer function which allows variants to be stored under one - name (like one for each force or player) - - -- serializer works in the same way as store serializer - -- so the function will world here but no value is stored only gui elements - Instances.register('score',Gui.categorize_by_force) - - Then when you draw the new element to a gui you will want to add the element to the group: - - Instances.add_element('score',new_element) - - Then when you want to get the instances you have two options; Instances.get_elements or Instances.apply_to_elements when you want loop - over the elements it is more efficient to use apply_to_elements: - - Instances.get_elements('score','player') -- returns all elements that were added with the 'player' category - Instances.apply_to_elements('score','player',function(element) -- runs the function on every valid element - element.caption = 0 - end) - - Note that if you don't give a serializer function then you don't need to give a category when getting the elements. - ->>>> Using unregistered instance groups - When using a registered group and the functions that go with them it is much simpler to use and more importantly includes error checking - for valid instance group names; the down side is that the group must be registered which can only be done during start-up and not during runtime. - To counter this there are two functions similar to those above in order to add and get instances but may lead to errors not being noticed due to - the error internal error checking being skipped to allow it to work. - - The main difference between the two groups of functions is that the category must always be present even if is nil; example below shows how a - instance group would work when registered vs unregistered: - - -- Registered with category - Instances.register('score',Gui.categorize_by_force) -- force_store will return the force name of an element - Instances.add_element('score',new_element) -- the new element is added to the category based on in force - Instances.apply_to_elements('score','player',function(element) - element.caption = '0' - end) -- gets all instances from the player force and sets the caption to 0 - - -- Unregistered with category - Instances.unregistered_add_element('score','player',new_element) -- adds the new element to the player category - Instances.unregistered_apply_to_elements('score','player',function(element) - element.caption = '0' - end) -- gets all instances from the player force and sets the caption to 0 - - -- Registered without category; note that category can just be ignored - Instances.register('score') -- all instances will be under one group with no categories - Instances.add_element('score',new_element) -- adds the new element to the instance list - Instances.apply_to_elements('score',function(element) - element.caption = '0' - end) -- gets all instances and sets the element caption to 0 - - -- Unregistered without category; note that category must be given as nil - Instances.unregistered_add_element('score',nil,new_element) -- adds the new element to a single group with no categories - Instances.unregistered_apply_to_elements('score',nil,function(element) - element.caption = '0' - end) -- gets all instances and sets the element caption to 0 - ->>>> Functions - Instances.has_categories(name) --- Returns if a instance group has a serializer function; must be registered - Instances.is_registered(name) --- Returns if the given name is a registered instance group - Instances.register(name,serializer) --- Registers the name of an instance group to allow for storing element instances - - Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered - Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered - Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid - - Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered - Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered -]] -local Global = require 'utils.global' --- @dep utils.global - -local Instances = { - serializer={}, - data={} -} -Global.register(Instances.data,function(tbl) - Instances.data = tbl -end) - ---- Returns if a instance group has a serializer function; must be registered --- @tparam string name the name of the instance group --- @treturn boolean true if there is a serializer function -function Instances.has_categories(name) - return type(Instances.serializer[name]) == 'function' -end - ---- Returns if the given name is a registered instance group --- @tparam string name the name of the instance group you are testing --- @treturn boolean true if the name is registered -function Instances.is_registered(name) - return Instances.serializer[name] ~= nil -end - ---- Registers the name of an instance group to allow for storing element instances --- @tparam string name the name of the instance group; must to unique --- @tparam[opt] function serializer function used to turn the element into a string --- serializer param - element LuaGuiElement - the gui element to be turned into a string --- serializer return - string - the category that the element will be added to like the player's name or force's name --- @treturn string the name that was added so it can be used as a variable -function Instances.register(name,serializer) - if _LIFECYCLE ~= _STAGE.control then - return error('Can only be called during the control stage', 2) - end - - if Instances.serializer[name] then - return error('Instances for '..name..' already exist.',2) - end - - serializer = type(serializer) == 'function' and serializer or true - - Instances.data[name] = {} - Instances.serializer[name] = serializer - - return name -end - ---- Adds an element to the instance group under the correct category; must be registered --- @tparam string name the name of the instance group to add the element to --- @tparam LuaGuiElement element the element to add the the instance group -function Instances.add_element(name,element) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - if Instances.has_categories(name) then - local category = Instances.serializer[name](element) - if not Instances.data[name][category] then Instances.data[name][category] = {} end - table.insert(Instances.data[name][category],element) - else - table.insert(Instances.data[name],element) - end -end - ---- Gets all element instances without first removing any invalid ones; used internally and must be registered --- @tparam string name the name of the instance group to get the instances of --- @tparam[opt] string category the category to get the instance from, not needed when no serializer function --- @treturn table the table of element instances of which some may be invalid -function Instances.get_elements_raw(name,category) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - if Instances.has_categories(name) then - return Instances.data[name][category] or {} - else - return Instances.data[name] - end -end - ---- Gets all valid element instances and has the option of running a callback on those that are valid --- @tparam string name the name of the instance group to get the instances of --- @tparam[opt] string category the category to get the instances of, not needed when no serializer function --- @tparam[opt] function callback when given the callback will be ran on all valid elements --- callback param - element LuaGuiElement - the current valid element --- @treturn table the table of element instances with all invalid ones removed -function Instances.get_valid_elements(name,category,callback) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - category = category or callback - local elements = Instances.get_elements_raw(name,category) - local serializer = Instances.has_categories(name) - - for key,element in pairs(elements) do - if not element or not element.valid then - elements[key] = nil - else - if serializer and callback then callback(element) - elseif category then category(element) end - end - end - - return elements -end -Instances.get_elements = Instances.get_valid_elements -Instances.apply_to_elements = Instances.get_valid_elements - ---- A version of add_element that does not require the group to be registered --- @tparam string name the name of the instance group to add the element to --- @tparam ?string|nil category the category to add the element to, can be nil but must still be given --- @tparam LuaGuiElement element the element to add to the instance group -function Instances.unregistered_add_element(name,category,element) - if not Instances.data[name] then Instances.data[name] = {} end - if category then - if not Instances.data[name][category] then Instances.data[name][category] = {} end - table.insert(Instances.data[name][category],element) - else - table.insert(Instances.data[name],element) - end -end - ---- A version of get_elements that does not require the group to be registered --- @tparam string name the name of the instance group to get the instances of --- @tparam ?string|nil category the category to get the instances of, can be nil but must still be given --- @tparam[opt] function callback when given will be called on all valid instances --- callback param - element LuaGuiElement - the current valid element --- @treturn table the table of element instances with all invalid ones removed -function Instances.unregistered_get_elements(name,category,callback) - local elements = Instances.data[name] - if elements and category then - elements = elements[category] - end - - if not elements then return {} end - - for key,element in pairs(elements) do - if not element or not element.valid then - elements[key] = nil - else - if callback then callback(element) end - end - end - - return elements -end -Instances.unregistered_apply_to_elements = Instances.runtime_get_elements - -return Instances \ No newline at end of file diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua deleted file mode 100644 index 790375aa..00000000 --- a/expcore/gui/prototype.lua +++ /dev/null @@ -1,300 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Prototype. --- Used to create new gui prototypes see elements and concepts --- @section prototype - ---[[ - >>>> Functions - Constructor.event(event_name) --- Creates a new function to add functions to an event handler - Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables - Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define - Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set - - Prototype:uid() --- Gets the uid for the element define - Prototype:debug_name(value) --- Sets a debug alias for the define - Prototype:set_caption(value) --- Sets the caption for the element define - Prototype:set_tooltip(value) --- Sets the tooltip for the element define - Prototype:set_style(style,callback) --- Sets the style for the element define - Prototype:set_embedded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function - - Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails - Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails - - Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given - Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element - - Prototype:get_store(category) --- Gets the value in this elements store, category needed if serializer function used - Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if serializer function used - Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if serializer function used -]] -local Game = require 'utils.game' --- @dep utils.game -local Store = require 'expcore.store' --- @dep expcore.store -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances - -local Constructor = {} -local Prototype = {} - ---- Creates a new function to add functions to an event handler --- @tparam string event_name the name of the event that callbacks will be added to --- @treturn function the function used to register handlers -function Constructor.event(event_name) - --- Adds a callback as a handler for an event - -- @tparam table self the gui define being acted on - -- @tparam function callback the function that will be added as a handler for the event - -- @treturn table self returned to allowing chaining of functions - return function(self,callback) - if type(callback) ~= 'function' then - return error('Event callback for '..event_name..' must be a function',2) - end - - local handlers = self.events[event_name] - if not handlers then - handlers = {} - self.events[event_name] = handlers - end - - handlers[#handlers+1] = callback - return self - end -end - ---- Extents a prototype with the base functions of all gui prototypes, no metatables --- @tparam table new_prototype the prototype that you want to add the functions to --- @treturn table the same prototype but with the new functions added -function Constructor.extend(new_prototype) - for key,value in pairs(Prototype) do - if type(value) == 'table' then - new_prototype[key] = table.deepcopy(value) - else - new_prototype[key] = value - end - end - for key,value in pairs(new_prototype) do - if value == Constructor.event then - new_prototype[key] = Constructor.event(key) - end - end - return new_prototype -end - ---- Creates a new function which adds a store to a gui define --- @tparam function callback the function called when needing to update the value of an element --- @treturn function the function that will add a store for this define -function Constructor.store(callback) - --- Adds a store for the define that is shared between all instances of the define in the same category, serializer is a function that returns a string - -- @tparam self table the gui define being acted on - -- @tparam[opt] function serializer function used to determine the category of a LuaGuiElement, when omitted all share one single category - -- serializer param - LuaGuiElement element - the element that needs to be converted - -- serializer return - string - a deterministic string that references to a category such as player name or force name - -- @treturn self the element define to allow chaining - return function(self,serializer) - if self.store then return end - serializer = serializer or function() return '' end - - self.store = Store.register(serializer) - - Instances.register(self.name,serializer) - - Store.watch(self.store,function(value,category) - self:raise_event('on_store_update',value,category) - - if Instances.is_registered(self.name) then - Instances.apply_to_elements(self.name,category,function(element) - callback(self,element,value) - end) - end - end) - - return self - end -end - ---- Creates a setter function that checks the type when a value is set --- @tparam string value_type the type that the value should be when it is set --- @tparam string key the key of the define that will be set --- @tparam[opt] string second_key allows for setting of a key in a sub table --- @treturn function the function that will check the type and set the value -function Constructor.setter(value_type,key,second_key) - local display_message = 'Gui define '..key..' must be of type '..value_type - if second_key then - display_message = 'Gui define '..second_key..' must be of type '..value_type - end - - local locale = false - if value_type == 'locale-string' then - locale = true - value_type = 'table' - end - - return function(self,value) - local v_type = type(value) - if v_type ~= value_type and (not locale or v_type ~= 'string') then - error(display_message,2) - end - - if second_key then - self[key][second_key] = value - else - self[key] = value - end - - return self - end -end - ---- Gets the uid for the element define --- @treturn string the uid of this element define -function Prototype:uid() - return self.name -end - ---- Sets a debug alias for the define --- @tparam string name the debug name for the element define that can be used to get this element define --- @treturn self the element define to allow chaining -Prototype.debug_name = Constructor.setter('string','debug_name') - ---- Sets the caption for the element define --- @tparam string caption the caption that will be drawn with the element --- @treturn self the element define to allow chaining -Prototype.set_caption = Constructor.setter('locale-string','draw_data','caption') - ---- Sets the tooltip for the element define --- @tparam string tooltip the tooltip that will be displayed for this element when drawn --- @treturn self the element define to allow chaining -Prototype.set_tooltip = Constructor.setter('locale-string','draw_data','tooltip') - ---- Sets an authenticator that blocks the draw function if check fails --- @tparam function callback the function that will be ran to test if the element should be drawn or not --- callback param - LuaPlayer player - the player that the element is being drawn to --- callback param - string define_name - the name of the define that is being drawn --- callback return - boolean - false will stop the element from being drawn --- @treturn self the element define to allow chaining -Prototype.set_pre_authenticator = Constructor.setter('function','pre_authenticator') - ---- Sets an authenticator that disables the element if check fails --- @tparam function callback the function that will be ran to test if the element should be enabled or not --- callback param - LuaPlayer player - the player that the element is being drawn to --- callback param - string define_name - the name of the define that is being drawn --- callback return - boolean - false will disable the element --- @treturn self the element define to allow chaining -Prototype.set_post_authenticator = Constructor.setter('function','post_authenticator') - ---- Registers a callback to the on_draw event --- @tparam function callback --- callback param - LuaPlayer player - the player that the element was drawn to --- callback param - LuaGuiElement element - the element that was drawn --- callback param - any ... - any other params passed by the draw_to function -Prototype.on_draw = Constructor.event('on_draw') - ---- Registers a callback to the on_style_update event --- @tparam function callback --- callback param - LuaStyle style - the style that was changed and/or needs changing -Prototype.on_style_update = Constructor.event('on_style_update') - ---- Sets the style for the element define --- @tparam string style the style that will be used for this element when drawn --- @tparam[opt] function callback function is called when element is drawn to alter its style --- @treturn self the element define to allow chaining -function Prototype:set_style(style,callback) - self.draw_data.style = style - if callback then - self:on_style_update(callback) - end - return self -end - ---- Sets the element to be drawn inside a nameless flow, can be given a name using a function --- @tparam ?boolean|function state when true a padless flow is created to contain the element --- @treturn self the element define to allow chaining -function Prototype:set_embedded_flow(state) - if state == false or type(state) == 'function' then - self.embedded_flow = state - else - self.embedded_flow = true - end - return self -end - ---- Raises a custom event for this define, any number of params can be given --- @tparam string event_name the name of the event that you want to raise --- @tparam any ... any params that you want to pass to the event --- @treturn number the number of handlers that were registered -function Prototype:raise_event(event_name,...) - local handlers = self.events[event_name] - if handlers then - for _,handler in pairs(handlers) do - handler(...) - end - end - return handlers and #handlers or 0 -end - ---- The main function for defines, when called will draw an instance of this define to the given element --- what is drawn is based on the data in draw_data which is set using other functions --- @tparam LuaGuiElement element the element that the define will draw a instance of its self onto --- @treturn LuaGuiElement the new element that was drawn -function Prototype:draw_to(element,...) - local name = self.name - if element[name] then return end - local player = Game.get_player_by_index(element.player_index) - - if self.pre_authenticator then - if not self.pre_authenticator(player,self.name) then return end - end - - if self.embedded_flow then - local embedded_name - if type(self.embedded_flow) == 'function' then - embedded_name = self.embedded_flow(element,...) - end - element = element.add{type='flow',name=embedded_name} - element.style.padding = 0 - end - - local new_element = element.add(self.draw_data) - - self:raise_event('on_style_update',new_element.style) - - if self.post_authenticator then - new_element.enabled = self.post_authenticator(player,self.name) - end - - if Instances.is_registered(self.name) then - Instances.add_element(self.name,new_element) - end - - self:raise_event('on_draw',player,new_element,...) - - return new_element -end - ---- Gets the value in this elements store, category needed if serializer function used --- @tparam string category[opt] the category to get such as player name or force name --- @treturn any the value that is stored for this define -function Prototype:get_store(category) - if not self.store then return end - return Store.get(self.store,category) -end - ---- Sets the value in this elements store, category needed if serializer function used --- @tparam string category[opt] the category to get such as player name or force name --- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc --- @treturn boolean true if the value was set -function Prototype:set_store(category,value) - if not self.store then return end - return Store.set(self.store,category,value) -end - ---- Sets the value in this elements store to nil, category needed if serializer function used --- @tparam[opt] string category the category to get such as player name or force name --- @treturn boolean true if the value was set -function Prototype:clear_store(category) - if not self.store then return end - return Store.clear(self.store,category) -end - -return Constructor \ No newline at end of file diff --git a/expcore/gui/test.lua b/expcore/gui/test.lua deleted file mode 100644 index 37cc54f8..00000000 --- a/expcore/gui/test.lua +++ /dev/null @@ -1,663 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias tests -]] - ---- Test. --- This file creates a test gui that is used to test every input method --- note that this does not cover every permutation only features in independence --- for example store in most cases is just by player name, but other store methods are tested with checkbox --- @section test - -local Gui = require 'expcore.gui' --- @dep expcore.gui -local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_colour','table_keys') --- @dep expcore.common -local Colors = require 'resources.color_presets' --- @dep resources.color_presets -local Event = require 'utils.event' --- @dep utils.event -local Store = require 'expcore.store' --- @dep expcore.store - -local tests = {} - ---[[ - Toolbar Tests - > No display - Toolbar button with no display - > With caption - Toolbar button with a caption display - > With icons - Toolbar button with an icon -]] - -Gui.new_toolbar_button('click-1') -:set_post_authenticator(function(player,button_name) - return global.click_one -end) -:on_click(function(player,element) - player.print('CLICK 1') -end) - -Gui.new_toolbar_button('click-2') -:set_caption('Click Two') -:set_post_authenticator(function(player,button_name) - return global.click_two -end) -:on_click(function(player,element) - player.print('CLICK 2') -end) - -Gui.new_toolbar_button('click-3') -:set_sprites('utility/questionmark') -:set_post_authenticator(function(player,button_name) - return global.click_three -end) -:on_click(function(player,element) - player.print('CLICK 3') -end) - ---[[ - Center Frame Tests - > Main test gui - Main test gui triggers all other tests -]] - -local test_gui = -Gui.new_center_frame('gui-test-open') -:set_caption('Open Test Gui') -:set_tooltip('Main test gui triggers all other tests') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) - -:on_creation(function(player,frame) - for test_group_name,test_group in pairs(tests) do - - player.print('Starting tests for: '..format_chat_colour(test_group_name,Colors.cyan)) - - local pass_count = 0 - local test_count = 0 - - local flow = frame.add{ - type='flow', - name=test_group_name, - direction='vertical' - } - - for test_name,test in pairs(test_group) do - local test_function = type(test) == 'function' and test or test.draw_to - test_count = test_count+1 - - local success,err = pcall(test_function,test,flow) - if success then - pass_count = pass_count+1 - else - player.print('Failed Test: '..format_chat_colour(test_name,Colors.red)) - log('Gui Test Failed: '..test_name..' stacktrace:\n'..err) - end - - end - - if pass_count == test_count then - player.print('All tests '..format_chat_colour('passed',Colors.green)..' ('..test_group_name..')') - else - player.print('Passed '..format_chat_colour(pass_count..'/'..test_count,Colors.cyan)..' ('..test_group_name..')') - end - - end -end) - ---[[ - Left Frame Test - > Left frame which holds all online player names, updates when player leaves or joins -]] - -local left_frame = -Gui.new_left_frame('test-left-frame') -:set_caption('Test Left Gui') -:set_tooltip('Left frame which holds all online player names, updates when player leaves or joins') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) - -:set_open_by_default() -:on_creation(function(_player,frame) - for _,player in pairs(game.connected_players) do - frame.add{ - type='label', - caption=player.name - } - end -end) - -Event.add(defines.events.on_player_joined_game,left_frame 'update_all') -Event.add(defines.events.on_player_left_game,left_frame 'update_all') - ---[[ - Popup Test - > Allows opening a popup which contains the players name and tick it was opened -]] - -local test_popup = -Gui.new_popup('test-popup') -:on_creation(function(player,frame) - frame.add{ - type='label', - caption=player.name - } - frame.add{ - type='label', - caption=game.tick - } -end) - -Gui.new_toolbar_button('test-popup-open') -:set_caption('Test Popup') -:set_tooltip('Allows opening a popup which contains the players name and tick it was opened') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) -:on_click(function(player,element) - test_popup(player,300) -end) - ---[[ - Button Tests - > No display - Simple button which has no display - > Caption - Simple button but has a caption on it - > Icons - Button with an icon display plus two icons for hover and select - > Auth - Button which can only be passed when auth is true (press no display to toggle; needs reopen) -]] - -local button_no_display = -Gui.new_button('test-button-no-display') -:set_tooltip('Button no display') -:on_click(function(player,element) - player.print('Button no display') - global.test_auth_button = not global.test_auth_button - player.print('Auth Button auth state: '..tostring(global.test_auth_button)) -end) - -local button_with_caption = -Gui.new_button('test-button-with-caption') -:set_tooltip('Button with caption') -:set_caption('Button Caption') -:on_click(function(player,element) - player.print('Button with caption') -end) - -local button_with_icon = -Gui.new_button('test-button-with-icon') -:set_tooltip('Button with icons') -:set_sprites('utility/warning_icon','utility/warning','utility/warning_white') -:on_click(function(player,element) - player.print('Button with icons') -end) - -local button_with_auth = -Gui.new_button('test-button-with-auth') -:set_tooltip('Button with auth') -:set_post_authenticator(function(player,button_name) - return global.test_auth_button -end) -:on_click(function(player,element) - player.print('Button with auth') -end) - -tests.Buttons = { - ['No display']=button_no_display, - ['Caption']=button_with_caption, - ['Icons']=button_with_icon, - ['Auth']=button_with_auth -} - ---[[ - Checkbox Test - > Local -- Simple checkbox that can toggle - > Game store -- Checkbox which syncs its state between all players - > Force store -- Checkbox which syncs its state with all players on the same force - > Player store -- Checkbox that stores its state between re-draws -]] - -local checkbox_local = -Gui.new_checkbox('test-checkbox-local') -:set_tooltip('Checkbox local') -:set_caption('Checkbox Local') -:on_element_update(function(player,element,state) - player.print('Checkbox local: '..tostring(state)) -end) - -local checkbox_game = -Gui.new_checkbox('test-checkbox-store-game') -:set_tooltip('Checkbox store game') -:set_caption('Checkbox Store Game') -:add_store() -:on_element_update(function(player,element,state) - player.print('Checkbox store game: '..tostring(state)) -end) - -local checkbox_force = -Gui.new_checkbox('test-checkbox-store-force') -:set_tooltip('Checkbox store force') -:set_caption('Checkbox Store Force') -:add_store(Gui.categorize_by_force) -:on_element_update(function(player,element,state) - player.print('Checkbox store force: '..tostring(state)) -end) - -local checkbox_player = -Gui.new_checkbox('test-checkbox-store-player') -:set_tooltip('Checkbox store player') -:set_caption('Checkbox Store Player') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,state) - player.print('Checkbox store player: '..tostring(state)) -end) - -tests.Checkboxes = { - ['Local']=checkbox_local, - ['Game store']=checkbox_game, - ['Force store']=checkbox_force, - ['Player store']=checkbox_player -} - ---[[ - Radiobutton Tests - > Local -- Simple radiobutton that can only be toggled true - > Player store -- Radio button that saves its state between re-draws - > Option set -- A set of radio buttons where only one can be true at a time -]] - -local radiobutton_local = -Gui.new_radiobutton('test-radiobutton-local') -:set_tooltip('Radiobutton local') -:set_caption('Radiobutton Local') -:on_element_update(function(player,element,state) - player.print('Radiobutton local: '..tostring(state)) -end) - -local radiobutton_player = -Gui.new_radiobutton('test-radiobutton-store') -:set_tooltip('Radiobutton store') -:set_caption('Radiobutton Store') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,state) - player.print('Radiobutton store: '..tostring(state)) -end) - -local radiobutton_option_set = -Gui.new_radiobutton_option_set(function(value,category) - game.print('Radiobutton option set for: '..category..' is now: '..tostring(value)) -end,Gui.categorize_by_player) - -local radiobutton_option_one = -Gui.new_radiobutton('test-radiobutton-option-one') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option One') -:add_as_option(radiobutton_option_set,'One') -:on_element_update(function(player,element,state) - player.print('Radiobutton option one: '..tostring(state)) -end) - -local radiobutton_option_two = -Gui.new_radiobutton('test-radiobutton-option-two') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option Two') -:add_as_option(radiobutton_option_set,'Two') -:on_element_update(function(player,element,state) - player.print('Radiobutton option two: '..tostring(state)) -end) - -local radiobutton_option_three = -Gui.new_radiobutton('test-radiobutton-option-three') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option Three') -:add_as_option(radiobutton_option_set,'Three') -:on_element_update(function(player,element,state) - player.print('Radiobutton option three: '..tostring(state)) -end) - -tests.Radiobuttons = { - ['Local']=radiobutton_local, - ['Player store']=radiobutton_player, - ['Option set']=function(self,frame) - Gui.draw_option_set(radiobutton_option_set,frame) - end -} - ---[[ - Dropdown Test - > Local static general -- Simple dropdown with all static options and general handler - > Player startic general -- Dropdown with all static options and general handler and stores option between re-draws - > Local static case -- Dropdown with all static options but case handlers and a general handler - > Player static case -- Dropdown with all static options but case handlers and a general handler and stores option between re-draws - > Local dynamic -- Dropdown with one static option with the reset generated by a function - > Player dynamic -- Dropdown with one static option with the reset generated by a function and stores option between re-draws -]] - -local dropdown_local_static_general = -Gui.new_dropdown('test-dropdown-local-static-general') -:set_tooltip('Dropdown local static general') -:add_options('One','Two','Three','Four') -:on_element_update(function(player,element,value) - player.print('Dropdown local static general: '..tostring(value)) -end) - -local dropdown_player_static_general = -Gui.new_dropdown('test-dropdown-store-static-general') -:set_tooltip('Dropdown store static general') -:add_options('One','Two','Three','Four') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store static general: '..tostring(value)) -end) - -local function print_option_selected_1(player,element,value) - player.print('Dropdown local static case (case): '..tostring(value)) -end - -local dropdown_local_static_case = -Gui.new_dropdown('test-dropdown-local-static-case') -:set_tooltip('Dropdown local static case') -:add_options('One','Two') -:add_option_callback('One',print_option_selected_1) -:add_option_callback('Two',print_option_selected_1) -:add_option_callback('Three',print_option_selected_1) -:add_option_callback('Four',print_option_selected_1) -:on_element_update(function(player,element,value) - player.print('Dropdown local static case (general): '..tostring(value)) -end) - -local function print_option_selected_2(player,element,value) - player.print('Dropdown store static case (case): '..tostring(value)) -end - -local dropdown_player_static_case = -Gui.new_dropdown('test-dropdown-store-static-case') -:set_tooltip('Dropdown store static case') -:add_store(Gui.categorize_by_player) -:add_options('One','Two') -:add_option_callback('One',print_option_selected_2) -:add_option_callback('Two',print_option_selected_2) -:add_option_callback('Three',print_option_selected_2) -:add_option_callback('Four',print_option_selected_2) -:on_element_update(function(player,element,value) - player.print('Dropdown store static case (general): '..tostring(value)) -end) - -local dropdown_local_dynamic = -Gui.new_dropdown('test-dropdown-local-dynamic') -:set_tooltip('Dropdown local dynamic') -:add_options('Static') -:add_dynamic(function(player,element) - return table_keys(Colors) -end) -:on_element_update(function(player,element,value) - player.print('Dropdown local dynamic: '..tostring(value)) -end) - -local dropdown_player_dynamic = -Gui.new_dropdown('test-dropdown-store-dynamic') -:set_tooltip('Dropdown store dynamic') -:add_options('Static') -:add_dynamic(function(player,element) - return table_keys(Colors) -end) -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store dynamic: '..tostring(value)) -end) - -tests.Dropdowns = { - ['Local static general']=dropdown_local_static_general, - ['Player startic general']=dropdown_player_static_general, - ['Local static case']=dropdown_local_static_case, - ['Player static case']=dropdown_player_static_case, - ['Local dynamic general']=dropdown_local_dynamic, - ['Player dynamic general']=dropdown_player_dynamic -} - ---[[ - List Box Tests - > Local -- A list box with all static options and general handler - > Store -- A list box with all static options and general handler and stores options between re-draws -]] - -local list_box_local = -Gui.new_list_box('test-list-box-local') -:set_tooltip('List box local') -:add_options('One','Two','Three','Four') -:on_element_update(function(player,element,value) - player.print('Dropdown local: '..tostring(value)) -end) - -local list_box_player = -Gui.new_list_box('test-list-box-store') -:set_tooltip('List box store') -:add_options('One','Two','Three','Four') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store: '..tostring(value)) -end) - -tests["List Boxes"] = { - ['Local']=list_box_local, - ['Player']=list_box_player -} - ---[[ - Slider Tests - > Local default -- Simple slider with default range - > Store default -- Slider with default range that stores value between re-draws - > Static range -- Simple slider with a static range - > Dynamic range -- Slider with a dynamic range - > Local label -- Simple slider with default range which has a label - > Store label -- Slider with default range which has a label and stores value between re-draws -]] - -local slider_local_default = -Gui.new_slider('test-slider-local-default') -:set_tooltip('Slider local default') -:on_element_update(function(player,element,value,percent) - player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - - -local slider_player_default = -Gui.new_slider('test-slider-store-default') -:set_tooltip('Slider store default') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value,percent) - player.print('Slider store default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local slider_static = -Gui.new_slider('test-slider-static-range') -:set_tooltip('Slider static range') -:set_range(5,50) -:on_element_update(function(player,element,value,percent) - player.print('Slider static range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local slider_dynamic = -Gui.new_slider('test-slider-dynamic-range') -:set_tooltip('Slider dynamic range') -:set_range(function(player,element) - return player.index - 5 -end,function(player,element) - return player.index + 4 -end) -:on_element_update(function(player,element,value,percent) - player.print('Slider dynamic range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local label_slider_local = -Gui.new_slider('test-slider-local-label') -:set_tooltip('Slider local label') -:enable_auto_draw_label() -:on_element_update(function(player,element,value,percent) - player.print('Slider local label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local label_slider_player = -Gui.new_slider('test-slider-store-label') -:set_tooltip('Slider store label') -:enable_auto_draw_label() -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value,percent) - player.print('Slider store label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -tests.Sliders = { - ['Local default']=slider_local_default, - ['Player default']=slider_player_default, - ['Static range']=slider_static, - ['Dynamic range']=slider_dynamic, - ['Local label']=function(self,frame) - local flow = frame.add{type='flow'} - label_slider_local:draw_to(flow) - end, - ['Player label']=function(self,frame) - local flow = frame.add{type='flow'} - label_slider_player:draw_to(flow) - end -} - ---[[ - Text Tests - > Local field -- Simple text field - > Store field -- Test field that stores text between re-draws - > Local box -- Simple text box - > Wrap box -- Text box which has word wrap and selection disabled -]] - -local text_filed_local = -Gui.new_text_filed('test-text-field-local') -:set_tooltip('Text field local') -:on_element_update(function(player,element,value) - player.print('Text field local: '..value) -end) - -local text_filed_store = -Gui.new_text_filed('test-text-field-store') -:set_tooltip('Text field store') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Text field store: '..value) -end) - -local text_box_local = -Gui.new_text_box('test-text-box-local') -:set_tooltip('Text box local') -:on_element_update(function(player,element,value) - player.print('Text box local: '..value) -end) - -local text_box_wrap = -Gui.new_text_box('test-text-box-wrap') -:set_tooltip('Text box wrap') -:set_selectable(false) -:set_word_wrap() -:on_element_update(function(player,element,value) - player.print('Text box wrap: '..value) -end) - -tests.Texts = { - ['Local field']=text_filed_local, - ['Store field']=text_filed_store, - ['Local box']=text_box_local, - ['Wrap box']=text_box_wrap -} - ---[[ - Elem Button Tests - > Local -- Simple elem button - > Default -- Simple elem button which has a default value - > Function -- Elem button which has a dynamic default - > Store -- Elem button which stores its value between re-draws -]] - -local elem_local = -Gui.new_elem_button('test-elem-local') -:set_tooltip('Elem') -:set_type('item') -:on_element_update(function(player,element,value) - player.print('Elem: '..value) -end) - -local elem_default = -Gui.new_elem_button('test-elem-default') -:set_tooltip('Elem default') -:set_type('item') -:set_default('iron-plate') -:on_element_update(function(player,element,value) - player.print('Elem default: '..value) -end) - -local elem_function = -Gui.new_elem_button('test-elem-function') -:set_tooltip('Elem function') -:set_type('item') -:set_default(function(player,element) - return 'iron-plate' -end) -:on_element_update(function(player,element,value) - player.print('Elem function: '..value) -end) - -local elem_store = -Gui.new_elem_button('test-elem-store') -:set_tooltip('Elem store') -:set_type('item') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Elem store: '..value) -end) - -tests["Elem Buttons"] = { - ['Local']=elem_local, - ['Default']=elem_default, - ['Function']=elem_function, - ['Store']=elem_store -} - ---[[ - Progress bar tests - > Simple -- Progress bar that fills every 2 seconds - > Store -- Progress bar that fills every 5 seconds with synced value - > Reverse -- Progress bar that decreases every 2 seconds -]] - -local progressbar_one = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(120) -:on_complete(function(player,element,reset_element) - reset_element() -end) - -local progressbar_two = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(300) -:add_store(Gui.categorize_by_force) -:on_complete(function(player,element,reset_element) - reset_element() -end) -:on_store_complete(function(category,reset_store) - reset_store() -end) - -local progressbar_three = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(120) -:use_count_down() -:on_complete(function(player,element,reset_element) - reset_element() -end) - -Event.add(defines.events.on_tick,function() - progressbar_one:increment() - progressbar_three:decrement() - local categories = Store.get(progressbar_two.store) or {} - for category,_ in pairs(categories) do - progressbar_two:increment(1,category) - end -end) - -tests["Progress Bars"] = { - ['Simple']=progressbar_one, - ['Store']=progressbar_two, - ['Reverse']=progressbar_three -} \ No newline at end of file From f7cff8b2361825ecb8f6e6d88adf2cf64c53b6d5 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 01:44:41 +0100 Subject: [PATCH 02/21] Task List Updated --- config/_file_loader.lua | 4 +- config/tasks.lua | 11 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 35 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 2 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 875 +++++++++++++++++- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 29 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 156 +++- docs/guis/Warps-List.html | 2 +- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- expcore/gui.lua | 391 ++++++-- expcore/store.lua | 34 +- modules/control/tasks.lua | 2 +- modules/gui/task-list.lua | 624 ++++++++----- 98 files changed, 1849 insertions(+), 488 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 44f73644..b7ccbd92 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -42,15 +42,13 @@ return { --'modules.gui.rocket-info', --'modules.gui.science-info', --'modules.gui.warp-list', - --'modules.gui.task-list', + 'modules.gui.task-list', --'modules.gui.player-list', --'modules.commands.debug', - 'expcore.gui', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config 'config.expcore-commands.auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups 'config.roles', -- loads some predefined roles - --'expcore.gui.test' -- loads multiple gui defines to test the gui system } \ No newline at end of file diff --git a/config/tasks.lua b/config/tasks.lua index 95165ee0..994acff8 100644 --- a/config/tasks.lua +++ b/config/tasks.lua @@ -2,8 +2,11 @@ -- @config Tasks return { - any_user_can_add_new_task = true, --- @setting any_user_can_add_new_task when false only people with edit permission can make new reports - user_can_edit_own_tasks = true, --- @setting user_can_edit_own_tasks when false only people with edit permission can edit reports - only_admins_can_edit = false, --- @setting only_admins_can_edit true will hide the edit and delete buttons from non (game) admins - edit_tasks_role_permission = 'gui/task-list/edit' --- @setting edit_tasks_role_permission value used with custom permission system + -- values can be all, admin, expcore.roles, none + allow_add_task = 'all', --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none + expcore_roles_add_permission = 'gui/task-list/add', --- @setting expcore_roles_add_permission if expcore.roles is used then this is the required permission + -- values can be all, admin, expcore.roles, none + allow_edit_task = 'expcore.roles', --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none + expcore_roles_edit_permission = 'gui/task-list/edit', --- @setting expcore_roles_edit_permission if expcore.roles is used then this is the required permission + user_can_edit_own_tasks = true --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting } \ No newline at end of file diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 4871b8c9..4fc1a161 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 3efd7ce5..31bafcd7 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index c5d3cfc4..740ed70e 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 57a4a065..6fb21b76 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index f42f7dee..4f5b7ae2 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 6f540b7d..8983690a 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e9f689ac..e0085ca5 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 06a8e29a..5de171a9 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 806b86fd..08b4fc10 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index bcfab620..dcc7f831 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 7f9b0c0a..54a470ef 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 0a936c4e..894d9fd7 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index e7e42cdd..bb480f1c 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 53b422c3..11a3faa5 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index 17ef4f9d..fb090d39 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 880bb18e..1960d836 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index f8d25958..ac910592 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index b7d54d80..5488f96a 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index d279fe65..371db9aa 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index 8458181f..ef15886c 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 214140d6..5f07e558 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index 421f28a9..a892d1aa 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index a31f9a45..c6e4fa94 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index 439294a8..d7dd8363 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 98e6942b..6225e155 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 1957df69..2c739395 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index 0f9bc8b1..d94c73f6 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index f72dbee2..24f01cf0 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 60783e88..2dd125fd 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 353738fe..8a4262f3 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index d33d1547..884b4a42 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 94b0896f..7d0e5d3d 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index e7bb072a..9612f09e 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index ee1e2dd2..021275cd 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index 157b0311..dd7c7ddb 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 59a9ed26..689ef12e 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index b299522c..9f3db256 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 42155a89..de12ef31 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 8128d402..76a3b440 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 0932f52e..d3162a9e 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 1e635943..38e0eee2 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 7214429c..f9d7156b 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 21a5ee90..9331d05b 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 1ab7621e..3deb9a8e 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index bd67fe6b..2d91ee39 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index d775b006..64fa59aa 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index 02436326..f648a0f5 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 2d2a05a7..267b19c9 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 5141d747..0449a9f1 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index f011e724..8d50f302 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index e435071a..33b1ba00 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index bea29f94..6aa0aa00 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index f271bf65..df64e68c 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index a1a68698..0cd0d9f7 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index e4f9760a..8a8ae44b 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -241,16 +241,16 @@ - any_user_can_add_new_task + allow_add_task - user_can_edit_own_tasks + expcore_roles_add_permission - only_admins_can_edit + allow_edit_task - edit_tasks_role_permission + expcore_roles_edit_permission @@ -264,15 +264,15 @@
    - # - any_user_can_add_new_task + # + allow_add_task

    -

    when false only people with edit permission can make new reports

    +

    dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none

    @@ -291,15 +291,16 @@
    - # - user_can_edit_own_tasks + # + expcore_roles_add_permission

    -

    when false only people with edit permission can edit reports

    +

    if expcore.roles is used then this is the required permission + values can be all, admin, expcore.roles, none

    @@ -318,15 +319,15 @@
    - # - only_admins_can_edit + # + allow_edit_task

    -

    true will hide the edit and delete buttons from non (game) admins

    +

    dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none

    @@ -345,15 +346,15 @@
    - # - edit_tasks_role_permission + # + expcore_roles_edit_permission

    -

    value used with custom permission system

    +

    if expcore.roles is used then this is the required permission

    @@ -384,7 +385,7 @@ generated by LDoc
    diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 751529ef..2a237eb2 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 3840e9b9..5ef899b2 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -684,7 +684,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 8ed47a2e..a809745f 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index 2cac6422..12a57823 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 16391654..a239a42c 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index 831e5343..a11e1edc 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index c68201ec..cbe14682 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index ff7f7802..84f5e53c 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 7791b32f..16a7f9de 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 075e5bb8..545ac82f 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index caba804c..fedadfc1 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 74601e95..c438edc4 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -48,6 +48,7 @@ + @@ -214,6 +215,7 @@ + @@ -245,34 +247,58 @@

    Usage

    -- Defining a button that prints the player's name
     local example_button =
    -Gui.new_element{
    +Gui.element{
         type = 'button',
         caption = 'Example Button'
     }
    -:on_click(function(event)
    -    local player = event.player
    +:on_click(function(player,element,event)
         player.print(player.name)
     end)
    -
    -- Defining using a custom function
    +    
    -- Defining a button with a custom style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style{
    +    height = 25,
    +    width = 100
    +}
    +:on_click(function(player,element,event)
    +    player.print(player.name)
    +end)
    +
    -- Defining a button using a custom function
     local example_flow_with_button =
    -Gui.new_element(function(event_trigger,parent)
    -    local flow =
    +Gui.element(function(event_trigger,parent)
    +    -- Add the flow the button is in
    +    local flow =
         parent.add{
             name = 'example_flow',
             type = 'flow'
         }
     
    -    local element =
    +    -- Get the players name
    +    local player = game.players[parent.player_index]
    +    local player_name = player.name
    +
    +    -- Add the button
    +    local element =
         flow.add{
             name = event_trigger,
             type = 'button',
    -        caption = 'Example Button'
    +        caption = 'Example Button: '..player_name
         }
     
    -    return element
    +    -- Set the style of the button
    +    local style = element.style
    +    style.height = 25
    +    style.width = 100]
    +    style.font_color = player.color
    +
    +    -- Return the element
    +    return element
     end)
    -:on_click(function(event)
    -    local player = event.player
    +:on_click(function(player,element,event)
         player.print(player.name)
     end)
    -- Drawing an element
    @@ -321,7 +347,7 @@ Gui.new_element(function(event_trigger,parent)
         
         
         _prototype_element
    -    The element prototype which is returned from Gui.new_element
    +    The element prototype which is returned from Gui.element
         
         
         _mt_element
    @@ -348,10 +374,14 @@ Gui.new_element(function(event_trigger,parent)
         
         
         
    -    new_element(element_define)
    +    element(element_define)
         Base function used to define new elements, can be used with a table or with a function
         
         
    +    Gui._prototype_element:style(style_define)
    +    Extension of Gui.element when using the table method, values applied after the element is drawn
    +    
    +    
         Gui._prototype_element:add_to_top_flow([authenticator])
         Adds an element to be drawn to the top flow when a player joins
         
    @@ -428,6 +458,10 @@ Gui.new_element(function(event_trigger,parent)
         Button which toggles the top flow elements
         
         
    +    top_flow_button_style
    +    The style that should be used for buttons on the top flow
    +    
    +    
         get_top_flow(player)
         Gets the flow which contains the elements for the top flow
         
    @@ -465,6 +499,42 @@ Gui.new_element(function(event_trigger,parent)
         
         
         
    +    
    +    
    +    

    Helper Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    get_player_from_element(element)Get the player that owns a gui element
    toggle_enabled_state(element[, state])Will toggle the enabled state of an element or set it to the one given
    toggle_visible_state(element[, state])Will toggle the visible state of an element or set it to the one given
    destroy_if_valid(element)Destory a gui element without causing any errors, likly if the element may have already been removed
    alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment'])Draw a flow that has custom element alignments, default is right align
    scroll_table(parent, height, column_count[, name='scroll'])Draw a scroll pane that has a table inside of it
    header(parent, caption[, tooltip][, add_alignment=false][, name='header'])Used to add a header to a frame, this has the option for a custom right alignment flow for buttons

    @@ -643,7 +713,7 @@ Gui.new_element(function(event_trigger,parent)
    -

    The element prototype which is returned from Gui.new_element

    +

    The element prototype which is returned from Gui.element

    @@ -764,8 +834,8 @@ Gui.new_element(function(event_trigger,parent)
    - # - new_element(element_define) + # + element(element_define)
    @@ -818,27 +888,115 @@ Gui.new_element(function(event_trigger,parent) Usage:
    -- Defining an element with a table
     local example_button =
    -Gui.new_element{
    +Gui.element{
         type = 'button',
         caption = 'Example Button'
     }
    -- Defining an element with a function
     local example_flow_with_button =
    -Gui.new_element(function(event_trigger,parent)
    -    local flow =
    +Gui.element(function(event_trigger,parent,...)
    +    -- Add the flow the button is in
    +    local flow =
         parent.add{
             name = 'example_flow',
             type = 'flow'
         }
     
    -    local element =
    +    -- Add the button
    +    local element =
         flow.add{
             name = event_trigger,
             type = 'button',
             caption = 'Example Button'
         }
     
    -    return element
    +    -- Set the style of the button
    +    local style = element.style
    +    style.height = 25
    +    style.width = 100
    +
    +    -- Return the element
    +    return element
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:style(style_define) +
    +
    +
    +
    + +

    Extension of Gui.element when using the table method, values applied after the element is drawn

    +

    + + + Parameters: + +
      + + + + + +
    • + + style_define + + : + + (table or function) + + used to define how the style is applied, using a table is the simplist way of doing this + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    + + + + + + + + Usage: +
    -- Setting the height and width of the example button
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style{
    +    height = 25,
    +    width = 100
    +}
    +
    -- Using a function to set the style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style(function(style,element,...)
    +    local player = game.players[element.player_index]
    +    style.height = 25
    +    style.width = 100
    +    style.font_color = player.color
     end)
    @@ -884,6 +1042,13 @@ Gui.new_element(function(event_trigger,parent) + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    @@ -941,6 +1106,13 @@ Gui.new_element(function(event_trigger,parent) + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    @@ -1568,6 +1740,33 @@ Gui.new_element(function(event_trigger,parent) + + + + + + +
    +
    +
    +
    + # + top_flow_button_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow

    +

    + + + + + + + + @@ -2004,6 +2203,638 @@ Gui.new_element(function(event_trigger,parent) Gui.toggle_top_flow(game.player,example_flow_with_button,true)
    +
    +
    +

    Helper Functions

    +
    +
    +
    +
    + # + get_player_from_element(element) +
    +
    +
    +
    + +

    Get the player that owns a gui element

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to get the owner of + +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaPlayer) + the player that owns this element +
    • +
    + + + + + + + + Usage: +
    -- Geting the owner of an element
    +local player = Gui.get_player_from_element(element)
    + + +
    +
    +
    +
    + # + toggle_enabled_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the enabled state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to toggle the state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + the state that you want to set + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new enabled state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the enabled state
    +local new_enabled_state = Gui.toggle_enabled_state(element)
    + + +
    +
    +
    +
    + # + toggle_visible_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the visible state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to toggle the state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + the state that you want to set + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the visible state
    +local new_visible_state = Gui.toggle_visible_state(element)
    + + +
    +
    +
    +
    + # + destroy_if_valid(element) +
    +
    +
    +
    + +

    Destory a gui element without causing any errors, likly if the element may have already been removed

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to remove + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the element was valid and has been removed +
    • +
    + + + + + + + + Usage: +
    -- Likely use case for element not existing
    +Gui.destroy_if_valid(element[child_name])
    + + +
    +
    +
    +
    + # + alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment']) +
    +
    +
    +
    + +

    Draw a flow that has custom element alignments, default is right align

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the alignment flow will be added to + +
    • + + + + + +
    • + + horizontal_align + + : + + (string) + + the horizontal alignment of the elements in the flow + + (default: 'right') +
    • + + + + + +
    • + + vertical_align + + : + + (string) + + the vertical alignment of the elements in the flow + + (default: 'center') +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the alignment flow + + (default: 'alignment') +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Adding a right align flow
    +local alignment = Gui.alignment(element,'example_right_alignment')
    +
    -- Adding a horizontal center and top align flow
    +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top')
    + + +
    +
    +
    +
    + # + scroll_table(parent, height, column_count[, name='scroll']) +
    +
    +
    +
    + +

    Draw a scroll pane that has a table inside of it

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the scroll table will be added to + +
    • + + + + + +
    • + + height + + : + + (number) + + the maximum height for the scroll pane + +
    • + + + + + +
    • + + column_count + + : + + (number) + + the number of columns that the table will have + +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the scroll pane that is added, the table is always called 'table' + + (default: 'scroll') +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Adding a scroll table with max height of 200 and column count of 3
    +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3)
    + + +
    +
    +
    +
    + # + header(parent, caption[, tooltip][, add_alignment=false][, name='header']) +
    +
    +
    +
    + +

    Used to add a header to a frame, this has the option for a custom right alignment flow for buttons

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the header will be added to + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the header + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the header + + (optional) +
    • + + + + + +
    • + + add_alignment + + : + + (boolean) + + when true an alignment flow will be added for buttons + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the header that is being added, the alignment is always called 'alignment' + + (default: 'header') +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaGuiElement) + either the header or the header alignment if add_alignment is true +
    • +
    + + + + + + + + Usage: +
    -- Adding a custom header
    +local header_alignment = Gui.header(
    +    element,
    +    'example_header',
    +    'Example Caption',
    +    'Example Tooltip',
    +    true
    +)
    + +
    @@ -2020,7 +2851,7 @@ Gui.new_element(function(event_trigger,parent) generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index d684f92e..13bacb25 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 2e261b19..cfb25893 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index c977f109..f5eb98bb 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -262,7 +262,7 @@ Store.set(scenario_diffculty,'hard') end) -- When any key in the store is changed this function will trigger -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -370,7 +370,7 @@ Store.set(player_scores,game.player,10) Used to trigger watcher functions, this may be used to trigger them if you did not use Store.update or Store.set - raw_trigger(store[, key][, value]) + raw_trigger(store[, key][, value][, old_value]) Used to trigger watcher functions, the value and key are passed directly to the watchers regardless if the value is correct @@ -791,7 +791,7 @@ Store.set(player_scores,game.player,10) end) -- Register the watcher so that when we change the value the message is printed -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -1361,7 +1361,7 @@ Store.set(player_scores,game.player,10)
    # - raw_trigger(store[, key][, value]) + raw_trigger(store[, key][, value][, old_value])
    @@ -1426,6 +1426,23 @@ Store.set(player_scores,game.player,10) + + + +
  • + + old_value + + : + + (any) + + the old value that was at this key or store often the same if value is a table, passed directly to the watcher + + (optional) +
  • + + @@ -1445,7 +1462,7 @@ Store.set(player_scores,game.player,10) -- Trigger the watchers with a fake change of diffculty -- This is mostly used internally but it can be useful in other cases -Store.raw_trigger(scenario_diffculty,nil,'normal')
    +Store.raw_trigger(scenario_diffculty,nil,'normal','normal')
    @@ -1464,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index ea78d5a3..9a0a180b 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index d1ca6a0e..e0e633ba 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 21253ddc..5714de34 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 3dc31aa5..12c80988 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 454a6901..a16009c7 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -271,27 +271,43 @@ add_new_task - Button in the header to add a new task + Button displayed in the ehader bar, used to add a new task confirm_edit - Used to save changes to a task + Button displayed next to tasks which the user is currently editing, used to save changes cancel_edit - Used to cancel any changes you made to a task + Button displayed next to tasks which the user is currently editing, used to discard changes discard_task - Removes the task from the list + Button displayed next to tasks which the user is can edit, used to delete a task from the list edit_task - Opens edit mode for the task + Button displayed next to tasks which the user is can edit, used to start editing a task - task_list - Registers the task list + add_task_base + Set of three elements which make up each row of the task table + + + task_label + Default state for a task, contains only a label with the task message + + + task_editing + Editing state for a task, contrins a text field and the two edit buttons + + + task_list_container + Main task list container for the left flow + + + task_list_toggle + Button on the top flow used to toggle the task list container @@ -465,7 +481,7 @@
    -

    Button in the header to add a new task

    +

    Button displayed in the ehader bar, used to add a new task

    @@ -492,7 +508,7 @@
    -

    Used to save changes to a task

    +

    Button displayed next to tasks which the user is currently editing, used to save changes

    @@ -519,7 +535,7 @@
    -

    Used to cancel any changes you made to a task

    +

    Button displayed next to tasks which the user is currently editing, used to discard changes

    @@ -546,7 +562,7 @@
    -

    Removes the task from the list

    +

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    @@ -573,7 +589,7 @@
    -

    Opens edit mode for the task

    +

    Button displayed next to tasks which the user is can edit, used to start editing a task

    @@ -593,14 +609,122 @@
    - # - task_list + # + add_task_base
    -

    Registers the task list

    +

    Set of three elements which make up each row of the task table

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_label +
    +
    +
    +
    + +

    Default state for a task, contains only a label with the task message

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_editing +
    +
    +
    +
    + +

    Editing state for a task, contrins a text field and the two edit buttons

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_container +
    +
    +
    +
    + +

    Main task list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the task list container

    @@ -632,7 +756,7 @@ generated by LDoc
    diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index a4647a51..18297a4b 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -837,7 +837,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index cd8ed91c..a5e3d006 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 2b73d7da..6cca966d 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index fc152587..6291b757 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index d3a78a5d..b6393f5d 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index 661eb841..c5882630 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index fff59dbb..2927bed7 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 663e8dcb..49848f9e 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index 26e97c55..ec13ecfc 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index c192045d..e4815bc6 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 51c8fb76..717e7598 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 5708101d..aeb9fd7f 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 2c9404e6..13f18afb 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index f1a4a0be..47a1f7d6 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index c22b2df7..df8680e8 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 6901e6e6..ffb5dd8e 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index e472eb59..7dba1a3c 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/expcore/gui.lua b/expcore/gui.lua index 8e25a7c3..b6237b87 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -5,35 +5,60 @@ @usage-- Defining a button that prints the player's name local example_button = -Gui.new_element{ +Gui.element{ type = 'button', caption = 'Example Button' } -:on_click(function(event) - local player = event.player +:on_click(function(player,element,event) player.print(player.name) end) -@usage-- Defining using a custom function +@usage-- Defining a button with a custom style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button using a custom function local example_flow_with_button = -Gui.new_element(function(event_trigger,parent) +Gui.element(function(event_trigger,parent) + -- Add the flow the button is in local flow = parent.add{ name = 'example_flow', type = 'flow' } + -- Get the players name + local player = game.players[parent.player_index] + local player_name = player.name + + -- Add the button local element = flow.add{ name = event_trigger, type = 'button', - caption = 'Example Button' + caption = 'Example Button: '..player_name } + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100] + style.font_color = player.color + + -- Return the element return element end) -:on_click(function(event) - local player = event.player +:on_click(function(player,element,event) player.print(player.name) end) @@ -62,14 +87,16 @@ local Gui = { --- An index used for debuging to find the file where different elements where registered -- @table file_paths file_paths = {}, - --- The element prototype which is returned from Gui.new_element + --- The element prototype which is returned from Gui.element -- @table _prototype_element _prototype_element = {}, --- The prototype metatable applied to new element defines -- @table _mt_element _mt_element = { __call = function(self,parent,...) - return self._draw(self.name,parent,...) + local element = self._draw(self.name,parent,...) + if self._style then self._style(element.style,element,...) end + return element end } } @@ -85,20 +112,22 @@ Gui._mt_element.__index = Gui._prototype_element @usage-- Defining an element with a table local example_button = -Gui.new_element{ +Gui.element{ type = 'button', caption = 'Example Button' } @usage-- Defining an element with a function local example_flow_with_button = -Gui.new_element(function(event_trigger,parent) +Gui.element(function(event_trigger,parent,...) + -- Add the flow the button is in local flow = parent.add{ name = 'example_flow', type = 'flow' } + -- Add the button local element = flow.add{ name = event_trigger, @@ -106,11 +135,17 @@ Gui.new_element(function(event_trigger,parent) caption = 'Example Button' } + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100 + + -- Return the element return element end) ]] -function Gui.new_element(element_define) +function Gui.element(element_define) -- Set the metatable to allow access to register events local element = setmetatable({}, Gui._mt_element) @@ -139,8 +174,54 @@ function Gui.new_element(element_define) return element end +--[[-- Extension of Gui.element when using the table method, values applied after the element is drawn +@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Setting the height and width of the example button +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} + +@usage-- Using a function to set the style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style(function(style,element,...) + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color +end) + +]] +function Gui._prototype_element:style(style_define) + -- Add the defination function + if type(style_define) == 'table' then + self._style = function(style) + for key,value in pairs(style_define) do + style[key] = value + end + end + else + self._style = style_define + end + + -- Return the element so event handers can be accessed + return self +end + --[[-- Adds an element to be drawn to the top flow when a player joins @tparam[opt] function authenticator called during toggle or update to decide if the element should be visible +@treturn table the new element define that is used to register events to this element @usage-- Adding the example button example_button:add_to_top_flow(function(player) @@ -151,10 +232,12 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) Gui.top_elements[self.name] = authenticator or true + return self end --[[-- Adds an element to be drawn to the left flow when a player joins @tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +@treturn table the new element define that is used to register events to this element @usage-- Adding the example button example_flow_with_button:add_to_left_flow(true) @@ -162,6 +245,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) Gui.left_elements[self.name] = open_on_join or false + return self end -- This function is called for event event @@ -186,7 +270,7 @@ local function general_event_handler(event) end event.player = player - local success, err = pcall(handler,event) + local success, err = pcall(handler,player,element,event) if not success then error('There as been an error with an event handler for a gui element:\n\t'..err) end @@ -259,31 +343,23 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Button which toggles the top flow elements -- @element toggle_top_flow local toggle_top_flow = -Gui.new_element(function(event_trigger,parent) - -- Draw the element - local element = - parent.add{ - name = event_trigger, - type = 'button', - style = mod_gui.button_style, - caption = '<', - tooltip = {'gui_util.button_tooltip'} - } - - -- Change its style - local style = element.style - style.width = 18 - style.height = 36 - style.padding = 0 - style.font = 'default-small-bold' - - -- Return the element - return element -end) -:on_click(function(event) - Gui.toggle_top_flow(event.player) +Gui.element{ + type = 'button', + style = 'back_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) end) +--- The style that should be used for buttons on the top flow +-- @field Gui.top_flow_button_style +Gui.top_flow_button_style = mod_gui.button_style + --[[-- Gets the flow which contains the elements for the top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @@ -305,7 +381,7 @@ Gui.update_top_flow(game.player) function Gui.update_top_flow(player) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local is_visible = toggle_button.caption == '<' + local is_visible = toggle_button.style.name == 'back_button' -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -335,7 +411,7 @@ Gui.toggle_top_flow(game.player,true) function Gui.toggle_top_flow(player,state) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local new_state = state or toggle_button.caption == '>' + local new_state = state or toggle_button.style.name == 'forward_button' -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -344,11 +420,15 @@ function Gui.toggle_top_flow(player,state) -- Change the style of the toggle button if new_state then - toggle_button.caption = '<' - toggle_button.style.height = 34 + toggle_button.style = 'back_button' + local style = toggle_button.style + style.height = 36 + style.width = 18 else - toggle_button.caption = '>' - toggle_button.style.height = 24 + toggle_button.style = 'forward_button' + local style = toggle_button.style + style.height = 20 + style.width = 18 end return new_state @@ -360,29 +440,17 @@ end --- Button which hides the elements in the left flow -- @element hide_left_flow local hide_left_flow = -Gui.new_element(function(event_trigger,parent) - -- Draw the element - local element = - parent.add{ - name = event_trigger, - type = 'button', - style = mod_gui.button_style, - caption = '<', - tooltip = {'expcore-gui.left-button-tooltip'} - } - - -- Change its style - local style = element.style - style.width = 18 - style.height = 36 - style.padding = 0 - style.font = 'default-small-bold' - - -- Return the element - return element -end) -:on_click(function(event) - Gui.hide_left_flow(event.player) +Gui.element{ + type = 'button', + style = 'back_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) end) --[[-- Gets the flow which contains the elements for the left flow @@ -486,4 +554,195 @@ Event.add(defines.events.on_player_joined_game,function(event) hide_left.visible = show_hide_left end) +--- Helper Functions. +-- @section helperFunctions + +--[[-- Get the player that owns a gui element +@tparam LuaGuiElement element the element that you want to get the owner of +@treturn LuaPlayer the player that owns this element + +@usage-- Geting the owner of an element +local player = Gui.get_player_from_element(element) + +]] +function Gui.get_player_from_element(element) + if not element or not element.valid then return end + return game.players[element.player_index] +end + +--[[-- Will toggle the enabled state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new enabled state that the element has + +@usage-- Toggling the the enabled state +local new_enabled_state = Gui.toggle_enabled_state(element) + +]] +function Gui.toggle_enabled_state(element,state) + if not element or not element.valid then return end + local new_state = state or not element.enabled + element.enabled = new_state + return new_state +end + +--[[-- Will toggle the visible state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new visible state that the element has + +@usage-- Toggling the the visible state +local new_visible_state = Gui.toggle_visible_state(element) + +]] +function Gui.toggle_visible_state(element,state) + if not element or not element.valid then return end + local new_state = state or not element.visible + element.visible = new_state + return new_state +end + +--[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +@tparam LuaGuiElement element the element that you want to remove +@treturn boolean true if the element was valid and has been removed + +@usage-- Likely use case for element not existing +Gui.destroy_if_valid(element[child_name]) + +]] +function Gui.destroy_if_valid(element) + if not element or not element.valid then return false end + element.destroy() + return true +end + +--[[-- Draw a flow that has custom element alignments, default is right align +@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow +@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow +@tparam[opt='alignment'] string name the name of the alignment flow +@treturn LuaGuiElement the alignment flow that was created + +@usage-- Adding a right align flow +local alignment = Gui.alignment(element,'example_right_alignment') + +@usage-- Adding a horizontal center and top align flow +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') + +]] +function Gui.alignment(parent,horizontal_align,vertical_align,name) + -- Draw the alignment flow + local alignment = + parent.add{ + name = name or 'alignment', + type = 'flow', + } + + -- Change its style + local style = alignment.style + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' + + -- Return the flow + return alignment +end + +--[[-- Draw a scroll pane that has a table inside of it +@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam number height the maximum height for the scroll pane +@tparam number column_count the number of columns that the table will have +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@treturn LuaGuiElement the table that was created + +@usage-- Adding a scroll table with max height of 200 and column count of 3 +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) + +]] +function Gui.scroll_table(parent,height,column_count,name) + -- Draw the scroll + local scroll = + parent.add{ + name = name or 'scroll', + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto-and-reserve-space', + style = 'scroll_pane_under_subheader' + } + + -- Change the style of the scroll + local scroll_style = scroll.style + scroll_style.padding = {1,2} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Draw the table + local scroll_table = + scroll.add{ + type = 'table', + name = 'table', + column_count = column_count + } + + -- Change the style of the table + local table_style = scroll_table.style + table_style.padding = 0 + table_style.cell_padding = 0 + table_style.vertical_align = 'center' + table_style.horizontally_stretchable = true + + -- Return the scroll table + return scroll_table +end + +--[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the header or the header alignment if add_alignment is true + +@usage-- Adding a custom header +local header_alignment = Gui.header( + element, + 'example_header', + 'Example Caption', + 'Example Tooltip', + true +) + +]] +function Gui.header(parent,caption,tooltip,add_alignment,name) + -- Draw the header + local header = + parent.add{ + name = name or 'header', + type = 'frame', + style = 'subheader_frame' + } + + -- Change the style of the header + local style = header.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + + -- Return either the header or the added alignment + return add_alignment and Gui.alignment(header) or header +end + +-- Module return return Gui \ No newline at end of file diff --git a/expcore/store.lua b/expcore/store.lua index f58e41b9..735ccef4 100644 --- a/expcore/store.lua +++ b/expcore/store.lua @@ -27,7 +27,7 @@ local player_scores = Store.register(function(player) -- Use player name as the end) -- When any key in the store is changed this function will trigger -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -175,7 +175,7 @@ local player_scores = Store.register(function(player) end) -- Register the watcher so that when we change the value the message is printed -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -274,18 +274,21 @@ Store.clear(player_scores) ]] function Store.clear(store,key) key = Store.validate(store,key,2) + local old_value -- Check if there is a key being used if key then if type(data_store[store]) == 'table' then + old_value = data_store[store][key] data_store[store][key] = nil end else + old_value = data_store[store] data_store[store] = nil end -- Trigger any watch functions - Store.raw_trigger(store,key,nil) + Store.raw_trigger(store,key,nil,old_value) end --[[-- Used to set the data in a store, will trigger any watchers, key is optional depending on if you are using them @@ -325,19 +328,22 @@ function Store.set(store,key,value) -- Check the store is valid key = Store.validate(store,key,2) + local old_value -- If there is a key being used then the store must be a able if key then if type(data_store[store]) ~= 'table' then data_store[store] = {_value = data_store[store]} end + old_value = data_store[store][key] data_store[store][key] = value else + old_value = data_store[store] data_store[store] = value end -- Trigger any watchers - Store.raw_trigger(store,key,value) + Store.raw_trigger(store,key,value,old_value) end --[[-- Used to update the data in a store, use this with tables, will trigger any watchers, key is optional depending on if you are using them @@ -386,7 +392,7 @@ function Store.update(store,key,updater) -- Check the store is valid key = Store.validate(store,key,2) - local value + local value, old_value -- If a key is used then the store must be a table if key then @@ -397,6 +403,7 @@ function Store.update(store,key,updater) -- Call the updater and if it returns a value then set this value local rtn = updater(data_store[store][key]) if rtn then + old_value = data_store[store][key] data_store[store][key] = rtn end value = data_store[store][key] @@ -405,6 +412,7 @@ function Store.update(store,key,updater) -- Call the updater and if it returns a value then set this value local rtn = updater(data_store[store]) if rtn then + old_value = data_store[store][key] data_store[store] = rtn end value = data_store[store] @@ -412,7 +420,7 @@ function Store.update(store,key,updater) end -- Trigger any watchers - Store.raw_trigger(store,key,value) + Store.raw_trigger(store,key,value,old_value) end --[[-- Used to update all values that are in a store, similar to Store.update but acts on all keys at once, will trigger watchers for every key present @@ -455,7 +463,7 @@ function Store.map(store,updater) if rtn then data[key] = rtn end - Store.raw_trigger(store,key,data[key]) + Store.raw_trigger(store,key,data[key],value) end end @@ -476,9 +484,10 @@ function Store.trigger(store,key) -- Get the data from the data store local data = data_store[store] if key then - Store.raw_trigger(store,key,data[key]) + data = data[key] + Store.raw_trigger(store,key,data,data) else - Store.raw_trigger(store,key,data) + Store.raw_trigger(store,key,data,data) end end @@ -486,6 +495,7 @@ end @tparam number store the uid of the store that you want to trigger @tparam[opt] ?string|any key the key that you want to trigger, must be a string unless you have a serializer @tparam[opt] any value the new value that is at this key or store, passed directly to the watcher +@tparam[opt] any old_value the old value that was at this key or store often the same if value is a table, passed directly to the watcher @usage-- Triggering a manule call of the watchers -- The type of store we use does not really matter for this as long as you pass it what you watchers are expecting @@ -493,16 +503,16 @@ local scenario_diffculty = Store.register() -- Trigger the watchers with a fake change of diffculty -- This is mostly used internally but it can be useful in other cases -Store.raw_trigger(scenario_diffculty,nil,'normal') +Store.raw_trigger(scenario_diffculty,nil,'normal','normal') ]] -function Store.raw_trigger(store,key,value) +function Store.raw_trigger(store,key,value,old_value) key = Store.validate(store,key,2) -- Get the watchers and then loop over them local watchers = Store.watchers[store] or {} for _,watcher in pairs(watchers) do - local success, err = pcall(watcher,value,key) + local success, err = pcall(watcher,value,key,old_value) if not success then error('Store watcher casued an error:\n\t'..err) end diff --git a/modules/control/tasks.lua b/modules/control/tasks.lua index 6b2d9630..0806efde 100644 --- a/modules/control/tasks.lua +++ b/modules/control/tasks.lua @@ -89,8 +89,8 @@ Tasks.remove_task(task_id) function Tasks.remove_task(task_id) local task = Store.get(task_store,task_id) local force_name = task.force_name - Store.clear(task_store,task_id) table.remove_element(force_tasks[force_name],task_id) + Store.clear(task_store,task_id) end --[[-- Update the message and last edited information for a task diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index d82a3a77..9f393205 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -12,337 +12,455 @@ local format_time,table_keys = ext_require('expcore.common','format_time','table local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks --- If a player is allowed to use the edit buttons -local function player_allowed_edit(player,task) +local function check_player_permissions(player,task) if task then + -- When a task is given check if the player can edit it + local allow_edit_task = config.allow_edit_task + + -- Check if the player being the last to edit will override existing permisisons if config.user_can_edit_own_tasks and task.last_edit_name == player.name then return true end - else - if config.any_user_can_add_new_task then + + -- Check player has permisison based on value in the config + if allow_edit_task == 'all' then return true + elseif allow_edit_task == 'admin' then + return player.admin + elseif allow_edit_task == 'expcore.roles' then + return Roles.player_allowed(player,config.edit_tasks_role_permission) end - end - if config.only_admins_can_edit and not player.admin then + -- Return false as all other condidtions have not been met + return false + else + -- When a task is not given check if the player can add a new task + local allow_add_task = config.allow_add_task + + -- Check player has permisison based on value in the config + if allow_add_task == 'all' then + return true + elseif allow_add_task == 'admin' then + return player.admin + elseif allow_add_task == 'expcore.roles' then + return Roles.player_allowed(player,config.expcore_roles_add_permission) + end + + -- Return false as all other condidtions have not been met return false end - - if config.edit_tasks_role_permission and not Roles.player_allowed(player,config.edit_tasks_role_permission) then - return false - end - - return true end ---- Button in the header to add a new task +--- Button displayed in the ehader bar, used to add a new task -- @element add_new_task local add_new_task = -Gui.new_button() -:set_sprites('utility/add') -:set_tooltip{'task-list.add-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/add', + tooltip = {'task-list.add-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,_,_) Tasks.add_task(player.force.name,nil,player.name) end) ---- Used to save changes to a task +--- Button displayed next to tasks which the user is currently editing, used to save changes -- @element confirm_edit local confirm_edit = -Gui.new_button() -:set_sprites('utility/downloaded') -:set_tooltip{'task-list.confirm-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'task-list.confirm-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) local task_id = element.parent.name - local new_message = element.parent.task.text + local new_message = element.parent.task_entry.text Tasks.set_editing(task_id,player.name) Tasks.update_task(task_id,new_message,player.name) end) ---- Used to cancel any changes you made to a task +--- Button displayed next to tasks which the user is currently editing, used to discard changes -- @element cancel_edit local cancel_edit = -Gui.new_button() -:set_sprites('utility/close_black') -:set_tooltip{'task-list.cancel-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'task-list.cancel-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) local task_id = element.parent.name Tasks.set_editing(task_id,player.name) end) ---- Removes the task from the list +--- Button displayed next to tasks which the user is can edit, used to delete a task from the list -- @element discard_task local discard_task = -Gui.new_button() -:set_sprites('utility/trash') -:set_tooltip{'task-list.discard-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local task_id = element.parent.name +Gui.element{ + type = 'sprite-button', + sprite = 'utility/trash', + tooltip = {'task-list.discard-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(_,element,_) + local task_id = element.parent.name:sub(6) Tasks.remove_task(task_id) end) ---- Opens edit mode for the task +--- Button displayed next to tasks which the user is can edit, used to start editing a task -- @element edit_task local edit_task = -Gui.new_button() -:set_sprites('utility/rename_icon_normal') -:set_tooltip{'task-list.edit-tooltip-none'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local task_id = element.parent.name +Gui.element{ + type = 'sprite-button', + sprite = 'utility/rename_icon_normal', + tooltip = {'task-list.edit-tooltip-none'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) + local task_id = element.parent.name:sub(6) Tasks.set_editing(task_id,player.name,true) end) ---[[ Generates each task, handles both view and edit mode - element - > count-"task_id" - >> label - > "task_id" - >> task - >> cancel_edit (edit mode) - >> confirm_edit (edit mode) - > edit-"task_id" - >> edit_task - >> discard_task -]] -local function generate_task(player,element,task_id) +--- Set of three elements which make up each row of the task table +-- @element add_task_base +local add_task_base = +Gui.element(function(_,parent,task_id) + -- Add the task number label + parent.add{ + name = 'count-'..task_id, + type = 'label', + caption = '0)' + } + + -- Add a flow which will contain the task message and edit buttons + local task_flow = + parent.add{ + name = task_id, + type = 'flow', + } + + -- Set the padding on the task flow + local task_flow_style = task_flow.style + task_flow_style.padding = 0 + + -- Add the two edit buttons outside the task flow + local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) + edit_task(edit_flow) + discard_task(edit_flow) + + -- Return the task flow as the main element + return task_flow +end) + +-- Removes the three elements that are added as part of the task base +local function remove_task_base(parent,task_id) + Gui.destroy_if_valid(parent['count-'..task_id]) + Gui.destroy_if_valid(parent['edit-'..task_id]) + Gui.destroy_if_valid(parent[task_id]) +end + +--- Default state for a task, contains only a label with the task message +-- @element task_label +local task_label = +Gui.element(function(_,parent,task) + local message = task.message + local last_edit_name = task.last_edit_name + local last_edit_time = task.last_edit_time + + -- Draw the element + local element = + parent.add{ + name = 'task_entry', + type = 'label', + caption = message, + tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} + } + + -- Change the style + local style = element.style + style.single_line = false + style.maximal_width = 150 + + -- Return the element + return element +end) + +--- Editing state for a task, contrins a text field and the two edit buttons +-- @element task_editing +local task_editing = +Gui.element(function(_,parent,task) + local message = task.message + + -- Draw the element + local element = + parent.add{ + name = 'task_entry', + type = 'textfield', + text = message + } + + -- Change the style + local style = element.style + style.maximal_width = 150 + style.height = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element +end) + +--- Updates a task for a player +local function update_task(player,task_table,task_id) local task = Tasks.get_task(task_id) local task_ids = Tasks.get_force_task_ids(player.force.name) local task_number = table.index_of(task_ids, task_id) + -- Task no longer exists so should be removed from the list if not task then - -- task is nil so remove it from the list - element.parent.no_tasks.visible = #task_ids == 1 - Gui.destroy_if_valid(element['count-'..task_id]) - Gui.destroy_if_valid(element['edit-'..task_id]) - Gui.destroy_if_valid(element[task_id]) - - else - local message = task.message - local editing = task.curently_editing[player.name] - local last_edit_name = task.last_edit_name - local last_edit_time = task.last_edit_time - - element.parent.no_tasks.visible = false - -- if it is not already present then add it now - local task_area = element[task_id] - if not task_area then - -- label to show the task number - element.add{ - name='count-'..task_id, - type='label', - caption=task_number..')' - } - - -- area which stores the task and buttons - task_area = - element.add{ - name=task_id, - type='flow', - } - Gui.set_padding(task_area) - - -- if the player can edit then it adds the edit and delete button - local flow = Gui.create_alignment(element,'edit-'..task_id) - local sub_flow = flow.add{type='flow',name=task_id} - - edit_task(sub_flow) - discard_task(sub_flow) - - end - - -- update the number indexes and the current editing players - element['count-'..task_id].caption = task_number..')' - - local edit_area = element['edit-'..task_id][task_id] - local players = table_keys(task.editing) - local allowed = player_allowed_edit(player,task) - - edit_area.visible = allowed - - if #players > 0 then - edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip',table.concat(players,', ')} - else - edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip-none'} - end - - -- draws/updates the task area - local element_type = task_area.task and task_area.task.type or nil - if not editing and element_type == 'label' then - -- update the label already present - task_area.task.caption = message - task_area.task.tooltip = {'task-list.last-edit',last_edit_name,format_time(last_edit_time)} - - elseif not editing then - -- create the label, view mode - if edit_area then - edit_area[edit_task.name].enabled = true - end - - task_area.clear() - - local label = - task_area.add{ - name='task', - type='label', - caption=message, - tooltip={'task-list.last-edit',last_edit_name,format_time(last_edit_time)} - } - label.style.single_line = false - label.style.maximal_width = 150 - - elseif editing and element_type ~= 'textfield' then - -- create the text field, edit mode, update it omitted as value is being edited - if edit_area then - edit_area[edit_task.name].enabled = false - end - - task_area.clear() - - local entry = - task_area.add{ - name='task', - type='textfield', - text=message - } - entry.style.maximal_width = 150 - entry.style.height = 20 - - cancel_edit(task_area) - confirm_edit(task_area) - - end - + task_table.parent.no_tasks.visible = #task_ids == 0 + remove_task_base(task_table,task_id) + return end + -- Get the task flow for this task + local task_flow = task_table[task_id] or add_task_base(task_table,task_id) + task_table.parent.no_tasks.visible = false + task_table['count-'..task_id].caption = task_number..')' + + -- Update the edit flow + local edit_flow = task_table['edit-'..task_id] + local player_allowed_edit = check_player_permissions(player,task) + local players_editing = table_keys(task.curently_editing) + local edit_task_element = edit_flow[edit_task.name] + local discard_task_element = edit_flow[discard_task.name] + + edit_task_element.visible = player_allowed_edit + discard_task_element.visible = player_allowed_edit + if #players_editing > 0 then + edit_task_element.tooltip = {'task-list.edit-tooltip',table.concat(players_editing,', ')} + else + edit_task_element.tooltip = {'task-list.edit-tooltip-none'} + end + + -- Check if the player is was editing and/or currently editing + local task_entry = task_flow.task_entry or task_label(task_flow,task) + local player_was_editing = task_entry.type == 'textfield' + local player_is_editing = task.curently_editing[player.name] + + -- Update the task flow + if not player_was_editing and not player_is_editing then + -- Update the task message label + local message = task.message + local last_edit_name = task.last_edit_name + local last_edit_time = task.last_edit_time + task_entry.caption = message + task_entry.tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} + + elseif player_was_editing and not player_is_editing then + -- Player was editing but is no longer, remove text field and add label + edit_task_element.enabled = true + task_flow.clear() + task_label(task_flow,task) + + elseif not player_was_editing and player_is_editing then + -- Player was not editing but now is, remove label and add text field + edit_task_element.enabled = false + task_flow.clear() + task_editing(task_flow,task) + + end end ---[[ generates the main gui structure - element - > container - >> header - >>> right aligned add_new_task - >> scroll - >>> no_tasks - >>> table -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +local function update_all_tasks(player,scroll_table) + local task_ids = Tasks.get_force_task_ids(player.force.name) + if #task_ids > 0 then + for _,task_id in ipairs(task_ids) do + update_task(player,scroll_table,task_id) + end + end +end - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main task list container for the left flow +-- @element task_list_container +local task_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - container.style.vertically_stretchable = false - -- main header for the gui - local header_area = Gui.create_header( + -- Set the frame style + frame.style.padding = 2 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + local header = Gui.header( container, {'task-list.main-caption'}, {'task-list.sub-tooltip'}, true ) - --- Right aligned button to toggle the section - if player_allowed_edit(player) then - add_new_task(header_area) - end + -- Draw the new task button + local player = Gui.get_player_from_element(parent) + local add_new_task_element = add_new_task(header) + add_new_task_element.visible = check_player_permissions(player) - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,3,185) - flow_table.draw_horizontal_lines = true - flow_table.vertical_centering = false - flow_table.style.top_cell_padding = 3 - flow_table.style.bottom_cell_padding = 3 + -- Draw the scroll table for the tasks + local scroll_table = Gui.scroll_table(container,185,3) + scroll_table.draw_horizontal_lines = true + scroll_table.vertical_centering = false - -- message to say that you have no tasks - local non_made = - flow_table.parent.add{ - name='no_tasks', - type='label', - caption={'task-list.no-tasks'} + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.top_cell_padding = 3 + scroll_table_style.bottom_cell_padding = 3 + + -- Draw the no tasks label + local no_tasks_label = + scroll_table.parent.add{ + name = 'no_tasks', + type = 'label', + caption = {'task-list.no-tasks'} } - non_made.style.width = 200 - non_made.style.single_line = false - return flow_table -end + -- Change the style of the no tasks label + local no_tasks_style = no_tasks_label.style + no_tasks_style.padding = {2,4} + no_tasks_style.single_line = false + no_tasks_style.width = 200 ---- Registers the task list --- @element task_list -local task_list = -Gui.new_left_frame('gui/task-list') -:set_sprites('utility/not_enough_repair_packs_icon') -:set_direction('vertical') -:set_tooltip{'task-list.main-tooltip'} -:set_open_by_default() -:on_creation(function(player,element) - local data_table = generate_container(player,element) + -- Add any existing tasks local task_ids = Tasks.get_force_task_ids(player.force.name) - - for _,task_id in pairs(task_ids) do - generate_task(player,data_table,task_id) + if #task_ids > 0 then + no_tasks_style.visible = false + for _,task_id in ipairs(task_ids) do + update_task(player,scroll_table,task_id) + end end + + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local data_table = element.container.scroll.table +:add_to_left_flow(function(player) local task_ids = Tasks.get_force_task_ids(player.force.name) + return #task_ids > 0 +end) - for _,task_id in pairs(task_ids) do - generate_task(player,data_table,task_id) - end +--- Button on the top flow used to toggle the task list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'utility/not_enough_repair_packs_icon', + tooltip = {'task-list.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/task-list') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, task_list_container) end) --- When a new task is added it will udpate the task list for everyone on that force -Tasks.on_update(function(task,task_id) - local players +Tasks.on_update(function(task,task_id,removed_task) + -- Get the force to update, task is nil when removed + local force if task then - local force = game.forces[task.force_name] - players = force.connected_players + force = game.forces[task.force_name] else - players = game.connected_players + force = game.forces[removed_task.force_name] end - for _,player in pairs(players) do - local frame = task_list:get_frame(player) - local element = frame.container.scroll.table - generate_task(player,element,task_id) + -- Update the task for all the players on the force + local task_ids = Tasks.get_force_task_ids(force.name) + for _,player in pairs(force.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[task_list_container.name] + local scroll_table = frame.container.scroll.table + + -- Update the task that was changed + update_task(player,scroll_table,task_id) + + -- Update the numbering of the other tasks if the task was removed + if not task then + for task_number, next_task_id in pairs(task_ids) do + scroll_table['count-'..next_task_id].caption = task_number..')' + end + end end + end) --- Update the tasks when the player joins -Event.add(defines.events.on_player_joined_game,task_list 'redraw') +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[task_list_container.name] + local scroll_table = frame.container.scroll.table + update_all_tasks(player,scroll_table) +end) --- Makes sure the right buttons are present when roles change -Event.add(Roles.events.on_role_assigned,task_list 'redraw') -Event.add(Roles.events.on_role_unassigned,task_list 'redraw') +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[task_list_container.name].container -return task_list \ No newline at end of file + -- Update the tasks, incase the user can now edit them + local scroll_table = container.scroll.table + update_all_tasks(player,scroll_table) + + -- Update the new task button incase the user can now add them + local add_new_task_element = container.header.alignment[add_new_task.name] + add_new_task_element.visible = check_player_permissions(player) +end + +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) \ No newline at end of file From b74c3349130005fd1d73012fecb0a7347083d044 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 17:23:44 +0100 Subject: [PATCH 03/21] Few Edits to task list --- expcore/gui.lua | 4 +- modules/gui/task-list.lua | 166 ++++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 79 deletions(-) diff --git a/expcore/gui.lua b/expcore/gui.lua index b6237b87..96193316 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -669,13 +669,13 @@ function Gui.scroll_table(parent,height,column_count,name) type = 'scroll-pane', direction = 'vertical', horizontal_scroll_policy = 'never', - vertical_scroll_policy = 'auto-and-reserve-space', + vertical_scroll_policy = 'auto', style = 'scroll_pane_under_subheader' } -- Change the style of the scroll local scroll_style = scroll.style - scroll_style.padding = {1,2} + scroll_style.padding = {1,3} scroll_style.maximal_height = height scroll_style.horizontally_stretchable = true diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 9f393205..c36c3422 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -69,13 +69,13 @@ Gui.element{ Tasks.add_task(player.force.name,nil,player.name) end) ---- Button displayed next to tasks which the user is currently editing, used to save changes --- @element confirm_edit -local confirm_edit = +--- Button displayed next to tasks which the user is can edit, used to start editing a task +-- @element edit_task +local edit_task = Gui.element{ type = 'sprite-button', - sprite = 'utility/downloaded', - tooltip = {'task-list.confirm-tooltip'}, + sprite = 'utility/rename_icon_normal', + tooltip = {'task-list.edit-tooltip-none'}, style = 'tool_button' } :style{ @@ -84,29 +84,8 @@ Gui.element{ width = 20 } :on_click(function(player,element,_) - local task_id = element.parent.name - local new_message = element.parent.task_entry.text - Tasks.set_editing(task_id,player.name) - Tasks.update_task(task_id,new_message,player.name) -end) - ---- Button displayed next to tasks which the user is currently editing, used to discard changes --- @element cancel_edit -local cancel_edit = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/close_black', - tooltip = {'task-list.cancel-tooltip'}, - style = 'tool_button' -} -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) - local task_id = element.parent.name - Tasks.set_editing(task_id,player.name) + local task_id = element.parent.name:sub(6) + Tasks.set_editing(task_id,player.name,true) end) --- Button displayed next to tasks which the user is can edit, used to delete a task from the list @@ -128,25 +107,6 @@ Gui.element{ Tasks.remove_task(task_id) end) ---- Button displayed next to tasks which the user is can edit, used to start editing a task --- @element edit_task -local edit_task = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/rename_icon_normal', - tooltip = {'task-list.edit-tooltip-none'}, - style = 'tool_button' -} -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) - local task_id = element.parent.name:sub(6) - Tasks.set_editing(task_id,player.name,true) -end) - --- Set of three elements which make up each row of the task table -- @element add_task_base local add_task_base = @@ -185,6 +145,83 @@ local function remove_task_base(parent,task_id) Gui.destroy_if_valid(parent[task_id]) end +--- Button displayed next to tasks which the user is currently editing, used to save changes +-- @element confirm_edit +local task_editing +local confirm_edit = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'task-list.confirm-tooltip'}, + style = 'shortcut_bar_button_green' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} +:on_click(function(player,element,_) + local task_id = element.parent.name + local new_message = element.parent[task_editing.name].text + Tasks.set_editing(task_id,player.name) + Tasks.update_task(task_id,new_message,player.name) +end) + +--- Button displayed next to tasks which the user is currently editing, used to discard changes +-- @element cancel_edit +local cancel_edit = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'task-list.cancel-tooltip'}, + style = 'shortcut_bar_button_red' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} +:on_click(function(player,element,_) + local task_id = element.parent.name + Tasks.set_editing(task_id,player.name) +end) + +--- Editing state for a task, contrins a text field and the two edit buttons +-- @element task_editing +task_editing = +Gui.element(function(event_trigger,parent,task) + local message = task.message + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'textfield', + text = message, + clear_and_focus_on_right_click = true + } + + -- Change the style + local style = element.style + style.maximal_width = 110 + style.height = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element +end) +:on_confirmed(function(player,element,_) + local task_id = element.parent.name + local new_message = element.text + Tasks.set_editing(task_id,player.name) + Tasks.update_task(task_id,new_message,player.name) +end) + --- Default state for a task, contains only a label with the task message -- @element task_label local task_label = @@ -196,7 +233,7 @@ Gui.element(function(_,parent,task) -- Draw the element local element = parent.add{ - name = 'task_entry', + name = task_editing.name, type = 'label', caption = message, tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} @@ -211,33 +248,6 @@ Gui.element(function(_,parent,task) return element end) ---- Editing state for a task, contrins a text field and the two edit buttons --- @element task_editing -local task_editing = -Gui.element(function(_,parent,task) - local message = task.message - - -- Draw the element - local element = - parent.add{ - name = 'task_entry', - type = 'textfield', - text = message - } - - -- Change the style - local style = element.style - style.maximal_width = 150 - style.height = 20 - - -- Add the edit buttons - cancel_edit(parent) - confirm_edit(parent) - - -- Return the element - return element -end) - --- Updates a task for a player local function update_task(player,task_table,task_id) local task = Tasks.get_task(task_id) @@ -266,13 +276,15 @@ local function update_task(player,task_table,task_id) edit_task_element.visible = player_allowed_edit discard_task_element.visible = player_allowed_edit if #players_editing > 0 then + edit_task_element.hovered_sprite = 'utility/warning_icon' edit_task_element.tooltip = {'task-list.edit-tooltip',table.concat(players_editing,', ')} else + edit_task_element.hovered_sprite = edit_task_element.sprite edit_task_element.tooltip = {'task-list.edit-tooltip-none'} end -- Check if the player is was editing and/or currently editing - local task_entry = task_flow.task_entry or task_label(task_flow,task) + local task_entry = task_flow[task_editing.name] or task_label(task_flow,task) local player_was_editing = task_entry.type == 'textfield' local player_is_editing = task.curently_editing[player.name] @@ -295,7 +307,7 @@ local function update_task(player,task_table,task_id) -- Player was not editing but now is, remove label and add text field edit_task_element.enabled = false task_flow.clear() - task_editing(task_flow,task) + task_editing(task_flow,task).focus() end end From 0b340ab899841cfa187b7d80ab189b8a05fdd9f7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 21:34:28 +0100 Subject: [PATCH 04/21] Updated Warps List --- config/_file_loader.lua | 2 +- config/roles.lua | 7 +- config/tasks.lua | 9 +- config/warps.lua | 43 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 17 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 324 +++--- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 2 +- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 198 ++-- docs/guis/Warps-List.html | 446 ++++++--- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- expcore/gui.lua | 28 +- locale/en/gui.cfg | 2 +- modules/control/warps.lua | 4 +- modules/gui/task-list.lua | 4 +- modules/gui/warp-list.lua | 947 ++++++++++-------- 101 files changed, 1294 insertions(+), 913 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index b7ccbd92..7629b905 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -41,7 +41,7 @@ return { -- GUI --'modules.gui.rocket-info', --'modules.gui.science-info', - --'modules.gui.warp-list', + 'modules.gui.warp-list', 'modules.gui.task-list', --'modules.gui.player-list', --'modules.commands.debug', diff --git a/config/roles.lua b/config/roles.lua index d46d08fe..8bc10b92 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -61,7 +61,8 @@ Roles.new_role('Administrator','Admin') :set_flag('instance-respawn') :set_parent('Moderator') :allow{ - 'gui/warp-list/no-limit', + 'gui/warp-list/bypass-cooldown', + 'gui/warp-list/bypass-proximity', } Roles.new_role('Moderator','Mod') @@ -179,7 +180,9 @@ Roles.new_role('Member','Mem') :set_custom_color{r=24,g=172,b=188} :set_parent('Regular') :allow{ + 'gui/task-list/add', 'gui/task-list/edit', + 'gui/warp-list/add', 'gui/warp-list/edit' } @@ -215,6 +218,8 @@ local default = Roles.new_role('Guest','') 'gui/science-info', 'gui/task-list', 'gui/warp-list', + 'gui/warp-list/apply-cooldown', + 'gui/warp-list/apply-proximity', } --- Jail role diff --git a/config/tasks.lua b/config/tasks.lua index 994acff8..f7968e8e 100644 --- a/config/tasks.lua +++ b/config/tasks.lua @@ -2,11 +2,12 @@ -- @config Tasks return { - -- values can be all, admin, expcore.roles, none + -- Adding tasks allow_add_task = 'all', --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none - expcore_roles_add_permission = 'gui/task-list/add', --- @setting expcore_roles_add_permission if expcore.roles is used then this is the required permission - -- values can be all, admin, expcore.roles, none + expcore_roles_allow_add_task = 'gui/task-list/add', --- @setting expcore_roles_allow_add_task if expcore.roles is used then this is the required permission + + -- Editing tasks allow_edit_task = 'expcore.roles', --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none - expcore_roles_edit_permission = 'gui/task-list/edit', --- @setting expcore_roles_edit_permission if expcore.roles is used then this is the required permission + expcore_roles_allow_edit_task = 'gui/task-list/edit', --- @setting expcore_roles_allow_edit_task if expcore.roles is used then this is the required permission user_can_edit_own_tasks = true --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting } \ No newline at end of file diff --git a/config/warps.lua b/config/warps.lua index fb620108..d1710ba8 100644 --- a/config/warps.lua +++ b/config/warps.lua @@ -2,24 +2,39 @@ -- @config Warps return { - recharge_time = 60, --- @setting recharge_time The amount of time in seconds that the player must wait between warps, acts as a balance - update_smoothing = 10, --- @setting update_smoothing Higher is better, the amount of smoothing applied to recharge timer and other gui updates, max is 60 - minimum_distance = 100, --- @setting minimum_distance The minimum distance that must be between warp points, creating new ones is blocked when too close - activation_range = 4, --- @setting activation_range The distance the player must be to a warp in order to use the warp gui, gui can still be viewed but not used - spawn_activation_range = 20, --- @setting spawn_activation_range A second activation range which is used for the forces spawn point - default_icon = 'discharge-defense-equipment', --- @setting default_icon The default icon which is used by warps; must be an item name - user_can_edit_own_warps = false, --- @setting user_can_edit_own_warps When true the user can always edit warps which they created regardless of other settings - any_user_can_add_new_warp = false, --- @setting any_user_can_add_new_warp When true any user is able to create new warps, however editing may still be restricted - only_admins_can_edit = false, --- @setting only_admins_can_edit When true only admins can edit warps - edit_warps_role_permission = 'gui/warp-list/edit', --- @setting edit_warps_role_permission Role permission used by the role system to allow editing warps - bypass_warp_limits_permission = 'gui/warp-list/no-limit', --- @setting bypass_warp_limits_permission Role permission used by the role system to allow bypassing the time and distance restrictions - entities = { --- @setting entities The entities which are created for warps + -- General config + update_smoothing = 10, --- @setting update_smoothing the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60 + minimum_distance = 100, --- @setting minimum_distance the minimum distance that is allowed between warps on the same force + default_icon = 'discharge-defense-equipment', --- @setting default_icon the default icon that will be used for warps + + -- Warp cooldowns + bypass_warp_cooldown = 'expcore.roles', --- @setting bypass_warp_cooldown dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none + expcore_roles_bypass_warp_cooldown = 'gui/warp-list/bypass-cooldown', --- @setting expcore_roles_bypass_warp_cooldown if expcore.roles is used then this is the required permission + cooldown_duraction = 60, --- @setting cooldown_duraction the duration of the warp cooldown in seconds + + -- Warp proximity + bypass_warp_proximity = 'expcore.roles', --- @setting bypass_warp_proximity dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none + expcore_roles_bypass_warp_proximity = 'gui/warp-list/bypass-proximity', --- @setting expcore_roles_bypass_warp_proximity if expcore.roles is used then this is the required permission + standard_proximity_radius = 4, --- @setting standard_proximity_radius the minimum distance a player is allowed to be to a warp in order to use it + spawn_proximity_radius = 20, --- @setting spawn_proximity_radius the minimum distance a player is allowed to be from they spawn point to use warps + + -- Adding warps + allow_add_warp = 'expcore.roles', --- @setting allow_add_warp dictates who is allowed to add warps; values: all, admin, expcore.roles, none + expcore_roles_allow_add_warp = 'gui/warp-list/add', --- @setting expcore_roles_allow_add_warp if expcore.roles is used then this is the required permission + + -- Editing warps + allow_edit_warp = 'expcore.roles', --- @setting allow_edit_warp dictates who is allowed to edit warps; values: all, admin, expcore.roles, none + expcore_roles_allow_edit_warp = 'gui/warp-list/edit', --- @setting expcore_roles_allow_edit_warp if expcore.roles is used then this is the required permission + user_can_edit_own_warps = false, --- @settings user_can_edit_own_warps if true then the user who made the warp can edit it regardless of the allow_edit_warp setting + + -- Warp area generation + entities = { --- @setting entities The entities which are created for warp areas {'small-lamp',-3,-2},{'small-lamp',-3,2},{'small-lamp',3,-2},{'small-lamp',3,2}, {'small-lamp',-2,-3},{'small-lamp',2,-3},{'small-lamp',-2,3},{'small-lamp',2,3}, {'small-electric-pole',-3,-3},{'small-electric-pole',3,3},{'small-electric-pole',-3,3},{'small-electric-pole',3,-3} }, - base_tile = 'tutorial-grid', --- @setting base_tile The tile which is used for the warps - tiles = { --- @setting tiles The tiles which are created for warps + base_tile = 'tutorial-grid', --- @setting base_tile The tile which is used for the warp areas + tiles = { --- @setting tiles The tiles which are created for warp areas {-3,-2},{-3,-1},{-3,0},{-3,1},{-3,2},{3,-2},{3,-1},{3,0},{3,1},{3,2}, {-2,-3},{-1,-3},{0,-3},{1,-3},{2,-3},{-2,3},{-1,3},{0,3},{1,3},{2,3} } diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 4fc1a161..a94550d3 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 31bafcd7..5104f56d 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 740ed70e..12b2d4b7 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 6fb21b76..eda52288 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index 4f5b7ae2..a9885689 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 8983690a..20304e86 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e0085ca5..b5db145a 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 5de171a9..b6c03a49 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 08b4fc10..8a822e46 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index dcc7f831..1beb5873 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 54a470ef..0545406e 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 894d9fd7..2cd5e62f 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index bb480f1c..7ed81faf 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 11a3faa5..9fe4825c 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index fb090d39..d14c747d 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 1960d836..c774d4d6 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index ac910592..5eae53a7 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index 5488f96a..b69015ea 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index 371db9aa..4f5e97b4 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index ef15886c..5f0aa397 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 5f07e558..15d03b28 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index a892d1aa..d857f4de 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index c6e4fa94..a1e124e2 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index d7dd8363..d81a5601 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 6225e155..89d221c1 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 2c739395..68d1dbac 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index d94c73f6..e76ebc00 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index 24f01cf0..ae86a1c8 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 2dd125fd..1308a173 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 8a4262f3..3766b23a 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index 884b4a42..f6b81295 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 7d0e5d3d..edadff82 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 9612f09e..93bd8e14 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 021275cd..0dda65b9 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index dd7c7ddb..82cc7f4b 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 689ef12e..f4b77ef8 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index 9f3db256..d72f5edf 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index de12ef31..00353bdc 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 76a3b440..5cd6e37d 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index d3162a9e..c1e53996 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 38e0eee2..e345fe69 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index f9d7156b..27950dfa 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 9331d05b..9f00aa0c 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 3deb9a8e..c794811b 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 2d91ee39..ae73091b 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 64fa59aa..6251d78c 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index f648a0f5..c39118c6 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 267b19c9..af464cc2 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 0449a9f1..858ae123 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index 8d50f302..d8c76b79 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index 33b1ba00..f08ad41d 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index 6aa0aa00..0abe99c3 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index df64e68c..5c8300dc 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 0cd0d9f7..46f1ca96 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 8a8ae44b..4b21194e 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -244,13 +244,13 @@ allow_add_task - expcore_roles_add_permission + expcore_roles_allow_add_task allow_edit_task - expcore_roles_edit_permission + expcore_roles_allow_edit_task @@ -291,16 +291,15 @@
    - # - expcore_roles_add_permission + # + expcore_roles_allow_add_task

    -

    if expcore.roles is used then this is the required permission - values can be all, admin, expcore.roles, none

    +

    if expcore.roles is used then this is the required permission

    @@ -346,8 +345,8 @@
    - # - expcore_roles_edit_permission + # + expcore_roles_allow_edit_task
    @@ -385,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 2a237eb2..e1fb3569 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 5ef899b2..723c7258 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -241,37 +241,46 @@ - recharge_time - - update_smoothing minimum_distance - activation_range - - - spawn_activation_range - - default_icon - user_can_edit_own_warps + bypass_warp_cooldown - any_user_can_add_new_warp + expcore_roles_bypass_warp_cooldown - only_admins_can_edit + cooldown_duraction - edit_warps_role_permission + bypass_warp_proximity - bypass_warp_limits_permission + expcore_roles_bypass_warp_proximity + + + standard_proximity_radius + + + spawn_proximity_radius + + + allow_add_warp + + + expcore_roles_allow_add_warp + + + allow_edit_warp + + + expcore_roles_allow_edit_warp entities @@ -294,33 +303,6 @@
    - # - recharge_time -
    -
    -
    -
    - -

    -

    The amount of time in seconds that the player must wait between warps, acts as a balance

    - - - - - - - - - - - - - - -
    -
    -
    -
    # update_smoothing
    @@ -329,7 +311,7 @@

    -

    Higher is better, the amount of smoothing applied to recharge timer and other gui updates, max is 60

    +

    the amount of smoothing applied to updates to the cooldown timer, higher is better

    @@ -356,61 +338,7 @@

    -

    The minimum distance that must be between warp points, creating new ones is blocked when too close

    - - - - - - - - - - - - - - - -
    -
    -
    - # - activation_range -
    -
    -
    -
    - -

    -

    The distance the player must be to a warp in order to use the warp gui, gui can still be viewed but not used

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - spawn_activation_range -
    -
    -
    -
    - -

    -

    A second activation range which is used for the forces spawn point

    +

    the minimum distance that is allowed between warps on the same force

    @@ -437,7 +365,7 @@

    -

    The default icon which is used by warps; must be an item name

    +

    the default icon that will be used for warps

    @@ -456,15 +384,15 @@
    - # - user_can_edit_own_warps + # + bypass_warp_cooldown

    -

    When true the user can always edit warps which they created regardless of other settings

    +

    dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none

    @@ -483,15 +411,15 @@
    - # - any_user_can_add_new_warp + # + expcore_roles_bypass_warp_cooldown

    -

    When true any user is able to create new warps, however editing may still be restricted

    +

    if expcore.roles is used then this is the required permission

    @@ -510,15 +438,15 @@
    - # - only_admins_can_edit + # + cooldown_duraction

    -

    When true only admins can edit warps

    +

    the duration of the warp cooldown in seconds

    @@ -537,15 +465,15 @@
    - # - edit_warps_role_permission + # + bypass_warp_proximity

    -

    Role permission used by the role system to allow editing warps

    +

    dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none

    @@ -564,15 +492,177 @@
    - # - bypass_warp_limits_permission + # + expcore_roles_bypass_warp_proximity

    -

    Role permission used by the role system to allow bypassing the time and distance restrictions

    +

    if expcore.roles is used then this is the required permission

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + standard_proximity_radius +
    +
    +
    +
    + +

    +

    the minimum distance a player is allowed to be to a warp in order to use it

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + spawn_proximity_radius +
    +
    +
    +
    + +

    +

    the minimum distance a player is allowed to be from they spawn point to use warps

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + allow_add_warp +
    +
    +
    +
    + +

    +

    dictates who is allowed to add warps; values: all, admin, expcore.roles, none

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore_roles_allow_add_warp +
    +
    +
    +
    + +

    +

    if expcore.roles is used then this is the required permission

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + allow_edit_warp +
    +
    +
    +
    + +

    +

    dictates who is allowed to edit warps; values: all, admin, expcore.roles, none

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore_roles_allow_edit_warp +
    +
    +
    +
    + +

    +

    if expcore.roles is used then this is the required permission

    @@ -599,7 +689,7 @@

    -

    The entities which are created for warps

    +

    The entities which are created for warp areas

    @@ -626,7 +716,7 @@

    -

    The tile which is used for the warps

    +

    The tile which is used for the warp areas

    @@ -653,7 +743,7 @@

    -

    The tiles which are created for warps

    +

    The tiles which are created for warp areas

    @@ -684,7 +774,7 @@ generated by LDoc
    diff --git a/docs/control/Jail.html b/docs/control/Jail.html index a809745f..65aeb8d0 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc
    diff --git a/docs/control/Production.html b/docs/control/Production.html index 12a57823..252850bf 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index a239a42c..c722290a 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index a11e1edc..b53870c6 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index cbe14682..64a3b413 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index 84f5e53c..31e9150f 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 16a7f9de..6580b84a 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 545ac82f..3a2e7a33 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index fedadfc1..dab10ae9 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index c438edc4..21d1c537 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -2851,7 +2851,7 @@ Gui.element{ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index 13bacb25..bf67317a 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index cfb25893..3beabbe4 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index f5eb98bb..5cf287d0 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1481,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 9a0a180b..479ac70d 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index e0e633ba..be347756 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 5714de34..2c0e4c87 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 12c80988..3ba61f51 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index a16009c7..6136165e 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -274,6 +274,18 @@ Button displayed in the ehader bar, used to add a new task + edit_task + Button displayed next to tasks which the user is can edit, used to start editing a task + + + discard_task + Button displayed next to tasks which the user is can edit, used to delete a task from the list + + + add_task_base + Set of three elements which make up each row of the task table + + confirm_edit Button displayed next to tasks which the user is currently editing, used to save changes @@ -282,26 +294,14 @@ Button displayed next to tasks which the user is currently editing, used to discard changes - discard_task - Button displayed next to tasks which the user is can edit, used to delete a task from the list - - - edit_task - Button displayed next to tasks which the user is can edit, used to start editing a task - - - add_task_base - Set of three elements which make up each row of the task table + task_editing + Editing state for a task, contrins a text field and the two edit buttons task_label Default state for a task, contains only a label with the task message - task_editing - Editing state for a task, contrins a text field and the two edit buttons - - task_list_container Main task list container for the left flow @@ -491,6 +491,87 @@ + + + + + + +
    +
    +
    +
    + # + edit_task +
    +
    +
    +
    + +

    Button displayed next to tasks which the user is can edit, used to start editing a task

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + discard_task +
    +
    +
    +
    + +

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + add_task_base +
    +
    +
    +
    + +

    Set of three elements which make up each row of the task table

    +

    + + + + + + + + @@ -555,68 +636,14 @@
    - # - discard_task + # + task_editing
    -

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - edit_task -
    -
    -
    -
    - -

    Button displayed next to tasks which the user is can edit, used to start editing a task

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - add_task_base -
    -
    -
    -
    - -

    Set of three elements which make up each row of the task table

    +

    Editing state for a task, contrins a text field and the two edit buttons

    @@ -653,33 +680,6 @@ - - - - - - -
    -
    -
    -
    - # - task_editing -
    -
    -
    -
    - -

    Editing state for a task, contrins a text field and the two edit buttons

    -

    - - - - - - - - @@ -756,7 +756,7 @@ generated by LDoc
    diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 18297a4b..db64af56 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -282,30 +282,10 @@ - zoom_to_map - Used on the name label to allow zoom to map - - - warp_timer - This timer controls when a player is able to warp, eg every 60 seconds - - - goto_warp - When the button is clicked it will teleport the player - - add_new_warp Will add a new warp to the list, checks if the player is too close to an existing one - confirm_edit - Confirms the edit to name or icon of the warp - - - cancel_edit - Cancels the editing changes of the selected warp name or icon - - discard_warp Removes a warp from the list, including the physical area and map tag @@ -314,8 +294,44 @@ Opens edit mode for the warp - warp_list - Registers the warp list + add_warp_base + Set of three elements which make up each row of the warp table + + + confirm_edit + Confirms the edit to name or icon of the warp + + + cancel_edit + Cancels the editing changes of the selected warp name or icon + + + warp_editing + Editing state for a warp, contrins a text field and the two edit buttons + + + warp_label + Default state for a warp, contains only a label with the warp name + + + warp_icon_button + Default state for the warp icon, when pressed teleports the player + + + warp_icon_editing + Editing state for the warp icon, chose elem used to chosse icon + + + warp_timer + This timer controls when a player is able to warp, eg every 60 seconds + + + warp_list_container + Main warp list container for the left flow + + + warp_list_toggle + Button on the top flow used to toggle the warp list container @@ -582,87 +598,6 @@
    - # - zoom_to_map -
    -
    -
    -
    - -

    Used on the name label to allow zoom to map

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - warp_timer -
    -
    -
    -
    - -

    This timer controls when a player is able to warp, eg every 60 seconds

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - goto_warp -
    -
    -
    -
    - -

    When the button is clicked it will teleport the player

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    # add_new_warp
    @@ -680,60 +615,6 @@ - - - - - - - -
    -
    -
    - # - confirm_edit -
    -
    -
    -
    - -

    Confirms the edit to name or icon of the warp

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - cancel_edit -
    -
    -
    -
    - -

    Cancels the editing changes of the selected warp name or icon

    -

    - - - - - - - - @@ -798,14 +679,257 @@
    - # - warp_list + # + add_warp_base
    -

    Registers the warp list

    +

    Set of three elements which make up each row of the warp table

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + confirm_edit +
    +
    +
    +
    + +

    Confirms the edit to name or icon of the warp

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + cancel_edit +
    +
    +
    +
    + +

    Cancels the editing changes of the selected warp name or icon

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_editing +
    +
    +
    +
    + +

    Editing state for a warp, contrins a text field and the two edit buttons

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_label +
    +
    +
    +
    + +

    Default state for a warp, contains only a label with the warp name

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_icon_button +
    +
    +
    +
    + +

    Default state for the warp icon, when pressed teleports the player

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_icon_editing +
    +
    +
    +
    + +

    Editing state for the warp icon, chose elem used to chosse icon

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_timer +
    +
    +
    +
    + +

    This timer controls when a player is able to warp, eg every 60 seconds

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_list_container +
    +
    +
    +
    + +

    Main warp list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the warp list container

    @@ -837,7 +961,7 @@ generated by LDoc
    diff --git a/docs/index.html b/docs/index.html index a5e3d006..6154fead 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 6cca966d..a712091a 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 6291b757..3ffd68e8 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index b6393f5d..48b74c3f 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index c5882630..b34baf22 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index 2927bed7..42ee92fc 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 49848f9e..f851a4f8 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index ec13ecfc..aed7f3cf 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index e4815bc6..f72252fd 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 717e7598..20e6ef12 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index aeb9fd7f..9fe3a7ae 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 13f18afb..d7c02aa1 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index 47a1f7d6..dda2c43f 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index df8680e8..98b6d7f3 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index ffb5dd8e..2d42a575 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 7dba1a3c..4284e0e5 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/expcore/gui.lua b/expcore/gui.lua index 96193316..70af10f9 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -411,15 +411,15 @@ Gui.toggle_top_flow(game.player,true) function Gui.toggle_top_flow(player,state) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local new_state = state or toggle_button.style.name == 'forward_button' + if state == nil then state = toggle_button.style.name == 'forward_button' end -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do - top_flow[name].visible = new_state and authenticator(player) or false + top_flow[name].visible = state and authenticator(player) or false end -- Change the style of the toggle button - if new_state then + if state then toggle_button.style = 'back_button' local style = toggle_button.style style.height = 36 @@ -431,7 +431,7 @@ function Gui.toggle_top_flow(player,state) style.width = 18 end - return new_state + return state end --- Left Flow. @@ -501,8 +501,8 @@ function Gui.toggle_left_element(player,element_define,state) -- Set the visible state local element = left_flow[element_define.name] - local new_state = state or not element.visible - element.visible = new_state + if state == nil then state = not element.visible end + element.visible = state -- Check if the hide button should be visible local show_hide_button = false @@ -514,11 +514,11 @@ function Gui.toggle_left_element(player,element_define,state) end hide_button.visible = show_hide_button - return new_state + return state end -- Draw the two flows when a player joins -Event.add(defines.events.on_player_joined_game,function(event) +Event.add(defines.events.on_player_created,function(event) local player = game.players[event.player_index] -- Draw the top flow @@ -581,9 +581,9 @@ local new_enabled_state = Gui.toggle_enabled_state(element) ]] function Gui.toggle_enabled_state(element,state) if not element or not element.valid then return end - local new_state = state or not element.enabled - element.enabled = new_state - return new_state + if state == nil then state = not element.enabled end + element.enabled = state + return state end --[[-- Will toggle the visible state of an element or set it to the one given @@ -597,9 +597,9 @@ local new_visible_state = Gui.toggle_visible_state(element) ]] function Gui.toggle_visible_state(element,state) if not element or not element.valid then return end - local new_state = state or not element.visible - element.visible = new_state - return new_state + if state == nil then state = not element.visible end + element.visible = state + return state end --[[-- Destory a gui element without causing any errors, likly if the element may have already been removed diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 91d1faf2..332d2f42 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -91,7 +91,7 @@ cancel-tooltip=Discard changes edit-tooltip=Currently being edited by: __1__ edit-tooltip-none=Currently being edited by: Nobody discard-tooltip=Remove warp -timer-tooltip=Warp charge, charge time __1__ seconds +timer-tooltip=Warp cooldown takes __1__ seconds goto-tooltip=Go to x __1__ y __2__ goto-disabled=You must be on a warp point and have a full charge to warp goto-edit=Edit warp icon diff --git a/modules/control/warps.lua b/modules/control/warps.lua index ad503c3a..8958c833 100644 --- a/modules/control/warps.lua +++ b/modules/control/warps.lua @@ -150,7 +150,7 @@ function Warps.make_warp_area(warp_id) local position = warp.position local posx = position.x local posy = position.y - local radius = config.activation_range + local radius = config.standard_proximity_radius local radius2 = radius^2 -- Get the tile that is being replaced, store.update not needed as we dont want it to trigger @@ -203,7 +203,7 @@ function Warps.remove_warp_area(warp_id) local warp = Store.get(warp_store,warp_id) local position = warp.position local surface = warp.surface - local radius = config.activation_range + local radius = config.standard_proximity_radius local radius2 = radius^2 -- Check that a warp area was created previously diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index c36c3422..68baedae 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -333,7 +333,9 @@ Gui.element(function(event_trigger,parent) } -- Set the frame style - frame.style.padding = 2 + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 -- Draw the internal container local container = diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index d5d12a4f..f39c562d 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -20,6 +20,11 @@ local player_in_range_store = Store.register(function(player) return player.name end) +-- Stores the time remaing for a players warp cooldown +local player_warp_cooldown_store = Store.register(function(player) + return player.name +end) + -- Table that stores a boolean value of weather to keep the warp gui open local keep_gui_open = {} Global.register(keep_gui_open,function(tbl) @@ -27,130 +32,160 @@ Global.register(keep_gui_open,function(tbl) end) --- Returns if a player is allowed to edit the given warp -local function player_allowed_edit(player,warp) - if warp then +--- If a player is allowed to use the edit buttons +local function check_player_permissions(player,action,warp) + -- Check if the action is allow edit and then check bypass settings + if action == 'allow_edit_warp' then + -- Check if the warp is the spawn then it cant be edited local spawn_id = Warps.get_spawn_warp_id(player.force.name) if spawn_id == warp.warp_id then return false end + + -- Check if the player being the last to edit will override existing permisisons if config.user_can_edit_own_warps and warp.last_edit_name == player.name then return true end - else - if config.any_user_can_add_new_warp then - return true - end end - if config.only_admins_can_edit and not player.admin then - return false + -- Check player has permisison based on value in the config + local action_config = config[action] + if action_config == 'all' then + return true + elseif action_config == 'admin' then + return player.admin + elseif action_config == 'expcore.roles' then + return Roles.player_allowed(player,config['expcore_roles_'..action]) end - if config.edit_warps_role_permission and not Roles.player_allowed(player,config.edit_warps_role_permission) then - return false - end - - return true + -- Return false as all other condidtions have not been met + return false end ---- Used on the name label to allow zoom to map --- @element zoom_to_map -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local warp_id = event.element.parent.name - local warp = Warps.get_warp(warp_id) - local position = warp.position - event.player.zoom_to_world(position,1.5) -end) - - ---- This timer controls when a player is able to warp, eg every 60 seconds --- @element warp_timer -local warp_timer = -Gui.new_progressbar() -:set_tooltip{'warp-list.timer-tooltip',config.recharge_time} -:set_default_maximum(math.floor(config.recharge_time*config.update_smoothing)) -:add_store(Gui.categorize_by_player) -:set_style(nil,function(style) - style.horizontally_stretchable = true - style.color = Colors.light_blue -end) -:on_store_complete(function(player_name,reset) - Store.trigger(player_in_range_store,player_name) -end) - ---- When the button is clicked it will teleport the player --- @element goto_warp -local goto_warp = -Gui.new_button() -:set_sprites('item/'..config.default_icon) -:set_tooltip{'warp-list.goto-tooltip',0,0} -:set_style('quick_bar_slot_button',function(style) - style.height = 32 - style.width = 32 -end) -:on_click(function(player,element) - local warp_id = element.parent.caption - Warps.teleport_player(warp_id,player) - - -- Reset the warp cooldown if the player does not have unlimited warps - if config.bypass_warp_limits_permission and not Roles.player_allowed(player,config.bypass_warp_limits_permission) then - warp_timer:set_store(player.name,0) - Store.trigger(player_in_range_store,player) - end -end) - --- Will add a new warp to the list, checks if the player is too close to an existing one -- @element add_new_warp local add_new_warp = -Gui.new_button() -:set_sprites('utility/add') -:set_tooltip{'warp-list.add-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/add', + tooltip = {'warp-list.add-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} :on_click(function(player,element) + -- Add the new warp local force_name = player.force.name local surface = player.surface local position = player.position - local px = position.x - local py = position.y - local dist2 = config.minimum_distance^2 - - -- Check the distance to all existing warps - local warp_ids = Warps.get_force_warp_ids(force_name) - for _,warp_id in pairs(warp_ids) do - local warp = Warps.get_warp(warp_id) - local pos = warp.position - if surface == warp.surface and (px-pos.x)^2+(py-pos.y)^2 < dist2 then - player.print{'warp-list.too-close',warp.name} - return - end - end - - -- Add the new warp local warp_id = Warps.add_warp(force_name,surface,position,player.name) Warps.make_warp_tag(warp_id) Warps.make_warp_area(warp_id) end) +--- Removes a warp from the list, including the physical area and map tag +-- @element discard_warp +local discard_warp = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/trash', + tooltip = {'warp-list.discard-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(_,element) + local warp_id = element.parent.name:sub(6) + Warps.remove_warp(warp_id) +end) + +--- Opens edit mode for the warp +-- @element edit_warp +local edit_warp = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/rename_icon_normal', + tooltip = {'warp-list.edit-tooltip-none'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element) + local warp_id = element.parent.name:sub(6) + Warps.set_editing(warp_id,player.name,true) +end) + +--- Set of three elements which make up each row of the warp table +-- @element add_warp_base +local add_warp_base = +Gui.element(function(_,parent,warp_id) + -- Add the icon flow + local icon_flow = + parent.add{ + name = 'icon-'..warp_id, + type = 'flow', + caption = warp_id + } + + -- Change the style of the flow + icon_flow.style.padding = 0 + + -- Add a flow which will contain the warp name and edit buttons + local warp_flow = + parent.add{ + name = warp_id, + type = 'flow', + } + + -- Set the padding on the warp flow + warp_flow.style.padding = 0 + + -- Add the two edit buttons outside the warp flow + local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..warp_id) + edit_warp(edit_flow) + discard_warp(edit_flow) + + -- Return the warp flow as the main element + return warp_flow +end) + +-- Removes the three elements that are added as part of the warp base +local function remove_warp_base(parent,warp_id) + Gui.destroy_if_valid(parent['icon-'..warp_id]) + Gui.destroy_if_valid(parent['edit-'..warp_id]) + Gui.destroy_if_valid(parent[warp_id]) +end + --- Confirms the edit to name or icon of the warp -- @element confirm_edit +local warp_editing +local warp_icon_button local confirm_edit = -Gui.new_button() -:set_sprites('utility/downloaded') -:set_tooltip{'warp-list.confirm-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'warp-list.confirm-tooltip'}, + style = 'shortcut_bar_button_green' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} :on_click(function(player,element) local warp_id = element.parent.name - local warp_name = element.parent.warp.text - local warp_icon = element.parent.parent['icon-'..warp_id].icon.elem_value + local warp_name = element.parent[warp_editing.name].text + local warp_icon = element.parent.parent['icon-'..warp_id][warp_icon_button.name].elem_value Warps.set_editing(warp_id,player.name) Warps.update_warp(warp_id,warp_name,warp_icon,player.name) end) @@ -158,360 +193,462 @@ end) --- Cancels the editing changes of the selected warp name or icon -- @element cancel_edit local cancel_edit = -Gui.new_button() -:set_sprites('utility/close_black') -:set_tooltip{'warp-list.cancel-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'warp-list.cancel-tooltip'}, + style = 'shortcut_bar_button_red' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} :on_click(function(player,element) local warp_id = element.parent.name Warps.set_editing(warp_id,player.name) end) ---- Removes a warp from the list, including the physical area and map tag --- @element discard_warp -local discard_warp = -Gui.new_button() -:set_sprites('utility/trash') -:set_tooltip{'warp-list.discard-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) +--- Editing state for a warp, contrins a text field and the two edit buttons +-- @element warp_editing +warp_editing = +Gui.element(function(event_trigger,parent,warp) + local name = warp.name + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'textfield', + text = name, + clear_and_focus_on_right_click = true + } + + -- Change the style + local style = element.style + style.maximal_width = 110 style.height = 20 - style.width = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element end) -:on_click(function(player,element) +:on_confirmed(function(player,element,_) local warp_id = element.parent.name - Warps.remove_warp(warp_id) + local warp_name = element.text + local warp_icon = element.parent.parent['icon-'..warp_id][warp_icon_button.name].elem_value + Warps.set_editing(warp_id,player.name) + Warps.update_warp(warp_id,warp_name,warp_icon,player.name) end) ---- Opens edit mode for the warp --- @element edit_warp -local edit_warp = -Gui.new_button() -:set_sprites('utility/rename_icon_normal') -:set_tooltip{'warp-list.edit-tooltip-none'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local warp_id = element.parent.name - Warps.set_editing(warp_id,player.name,true) -end) +--- Default state for a warp, contains only a label with the warp name +-- @element warp_label +local warp_label = +Gui.element(function(event_trigger,parent,warp) + local name = warp.name + local last_edit_name = warp.last_edit_name + local last_edit_time = warp.last_edit_time ---[[ Generates each warp, handles both view and edit mode - element - > icon-"warp_id" - >> goto_warp or icon - > "warp_id" - >> warp - >> cancel_edit (edit mode) - >> confirm_edit (edit mode) - > edit-"warp_id" - >> "warp_id" - >>> edit_warp - >>> discard_warp -]] -local function generate_warp(player,element,warp_id) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'label', + caption = name, + tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} + } + + -- Change the style + local style = element.style + style.single_line = false + style.maximal_width = 150 + + -- Return the element + return element +end) +:on_click(function(player,element,_) + local warp_id = element.parent.name local warp = Warps.get_warp(warp_id) + local position = warp.position + player.zoom_to_world(position,1.5) +end) + + +--- Default state for the warp icon, when pressed teleports the player +-- @element warp_icon_button +warp_icon_button = +Gui.element(function(event_trigger,parent,warp) + local warp_position = warp.position + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'sprite-button', + sprite = 'item/'..warp.icon, + tooltip = {'warp-list.goto-tooltip',warp_position.x,warp_position.y}, + style = 'quick_bar_slot_button' + } + + -- Change the style + local style = element.style + style.height = 32 + style.width = 32 + + -- Return the element + return element +end) +:on_click(function(player,element,_) + local warp_id = element.parent.caption + Warps.teleport_player(warp_id,player) + + -- Reset the warp cooldown if the player does not have unlimited warps + if not check_player_permissions(player,'bypass_warp_cooldown') then + Store.set(player_warp_cooldown_store,player,config.cooldown_duraction) + Store.trigger(player_in_range_store,player) + end +end) + +--- Editing state for the warp icon, chose elem used to chosse icon +-- @element warp_icon_editing +local warp_icon_editing = +Gui.element(function(event_trigger,parent,warp) + local warp_icon = warp.icon + + -- Draw the element + local element = + parent.add{ + name = warp_icon_button.name, + type = 'choose-elem-button', + elem_type = 'item', + item = warp_icon, + tooltip = {'warp-list.goto-edit'}, + } + + -- Change the style + local style = element.style + style.height = 32 + style.width = 32 + + -- Return the element + return element +end) + +--- This timer controls when a player is able to warp, eg every 60 seconds +-- @element warp_timer +local warp_timer = +Gui.element{ + type = 'progressbar', + tooltip = {'warp-list.timer-tooltip',config.cooldown_duraction}, + minimum_value = 0, + maximum_value = config.cooldown_duraction*config.update_smoothing +} +:style{ + horizontally_stretchable = true, + color = Colors.light_blue +} + +--- Updates a warp for a player +local function update_warp(player,warp_table,warp_id) + local warp = Warps.get_warp(warp_id) + + -- Warp no longer exists so should be removed from the list if not warp then - -- warp is nil so remove it from the list - Gui.destroy_if_valid(element['icon-'..warp_id]) - Gui.destroy_if_valid(element['edit-'..warp_id]) - Gui.destroy_if_valid(element[warp_id]) - - else - local warp_name = warp.name - local warp_icon = warp.icon - local editing = warp.currently_editing[player.name] - local last_edit_name = warp.last_edit_name - local last_edit_time = warp.last_edit_time - local position = warp.position - - -- if it is not already present then add it now - local warp_area = element[warp_id] - local icon_area = element['icon-'..warp_id] - if not warp_area then - -- area to store the warp icon - icon_area = - element.add{ - name='icon-'..warp_id, - type='flow', - caption=warp_id - } - Gui.set_padding(icon_area) - - -- area which stores the warp and buttons - warp_area = - element.add{ - name=warp_id, - type='flow', - } - Gui.set_padding(warp_area) - - -- if the player can edit then it adds the edit and delete button - local flow = Gui.create_alignment(element,'edit-'..warp_id) - local sub_flow = flow.add{type='flow',name=warp_id} - - edit_warp(sub_flow) - discard_warp(sub_flow) - - end - - local edit_area = element['edit-'..warp_id][warp_id] - local players = warp.currently_editing and table_keys(warp.currently_editing) or {} - local allowed = player_allowed_edit(player,warp) - - edit_area.visible = allowed - - if #players > 0 then - edit_area[edit_warp.name].tooltip = {'warp-list.edit-tooltip',table.concat(players,', ')} - else - edit_area[edit_warp.name].tooltip = {'warp-list.edit-tooltip-none'} - end - - -- draws/updates the warp area - local label_element = warp_area.warp or warp_area[zoom_to_map_name] or nil - local element_type = label_element and label_element.type or nil - if not editing and element_type == 'label' then - -- update the label already present - label_element.caption = warp_name - label_element.tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} - icon_area[goto_warp.name].sprite = 'item/'..warp_icon - - elseif not editing then - -- create the label, view mode - if edit_area then - edit_area[edit_warp.name].enabled = true - end - - -- redraws the icon for the warp - icon_area.clear() - - local btn = goto_warp(icon_area) - btn.sprite = 'item/'..warp_icon - btn.tooltip = {'warp-list.goto-tooltip',position.x,position.y} - - local timer = warp_timer:get_store(player.name) - local enabled = not timer and Store.get(player_in_range_store,player) - or Roles.player_allowed(player,config.bypass_warp_limits_permission) - if not enabled then - btn.enabled = false - btn.tooltip = {'warp-list.goto-disabled'} - end - - -- redraws the label for the warp name - warp_area.clear() - - local label = - warp_area.add{ - name=zoom_to_map_name, - type='label', - caption=warp_name, - tooltip={'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} - } - label.style.single_line = false - label.style.maximal_width = 150 - - elseif editing and element_type ~= 'textfield' then - -- create the text field, edit mode, update it omitted as value is being edited - if edit_area then - edit_area[edit_warp.name].enabled = false - end - - -- redraws the icon for the warp and allows selection - icon_area.clear() - - local btn = - icon_area.add{ - name='icon', - type='choose-elem-button', - elem_type='item', - item=warp_icon, - tooltip={'warp-list.goto-edit'}, - } - btn.style.height = 32 - btn.style.width = 32 - - -- redraws the label for the warp name and allows editing - warp_area.clear() - - local entry = - warp_area.add{ - name='warp', - type='textfield', - text=warp_name - } - entry.style.maximal_width = 150 - entry.style.height = 20 - - cancel_edit(warp_area) - confirm_edit(warp_area) - - end - + remove_warp_base(warp_table,warp_id) + return end + -- Get the warp flow for this warp + local warp_flow = warp_table[warp_id] or add_warp_base(warp_table,warp_id) + local icon_flow = warp_table['icon-'..warp_id] + + -- Update the edit flow + local edit_flow = warp_table['edit-'..warp_id] + local player_allowed_edit = check_player_permissions(player,'allow_edit_warp',warp) + local players_editing = table_keys(warp.currently_editing) + local edit_warp_element = edit_flow[edit_warp.name] + local discard_warp_element = edit_flow[discard_warp.name] + + edit_warp_element.visible = player_allowed_edit + discard_warp_element.visible = player_allowed_edit + if #players_editing > 0 then + edit_warp_element.hovered_sprite = 'utility/warning_icon' + edit_warp_element.tooltip = {'warp-list.edit-tooltip',table.concat(players_editing,', ')} + else + edit_warp_element.hovered_sprite = edit_warp_element.sprite + edit_warp_element.tooltip = {'warp-list.edit-tooltip-none'} + end + + -- Check if the player is was editing and/or currently editing + local warp_label_element = warp_flow[warp_label.name] or warp_label(warp_flow,warp) + local icon_entry = icon_flow[warp_icon_button.name] or warp_icon_button(icon_flow,warp) + local player_was_editing = icon_entry.type == 'choose-elem-button' + local player_is_editing = warp.currently_editing[player.name] + + -- Update the warp and icon flow + if not player_was_editing and not player_is_editing then + -- Update the warp name label and icon + local warp_name = warp.name + local warp_icon = warp.icon + local last_edit_name = warp.last_edit_name + local last_edit_time = warp.last_edit_time + warp_label_element.caption = warp_name + warp_label_element.tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} + icon_entry.sprite = 'item/'..warp_icon + + elseif player_was_editing and not player_is_editing then + -- Player was editing but is no longer, remove text field and add label + edit_warp_element.enabled = true + warp_flow.clear() + warp_label(warp_flow,warp) + + icon_flow.clear() + local warp_icon_element = warp_icon_button(icon_flow,warp) + local timer = Store.get(player_warp_cooldown_store,player) + local in_range = Store.get(player_in_range_store,player) + local apply_proximity = not check_player_permissions(player,'bypass_warp_proximity') + if (timer and timer > 0) or (apply_proximity and not in_range) then + warp_icon_element.enabled = false + warp_icon_element.tooltip = {'warp-list.goto-disabled'} + end + + elseif not player_was_editing and player_is_editing then + -- Player was not editing but now is, remove label and add text field + edit_warp_element.enabled = false + warp_flow.clear() + warp_editing(warp_flow,warp).focus() + icon_flow.clear() + warp_icon_editing(icon_flow,warp) + + end end ---[[ generates the main gui structure - element - > container - >> header - >>> right aligned add_new_warp - >> scroll - >>> table - >> warp_timer -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +local function update_all_warps(player,warp_table) + local warp_ids = Warps.get_force_warp_ids(player.force.name) + if #warp_ids > 0 then + for _,warp_id in ipairs(warp_ids) do + update_warp(player,warp_table,warp_id) + end + end +end - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main warp list container for the left flow +-- @element warp_list_container +local warp_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - container.style.vertically_stretchable = false - -- main header for the gui - local header_area = Gui.create_header( + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + local header = Gui.header( container, {'warp-list.main-caption'}, - {'warp-list.sub-tooltip',config.recharge_time,config.activation_range}, + {'warp-list.sub-tooltip', config.cooldown_duraction, config.standard_proximity_radius}, true ) - --- Right aligned button to toggle the section - if player_allowed_edit(player) then - add_new_warp(header_area) + -- Draw the new warp button + local player = Gui.get_player_from_element(parent) + local add_new_warp_element = add_new_warp(header) + add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') + + -- Draw the scroll table for the warps + local scroll_table = Gui.scroll_table(container,258,3) + + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.top_cell_padding = 3 + scroll_table_style.bottom_cell_padding = 3 + + -- Draw the warp cooldown progress bar + local warp_timer_element = warp_timer(container) + + -- Change the progress of the warp timer + local progress = 1 + local timer = Store.get(player_warp_cooldown_store,player) + if timer and timer > 0 then + progress = 1 - (timer/config.cooldown_duraction) end + warp_timer_element.value = progress - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,3,258) - flow_table.style.top_cell_padding = 3 - flow_table.style.bottom_cell_padding = 3 + -- Add any existing warps + update_all_warps(player,scroll_table) - warp_timer(container) - - return flow_table -end - ---- Registers the warp list --- @element warp_list -local warp_list = -Gui.new_left_frame('gui/warp-list') -:set_sprites('item/'..config.default_icon) -:set_tooltip{'warp-list.main-tooltip',config.activation_range} -:set_direction('vertical') -:on_creation(function(player,element) - local data_table = generate_container(player,element) - local warp_ids = Warps.get_force_warp_ids(player.force.name) - - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,data_table,warp_id) - end + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local data_table = element.container.scroll.table - local warp_ids = Warps.get_force_warp_ids(player.force.name) +:add_to_left_flow() - data_table.clear() - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,data_table,warp_id) - end +--- Button on the top flow used to toggle the warp list container +-- @element warp_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'item/'..config.default_icon, + tooltip = {'warp-list.main-tooltip',config.standard_proximity_radius}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/warp-list') end) -:on_player_toggle(function(player,element,visible) - keep_gui_open[player.name] = visible +:on_click(function(player,_,_) + local visible_state = Gui.toggle_left_element(player, warp_list_container) + keep_gui_open[player.name] = visible_state end) --- When the name of a warp is updated this is triggered -Warps.on_update(function(warp) - local players - local force_name +Warps.on_update(function(warp,_,removed_warp) + -- Get the force to update, warp is nil when removed + local force if warp then - local force = game.forces[warp.force_name] - players = force.connected_players - force_name = warp.force_name + force = game.forces[warp.force_name] else - players = game.connected_players + force = game.forces[removed_warp.force_name] end -- Update the gui for selected players - local force_warps = {} - for _,player in pairs(players) do - local frame = warp_list:get_frame(player) - local element = frame.container.scroll.table - - -- Get the warp ids for the players force - force_name = force_name or player.force.name - local warp_ids = force_warps[force_name] - if not warp_ids then - warp_ids = Warps.get_force_warp_ids(force_name) - force_warps[force_name] = warp_ids - end + local warp_ids = Warps.get_force_warp_ids(force.name) + for _,player in pairs(force.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table -- Update the gui - element.clear() - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,element,warp_id) + scroll_table.clear() + for _,next_warp_id in ipairs(warp_ids) do + update_warp(player,scroll_table,next_warp_id) end end end) --- Update the warps when the player joins -Event.add(defines.events.on_player_joined_game,warp_list 'redraw') -Event.add(Roles.events.on_role_assigned,warp_list 'redraw') -Event.add(Roles.events.on_role_unassigned,warp_list 'redraw') +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table + update_all_warps(player,scroll_table) +end) + +--- Makes sure the right buttons are present when roles change +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[warp_list_container.name].container + + -- Update the warps, incase the user can now edit them + local scroll_table = container.scroll.table + update_all_warps(player,scroll_table) + + -- Update the new warp button incase the user can now add them + local add_new_warp_element = container.header.alignment[add_new_warp.name] + add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') +end + +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) --- When the player leaves or enters range of a warp this is triggered Store.watch(player_in_range_store,function(value,player_name) local player = game.players[player_name] local force = player.force - local frame = warp_list:get_frame(player_name) - local table_area = frame.container.scroll.table - local timer = warp_timer:get_store(player_name) - local state = not timer and value + -- Change if the frame is visible based on if the player is in range if not keep_gui_open[player.name] then - Gui.toggle_left_frame(warp_list.name,player,value) + Gui.toggle_left_element(player,warp_list_container,value) end - if Roles.player_allowed(player,config.bypass_warp_limits_permission) then + -- Check if the player requires proximity + if check_player_permissions(player,'bypass_warp_proximity') then return end + -- Get the warp table + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table + + -- Check if the buttons should be active + local timer = Store.get(player_warp_cooldown_store,player) + local button_disabled = timer and timer > 0 or not value + + -- Change the enabled state of the warp buttons local warp_ids = Warps.get_force_warp_ids(force.name) for _,warp_id in pairs(warp_ids) do - local element = table_area['icon-'..warp_id][goto_warp.name] + local element = scroll_table['icon-'..warp_id][warp_icon_button.name] if element and element.valid then - element.enabled = state - if state then + element.enabled = not button_disabled + if button_disabled then + element.tooltip = {'warp-list.goto-disabled'} + else local position = Warps.get_warp(warp_id).position element.tooltip = {'warp-list.goto-tooltip',position.x,position.y} - else - element.tooltip = {'warp-list.goto-disabled'} end end end end) ---- Handles updating the timer and checking distance from a warp -local r2 = config.activation_range^2 -local rs2 = config.spawn_activation_range^2 -Event.on_nth_tick(math.floor(60/config.update_smoothing),function() - local categories = Store.get(warp_timer.store) or {} - for category,_ in pairs(categories) do - warp_timer:increment(1,category) +--- Update the warp cooldown progress bars to match the store +Store.watch(player_warp_cooldown_store,function(value,player_name,old_value) + if value == old_value then return end + -- Get the progress bar element + local player = game.players[player_name] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local warp_timer_element = frame.container[warp_timer.name] + + -- Set the progress + local progress = 1 + local timer = Store.get(player_warp_cooldown_store,player) + if timer and timer > 0 then + progress = 1 - (timer/config.cooldown_duraction) end + warp_timer_element.value = progress + + -- Trigger update of buttons if cooldown is now 0 + if value == 0 then + Store.trigger(player_in_range_store,player_name) + end +end) + +--- Handles updating the timer and checking distance from a warp +local r2 = config.standard_proximity_radius^2 +local rs2 = config.spawn_proximity_radius^2 +local mr2 = config.minimum_distance^2 +Event.on_nth_tick(math.floor(60/config.update_smoothing),function() + Store.map(player_warp_cooldown_store,function(value) + if value > 0 then + return value - 1 + end + end) local force_warps = {} local warps = {} @@ -527,6 +664,8 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end -- Check if the force has any warps + local closest_warp + local closest_distance if #warp_ids > 0 then local surface = player.surface local pos = player.position @@ -545,20 +684,35 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() local warp_pos = warp.position if warp.surface == surface then local dx, dy = px-warp_pos.x, py-warp_pos.y - if (warp_id == warp_ids.spawn and (dx*dx)+(dy*dy) < rs2) or (dx*dx)+(dy*dy) < r2 then - -- Set in range to true if the player was preiovusly out of range - if not was_in_range then - Store.set(player_in_range_store,player,true) - end - was_in_range = false -- stops setting back to false below - break + local dist = (dx*dx)+(dy*dy) + if closest_distance == nil or dist < closest_distance then + closest_warp = warp + closest_distance = dist + if dist < r2 then break end end end end - -- Set in range to false if the player was preiovusly in range - if was_in_range then + -- Check the dist to the closest warp + local in_range = closest_warp.warp_id == warp_ids.spawn and closest_distance < rs2 or closest_distance < r2 + if was_in_range and not in_range then Store.set(player_in_range_store,player,false) + elseif not was_in_range and in_range then + Store.set(player_in_range_store,player,true) + end + + -- Change the enabled state of the add warp button + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local add_warp_element = frame.container.header.alignment[add_new_warp.name] + local was_able_to_make_warp = add_warp_element.enabled + local can_make_warp = closest_distance > mr2 + if can_make_warp and not was_able_to_make_warp then + add_warp_element.enabled = true + add_warp_element.tooltip = {'warp-list.add-tooltip'} + elseif not can_make_warp and was_able_to_make_warp then + add_warp_element.enabled = false + add_warp_element.tooltip = {'warp-list.too-close',closest_warp.name} end end @@ -567,18 +721,10 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end) ---- When a player is created it will set them being in range to false to stop warping on join +--- When a player is created make sure that there is a spawn warp created Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - - -- Check if a player is allowed unlimited warps - local allowed = config.bypass_warp_limits_permission and Roles.player_allowed(player,config.bypass_warp_limits_permission) or false - Store.set(player_in_range_store,player,allowed) - if allowed then - warp_timer:set_store(player.name,1) - end - -- If the force has no spawn then make a spawn warp + local player = Game.get_player_by_index(event.player_index) local force = player.force local spawn_id = Warps.get_spawn_warp_id(force.name) if not spawn_id then @@ -590,6 +736,7 @@ Event.add(defines.events.on_player_created,function(event) end end) +--- When a chart tag is removed or edited make sure it is not one that belongs to a warp local function maintain_tag(event) if not event.player_index then return end local tag = event.tag @@ -608,6 +755,4 @@ local function maintain_tag(event) end Event.add(defines.events.on_chart_tag_modified,maintain_tag) -Event.add(defines.events.on_chart_tag_removed,maintain_tag) - -return warp_list \ No newline at end of file +Event.add(defines.events.on_chart_tag_removed,maintain_tag) \ No newline at end of file From ebf08fa989ab4f1d5bc5acbb0da05b295ca6dbfa Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 25 Oct 2019 23:42:35 +0100 Subject: [PATCH 05/21] Updated science info --- config/_file_loader.lua | 2 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 2 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 4 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 2 +- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 133 +++- docs/guis/Task-List.html | 2 +- docs/guis/Warps-List.html | 2 +- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- modules/gui/science-info.lua | 630 +++++++++++------- 94 files changed, 605 insertions(+), 344 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 7629b905..fa73ff34 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -40,7 +40,7 @@ return { 'modules.addons.chat-reply', -- GUI --'modules.gui.rocket-info', - --'modules.gui.science-info', + 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', --'modules.gui.player-list', diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index a94550d3..e06593f6 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 5104f56d..7cb0c9b2 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 12b2d4b7..6c368f68 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index eda52288..135ff83a 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index a9885689..df0b8737 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 20304e86..4f94aece 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index b5db145a..12bccc87 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index b6c03a49..0682c770 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 8a822e46..8ecf95bf 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index 1beb5873..84ea1706 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 0545406e..9cd696ab 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 2cd5e62f..7967ea77 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index 7ed81faf..f0b1fc7b 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 9fe4825c..680b91e8 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index d14c747d..7026f517 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index c774d4d6..6667e00b 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index 5eae53a7..e95e5332 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index b69015ea..deb9aa2a 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index 4f5e97b4..e9b13bfd 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index 5f0aa397..89212f3b 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 15d03b28..2c670b45 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index d857f4de..f6e57348 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index a1e124e2..59c4534a 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index d81a5601..6c90fe3f 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 89d221c1..004ec4bd 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 68d1dbac..2f71921c 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index e76ebc00..ba0318c7 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index ae86a1c8..fda9f645 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 1308a173..9cf7157a 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 3766b23a..e9131888 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index f6b81295..ac587916 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index edadff82..75ce3491 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 93bd8e14..cc4d5595 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 0dda65b9..d7ae726a 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index 82cc7f4b..4a48d6da 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index f4b77ef8..ed1c5b7f 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index d72f5edf..e72d1a81 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 00353bdc..f9d62d80 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 5cd6e37d..d1d21e74 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index c1e53996..7dc0e1b5 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index e345fe69..ab9a69db 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 27950dfa..40ee9ed3 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 9f00aa0c..11aeb9af 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index c794811b..6329eb61 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index ae73091b..2d23727d 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 6251d78c..2c6dc312 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index c39118c6..bf97ecf9 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index af464cc2..3fd3eca5 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 858ae123..82dcaa12 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index d8c76b79..a318f0cd 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index f08ad41d..c324a6ac 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index 0abe99c3..f5dca812 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index 5c8300dc..f011372b 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 46f1ca96..fac7d663 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 4b21194e..4e84ef99 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index e1fb3569..09b6a980 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 723c7258..0353eba6 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -311,7 +311,7 @@

    -

    the amount of smoothing applied to updates to the cooldown timer, higher is better

    +

    the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60

    @@ -774,7 +774,7 @@ generated by LDoc
    diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 65aeb8d0..4f02fcb1 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index 252850bf..301380da 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index c722290a..349a872c 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index b53870c6..2f5efd39 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 64a3b413..440f1c35 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index 31e9150f..32c13b69 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 6580b84a..5a52b7df 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 3a2e7a33..26e2e30e 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index dab10ae9..6b2cd701 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 21d1c537..72fc7784 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -2851,7 +2851,7 @@ Gui.element{ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index bf67317a..dc36167e 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 3beabbe4..25ceecf4 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index 5cf287d0..fd876dbc 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1481,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 479ac70d..27c2542b 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index be347756..0dbdaafd 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 2c0e4c87..3de18001 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 3ba61f51..5d2fbcd2 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -247,6 +247,9 @@ expcore.gui + expcore.gui + + utils.event @@ -267,8 +270,20 @@ - science_info - Registers the science info + production_label + Data label that contains the value and the surfix + + + science_pack_base + Adds 4 elements that show the data for a science pack + + + task_list_container + Main task list container for the left flow + + + task_list_toggle + Button on the top flow used to toggle the task list container @@ -297,6 +312,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.gui +
    +
    +
    +
    + + + + + + + + + @@ -410,14 +450,95 @@
    - # - science_info + # + production_label
    -

    Registers the science info

    +

    Data label that contains the value and the surfix

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + science_pack_base +
    +
    +
    +
    + +

    Adds 4 elements that show the data for a science pack

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_container +
    +
    +
    +
    + +

    Main task list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the task list container

    @@ -449,7 +570,7 @@ generated by LDoc
    diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 6136165e..8e546493 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -756,7 +756,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index db64af56..2f4ac049 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -961,7 +961,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index 6154fead..2b553d42 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index a712091a..4fc84050 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 3ffd68e8..fdb538e2 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index 48b74c3f..c94a85ca 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index b34baf22..d9fc0fa5 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index 42ee92fc..1a275d2f 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index f851a4f8..0613535f 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index aed7f3cf..4714e6ed 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index f72252fd..24562934 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 20e6ef12..11b985c3 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 9fe3a7ae..0166e736 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index d7c02aa1..f5c0e283 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index dda2c43f..4d025c24 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index 98b6d7f3..ffcfd375 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 2d42a575..6d78546c 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 4284e0e5..488a3235 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 9ecce6e2..a3d74b33 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -5,6 +5,7 @@ ]] local Gui = require 'expcore.gui' --- @dep expcore.gui +local Roles = require 'expcore.roles' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common local config = require 'config.science' --- @dep config.science @@ -13,275 +14,414 @@ local Production = require 'modules.control.production' --- @dep modules.control local null_time_short = {'science-info.eta-time',format_time(0,{hours=true,minutes=true,seconds=true,time=true,null=true})} local null_time_long = format_time(0,{hours=true,minutes=true,seconds=true,long=true,null=true}) ---[[ Generates the main structure for the gui - element - > container - >> header - >> scroll - >>> non_made - >>> table - >> footer (when eta is enabled) - >>> eta-label - >>> eta - >>>> label -]] -local function generate_container(element) - Gui.set_padding(element,1,2,2,2) - element.style.minimal_width = 200 +--- Data label that contains the value and the surfix +-- @element production_label +local production_label = +Gui.element(function(_,parent,production_label_data) + local name = production_label_data.name + local tooltip = production_label_data.tooltip + local color = production_label_data.color - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' + -- Add an alignment for the number + local alignment = Gui.alignment(parent,nil,nil,name) + + -- Add the main value label + local element = + alignment.add{ + name = 'label', + type = 'label', + caption = production_label_data.caption, + tooltip = tooltip } - Gui.set_padding(container) - -- main header for the gui - Gui.create_header( + -- Change the style + element.style.font_color = color + + -- Add the surfix label + local surfix_element = + parent.add{ + name = 'surfix-'..name, + type = 'label', + caption = {'science-info.unit',production_label_data.surfix}, + tooltip = tooltip + } + + -- Change the style + surfix_element.style.font_color = color + + -- Return the value label + return element +end) + +-- Get the data that is used with the production label +local function get_production_label_data(name,tooltip,value,secondary) + local data_colour = Production.get_color(config.color_clamp, value, secondary) + local surfix,caption = Production.format_number(value) + + return { + name = name, + caption = caption, + surfix = surfix, + tooltip = tooltip, + color = data_colour + } +end + +-- Updates a prodution label to match the current data +local function update_production_label(parent,production_label_data) + local name = production_label_data.name + local tooltip = production_label_data.tooltip + local color = production_label_data.color + + -- Update the production label + local production_label_element = parent[name] and parent[name].label or production_label(parent,production_label_data) + production_label_element.caption = production_label_data.caption + production_label_element.tooltip = production_label_data.tooltip + production_label_element.style.font_color = color + + -- Update the surfix label + local surfix_element = parent['surfix-'..name] + surfix_element.caption = {'science-info.unit',production_label_data.surfix} + surfix_element.tooltip = tooltip + surfix_element.style.font_color = color + +end + +--- Adds 4 elements that show the data for a science pack +-- @element science_pack_base +local science_pack_base = +Gui.element(function(_,parent,science_pack_data) + local science_pack = science_pack_data.science_pack + + -- Draw the icon for the science pack + local icon_style = science_pack_data.icon_style + local pack_icon = + parent.add{ + name = 'icon-'..science_pack, + type = 'sprite-button', + sprite = 'item/'..science_pack, + tooltip = {'item-name.'..science_pack}, + style = icon_style + } + + -- Change the style of the icon + local pack_icon_style = pack_icon.style + pack_icon_style.height = 55 + if icon_style == 'quick_bar_slot_button' then + pack_icon_style.padding = {0,-2} + pack_icon_style.width = 36 + end + + -- Draw the delta flow + local delta_flow = + parent.add{ + name = 'delta-'..science_pack, + type = 'frame', + style = 'bordered_frame' + } + + -- Change the style of the delta flow + delta_flow.style.padding = {0,3} + + -- Draw the delta flow table + local delta_table = + delta_flow.add{ + name = 'table', + type = 'table', + column_count = 2 + } + + -- Change the style of the delta flow table + delta_table.style.padding = 0 + + -- Draw the production labels + update_production_label(delta_table,science_pack_data.positive) + update_production_label(delta_table,science_pack_data.negative) + update_production_label(parent,science_pack_data.net) + + -- Return the pack icon + return pack_icon +end) + +local function get_science_pack_data(player,science_pack) + local force = player.force + + -- Check that some packs have been made + local total = Production.get_production_total(force, science_pack) + local minute = Production.get_production(force, science_pack, defines.flow_precision_index.one_minute) + if total.made == 0 then + return + end + + -- Get the icon style + local icon_style = 'quick_bar_slot_button' + local flux = Production.get_fluctuations(force, science_pack, defines.flow_precision_index.one_minute) + if minute.net > 0 and flux.net > -config.color_flux/2 then + icon_style = 'green_slot_button' + elseif flux.net < -config.color_flux then + icon_style = 'red_slot_button' + elseif minute.made > 0 then + icon_style = 'selected_slot_button' + end + + -- Return the pack data + return { + science_pack = science_pack, + icon_style = icon_style, + positive = get_production_label_data( + 'pos-'..science_pack, + {'science-info.pos-tooltip', total.made}, + minute.made + ), + negative = get_production_label_data( + 'neg-'..science_pack, + {'science-info.neg-tooltip', total.used}, + -minute.used + ), + net = get_production_label_data( + 'net-'..science_pack, + {'science-info.net-tooltip', total.net}, + minute.net, + minute.made+minute.used + ) + } + +end + +local function update_science_pack(pack_table,science_pack_data) + if not science_pack_data then return end + local science_pack = science_pack_data.science_pack + pack_table.parent.non_made.visible = false + + -- Update the icon + local pack_icon = pack_table['icon-'..science_pack] or science_pack_base(pack_table,science_pack_data) + local icon_style = science_pack_data.icon_style + pack_icon.style = icon_style + + local pack_icon_style = pack_icon.style + pack_icon_style.height = 55 + if icon_style == 'quick_bar_slot_button' then + pack_icon_style.padding = {0,-2} + pack_icon_style.width = 36 + end + + -- Update the production labels + local delta_table = pack_table['delta-'..science_pack].table + update_production_label(delta_table,science_pack_data.positive) + update_production_label(delta_table,science_pack_data.negative) + update_production_label(pack_table,science_pack_data.net) + +end + +--- Gets the data that is used with the eta label +local function get_eta_label_data(player) + local force = player.force + + -- If there is no current research then return no research + local research = force.current_research + if not research then + return { research = false } + end + + local progress = force.research_progress + local remaining = research.research_unit_count*(1-progress) + local limit + + -- Check for the limiting science pack + for _,ingredient in pairs(research.research_unit_ingredients) do + local pack_name = ingredient.name + local required = ingredient.amount * remaining + local time = Production.get_consumsion_eta(force, pack_name, defines.flow_precision_index.one_minute, required) + if not limit or limit < time then + limit = time + end + end + + -- Return the caption and tooltip + return limit and limit > 0 and { + research = true, + caption = format_time(limit,{hours=true,minutes=true,seconds=true,time=true}), + tooltip = format_time(limit,{hours=true,minutes=true,seconds=true,long=true}) + } or { research = false } + +end + +-- Updates the eta label +local function update_eta_label(element,eta_label_data) + -- If no research selected show null + if not eta_label_data.research then + element.caption = null_time_short + element.tooltip = null_time_long + return + end + + -- Update the element + element.caption = {'science-info.eta-time',eta_label_data.caption} + element.tooltip = eta_label_data.tooltip +end + +--- Main task list container for the left flow +-- @element task_list_container +local science_info_container = +Gui.element(function(event_trigger,parent) + local player = Gui.get_player_from_element(parent) + + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' + } + + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + Gui.header( container, {'science-info.main-caption'}, {'science-info.main-tooltip'} ) - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,4,185) + -- Draw the scroll table for the tasks + local scroll_table = Gui.scroll_table(container,185,4) - -- message to say that you have not made any packs yet - local non_made = - flow_table.parent.add{ - name='non_made', - type='label', - caption={'science-info.no-packs'} + -- Draw the no packs label + local no_packs_label = + scroll_table.parent.add{ + name = 'non_made', + type = 'label', + caption = {'science-info.no-packs'} } - non_made.style.width = 200 - non_made.style.single_line = false - local eta + -- Change the style of the no packs label + local no_packs_style = no_packs_label.style + no_packs_style.padding = {2,4} + no_packs_style.single_line = false + no_packs_style.width = 200 + + -- Add the footer and eta if config.show_eta then - -- footer used to store the eta - local footer = - container.add{ - name='footer', - type='frame', - style='subheader_frame' - } - Gui.set_padding(footer,2,2,4,4) - footer.style.horizontally_stretchable = true + -- Draw the footer + local footer = Gui.header( + container, + {'science-info.eta-caption'}, + {'science-info.eta-tooltip'}, + true, + 'footer' + ) - -- label for the footer + -- Set the style + footer.parent.style = 'subheader_frame' + local footer_style = footer.parent.style + footer_style.padding = {2,4} + footer_style.use_header_filler = false + footer_style.horizontally_stretchable = true + + -- Draw the eta label + local eta_label = footer.add{ - name='eta-label', - type='label', - caption={'science-info.eta-caption'}, - tooltip={'science-info.eta-tooltip'}, - style='heading_1_label' + name = 'label', + type = 'label', + caption = null_time_short, + tooltip = null_time_long, + style = 'heading_1_label' } - -- data for the footer - local right_align = Gui.create_alignment(footer,'eta') - eta = - right_align.add{ - name='label', - type='label', - caption=null_time_short, - tooltip=null_time_long, - style='heading_1_label' - } + -- Update the eta + update_eta_label(eta_label,get_eta_label_data(player)) + end - return flow_table, eta -end - ---[[ Adds two labels where one is right aligned and the other is a unit - element - > "name" - >> label - > spm-"name" -]] -local function add_data_label(element,name,value,secondary,tooltip) - local data_colour = Production.get_color(config.color_clamp, value, secondary) - local surfix,caption = Production.format_number(value) - - if element[name] then - local data = element[name].label - data.caption = caption - data.tooltip = tooltip - data.style.font_color = data_colour - local label = element['spm-'..name] - label.caption = {'science-info.unit',surfix} - label.tooltip = tooltip - label.style.font_color = data_colour - - else - -- right aligned number - local right_align = Gui.create_alignment(element,name) - local data = - right_align.add{ - name='label', - type='label', - caption=caption, - tooltip=tooltip - } - data.style.font_color = data_colour - - -- adds the unit onto the end - local label = - element.add{ - name='spm-'..name, - type='label', - caption={'science-info.unit',surfix}, - tooltip=tooltip - } - label.style.font_color = data_colour - end -end - ---[[ Adds a science pack to the list - element - > icon-"science_pack" - > delta-"science_pack" - >> table - >>> pos-"science_pack" (add_data_label) - >>> neg-"science_pack" (add_data_label) - > net-"science_pack" (add_data_label) -]] -local function generate_science_pack(player,element,science_pack) - local total = Production.get_production_total(player.force, science_pack) - local minute = Production.get_production(player.force, science_pack, defines.flow_precision_index.one_minute) - if total.made > 0 then - element.parent.non_made.visible = false - - local icon_style = 'quick_bar_slot_button' - local flux = Production.get_fluctuations(player.force, science_pack, defines.flow_precision_index.one_minute) - if flux.net > -config.color_flux/2 then - icon_style = 'green_slot_button' - elseif flux.net < -config.color_flux then - icon_style = 'red_slot_button' - elseif minute.made > 0 then - icon_style = 'selected_slot_button' - end - - local icon = element['icon-'..science_pack] - - if icon then - icon.style = icon_style - icon.style.height = 55 - if icon_style == 'quick_bar_slot_button' then - icon.style.width = 36 - Gui.set_padding(icon,0,0,-2,-2) - end - - else - icon = - element.add{ - name='icon-'..science_pack, - type='sprite-button', - sprite='item/'..science_pack, - tooltip={'item-name.'..science_pack}, - style=icon_style - } - icon.style.height = 55 - if icon_style == 'quick_bar_slot_button' then - icon.style.width = 36 - Gui.set_padding(icon,0,0,-2,-2) - end - - end - - local delta = element['delta-'..science_pack] - - if not delta then - delta = - element.add{ - name='delta-'..science_pack, - type='frame', - style='bordered_frame' - } - Gui.set_padding(delta,0,0,3,3) - - local delta_table = - delta.add{ - name='table', - type='table', - column_count=2 - } - Gui.set_padding(delta_table) - end - - add_data_label(delta.table,'pos-'..science_pack,minute.made,nil,{'science-info.pos-tooltip',total.made}) - add_data_label(delta.table,'neg-'..science_pack,-minute.used,nil,{'science-info.neg-tooltip',total.used}) - add_data_label(element,'net-'..science_pack,minute.net,minute.made+minute.used,{'science-info.net-tooltip',total.net}) - end -end - ---- Updates the eta label that was created with generate_container -local function update_eta(player,element) - if not config.show_eta then return end - local force = player.force - local research = force.current_research - if not research then - element.caption = null_time_short - element.tooltip = null_time_long - - else - local progress = force.research_progress - local remaining = research.research_unit_count*(1-progress) - local limit - - local stats = player.force.item_production_statistics - for _,ingredient in pairs(research.research_unit_ingredients) do - local pack_name = ingredient.name - local required = ingredient.amount * remaining - local time = Production.get_consumsion_eta(force, pack_name, defines.flow_precision_index.one_minute, required) - if not limit or limit < time then - limit = time - end - end - - if not limit or limit == -1 then - element.caption = null_time_short - element.tooltip = null_time_long - - else - element.caption = {'science-info.eta-time',format_time(limit,{hours=true,minutes=true,seconds=true,time=true})} - element.tooltip = format_time(limit,{hours=true,minutes=true,seconds=true,long=true}) - - end - end -end - ---- Registers the science info --- @element science_info -local science_info = -Gui.new_left_frame('gui/science-info') -:set_sprites('entity/lab') -:set_direction('vertical') -:set_tooltip{'science-info.main-tooltip'} -:on_creation(function(player,element) - local table, eta = generate_container(element) - + -- Add packs which have been made for _,science_pack in ipairs(config) do - generate_science_pack(player,table,science_pack) + update_science_pack(scroll_table,get_science_pack_data(player,science_pack)) end - update_eta(player,eta) + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local container = element.container - local table = container.scroll.table - local eta = container.footer.eta.label +:add_to_left_flow() - for _,science_pack in ipairs(config) do - generate_science_pack(player,table,science_pack) - end - - update_eta(player,eta) +--- Button on the top flow used to toggle the task list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/lab', + tooltip = {'science-info.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/science-info') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, science_info_container) end) --- Updates the gui every 1 second -Event.on_nth_tick(60,science_info 'update_all') +Event.on_nth_tick(60,function() + local force_pack_data = {} + local force_eta_data = {} + for _,player in pairs(game.connected_players) do + local force_name = player.force.name + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[science_info_container.name] + local container = frame.container -return science_info \ No newline at end of file + -- Update the science packs + local scroll_table = container.scroll.table + local pack_data = force_pack_data[force_name] + if not pack_data then + -- No data in chache so it needs to be generated + pack_data = {} + force_pack_data[force_name] = pack_data + for _,science_pack in ipairs(config) do + local next_data = get_science_pack_data(player,science_pack) + pack_data[science_pack] = next_data + update_science_pack(scroll_table,next_data) + end + + else + -- Data found in chache is no need to generate it + for _,next_data in ipairs(pack_data) do + update_science_pack(scroll_table,next_data) + end + + end + + -- Update the eta times + if not config.show_eta then return end + local eta_label = container.footer.alignment.label + local eta_data = force_eta_data[force_name] + if not eta_data then + -- No data in chache so it needs to be generated + eta_data = get_eta_label_data(player) + force_eta_data[force_name] = eta_data + update_eta_label(eta_label,eta_data) + + else + -- Data found in chache is no need to generate it + update_eta_label(eta_label,eta_data) + + end + + end +end) \ No newline at end of file From ecf99b11420d4a28317a9dce44d73c3325c15faf Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 11 Jan 2020 01:32:16 +0000 Subject: [PATCH 06/21] Rocket Info Gui --- README.md | 2 +- config/_file_loader.lua | 2 +- locale/en/gui.cfg | 2 + modules/gui/rocket-info.lua | 981 ++++++++++++++++++++---------------- 4 files changed, 554 insertions(+), 433 deletions(-) diff --git a/README.md b/README.md index affbc44a..c1ab73b8 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Please report these errors to [the issues page](issues). ## Contributing -All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. To find out what we already have please read our [docs]. Please keep in mind while making code changes: * New features should have the branch names: `feature/feature-name` * New features are merged into `dev` after it has been completed, this can be done through a pull request. diff --git a/config/_file_loader.lua b/config/_file_loader.lua index fa73ff34..474cc842 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -39,7 +39,7 @@ return { 'modules.addons.discord-alerts', 'modules.addons.chat-reply', -- GUI - --'modules.gui.rocket-info', + 'modules.gui.rocket-info', 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 332d2f42..440f485d 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -46,6 +46,8 @@ data-caption-avg-launch-n=Average Time __1__ data-tooltip-avg-launch-n=The average amount of time taken to launch the last __1__ rockets data-caption-milestone-n=Milestone __1__ data-tooltip-milestone-n=Time taken to each __1__ rockets +data-caption-milestone-next=N/A +data-tooltip-milestone-next=Not yet achieved progress-x-pos=X __1__ progress-y-pos=Y __1__ progress-label-tooltip=View on map diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index fd384627..69c2d9d9 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -12,8 +12,15 @@ local format_time = ext_require('expcore.common','format_time') --- @dep expcore local Colors = require 'resources.color_presets' --- @dep resources.color_presets local Rockets = require 'modules.control.rockets' --- @dep modules.control.rockets ---- Gets if a player is allowed to use the action buttons -local function player_allowed(player,action) +local time_formats = { + caption = function(value) return format_time(value, {minutes=true, seconds=true}) end, + caption_hours = function(value) return format_time(value) end, + tooltip = function(value) return format_time(value, {minutes=true, seconds=true, long=true}) end, + tooltip_hours = function(value) return format_time(value, {hours=true, minutes=true, seconds=true, long=true}) end +} + +--- Check if a player is allowed to use certain interactions +local function check_player_permissions(player,action) if not config.progress['allow_'..action] then return false end @@ -29,31 +36,191 @@ local function player_allowed(player,action) return true end ---- Used on the name label to allow zoom to map --- @element zoom_to_map -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local rocket_silo_name = event.element.parent.caption - local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) - event.player.zoom_to_world(rocket_silo.position,2) +--- Data label which contains a name and a value label pair +-- @element data_label +local data_label = +Gui.element(function(_,parent,label_data) + local data_name = label_data.name + local data_subname = label_data.subname + local data_fullname = data_subname and data_name..data_subname or data_name + + -- Add the name label + parent.add{ + type = 'label', + name = data_fullname..'-label', + caption = {'rocket-info.data-caption-'..data_name,data_subname}, + tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} + } + + --- Right aligned label to store the data + local alignment = Gui.alignment(parent,nil,nil,data_fullname) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = label_data.value, + tooltip = label_data.tooltip + } + + return element end) ---- Used to launch the rocket, when it is ready +local function update_data_labels(parent,data_label_data) + for _, label_data in ipairs(data_label_data) do + local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name + if not parent[data_name] then + data_label(parent,label_data) + else + local data_label_element = parent[data_name].label + data_label_element.tooltip = label_data.tooltip + data_label_element.caption = label_data.value + end + end +end + +--- Gets the label data for all the different stats +local function get_stats_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local stats = Rockets.get_stats(force_name) + local stats_data = {} + + -- Format the first launch data + if config.stats.show_first_rocket then + local value = stats.first_launch or 0 + table.insert(stats_data,{ + name = 'first-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format the last launch data + if config.stats.show_last_rocket then + local value = stats.last_launch or 0 + table.insert(stats_data,{ + name = 'last-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format fastest launch data + if config.stats.show_fastest_rocket then + local value = stats.fastest_launch or 0 + table.insert(stats_data,{ + name = 'fastest-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format total rocket data + if config.stats.show_total_rockets then + local total_rockets = Rockets.get_game_rocket_count() + total_rockets = total_rockets == 0 and 1 or total_rockets + local percentage = math.round(force_rockets/total_rockets,3)*100 + table.insert(stats_data,{ + name = 'total-rockets', + value = force_rockets, + tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} + }) + end + + -- Format game avg data + if config.stats.show_game_avg then + local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 + table.insert(stats_data,{ + name = 'avg-launch', + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Format rolling avg data + for _,avg_over in pairs(config.stats.rolling_avg) do + local avg = Rockets.get_rolling_average(force_name,avg_over) + table.insert(stats_data,{ + name = 'avg-launch-n', + subname = avg_over, + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Return formated data + return stats_data +end + +--- Gets the label data for the milestones +local function get_milestone_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local milestone_data = {} + + for _,milestone in ipairs(config.milestones) do + if milestone <= force_rockets then + local time = Rockets.get_rocket_time(force_name,milestone) + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = time_formats.caption_hours(time), + tooltip = time_formats.tooltip_hours(time) + }) + else + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = {'rocket-info.data-caption-milestone-next'}, + tooltip = {'rocket-info.data-tooltip-milestone-next'} + }) + break + end + end + + return milestone_data +end + +--- Button to toggle the auto launch on a rocket silo +-- @elemeent toggle_launch +local toggle_launch = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/play', + tooltip = {'rocket-info.toggle-rocket-tooltip'} +} +:style{ + padding = -2, + width = 16, + height = 16 +} +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.name:sub(8) + local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) + if rocket_silo.auto_launch then + element.sprite = 'utility/play' + element.tooltip = {'rocket-info.toggle-rocket-tooltip'} + rocket_silo.auto_launch = false + else + element.sprite = 'utility/stop' + element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} + rocket_silo.auto_launch = true + end +end) + +--- Button to remotely launch a rocket from a silo -- @element launch_rocket local launch_rocket = -Gui.new_button() -:set_sprites('utility/center') -:set_tooltip{'rocket-info.launch-tooltip'} -:set_embedded_flow(function(element,rocket_silo_name) - return 'launch-'..rocket_silo_name -end) -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 16 - style.height = 16 -end) -:on_click(function(player,element) - local rocket_silo_name = element.parent.name:sub(8) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/center', + tooltip = {'rocket-info.launch-tooltip'} +} +:style{ + padding = -2, + width = 16, + height = 16 +} +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.name:sub(8) local silo_data = Rockets.get_silo_data_by_name(rocket_silo_name) if silo_data.entity.launch_rocket() then silo_data.awaiting_reset = true @@ -66,457 +233,409 @@ end) end end) ---- Used to toggle the auto launch on a rocket --- @element toggle_rocket -local toggle_rocket = -Gui.new_button() -:set_sprites('utility/play') -:set_tooltip{'rocket-info.toggle-rocket-tooltip'} -:set_embedded_flow(function(element,rocket_silo_name) - return 'toggle-'..rocket_silo_name +--- XY cords that allow zoom to map when pressed +-- @element silo_cords +local silo_cords = +Gui.element(function(event_trigger,parent,silo_data) + local silo_name = silo_data.silo_name + local pos = silo_data.position + local name = config.progress.allow_zoom_to_map and event_trigger or nil + local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil + + -- Add the x cord flow + local flow_x = parent.add{ + type ='flow', + name = 'label-x-'..silo_name, + caption = silo_name + } + flow_x.style.padding = {0,2,0,1} + + -- Add the x cord label + flow_x.add{ + type = 'label', + name = name, + caption = {'rocket-info.progress-x-pos',pos.x}, + tooltip = tooltip + } + + -- Add the y cord flow + local flow_y = parent.add{ + type ='flow', + name = 'label-y-'..silo_name, + caption = silo_name + } + flow_y.style.padding = {0,2,0,1} + + -- Add the y cord label + flow_y.add{ + type = 'label', + name = name, + caption = {'rocket-info.progress-y-pos',pos.y}, + tooltip = tooltip + } + end) -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 16 - style.height = 16 -end) -:on_click(function(player,element) - local rocket_silo_name = element.parent.name:sub(8) +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.caption local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) - if rocket_silo.auto_launch then - element.sprite = 'utility/play' - element.tooltip = {'rocket-info.toggle-rocket-tooltip'} - rocket_silo.auto_launch = false - else - element.sprite = 'utility/stop' - element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} - rocket_silo.auto_launch = true - end + player.zoom_to_world(rocket_silo.position,2) end) ---- Used to toggle the visibility of the different sections +--- Base element for each rocket in the progress list +-- @element rocket_entry +local rocket_entry = +Gui.element(function(_,parent,silo_data) + local silo_name = silo_data.silo_name + local player = Gui.get_player_from_element(parent) + + -- Add the toggle auto launch if the player is allowed it + if check_player_permissions(player,'toggle_active') then + local flow = parent.add{ type = 'flow', name = 'toggle-'..silo_name} + local button = toggle_launch(flow) + button.tooltip = silo_data.toggle_tooltip + button.sprite = silo_data.toggle_sprite + end + + -- Add the remote launch if the player is allowed it + if check_player_permissions(player,'remote_launch') then + local flow = parent.add{ type = 'flow', name = 'launch-'..silo_name} + local button = launch_rocket(flow) + button.enabled = silo_data.allow_launch + end + + -- Draw the silo cords element + silo_cords(parent,silo_data) + + -- Add a progress label + local alignment = Gui.alignment(parent,nil,nil,silo_name) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = silo_data.progress_caption, + tooltip = silo_data.progress_tooltip + } + + -- Return the progress label + return element +end) + +local function get_progress_data(force_name) + local force_silos = Rockets.get_silos(force_name) + local progress_data = {} + + for _, silo_data in pairs(force_silos) do + local rocket_silo = silo_data.entity + if not rocket_silo or not rocket_silo.valid then + -- Remove from list if not valid + force_silos[silo_data.name] = nil + table.insert(progress_data,{ + silo_name = silo_data.name, + remove = true + }) + else + -- Get the progress caption and tooltip + local progress_color = Colors.white + local progress_caption = {'rocket-info.progress-caption',rocket_silo.rocket_parts} + local progress_tooltip = {'rocket-info.progress-tooltip',silo_data.launched or 0} + local status = rocket_silo.status == defines.entity_status.waiting_to_launch_rocket + if status and silo_data.awaiting_reset then + progress_caption = {'rocket-info.progress-launched'} + progress_color = Colors.green + elseif status then + progress_caption = {'rocket-info.progress-caption',100} + progress_color = Colors.cyan + else + silo_data.awaiting_reset = false + end + + -- Get the toggle button data + local toggle_tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} + local toggle_sprite = 'utility/play' + if rocket_silo.auto_launch then + toggle_tooltip = {'rocket-info.toggle-rocket-tooltip'} + toggle_sprite = 'utility/stop' + end + + -- Insert the gui data + table.insert(progress_data,{ + silo_name = silo_data.name, + position = rocket_silo.position, + allow_launch = not silo_data.awaiting_reset and status or false, + progress_color = progress_color, + progress_caption = progress_caption, + progress_tooltip = progress_tooltip, + toggle_tooltip = toggle_tooltip, + toggle_sprite = toggle_sprite + }) + end + end + + return progress_data +end + +--- Update the build progress section +local function update_build_progress(parent,progress_data) + local show_message = true + for _, silo_data in ipairs(progress_data) do + parent.no_silos.visible = false + local silo_name = silo_data.silo_name + local progress_label = parent[silo_name] + if silo_data.remove then + -- Remove the rocket from the list + Gui.destroy_if_valid(parent['toggle-'..silo_name]) + Gui.destroy_if_valid(parent['launch-'..silo_name]) + Gui.destroy_if_valid(parent['label-x-'..silo_name]) + Gui.destroy_if_valid(parent['label-y-'..silo_name]) + Gui.destroy_if_valid(parent[silo_name]) + + elseif not progress_label then + -- Add the rocket to the list + show_message = false + rocket_entry(parent,silo_data) + + else + show_message = false + -- Update the existing labels + progress_label = progress_label.label + progress_label.caption = silo_data.progress_caption + progress_label.tooltip = silo_data.progress_tooltip + progress_label.style.font_color = silo_data.progress_color + + -- Update the toggle button + local toggle_button = parent['toggle-'..silo_name] + if toggle_button then + toggle_button = toggle_button[toggle_launch.name] + toggle_button.tooltip = silo_data.toggle_tooltip + toggle_button.sprite = silo_data.toggle_sprite + end + + -- Update the launch button + local launch_button = parent['launch-'..silo_name] + if launch_button then + launch_button = launch_button[launch_rocket.name] + launch_button.enabled = silo_data.allow_launch + end + end + end + if show_message then parent.no_silos.visible = true end +end + +-- Button to toggle a section dropdown -- @element toggle_section local toggle_section = -Gui.new_button() -:set_sprites('utility/expand_dark','utility/expand') -:set_tooltip{'rocket-info.toggle-section-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local flow_name = element.parent.caption - local flow = element.parent.parent.parent[flow_name] - if Gui.toggle_visible(flow) then +Gui.element{ + type = 'sprite-button', + sprite = 'utility/expand_dark', + hovered_sprite = 'utility/expand', + tooltip = {'rocket-info.toggle-section-tooltip'} +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) + local header_flow = element.parent + local flow_name = header_flow.caption + local flow = header_flow.parent.parent[flow_name] + if Gui.toggle_visible_state(flow) then element.sprite = 'utility/collapse_dark' element.hovered_sprite = 'utility/collapse' element.tooltip = {'rocket-info.toggle-section-collapse-tooltip'} - else + else element.sprite = 'utility/expand_dark' element.hovered_sprite = 'utility/expand' element.tooltip = {'rocket-info.toggle-section-tooltip'} - end + end end) ---- Used to create the three different sections -local function create_section(container,section_name,table_size) - -- Header for the section - local header_area = Gui.create_header( - container, - {'rocket-info.section-caption-'..section_name}, +-- Draw a section header and main scroll +-- @element rocket_list_container +local section = +Gui.element(function(_,parent,section_name,table_size) + -- Draw the header for the section + local header = Gui.header( + parent, + {'rocket-info.section-caption-'..section_name}, {'rocket-info.section-tooltip-'..section_name}, - true, - section_name..'-header' - ) + true, + section_name..'-header' + ) - -- Right aligned button to toggle the section - header_area.caption = section_name - toggle_section(header_area) + -- Right aligned button to toggle the section + header.caption = section_name + toggle_section(header) -- Table used to store the data - local flow_table = Gui.create_scroll_table(container,table_size,215,section_name) - flow_table.parent.visible = false + local scroll_table = Gui.scroll_table(parent,215,table_size,section_name) + scroll_table.parent.visible = false -end + -- Return the flow table + return scroll_table +end) ---[[ Creates the main structure for the gui - element - > container - - >> stats-header - >>> stats - >>>> toggle_section.name - >> stats - >>> table - - >> milestones-header - >>> milestones - >>>> toggle_section.name - >> milestones - >>> table - - >> progress-header - >>> progress - >>>> toggle_section.name - >> progress - >>> table -]] -local function generate_container(player,element) - Gui.set_padding(element,1,2,2,2) - element.style.minimal_width = 200 - - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main gui container for the left flow +-- @element rocket_list_container +local rocket_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - if config.stats.show_stats then - create_section(container,'stats',2) - end + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 - if config.milestones.show_milestones then - create_section(container,'milestones',2) - end + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } - if config.progress.show_progress then - local col_count = 3 - if player_allowed(player,'remote_launch') then col_count = col_count+1 end - if player_allowed(player,'toggle_active') then col_count = col_count+1 end - create_section(container,'progress',col_count) - --- label used when no active silos - container.progress.add{ - type='label', - name='no_silos', - caption={'rocket-info.progress-no-silos'} + -- Set the container style + local style = container.style + style.vertically_stretchable = false + style.padding = 0 + + + local player = Gui.get_player_from_element(parent) + local force_name = player.force.name + -- Draw stats section + if config.stats.show_stats then + update_data_labels(section(container,'stats',2),get_stats_data(force_name)) + end + + -- Draw milestones section + if config.milestones.show_milestones then + update_data_labels(section(container,'milestones',2),get_milestone_data(force_name)) + end + + -- Draw build progress list + if config.progress.show_progress then + local col_count = 3 + if check_player_permissions(player,'remote_launch') then col_count = col_count+1 end + if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end + local progress = section(container,'progress',col_count) + -- Label used when there are no active silos + progress.add{ + type = 'label', + name = 'no_silos', + caption = {'rocket-info.progress-no-silos'} } - end + update_build_progress(progress,get_progress_data(force_name)) + end -end - ---[[ Creates a text label followed by a data label, or updates them if already present - element - > "data_name_extra"-label - > "data_name_extra" - >> label -]] -local function create_label_value_pair(element,data_name,value,tooltip,extra) - local data_name_extra = extra and data_name..extra or data_name - if element[data_name_extra] then - element[data_name_extra].label.caption = value - element[data_name_extra].label.tooltip = tooltip - else - --- Label used with the data - element.add{ - type='label', - name=data_name_extra..'-label', - caption={'rocket-info.data-caption-'..data_name,extra}, - tooltip={'rocket-info.data-tooltip-'..data_name,extra} - } - --- Right aligned label to store the data - local right_flow = Gui.create_alignment(element,data_name_extra) - right_flow.add{ - type='label', - name='label', - caption=value, - tooltip=tooltip - } - end -end - ---- Creates a text and data label using times as the data -local function create_label_value_pair_time(element,data_name,raw_value,no_hours,extra) - local value = no_hours and format_time(raw_value,{minutes=true,seconds=true}) or format_time(raw_value) - local tooltip = format_time(raw_value,{hours=not no_hours,minutes=true,seconds=true,long=true}) - create_label_value_pair(element,data_name,value,tooltip,extra) -end - ---- Adds the different data values to the stats section -local function generate_stats(player,frame) - if not config.stats.show_stats then return end - local element = frame.container.stats.table - local force_name = player.force.name - local force_rockets = Rockets.get_rocket_count(force_name) - local stats = Rockets.get_stats(force_name) - - if config.stats.show_first_rocket then - create_label_value_pair_time(element,'first-launch',stats.first_launch or 0) - end - - if config.stats.show_last_rocket then - create_label_value_pair_time(element,'last-launch',stats.last_launch or 0) - end - - if config.stats.show_fastest_rocket then - create_label_value_pair_time(element,'fastest-launch',stats.fastest_launch or 0,true) - end - - if config.stats.show_total_rockets then - local total_rockets = Rockets.get_game_rocket_count() - total_rockets = total_rockets == 0 and 1 or total_rockets - local percentage = math.round(force_rockets/total_rockets,3)*100 - create_label_value_pair(element,'total-rockets',force_rockets,{'rocket-info.value-tooltip-total-rockets',percentage}) - end - - if config.stats.show_game_avg then - local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 - create_label_value_pair_time(element,'avg-launch',avg,true) - end - - for _,avg_over in pairs(config.stats.rolling_avg) do - local avg = Rockets.get_rolling_average(force_name,avg_over) - create_label_value_pair_time(element,'avg-launch-n',avg,true,avg_over) - end - -end - ---- Creates the list of milestones -local function generate_milestones(player,frame) - if not config.milestones.show_milestones then return end - local element = frame.container.milestones.table - local force_name = player.force.name - local force_rockets = Rockets.get_rocket_count(force_name) - - for _,milestone in ipairs(config.milestones) do - if milestone <= force_rockets then - local time = Rockets.get_rocket_time(force_name,milestone) - create_label_value_pair_time(element,'milestone-n',time,false,milestone) - else - create_label_value_pair_time(element,'milestone-n',0,false,milestone) - break - end - end -end - ---- Creats the different buttons used with the rocket silos -local function generate_progress_buttons(player,element,silo_data) - local silo_name = silo_data.name - local rocket_silo = silo_data.entity - local status = rocket_silo.status == defines.entity_status.waiting_to_launch_rocket - local active = rocket_silo.auto_launch - - if player_allowed(player,'toggle_active') then - local button_element = element['toggle-'..silo_name] - - if button_element then - button_element = button_element[toggle_rocket.name] - else - button_element = toggle_rocket(element,silo_name) - end - - if active then - button_element.tooltip = {'rocket-info.toggle-rocket-tooltip'} - button_element.sprite = 'utility/stop' - else - button_element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} - button_element.sprite = 'utility/play' - end - end - - if player_allowed(player,'remote_launch') then - local button_element = element['launch-'..silo_name] - - if button_element then - button_element = button_element[launch_rocket.name] - else - button_element = launch_rocket(element,silo_name) - end - - if silo_data.awaiting_reset then - button_element.enabled = false - else - button_element.enabled = status - end - end - -end - ---[[ Creates build progress section - element - > toggle-"silo_name" (generate_progress_buttons) - > launch-"silo_name" (generate_progress_buttons) - > label-x-"silo_name" - >> "silo_name" - > label-y-"silo_name" - >> "silo_name" - > "silo_name" - >> label -]] -local function generate_progress(player,frame) - if not config.progress.show_progress then return end - local element = frame.container.progress.table - local force = player.force - local force_name = force.name - local force_silos = Rockets.get_silos(force_name) - - if not force_silos or table.size(force_silos) == 0 then - element.parent.no_silos.visible = true - - else - element.parent.no_silos.visible = false - - for _,silo_data in pairs(force_silos) do - local silo_name = silo_data.name - if not silo_data.entity or not silo_data.entity.valid then - force_silos[silo_name] = nil - Gui.destroy_if_valid(element['toggle-'..silo_name]) - Gui.destroy_if_valid(element['launch-'..silo_name]) - Gui.destroy_if_valid(element['label-x-'..silo_name]) - Gui.destroy_if_valid(element['label-y-'..silo_name]) - Gui.destroy_if_valid(element[silo_name]) - - elseif not element[silo_name] then - local entity = silo_data.entity - local progress = entity.rocket_parts - local pos = { - x=entity.position.x, - y=entity.position.y - } - - generate_progress_buttons(player,element,silo_data) - - --- Creates two flows and two labels for the X and Y position - local name = config.progress.allow_zoom_to_map and zoom_to_map_name or nil - local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil - local flow_x = element.add{ - type='flow', - name='label-x-'..silo_name, - caption=silo_name - } - Gui.set_padding(flow_x,0,0,1,2) - flow_x.add{ - type='label', - name=name, - caption={'rocket-info.progress-x-pos',pos.x}, - tooltip=tooltip - } - - local flow_y = element.add{ - type='flow', - name='label-y-'..silo_name, - caption=silo_name - } - Gui.set_padding(flow_y,0,0,1,2) - flow_y.add{ - type='label', - name=name, - caption={'rocket-info.progress-y-pos',pos.y}, - tooltip=tooltip - } - - --- Creates the progress value which is right aligned - local right_flow = Gui.create_alignment(element,silo_name) - right_flow.add{ - type='label', - name='label', - caption={'rocket-info.progress-caption',progress}, - tooltip={'rocket-info.progress-tooltip',silo_data.launched or 0} - } - - else - local entity = silo_data.entity - local progress = entity.rocket_parts - local status = entity.status == 21 - - local label = element[silo_name].label - label.caption = {'rocket-info.progress-caption',progress} - label.tooltip = {'rocket-info.progress-tooltip',silo_data.launched or 0} - - if status and silo_data.awaiting_reset then - label.caption = {'rocket-info.progress-launched'} - label.style.font_color = Colors.green - elseif status then - label.caption = {'rocket-info.progress-caption',100} - label.style.font_color = Colors.cyan - else - silo_data.awaiting_reset = false - label.style.font_color = Colors.white - end - - generate_progress_buttons(player,element,silo_data) - - end - end - - end -end - ---- Registers the rocket info --- @element rocket_info -local rocket_info = -Gui.new_left_frame('gui/rocket-info') -:set_sprites('entity/rocket-silo') -:set_post_authenticator(function(player,define_name) - return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(player,define_name) + -- Return the exteral container + return frame end) -:set_open_by_default(function(player,define_name) - return player.force.rockets_launched > 0 -end) -:set_direction('vertical') -:on_creation(function(player,element) - generate_container(player,element) - generate_stats(player,element) - generate_milestones(player,element) - generate_progress(player,element) -end) -:on_update(function(player,element) - generate_stats(player,element) - generate_milestones(player,element) - generate_progress(player,element) +:add_to_left_flow(function(player) + return player.force.rockets_launched > 0 and Roles.player_allowed(player,'gui/rocket-info') end) ---- Event used to update the stats and the hui when a rocket is launched +--- Button on the top flow used to toggle the container +-- @element rocket_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/rocket-silo', + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/rocket-info') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, rocket_list_container) +end) + +--- Update the gui for all players on a force +local function update_rocket_gui_all(force_name) + local stats = get_stats_data(force_name) + local milestones = get_milestone_data(force_name) + local progress = get_progress_data(force_name) + for _,player in pairs(game.forces[force_name].players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[rocket_list_container.name] + local container = frame.container + update_data_labels(container.stats.table,stats) + update_data_labels(container.milestones.table,milestones) + update_build_progress(container.progress.table,progress) + end +end + +--- Event used to update the stats when a rocket is launched Event.add(defines.events.on_rocket_launched,function(event) local force = event.rocket_silo.force - local rockets_launched = force.rockets_launched - local first_rocket = rockets_launched == 1 + update_rocket_gui_all(force.name) + if force.rockets_launched == 1 then + for _,player in pairs(force.players) do + Gui.update_top_flow(player) + end + end +end) - --- Updates all the guis (and toolbar since the button may now be visible) - for _,player in pairs(force.players) do - rocket_info:update(player) - if first_rocket then - Gui.update_toolbar(player) - rocket_info:toggle(player) - end - end +--- Update only the progress gui for a force +local function update_rocket_gui_progress(force_name) + local progress = get_progress_data(force_name) + for _,player in pairs(game.forces[force_name].players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[rocket_list_container.name] + local container = frame.container + update_build_progress(container.progress.table,progress) + end +end + +Event.on_nth_tick(150,function() + for _,force in pairs(game.forces) do + if #Rockets.get_silos(force.name) > 0 then + update_rocket_gui_progress(force.name) + end + end end) --- Adds a silo to the list when it is built local function on_built(event) local entity = event.created_entity if entity.valid and entity.name == 'rocket-silo' then - local force = entity.force - - for _,player in pairs(force.players) do - local frame = rocket_info:get_frame(player) - generate_progress(player,frame) - end + update_rocket_gui_progress(entity.force.name) end end Event.add(defines.events.on_built_entity,on_built) Event.add(defines.events.on_robot_built_entity,on_built) ---- Optimised update for only the build progress -Event.on_nth_tick(150,function() - for _,force in pairs(game.forces) do - local silos = Rockets.get_silos(force.name) - if #silos > 0 then - for _,player in pairs(force.connected_players) do - local frame = rocket_info:get_frame(player) - generate_progress(player,frame) - end - end - end -end) +--- Redraw the progress section on role change +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[rocket_list_container.name].container + local progress = container.progress + if config.progress.show_progress then + progress.destroy() + local col_count = 3 + if check_player_permissions(player,'remote_launch') then col_count = col_count+1 end + if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end + progress = section(container,'progress',col_count) + -- Label used when there are no active silos + progress.add{ + type = 'label', + name = 'no_silos', + caption = {'rocket-info.progress-no-silos'} + } + update_build_progress(progress,get_progress_data(player.force.name)) + end +end ---- Makes sure the right buttons are present when role changes -Event.add(Roles.events.on_role_assigned,rocket_info 'redraw') -Event.add(Roles.events.on_role_unassigned,rocket_info 'redraw') +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) -return rocket_info \ No newline at end of file +return rocket_list_container \ No newline at end of file From 05f706797aa460e194879d33b33f1e1405fa042d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 12 Feb 2020 21:32:28 +0000 Subject: [PATCH 07/21] Player list added --- config/_file_loader.lua | 2 +- config/action_buttons.lua | 92 ++---- modules/gui/player-list.lua | 547 +++++++++++++++++++++--------------- 3 files changed, 352 insertions(+), 289 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 474cc842..f7ad4c42 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -43,7 +43,7 @@ return { 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', - --'modules.gui.player-list', + 'modules.gui.player-list', --'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins diff --git a/config/action_buttons.lua b/config/action_buttons.lua index 2ce10565..0ce8aff1 100644 --- a/config/action_buttons.lua +++ b/config/action_buttons.lua @@ -22,13 +22,6 @@ local function set_store_uids(player,action) selected_action_store = action end --- common style used by all action buttons -local function tool_button_style(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end - -- auth that will only allow when on player's of lower roles local function auth_lower_role(player,selected_player_name) local player_highest = Roles.get_player_highest_role(player) @@ -56,14 +49,23 @@ local function teleport(from_player,to_player) return true end +local function new_button(sprite,tooltip) + return Gui.element{ + type = 'sprite-button', + style = 'tool_button', + sprite = sprite, + tooltip = tooltip + }:style{ + padding = -1, + height = 28, + width = 28 + } +end + --- Teleports the user to the action player -- @element goto_player -local goto_player = -Gui.new_button() -:set_sprites('utility/export') -:set_tooltip{'player-list.goto-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local goto_player = new_button('utility/export',{'player-list.goto-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if not player.character or not selected_player.character then @@ -75,12 +77,8 @@ end) --- Teleports the action player to the user -- @element bring_player -local bring_player = -Gui.new_button() -:set_sprites('utility/import') -:set_tooltip{'player-list.bring-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local bring_player = new_button('utility/import',{'player-list.bring-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if not player.character or not selected_player.character then @@ -92,12 +90,8 @@ end) --- Kills the action player, if there are alive -- @element kill_player -local kill_player = -Gui.new_button() -:set_sprites('utility/too_far') -:set_tooltip{'player-list.kill-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local kill_player = new_button('utility/too_far',{'player-list.kill-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if selected_player.character then @@ -109,12 +103,8 @@ end) --- Reports the action player, requires a reason to be given -- @element report_player -local report_player = -Gui.new_button() -:set_sprites('utility/spawn_flag') -:set_tooltip{'player-list.report-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local report_player = new_button('utility/spawn_flag',{'player-list.report-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) if Reports.is_reported(selected_player_name,player.name) then player.print({'expcom-report.already-reported'},Colors.orange_red) @@ -133,12 +123,8 @@ end --- Gives the action player a warning, requires a reason -- @element warn_player -local warn_player = -Gui.new_button() -:set_sprites('utility/spawn_flag') -:set_tooltip{'player-list.warn-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local warn_player = new_button('utility/spawn_flag',{'player-list.warn-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/give-warning') end) @@ -151,12 +137,8 @@ end --- Jails the action player, requires a reason -- @element jail_player -local jail_player = -Gui.new_button() -:set_sprites('utility/item_editor_icon') -:set_tooltip{'player-list.jail-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local jail_player = new_button('utility/item_editor_icon',{'player-list.jail-player'}) +:on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then player.print({'expcom-jail.already-jailed', selected_player_color},Colors.orange_red) @@ -174,12 +156,8 @@ end --- Temp bans the action player, requires a reason -- @element temp_ban_player -local temp_ban_player = -Gui.new_button() -:set_sprites('utility/clock') -:set_tooltip{'player-list.temp-ban-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local temp_ban_player = new_button('utility/clock',{'player-list.temp-ban-player'}) +:on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then player.print({'expcom-jail.already-banned', selected_player_color},Colors.orange_red) @@ -197,12 +175,8 @@ end --- Kicks the action player, requires a reason -- @element kick_player -local kick_player = -Gui.new_button() -:set_sprites('utility/warning_icon') -:set_tooltip{'player-list.kick-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local kick_player = new_button('utility/warning_icon',{'player-list.kick-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/kick') end) @@ -213,12 +187,8 @@ end --- Bans the action player, requires a reason -- @element ban_player -local ban_player = -Gui.new_button() -:set_sprites('utility/danger_icon') -:set_tooltip{'player-list.ban-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local ban_player = new_button('utility/danger_icon',{'player-list.ban-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/ban') end) diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 80e81c13..10ae6e5a 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -26,42 +26,21 @@ end) -- Set the config to use these stores config.set_store_uids(selected_player_store,selected_action_store) ---- Used to open the map on a player or toggle the settings -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local selected_player_name = event.element.caption - local selected_player = Game.get_player_from_any(selected_player_name) - if event.button == defines.mouse_button_type.left then - -- LMB will open the map to the selected player - local position = selected_player.position - event.player.zoom_to_world(position,1.75) - else - -- RMB will toggle the settings - local player = event.player - local old_selected_player_name = Store.get(selected_player_store,player) - if selected_player_name == old_selected_player_name then - Store.clear(selected_player_store,player) - else - Store.set(selected_player_store,player,selected_player_name) - end - end -end) - --- Button used to open the action bar -- @element open_action_bar local open_action_bar = -Gui.new_button() -:set_sprites('utility/expand_dots_white') -:set_tooltip{'player-list.open-action-bar'} -:set_embedded_flow(function(element,selected_player_name) - return selected_player_name -end) -:set_style('frame_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 8 - style.height = 14 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/expand_dots_white', + tooltip = {'player-list.open-action-bar'}, + style = 'frame_button' +} +:style{ + padding = -2, + width = 8, + height = 14 +} +:on_click(function(player,element,_) local selected_player_name = element.parent.name local old_selected_player_name = Store.get(selected_player_store,player) if selected_player_name == old_selected_player_name then @@ -74,14 +53,18 @@ end) --- Button used to close the action bar -- @element close_action_bar local close_action_bar = -Gui.new_button() -:set_sprites('utility/close_black','utility/close_white') -:set_tooltip{'player-list.close-action-bar'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + hovered_sprite = 'utility/close_white', + tooltip = {'player-list.close-action-bar'}, + style = 'tool_button' +} +:style{ + padding = -1, + width = 28, + height = 28 +} :on_click(function(player,element) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) @@ -90,14 +73,17 @@ end) --- Button used to confirm a reason -- @element reason_confirm local reason_confirm = -Gui.new_button() -:set_sprites('utility/confirm_slot') -:set_tooltip{'player-list.reason-confirm'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/confirm_slot', + tooltip = {'player-list.reason-confirm'}, + style = 'tool_button' +} +:style{ + padding = -1, + width = 28, + height = 28 +} :on_click(function(player,element) local reason = element.parent.entry.text or 'Non Given' local action_name = Store.get(selected_action_store,player) @@ -108,106 +94,98 @@ end) element.parent.entry.text = '' end) ---[[ Creates the main gui areas for the player list - element - > container - >> scroll - >>> table - >> action_bar -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +--- Set of elements that are used to make up a row of the player table +-- @element add_player_base +local add_player_base = +Gui.element(function(event_trigger,parent,player_data) + -- Add the button to open the action bar + local toggle_action_bar_flow = parent.add{ type = 'flow', name = player_data.name } + open_action_bar(toggle_action_bar_flow) - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' + -- Add the player name + local player_name_flow = parent.add{ type = 'flow', 'player-name-'..player_data.index } + local player_name = player_name_flow.add{ + type = 'label', + name = event_trigger, + caption = player_data.name, + tooltip = {'player-list.open-map',player_data.name,player_data.tag,player_data.role_name} } - Gui.set_padding(container) + player_name.style.padding = {0,2,0,0} + player_name.style.font_color = player_data.chat_color - -- 3 wide table to contain: action button, player name, and play time - local list_table = Gui.create_scroll_table(container,3,188) - - -- action bar which contains the different action buttons - local action_bar = - container.add{ - name='action_bar', - type='frame', - style='subfooter_frame' + -- Add the time played label + local alignment = Gui.alignment(parent,nil,nil,'player-time-'..player_data.index) + local time_label = alignment.add{ + name = 'label', + type = 'label', + caption = player_data.caption, + tooltip = player_data.tooltip } - Gui.set_padding(action_bar,1,1,3,3) - action_bar.style.horizontally_stretchable = true - action_bar.style.height = 35 + time_label.style.padding = 0 - -- reason bar which contains the reason text field and confirm button - local reason_bar = - container.add{ - name='reason_bar', - type='frame', - style='subfooter_frame' - } - Gui.set_padding(reason_bar,-1,-1,3,3) - reason_bar.style.horizontally_stretchable = true - reason_bar.style.height = 35 - local action_name = Store.get(selected_action_store,player) - reason_bar.visible = action_name ~= nil + return time_label +end) +:on_click(function(player,element,event) + local selected_player_name = element.caption + local selected_player = Game.get_player_from_any(selected_player_name) + if event.button == defines.mouse_button_type.left then + -- LMB will open the map to the selected player + local position = selected_player.position + event.player.zoom_to_world(position,1.75) + else + -- RMB will toggle the settings + local old_selected_player_name = Store.get(selected_player_store,player) + if selected_player_name == old_selected_player_name then + Store.clear(selected_player_store,player) + else + Store.set(selected_player_store,player,selected_player_name) + end + end +end) - -- text entry for the reason bar - local reason_field = - reason_bar.add{ - name='entry', - type='textfield', - style='stretchable_textfield', - tooltip={'player-list.reason-entry'} - } - Gui.set_padding(reason_field) - reason_field.style.height = 28 - reason_field.style.minimal_width = 160 - - reason_confirm(reason_bar) - - return list_table, action_bar +-- Removes the three elements that are added as part of the base +local function remove_player_base(parent,player) + Gui.destroy_if_valid(parent[player.name]) + Gui.destroy_if_valid(parent['player-name-'..player.index]) + Gui.destroy_if_valid(parent['player-time-'..player.index]) end ---- Adds buttons and permission flows to the action bar -local function generate_action_bar(player,element) - close_action_bar(element) - local selected_player_name = Store.get(selected_player_store,player) +-- Update the time label for a player using there player time data +local function update_player_base(parent,player_time) + local time_element = parent[player_time.element_name] + if time_element and time_element.valid then + time_element.label.caption = player_time.caption + time_element.label.tooltip = player_time.tooltip + end +end - for action_name,buttons in pairs(config.buttons) do +--- Adds all the buttons and flows that make up the action bar +-- @element add_action_bar +local add_action_bar_buttons = +Gui.element(function(_,parent) + close_action_bar(parent) + -- Loop over all the buttons in the config + for action_name,button_data in pairs(config.buttons) do + -- Added the permission flow local permission_flow = - element.add{ - type='flow', - name=action_name + parent.add{ + type = 'flow', + name = action_name } - - for _,button in ipairs(buttons) do + -- Add the buttons under that permission + for _,button in ipairs(button_data) do button(permission_flow) end - - if not Roles.player_allowed(player,action_name) then - permission_flow.visible = false - end - - if buttons.auth and selected_player_name and not buttons.auth(player,selected_player_name) then - permission_flow.visible = false - end + -- Hide the flow by default, will be made visble when a player is selected + permission_flow.visible = false end - if not selected_player_name then - element.visible = false - end -end + return parent +end) ---- Updates the action bar -local player_list_name -local function update_action_bar(player) - local frame = Gui.classes.left_frames.get_frame(player_list_name,player) - local element = frame.container.action_bar +--- Updates the visible state of the action bar buttons +local function update_action_bar_buttons(element) + local player = Gui.get_player_from_element(element) local selected_player_name = Store.get(selected_player_store,player) if not selected_player_name then @@ -236,132 +214,256 @@ local function update_action_bar(player) end end ---- Adds a player to the player list -local function add_player(list_table,player,role_name) - open_action_bar(list_table,player.name) - - -- flow to contain player_name to allow all to have trigger for zoom to map - local player_name_flow = - list_table.add{ - type='flow' +--- Main player list container for the left flow +-- @element player_list_container +local player_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(player_name_flow) - -- player name with the tooltip of their highest role and in they colour - local player_name = - player_name_flow.add{ - name=zoom_to_map_name, - type='label', - caption=player.name, - tooltip={'player-list.open-map',player.name,player.tag,role_name} + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' } - Gui.set_padding(player_name,0,0,0,2) - player_name.style.font_color = player.chat_color - -- flow which allows right align for the play time - local time_flow = Gui.create_alignment(list_table,'player-time-'..player.index) + -- Set the container style + local style = container.style + style.vertically_stretchable = false - -- time given in Xh Ym and is right aligned - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(player.online_time/tick,3)*100 - local time = - time_flow.add{ - name='label', - type='label', - caption=format_time(player.online_time), - tooltip={'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + -- Draw the scroll table for the players + local scroll_table = Gui.scroll_table(container,184,3) + + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.padding = {1,0,1,2} + + -- Add the action bar + local action_bar = + container.add{ + name = 'action_bar', + type = 'frame', + style = 'subfooter_frame' } - Gui.set_padding(time) -end ---- Adds fake players to the player list -local function add_fake_players(list_table,count) - local role_name = 'Fake Player' - for i = 1,count do - add_player(list_table,{ - name='Player '..i, - index=0-i, - tag='', - online_time=math.random(0,game.tick), - afk_time=math.random(0,game.tick), - chat_color=table.get_random_dictionary_entry(Colors) - },role_name) + -- Change the style of the action bar + local action_bar_style = action_bar.style + action_bar_style.height = 35 + action_bar_style.padding = {1,3} + action_bar_style.use_header_filler = false + action_bar_style.horizontally_stretchable = true + action_bar.visible = false + + -- Add the buttons to the action bar + add_action_bar_buttons(action_bar) + + -- Add the reason bar + local reason_bar = + container.add{ + name = 'reason_bar', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the reason bar + local reason_bar_style = reason_bar.style + reason_bar_style.height = 35 + reason_bar_style.padding = {-1,3} + reason_bar_style.use_header_filler = false + reason_bar_style.horizontally_stretchable = true + reason_bar.visible = false + + -- Add the text entry for the reason bar + local reason_field = + reason_bar.add{ + name = 'entry', + type = 'textfield', + style = 'stretchable_textfield', + tooltip = {'player-list.reason-entry'} + } + + -- Change the style of the text entry + local reason_entry_style = reason_field.style + reason_entry_style.padding = 0 + reason_entry_style.height = 28 + reason_entry_style.minimal_width = 160 + + -- Add the confirm reason button + reason_confirm(reason_bar) + + -- Return the exteral container + return frame +end) +:add_to_left_flow(true) + +--- Button on the top flow used to toggle the player list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/character', + tooltip = {'player-list.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/player-list') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, player_list_container) +end) + +-- Get the player time to be used to update time label +local function get_player_times() + local ctn = 0 + local player_times = {} + for _, player in pairs(game.connected_players) do + ctn = ctn + 1 + local tick = game.tick > 0 and game.tick or 1 + local percent = math.round(player.online_time/tick,3)*100 + player_times[ctn] = { + element_name = 'player-time-'..player.index, + caption = format_time(player.online_time), + tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + } end + + return player_times end ---- Registers the player list --- @element player_list -local player_list = -Gui.new_left_frame('gui/player-list') -:set_sprites('entity/character') -:set_tooltip{'player-list.main-tooltip'} -:set_open_by_default() -:set_direction('vertical') -:on_creation(function(player,element) - local list_table,action_bar = generate_container(player,element) - generate_action_bar(player,action_bar) - +local function get_player_list_order() + -- Sort all the online players into roles local players = {} - for _,next_player in pairs(game.connected_players) do - local highest_role = Roles.get_player_highest_role(next_player) + for _,player in pairs(game.connected_players) do + local highest_role = Roles.get_player_highest_role(player) if not players[highest_role.name] then players[highest_role.name] = {} end - table.insert(players[highest_role.name],next_player) + table.insert(players[highest_role.name],player) end + -- Sort the players from roles into a set order + local ctn = 0 + local player_list_order = {} + local tick = game.tick > 0 and game.tick or 1 for _,role_name in pairs(Roles.config.order) do if players[role_name] then - for _,next_player in pairs(players[role_name]) do - add_player(list_table,next_player,role_name) + for _,player in pairs(players[role_name]) do + ctn = ctn + 1 + local percent = math.round(player.online_time/tick,3)*100 + player_list_order[ctn] = { + name = player.name, + index = player.index, + tag = player.tag, + role_name = role_name, + chat_color = player.chat_color, + caption = format_time(player.online_time), + tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + } end end end - --add_fake_players(list_table,6) - --add_fake_players(list_table,20) -end) -:on_update(function(player,element) - local list = element.container.scroll.table - for _,next_player in pairs(game.connected_players) do - local time_element_name = 'player-time-'..next_player.index - local time_element = list[time_element_name] - if time_element and time_element.valid then - time_element.label.caption = format_time(next_player.online_time) - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(next_player.online_time/tick,3)*100 - time_element.label.tooltip = {'player-list.afk-time',percent,format_time(next_player.afk_time,{minutes=true,long=true})} + --[[Adds fake players to the player list + for i = 1, 10 do + local online_time = math.random(1,tick) + local afk_time = math.random(online_time-(tick/10),tick) + local percent = math.round(online_time/tick,3)*100 + player_list_order[ctn+i] = { + name='Player '..i, + index=0-i, + tag='', + role_name = 'Fake Player', + chat_color=table.get_random_dictionary_entry(Colors), + caption = format_time(online_time), + tooltip = {'player-list.afk-time',percent,format_time(afk_time,{minutes=true,long=true})}, + } + end]] + + return player_list_order +end + +--- Update the play times every 30 sections +Event.on_nth_tick(1800,function() + local player_times = get_player_times() + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + for _,player_time in pairs(player_times) do + update_player_base(scroll_table,player_time) end end end) -player_list_name = player_list:uid() +--- When a player leaves only remove they entry +Event.add(defines.events.on_player_left_game,function(event) + local remove_player = event.player + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + remove_player_base(scroll_table,remove_player) + end +end) + +--- All other events require a full redraw of the table +local function redraw_player_list() + local player_list_order = get_player_list_order() + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + scroll_table.clear() + for _,next_player_data in ipairs(player_list_order) do + add_player_base(scroll_table,next_player_data) + end + end +end + +Event.add(defines.events.on_player_joined_game,redraw_player_list) +Event.add(Roles.events.on_role_assigned,redraw_player_list) +Event.add(Roles.events.on_role_unassigned,redraw_player_list) --- When the action player is changed the action bar will update Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - update_action_bar(player) - - -- Change the style of the option buttons - local frame = player_list:get_frame(player) - local data_table = frame.container.scroll.table + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + update_action_bar_buttons(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do - local element = data_table[next_player.name][open_action_bar.name] + local element = scroll_table[next_player.name][open_action_bar.name] local style = 'frame_button' if next_player.name == value then style = 'tool_button' end element.style = style - Gui.set_padding(element,-2,-2,-2,-2) - element.style.width = 8 - element.style.height = 14 + local element_style = element.style + element_style.padding = -2 + element_style.width = 8 + element_style.height = 14 end end) --- When the action name is changed the reason input will update Store.watch(selected_action_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local frame = Gui.classes.left_frames.get_frame(player_list_name,player) + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] local element = frame.container.reason_bar if value then -- if there is a new value then check the player is still online @@ -379,13 +481,4 @@ Store.watch(selected_action_store,function(value,player_name) element.visible = false end -end) - ---- Many events which trigger the gui to be re drawn, it will also update the times every 30 seconds -Event.on_nth_tick(1800,player_list 'update_all') -Event.add(defines.events.on_player_joined_game,player_list 'redraw_all') -Event.add(defines.events.on_player_left_game,player_list 'redraw_all') -Event.add(Roles.events.on_role_assigned,player_list 'redraw_all') -Event.add(Roles.events.on_role_unassigned,player_list 'redraw_all') - -return player_list \ No newline at end of file +end) \ No newline at end of file From cc120390c0034ff29b85a99a541eccd5ec7038d7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 16 Feb 2020 00:16:59 +0000 Subject: [PATCH 08/21] Drying Code --- config/action_buttons.lua | 4 +- expcore/gui.lua | 358 +++++++++++++++++++++++++---------- modules/gui/player-list.lua | 136 ++++--------- modules/gui/rocket-info.lua | 81 ++------ modules/gui/science-info.lua | 78 ++------ modules/gui/task-list.lua | 132 ++++--------- modules/gui/warp-list.lua | 157 ++++----------- 7 files changed, 408 insertions(+), 538 deletions(-) diff --git a/config/action_buttons.lua b/config/action_buttons.lua index 0ce8aff1..b5306cf1 100644 --- a/config/action_buttons.lua +++ b/config/action_buttons.lua @@ -137,7 +137,7 @@ end --- Jails the action player, requires a reason -- @element jail_player -local jail_player = new_button('utility/item_editor_icon',{'player-list.jail-player'}) +local jail_player = new_button('utility/multiplayer_waiting_icon',{'player-list.jail-player'}) :on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then @@ -156,7 +156,7 @@ end --- Temp bans the action player, requires a reason -- @element temp_ban_player -local temp_ban_player = new_button('utility/clock',{'player-list.temp-ban-player'}) +local temp_ban_player = new_button('utility/warning_white',{'player-list.temp-ban-player'}) :on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then diff --git a/expcore/gui.lua b/expcore/gui.lua index 70af10f9..e6874e31 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -340,22 +340,6 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Top Flow. -- @section topFlow ---- Button which toggles the top flow elements --- @element toggle_top_flow -local toggle_top_flow = -Gui.element{ - type = 'button', - style = 'back_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - --- The style that should be used for buttons on the top flow -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style @@ -371,6 +355,42 @@ local top_flow = Gui.get_top_flow(game.player) ]] Gui.get_top_flow = mod_gui.get_button_flow +--- Button which toggles the top flow elements, shows inside top flow +-- @element hide_top_flow +local hide_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) + +--- Button which toggles the top flow elements, shows inside left flow +-- @element show_top_flow +local show_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) + --[[-- Updates the visible states of all the elements on a players top flow @tparam LuaPlayer player the player that you want to update the flow for @@ -380,8 +400,8 @@ Gui.update_top_flow(game.player) ]] function Gui.update_top_flow(player) local top_flow = Gui.get_top_flow(player) - local toggle_button = top_flow[toggle_top_flow.name] - local is_visible = toggle_button.style.name == 'back_button' + local hide_button = top_flow[hide_top_flow.name] + local is_visible = hide_button.visible -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -409,27 +429,15 @@ Gui.toggle_top_flow(game.player,true) ]] function Gui.toggle_top_flow(player,state) + -- Get the top flow and hide button local top_flow = Gui.get_top_flow(player) - local toggle_button = top_flow[toggle_top_flow.name] - if state == nil then state = toggle_button.style.name == 'forward_button' end + if state == nil then state = not top_flow.visible end - -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do - top_flow[name].visible = state and authenticator(player) or false - end - - -- Change the style of the toggle button - if state then - toggle_button.style = 'back_button' - local style = toggle_button.style - style.height = 36 - style.width = 18 - else - toggle_button.style = 'forward_button' - local style = toggle_button.style - style.height = 20 - style.width = 18 - end + -- Change the visiblty of the flow + local left_flow = Gui.get_left_flow(player) + local show_button = left_flow.gui_core_buttons[show_top_flow.name] + show_button.visible = not state + top_flow.visible = state return state end @@ -437,22 +445,6 @@ end --- Left Flow. -- @section leftFlow ---- Button which hides the elements in the left flow --- @element hide_left_flow -local hide_left_flow = -Gui.element{ - type = 'button', - style = 'back_button', - tooltip = {'expcore-gui.left-button-tooltip'} -} -:style{ - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.hide_left_flow(player) -end) - --[[-- Gets the flow which contains the elements for the left flow @function Gui.get_left_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @@ -464,6 +456,52 @@ local left_flow = Gui.get_left_flow(game.player) ]] Gui.get_left_flow = mod_gui.get_frame_flow +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) + +--[[-- Button which can be used to toggle a left element, placed on the top flow +@tparam string sprite the sprite that you want to use on the button +@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have +@tparam table element_define the element define that you want to be toggled on the left flow +@tparam[opt] function authenticator used to decide if the button should be visible to a player + +@usage-- Add a button to toggle a left element +local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) + return player.admin +end) + +]] +function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) + return Gui.element{ + type = 'sprite-button', + sprite = sprite, + tooltip = tooltip, + style = Gui.top_flow_button_style + } + :style{ + padding = -2 + } + :add_to_top_flow(authenticator) + :on_click(function(player,_,_) + Gui.toggle_left_element(player, element_define) + end) +end + --[[-- Hides all left elements for a player @tparam LuaPlayer player the player to hide the elements for @@ -473,7 +511,7 @@ Gui.hide_left_flow(game.player) ]] function Gui.hide_left_flow(player) local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow[hide_left_flow.name] + local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] -- Set the visible state of all elements in the flow hide_button.visible = false @@ -482,7 +520,21 @@ function Gui.hide_left_flow(player) end end ---[[-- Toggles the visible state of all a left element for a player +--[[-- Get the element define that is in the left flow +@tparam LuaPlayer player the player that you want tog et the element for +@tparam table element_define the element that you want to get for the player +@treturn LuaGuiElement the gui element linked to this define in the left flow + +@usage-- Get your left element +local frame = Gui.get_left_element(game.player,example_flow_with_button) + +]] +function Gui.get_left_element(player,element_define) + local left_flow = Gui.get_left_flow(player) + return left_flow[element_define.name] +end + +--[[-- Toggles the visible state of a left element for a player @tparam LuaPlayer player the player that you want to toggle the element for @tparam table element_define the element that you want to toggle for the player @tparam[opt] boolean state if given then the state will be set to this state @@ -497,7 +549,7 @@ Gui.toggle_top_flow(game.player,example_flow_with_button,true) ]] function Gui.toggle_left_element(player,element_define,state) local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow[hide_left_flow.name] + local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] -- Set the visible state local element = left_flow[element_define.name] @@ -523,12 +575,15 @@ Event.add(defines.events.on_player_created,function(event) -- Draw the top flow local top_flow = Gui.get_top_flow(player) - toggle_top_flow(top_flow) + hide_top_flow(top_flow) Gui.update_top_flow(player) -- Draw the left flow local left_flow = Gui.get_left_flow(player) - local hide_left = hide_left_flow(left_flow) + local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } + local show_top = show_top_flow(button_flow) + local hide_left = hide_left_flow(button_flow) + show_top.visible = false -- Draw the elements on the left flow local show_hide_left = false @@ -538,7 +593,7 @@ Event.add(defines.events.on_player_created,function(event) -- Check if the element should be visible local visible = type(open_on_join) == 'boolean' and open_on_join or false if type(open_on_join) == 'function' then - local success, err = pcall(open_on_join,player) + local success, err = pcall(open_on_join, player) if not success then error('There as been an error with an open on join hander for a gui element:\n\t'..err) end @@ -616,7 +671,31 @@ function Gui.destroy_if_valid(element) return true end +--[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +@tparam number size the size that you want the button to be +@tparam[opt=-2] number padding the padding that you want on the sprite +@tparam[opt] table style any extra style settings that you want to have +@treturn table the style table to be used with element_define:style() + +@usage-- Adding a sprite button with size 20 +local button = +Gui.element{ + type = 'sprite-button', + sprite = 'entity/inserter' +} +:style(Gui.sprite_style(20)) + +]] +function Gui.sprite_style(size,padding,style) + style = style or {} + style.padding = padding or -2 + style.height = size + style.width = size + return style +end + --[[-- Draw a flow that has custom element alignments, default is right align +@element Gui.alignment @tparam LuaGuiElement parent the parent element that the alignment flow will be added to @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow @tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow @@ -630,27 +709,23 @@ local alignment = Gui.alignment(element,'example_right_alignment') local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') ]] -function Gui.alignment(parent,horizontal_align,vertical_align,name) - -- Draw the alignment flow - local alignment = - parent.add{ +Gui.alignment = +Gui.element(function(_,parent,_,_,name) + return parent.add{ name = name or 'alignment', type = 'flow', } - - -- Change its style - local style = alignment.style +end) +:style(function(style,_,horizontal_align,vertical_align,_) style.padding = {1,2} style.vertical_align = vertical_align or 'center' style.horizontal_align = horizontal_align or 'right' style.vertically_stretchable = style.vertical_align ~= 'center' style.horizontally_stretchable = style.horizontal_align ~= 'center' - - -- Return the flow - return alignment -end +end) --[[-- Draw a scroll pane that has a table inside of it +@element Gui.scroll_table @tparam LuaGuiElement parent the parent element that the scroll table will be added to @tparam number height the maximum height for the scroll pane @tparam number column_count the number of columns that the table will have @@ -661,9 +736,10 @@ end local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) ]] -function Gui.scroll_table(parent,height,column_count,name) +Gui.scroll_table = +Gui.element(function(_,parent,_,column_count,name) -- Draw the scroll - local scroll = + local scroll_pane = parent.add{ name = name or 'scroll', type = 'scroll-pane', @@ -673,32 +749,33 @@ function Gui.scroll_table(parent,height,column_count,name) style = 'scroll_pane_under_subheader' } - -- Change the style of the scroll - local scroll_style = scroll.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true - -- Draw the table local scroll_table = - scroll.add{ + scroll_pane.add{ type = 'table', name = 'table', column_count = column_count } - -- Change the style of the table - local table_style = scroll_table.style - table_style.padding = 0 - table_style.cell_padding = 0 - table_style.vertical_align = 'center' - table_style.horizontally_stretchable = true - -- Return the scroll table return scroll_table -end +end) +:style(function(style,element,height,_,_) + -- Change the style of the scroll + local scroll_style = element.parent.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Change the style of the table + style.padding = 0 + style.cell_padding = 0 + style.vertical_align = 'center' + style.horizontally_stretchable = true +end) --[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header @tparam LuaGuiElement parent the parent element that the header will be added to @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header @@ -706,17 +783,17 @@ end @tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' @treturn LuaGuiElement either the header or the header alignment if add_alignment is true -@usage-- Adding a custom header +@usage-- Adding a custom header with a label local header_alignment = Gui.header( element, - 'example_header', 'Example Caption', 'Example Tooltip', true ) ]] -function Gui.header(parent,caption,tooltip,add_alignment,name) +Gui.header = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) -- Draw the header local header = parent.add{ @@ -732,17 +809,102 @@ function Gui.header(parent,caption,tooltip,add_alignment,name) style.horizontally_stretchable = true -- Draw the caption label - header.add{ - name = 'header_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } + if caption then + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end -- Return either the header or the added alignment return add_alignment and Gui.alignment(header) or header -end +end) + +--[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the footer will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true + +@usage-- Adding a custom footer with a label +local header_alignment = Gui.footer( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.footer = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local footer = + parent.add{ + name = name or 'footer', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the footer + local style = footer.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + footer.add{ + name = 'footer_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the footer or the added alignment + return add_alignment and Gui.alignment(footer) or footer +end) + +--[[-- Used for left frame to add a nice boarder to them and contain them +@element Gui.container +@tparam LuaGuiElement parent the parent element that the container will be added to +@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam number width the minimal width that the frame will have + +@usage-- Adding a container as a base +local container = Gui.container(parent,'my_container',200) + +]] +Gui.container = +Gui.element(function(_,parent,name,_) + -- Draw the external container + local frame = + parent.add{ + name = name, + type = 'frame' + } + + -- Return the container + return frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } +end) +:style(function(style,element,_,width) + style.vertically_stretchable = false + local frame_style = element.parent.style + frame_style.padding = 2 + frame_style.minimal_width = width +end) -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 10ae6e5a..13bb1c7c 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -56,15 +56,10 @@ local close_action_bar = Gui.element{ type = 'sprite-button', sprite = 'utility/close_black', - hovered_sprite = 'utility/close_white', tooltip = {'player-list.close-action-bar'}, - style = 'tool_button' -} -:style{ - padding = -1, - width = 28, - height = 28 + style = 'shortcut_bar_button_red' } +:style(Gui.sprite_style(30,-1,{ top_margin = -1, right_margin = -1 })) :on_click(function(player,element) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) @@ -77,13 +72,9 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/confirm_slot', tooltip = {'player-list.reason-confirm'}, - style = 'tool_button' -} -:style{ - padding = -1, - width = 28, - height = 28 + style = 'shortcut_bar_button_green' } +:style(Gui.sprite_style(30,-1,{ left_margin = -2, right_margin = -1 })) :on_click(function(player,element) local reason = element.parent.entry.text or 'Non Given' local action_name = Store.get(selected_action_store,player) @@ -167,17 +158,12 @@ Gui.element(function(_,parent) -- Loop over all the buttons in the config for action_name,button_data in pairs(config.buttons) do -- Added the permission flow - local permission_flow = - parent.add{ - type = 'flow', - name = action_name - } + local permission_flow = parent.add{ type = 'flow', name = action_name } + permission_flow.visible = false -- Add the buttons under that permission for _,button in ipairs(button_data) do button(permission_flow) end - -- Hide the flow by default, will be made visble when a player is selected - permission_flow.visible = false end return parent @@ -189,6 +175,7 @@ local function update_action_bar_buttons(element) local selected_player_name = Store.get(selected_player_store,player) if not selected_player_name then + -- Hide the action bar when no player is selected element.visible = false else @@ -218,30 +205,8 @@ end -- @element player_list_container local player_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the scroll table for the players local scroll_table = Gui.scroll_table(container,184,3) @@ -251,38 +216,24 @@ Gui.element(function(event_trigger,parent) scroll_table_style.padding = {1,0,1,2} -- Add the action bar - local action_bar = - container.add{ - name = 'action_bar', - type = 'frame', - style = 'subfooter_frame' - } + local action_bar = Gui.footer(container,nil,nil,false,'action_bar') -- Change the style of the action bar local action_bar_style = action_bar.style action_bar_style.height = 35 action_bar_style.padding = {1,3} - action_bar_style.use_header_filler = false - action_bar_style.horizontally_stretchable = true action_bar.visible = false -- Add the buttons to the action bar add_action_bar_buttons(action_bar) -- Add the reason bar - local reason_bar = - container.add{ - name = 'reason_bar', - type = 'frame', - style = 'subfooter_frame' - } + local reason_bar = Gui.footer(container,nil,nil,false,'reason_bar') -- Change the style of the reason bar local reason_bar_style = reason_bar.style reason_bar_style.height = 35 reason_bar_style.padding = {-1,3} - reason_bar_style.use_header_filler = false - reason_bar_style.horizontally_stretchable = true reason_bar.visible = false -- Add the text entry for the reason bar @@ -304,27 +255,24 @@ Gui.element(function(event_trigger,parent) reason_confirm(reason_bar) -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(true) --- Button on the top flow used to toggle the player list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/character', - tooltip = {'player-list.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/character', {'player-list.main-tooltip'}, player_list_container, function(player) return Roles.player_allowed(player,'gui/player-list') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, player_list_container) -end) + +-- Get caption and tooltip format for a player +local function get_time_formats(online_time,afk_time) + local tick = game.tick > 0 and game.tick or 1 + local percent = math.round(online_time/tick,3)*100 + local caption = format_time(online_time) + local tooltip = {'player-list.afk-time', percent, format_time(afk_time,{minutes=true,long=true})} + return caption, tooltip +end -- Get the player time to be used to update time label local function get_player_times() @@ -332,18 +280,19 @@ local function get_player_times() local player_times = {} for _, player in pairs(game.connected_players) do ctn = ctn + 1 - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(player.online_time/tick,3)*100 + -- Add the player time details to the array + local caption, tooltip = get_time_formats(player.online_time, player.afk_time) player_times[ctn] = { element_name = 'player-time-'..player.index, - caption = format_time(player.online_time), - tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + caption = caption, + tooltip = tooltip } end return player_times end +-- Get a sorted list of all online players local function get_player_list_order() -- Sort all the online players into roles local players = {} @@ -358,20 +307,20 @@ local function get_player_list_order() -- Sort the players from roles into a set order local ctn = 0 local player_list_order = {} - local tick = game.tick > 0 and game.tick or 1 for _,role_name in pairs(Roles.config.order) do if players[role_name] then for _,player in pairs(players[role_name]) do ctn = ctn + 1 - local percent = math.round(player.online_time/tick,3)*100 + -- Add the player data to the array + local caption, tooltip = get_time_formats(player.online_time, player.afk_time) player_list_order[ctn] = { name = player.name, index = player.index, tag = player.tag, role_name = role_name, chat_color = player.chat_color, - caption = format_time(player.online_time), - tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + caption = caption, + tooltip = tooltip } end end @@ -381,15 +330,15 @@ local function get_player_list_order() for i = 1, 10 do local online_time = math.random(1,tick) local afk_time = math.random(online_time-(tick/10),tick) - local percent = math.round(online_time/tick,3)*100 + local caption, tooltip = get_time_formats(online_time, afk_time) player_list_order[ctn+i] = { name='Player '..i, index=0-i, tag='', role_name = 'Fake Player', - chat_color=table.get_random_dictionary_entry(Colors), - caption = format_time(online_time), - tooltip = {'player-list.afk-time',percent,format_time(afk_time,{minutes=true,long=true})}, + chat_color = table.get_random_dictionary_entry(Colors), + caption = caption, + tooltip = tooltip } end]] @@ -400,8 +349,7 @@ end Event.on_nth_tick(1800,function() local player_times = get_player_times() for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table for _,player_time in pairs(player_times) do update_player_base(scroll_table,player_time) @@ -413,8 +361,7 @@ end) Event.add(defines.events.on_player_left_game,function(event) local remove_player = event.player for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table remove_player_base(scroll_table,remove_player) end @@ -424,8 +371,7 @@ end) local function redraw_player_list() local player_list_order = get_player_list_order() for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table scroll_table.clear() for _,next_player_data in ipairs(player_list_order) do @@ -441,8 +387,7 @@ Event.add(Roles.events.on_role_unassigned,redraw_player_list) --- When the action player is changed the action bar will update Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table update_action_bar_buttons(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do @@ -462,8 +407,7 @@ end) --- When the action name is changed the reason input will update Store.watch(selected_action_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local element = frame.container.reason_bar if value then -- if there is a new value then check the player is still online diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 69c2d9d9..b2490ed3 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -29,7 +29,8 @@ local function check_player_permissions(player,action) return false end - if config.progress[action..'_role_permission'] and not Roles.player_allowed(player,config.progress[action..'_role_permission']) then + if config.progress[action..'_role_permission'] + and not Roles.player_allowed(player,config.progress[action..'_role_permission']) then return false end @@ -45,12 +46,13 @@ Gui.element(function(_,parent,label_data) local data_fullname = data_subname and data_name..data_subname or data_name -- Add the name label - parent.add{ + local name_label = parent.add{ type = 'label', name = data_fullname..'-label', caption = {'rocket-info.data-caption-'..data_name,data_subname}, tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} } + name_label.style.padding = {0,2} --- Right aligned label to store the data local alignment = Gui.alignment(parent,nil,nil,data_fullname) @@ -61,6 +63,7 @@ Gui.element(function(_,parent,label_data) caption = label_data.value, tooltip = label_data.tooltip } + element.style.padding = {0,2} return element end) @@ -187,11 +190,7 @@ Gui.element{ sprite = 'utility/play', tooltip = {'rocket-info.toggle-rocket-tooltip'} } -:style{ - padding = -2, - width = 16, - height = 16 -} +:style(Gui.sprite_style(16)) :on_click(function(player,element,_) local rocket_silo_name = element.parent.name:sub(8) local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) @@ -214,11 +213,7 @@ Gui.element{ sprite = 'utility/center', tooltip = {'rocket-info.launch-tooltip'} } -:style{ - padding = -2, - width = 16, - height = 16 -} +:style(Gui.sprite_style(16,-1)) :on_click(function(player,element,_) local rocket_silo_name = element.parent.name:sub(8) local silo_data = Rockets.get_silo_data_by_name(rocket_silo_name) @@ -333,6 +328,7 @@ local function get_progress_data(force_name) silo_name = silo_data.name, remove = true }) + else -- Get the progress caption and tooltip local progress_color = Colors.white @@ -430,12 +426,8 @@ Gui.element{ hovered_sprite = 'utility/expand', tooltip = {'rocket-info.toggle-section-tooltip'} } -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) +:style(Gui.sprite_style(20)) +:on_click(function(_,element,_) local header_flow = element.parent local flow_name = header_flow.caption local flow = header_flow.parent.parent[flow_name] @@ -479,33 +471,13 @@ end) -- @element rocket_list_container local rocket_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } + local container = Gui.container(parent,event_trigger,200) -- Set the container style local style = container.style - style.vertically_stretchable = false style.padding = 0 - local player = Gui.get_player_from_element(parent) local force_name = player.force.name -- Draw stats section @@ -525,37 +497,27 @@ Gui.element(function(event_trigger,parent) if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end local progress = section(container,'progress',col_count) -- Label used when there are no active silos - progress.add{ + local no_silos = progress.add{ type = 'label', name = 'no_silos', caption = {'rocket-info.progress-no-silos'} - } + } + no_silos.style.padding = {1,2} update_build_progress(progress,get_progress_data(force_name)) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(function(player) return player.force.rockets_launched > 0 and Roles.player_allowed(player,'gui/rocket-info') end) --- Button on the top flow used to toggle the container --- @element rocket_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/rocket-silo', - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/rocket-silo', {'rocket-info.main-tooltip'}, rocket_list_container, function(player) return Roles.player_allowed(player,'gui/rocket-info') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, rocket_list_container) -end) --- Update the gui for all players on a force local function update_rocket_gui_all(force_name) @@ -563,8 +525,7 @@ local function update_rocket_gui_all(force_name) local milestones = get_milestone_data(force_name) local progress = get_progress_data(force_name) for _,player in pairs(game.forces[force_name].players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[rocket_list_container.name] + local frame = Gui.get_left_element(player,rocket_list_container) local container = frame.container update_data_labels(container.stats.table,stats) update_data_labels(container.milestones.table,milestones) @@ -587,8 +548,7 @@ end) local function update_rocket_gui_progress(force_name) local progress = get_progress_data(force_name) for _,player in pairs(game.forces[force_name].players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[rocket_list_container.name] + local frame = Gui.get_left_element(player,rocket_list_container) local container = frame.container update_build_progress(container.progress.table,progress) end @@ -616,8 +576,7 @@ Event.add(defines.events.on_robot_built_entity,on_built) --- Redraw the progress section on role change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[rocket_list_container.name].container + local container = Gui.get_left_element(player,rocket_list_container).container local progress = container.progress if config.progress.show_progress then progress.destroy() diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index a3d74b33..0fd224fb 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -47,7 +47,9 @@ Gui.element(function(_,parent,production_label_data) } -- Change the style - surfix_element.style.font_color = color + local surfix_element_style = surfix_element.style + surfix_element_style.font_color = color + surfix_element_style.right_margin = 1 -- Return the value label return element @@ -119,8 +121,6 @@ Gui.element(function(_,parent,science_pack_data) type = 'frame', style = 'bordered_frame' } - - -- Change the style of the delta flow delta_flow.style.padding = {0,3} -- Draw the delta flow table @@ -130,8 +130,6 @@ Gui.element(function(_,parent,science_pack_data) type = 'table', column_count = 2 } - - -- Change the style of the delta flow table delta_table.style.padding = 0 -- Draw the production labels @@ -223,9 +221,9 @@ local function get_eta_label_data(player) return { research = false } end + local limit local progress = force.research_progress local remaining = research.research_unit_count*(1-progress) - local limit -- Check for the limiting science pack for _,ingredient in pairs(research.research_unit_ingredients) do @@ -266,40 +264,14 @@ local science_info_container = Gui.element(function(event_trigger,parent) local player = Gui.get_player_from_element(parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header - Gui.header( - container, - {'science-info.main-caption'}, - {'science-info.main-tooltip'} - ) + Gui.header(container, {'science-info.main-caption'}, {'science-info.main-tooltip'}) -- Draw the scroll table for the tasks - local scroll_table = Gui.scroll_table(container,185,4) + local scroll_table = Gui.scroll_table(container,178,4) -- Draw the no packs label local no_packs_label = @@ -318,20 +290,7 @@ Gui.element(function(event_trigger,parent) -- Add the footer and eta if config.show_eta then -- Draw the footer - local footer = Gui.header( - container, - {'science-info.eta-caption'}, - {'science-info.eta-tooltip'}, - true, - 'footer' - ) - - -- Set the style - footer.parent.style = 'subheader_frame' - local footer_style = footer.parent.style - footer_style.padding = {2,4} - footer_style.use_header_filler = false - footer_style.horizontally_stretchable = true + local footer = Gui.footer(container, {'science-info.eta-caption'}, {'science-info.eta-tooltip'}, true) -- Draw the eta label local eta_label = @@ -354,27 +313,15 @@ Gui.element(function(event_trigger,parent) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow() --- Button on the top flow used to toggle the task list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/lab', - tooltip = {'science-info.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/lab', {'science-info.main-tooltip'}, science_info_container, function(player) return Roles.player_allowed(player,'gui/science-info') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, science_info_container) -end) --- Updates the gui every 1 second Event.on_nth_tick(60,function() @@ -382,8 +329,7 @@ Event.on_nth_tick(60,function() local force_eta_data = {} for _,player in pairs(game.connected_players) do local force_name = player.force.name - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[science_info_container.name] + local frame = Gui.get_left_element(player,science_info_container) local container = frame.container -- Update the science packs diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 68baedae..b1ef31e4 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -11,6 +11,12 @@ local config = require 'config.tasks' --- @dep config.tasks local format_time,table_keys = ext_require('expcore.common','format_time','table_keys') --- @dep expcore.common local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks +-- Styles used for sprite buttons +local Styles = { + sprite20 = Gui.sprite_style(20), + sprite22 = Gui.sprite_style(20, nil, { right_margin = -3 }) +} + --- If a player is allowed to use the edit buttons local function check_player_permissions(player,task) if task then @@ -60,11 +66,7 @@ Gui.element{ tooltip = {'task-list.add-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,_,_) Tasks.add_task(player.force.name,nil,player.name) end) @@ -78,11 +80,7 @@ Gui.element{ tooltip = {'task-list.edit-tooltip-none'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element,_) local task_id = element.parent.name:sub(6) Tasks.set_editing(task_id,player.name,true) @@ -97,11 +95,7 @@ Gui.element{ tooltip = {'task-list.discard-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(_,element,_) local task_id = element.parent.name:sub(6) Tasks.remove_task(task_id) @@ -112,22 +106,16 @@ end) local add_task_base = Gui.element(function(_,parent,task_id) -- Add the task number label - parent.add{ + local task_number = parent.add{ name = 'count-'..task_id, type = 'label', caption = '0)' } + task_number.style.left_margin = 1 -- Add a flow which will contain the task message and edit buttons - local task_flow = - parent.add{ - name = task_id, - type = 'flow', - } - - -- Set the padding on the task flow - local task_flow_style = task_flow.style - task_flow_style.padding = 0 + local task_flow = parent.add{ name = task_id, type = 'flow', } + task_flow.style.padding = 0 -- Add the two edit buttons outside the task flow local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) @@ -155,12 +143,7 @@ Gui.element{ tooltip = {'task-list.confirm-tooltip'}, style = 'shortcut_bar_button_green' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element,_) local task_id = element.parent.name local new_message = element.parent[task_editing.name].text @@ -177,12 +160,7 @@ Gui.element{ tooltip = {'task-list.cancel-tooltip'}, style = 'shortcut_bar_button_red' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element,_) local task_id = element.parent.name Tasks.set_editing(task_id,player.name) @@ -203,11 +181,6 @@ Gui.element(function(event_trigger,parent,task) clear_and_focus_on_right_click = true } - -- Change the style - local style = element.style - style.maximal_width = 110 - style.height = 20 - -- Add the edit buttons cancel_edit(parent) confirm_edit(parent) @@ -215,6 +188,10 @@ Gui.element(function(event_trigger,parent,task) -- Return the element return element end) +:style{ + maximal_width = 110, + height = 20 +} :on_confirmed(function(player,element,_) local task_id = element.parent.name local new_message = element.text @@ -229,24 +206,18 @@ Gui.element(function(_,parent,task) local message = task.message local last_edit_name = task.last_edit_name local last_edit_time = task.last_edit_time - -- Draw the element - local element = - parent.add{ + return parent.add{ name = task_editing.name, type = 'label', caption = message, tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} } - - -- Change the style - local style = element.style - style.single_line = false - style.maximal_width = 150 - - -- Return the element - return element end) +:style{ + single_line = false, + maximal_width = 150 +} --- Updates a task for a player local function update_task(player,task_table,task_id) @@ -308,10 +279,12 @@ local function update_task(player,task_table,task_id) edit_task_element.enabled = false task_flow.clear() task_editing(task_flow,task).focus() + task_table.parent.scroll_to_element(task_flow,'top-third') end end +-- Update all the tasks for a player local function update_all_tasks(player,scroll_table) local task_ids = Tasks.get_force_task_ids(player.force.name) if #task_ids > 0 then @@ -325,30 +298,8 @@ end -- @element task_list_container local task_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header local header = Gui.header( @@ -364,7 +315,7 @@ Gui.element(function(event_trigger,parent) add_new_task_element.visible = check_player_permissions(player) -- Draw the scroll table for the tasks - local scroll_table = Gui.scroll_table(container,185,3) + local scroll_table = Gui.scroll_table(container,190,3) scroll_table.draw_horizontal_lines = true scroll_table.vertical_centering = false @@ -397,7 +348,7 @@ Gui.element(function(event_trigger,parent) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(function(player) local task_ids = Tasks.get_force_task_ids(player.force.name) @@ -405,22 +356,10 @@ end) end) --- Button on the top flow used to toggle the task list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'utility/not_enough_repair_packs_icon', - tooltip = {'task-list.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('utility/not_enough_repair_packs_icon', {'task-list.main-tooltip'}, task_list_container, function(player) return Roles.player_allowed(player,'gui/task-list') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, task_list_container) -end) --- When a new task is added it will udpate the task list for everyone on that force Tasks.on_update(function(task,task_id,removed_task) @@ -435,8 +374,7 @@ Tasks.on_update(function(task,task_id,removed_task) -- Update the task for all the players on the force local task_ids = Tasks.get_force_task_ids(force.name) for _,player in pairs(force.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[task_list_container.name] + local frame = Gui.get_left_element(player,task_list_container) local scroll_table = frame.container.scroll.table -- Update the task that was changed @@ -455,8 +393,7 @@ end) --- Update the tasks when the player joins Event.add(defines.events.on_player_joined_game,function(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[task_list_container.name] + local frame = Gui.get_left_element(player,task_list_container) local scroll_table = frame.container.scroll.table update_all_tasks(player,scroll_table) end) @@ -464,8 +401,7 @@ end) --- Makes sure the right buttons are present when roles change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[task_list_container.name].container + local container = Gui.get_left_element(player,task_list_container).container -- Update the tasks, incase the user can now edit them local scroll_table = container.scroll.table diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index f39c562d..e51e01c3 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -31,6 +31,13 @@ Global.register(keep_gui_open,function(tbl) keep_gui_open = tbl end) +-- Styles used for sprite buttons +local Styles = { + sprite20 = Gui.sprite_style(20), + sprite22 = Gui.sprite_style(20, nil, { right_margin = -3 }), + sprite32 = { height = 32, width = 32, left_margin = 1 } +} + --- Returns if a player is allowed to edit the given warp --- If a player is allowed to use the edit buttons local function check_player_permissions(player,action,warp) @@ -71,11 +78,7 @@ Gui.element{ tooltip = {'warp-list.add-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element) -- Add the new warp local force_name = player.force.name @@ -95,11 +98,7 @@ Gui.element{ tooltip = {'warp-list.discard-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(_,element) local warp_id = element.parent.name:sub(6) Warps.remove_warp(warp_id) @@ -114,11 +113,7 @@ Gui.element{ tooltip = {'warp-list.edit-tooltip-none'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element) local warp_id = element.parent.name:sub(6) Warps.set_editing(warp_id,player.name,true) @@ -135,18 +130,10 @@ Gui.element(function(_,parent,warp_id) type = 'flow', caption = warp_id } - - -- Change the style of the flow icon_flow.style.padding = 0 -- Add a flow which will contain the warp name and edit buttons - local warp_flow = - parent.add{ - name = warp_id, - type = 'flow', - } - - -- Set the padding on the warp flow + local warp_flow = parent.add{ type = 'flow', name = warp_id } warp_flow.style.padding = 0 -- Add the two edit buttons outside the warp flow @@ -176,12 +163,7 @@ Gui.element{ tooltip = {'warp-list.confirm-tooltip'}, style = 'shortcut_bar_button_green' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element) local warp_id = element.parent.name local warp_name = element.parent[warp_editing.name].text @@ -199,12 +181,7 @@ Gui.element{ tooltip = {'warp-list.cancel-tooltip'}, style = 'shortcut_bar_button_red' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element) local warp_id = element.parent.name Warps.set_editing(warp_id,player.name) @@ -225,11 +202,6 @@ Gui.element(function(event_trigger,parent,warp) clear_and_focus_on_right_click = true } - -- Change the style - local style = element.style - style.maximal_width = 110 - style.height = 20 - -- Add the edit buttons cancel_edit(parent) confirm_edit(parent) @@ -237,6 +209,10 @@ Gui.element(function(event_trigger,parent,warp) -- Return the element return element end) +:style{ + maximal_width = 110, + height = 20 +} :on_confirmed(function(player,element,_) local warp_id = element.parent.name local warp_name = element.text @@ -249,27 +225,20 @@ end) -- @element warp_label local warp_label = Gui.element(function(event_trigger,parent,warp) - local name = warp.name local last_edit_name = warp.last_edit_name local last_edit_time = warp.last_edit_time - -- Draw the element - local element = - parent.add{ + return parent.add{ name = event_trigger, type = 'label', - caption = name, + caption = warp.name, tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} } - - -- Change the style - local style = element.style - style.single_line = false - style.maximal_width = 150 - - -- Return the element - return element end) +:style{ + single_line = false, + maximal_width = 150 +} :on_click(function(player,element,_) local warp_id = element.parent.name local warp = Warps.get_warp(warp_id) @@ -283,25 +252,16 @@ end) warp_icon_button = Gui.element(function(event_trigger,parent,warp) local warp_position = warp.position - -- Draw the element - local element = - parent.add{ + return parent.add{ name = event_trigger, type = 'sprite-button', sprite = 'item/'..warp.icon, tooltip = {'warp-list.goto-tooltip',warp_position.x,warp_position.y}, style = 'quick_bar_slot_button' } - - -- Change the style - local style = element.style - style.height = 32 - style.width = 32 - - -- Return the element - return element end) +:style(Styles.sprite32) :on_click(function(player,element,_) local warp_id = element.parent.caption Warps.teleport_player(warp_id,player) @@ -316,27 +276,16 @@ end) --- Editing state for the warp icon, chose elem used to chosse icon -- @element warp_icon_editing local warp_icon_editing = -Gui.element(function(event_trigger,parent,warp) - local warp_icon = warp.icon - - -- Draw the element - local element = - parent.add{ +Gui.element(function(_,parent,warp) + return parent.add{ name = warp_icon_button.name, type = 'choose-elem-button', elem_type = 'item', - item = warp_icon, + item = warp.icon, tooltip = {'warp-list.goto-edit'}, } - - -- Change the style - local style = element.style - style.height = 32 - style.width = 32 - - -- Return the element - return element end) +:style(Styles.sprite32) --- This timer controls when a player is able to warp, eg every 60 seconds -- @element warp_timer @@ -421,12 +370,14 @@ local function update_warp(player,warp_table,warp_id) edit_warp_element.enabled = false warp_flow.clear() warp_editing(warp_flow,warp).focus() + warp_table.parent.scroll_to_element(warp_flow,'top-third') icon_flow.clear() warp_icon_editing(icon_flow,warp) end end +-- Update all the warps for a player local function update_all_warps(player,warp_table) local warp_ids = Warps.get_force_warp_ids(player.force.name) if #warp_ids > 0 then @@ -440,30 +391,8 @@ end -- @element warp_list_container local warp_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header local header = Gui.header( @@ -479,7 +408,7 @@ Gui.element(function(event_trigger,parent) add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') -- Draw the scroll table for the warps - local scroll_table = Gui.scroll_table(container,258,3) + local scroll_table = Gui.scroll_table(container,250,3) -- Change the style of the scroll table local scroll_table_style = scroll_table.style @@ -501,7 +430,7 @@ Gui.element(function(event_trigger,parent) update_all_warps(player,scroll_table) -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow() @@ -537,8 +466,7 @@ Warps.on_update(function(warp,_,removed_warp) -- Update the gui for selected players local warp_ids = Warps.get_force_warp_ids(force.name) for _,player in pairs(force.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table -- Update the gui @@ -552,8 +480,7 @@ end) --- Update the warps when the player joins Event.add(defines.events.on_player_joined_game,function(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table update_all_warps(player,scroll_table) end) @@ -561,8 +488,7 @@ end) --- Makes sure the right buttons are present when roles change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[warp_list_container.name].container + local container = Gui.get_left_element(player,warp_list_container).container -- Update the warps, incase the user can now edit them local scroll_table = container.scroll.table @@ -592,8 +518,7 @@ Store.watch(player_in_range_store,function(value,player_name) end -- Get the warp table - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table -- Check if the buttons should be active @@ -621,8 +546,7 @@ Store.watch(player_warp_cooldown_store,function(value,player_name,old_value) if value == old_value then return end -- Get the progress bar element local player = game.players[player_name] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local warp_timer_element = frame.container[warp_timer.name] -- Set the progress @@ -702,8 +626,7 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end -- Change the enabled state of the add warp button - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local add_warp_element = frame.container.header.alignment[add_new_warp.name] local was_able_to_make_warp = add_warp_element.enabled local can_make_warp = closest_distance > mr2 From 2a5d30961b252a65a9d70f2627c608c000a801c1 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 16 Feb 2020 16:27:34 +0000 Subject: [PATCH 09/21] Added redmew compatibilty --- config/_file_loader.lua | 2 +- expcore/gui.lua | 11 +- modules/commands/debug.lua | 2 +- modules/gui/debug/event_view.lua | 86 ++++++++-- modules/gui/debug/expcore_gui_view.lua | 128 +++++++++++++++ modules/gui/debug/expcore_store_view.lua | 4 +- modules/gui/debug/main_view.lua | 3 +- utils/gui.lua | 198 ++--------------------- 8 files changed, 230 insertions(+), 204 deletions(-) create mode 100644 modules/gui/debug/expcore_gui_view.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index f7ad4c42..1b21e619 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -44,7 +44,7 @@ return { 'modules.gui.warp-list', 'modules.gui.task-list', 'modules.gui.player-list', - --'modules.commands.debug', + 'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config diff --git a/expcore/gui.lua b/expcore/gui.lua index e6874e31..de0cd8f9 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -87,6 +87,9 @@ local Gui = { --- An index used for debuging to find the file where different elements where registered -- @table file_paths file_paths = {}, + --- An index used for debuging to show the raw data used to define an element + -- @table debug_info + debug_info = {}, --- The element prototype which is returned from Gui.element -- @table _prototype_element _prototype_element = {}, @@ -154,14 +157,17 @@ function Gui.element(element_define) Gui.uid = uid local name = tostring(uid) element.name = name + Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } -- Add the defination function if type(element_define) == 'table' then + Gui.debug_info[name].draw = element_define element_define.name = name element._draw = function(_,parent) return parent.add(element_define) end else + Gui.debug_info[name].draw = 'Function' element._draw = element_define end @@ -206,12 +212,14 @@ end) function Gui._prototype_element:style(style_define) -- Add the defination function if type(style_define) == 'table' then + Gui.debug_info[self.name].style = style_define self._style = function(style) for key,value in pairs(style_define) do style[key] = value end end else + Gui.debug_info[self.name].style = 'Function' self._style = style_define end @@ -281,6 +289,7 @@ local function event_handler_factory(event_name) Event.add(event_name, general_event_handler) return function(self,handler) + table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) self[event_name] = handler return self end @@ -331,7 +340,7 @@ Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events. --- Called when LuaGuiElement text is changed by the player. -- @tparam function handler the event handler which will be called -Gui._prototype_element.on_text_change = event_handler_factory(defines.events.on_gui_text_changed) +Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) --- Called when LuaGuiElement slider value is changed (related to the slider element). -- @tparam function handler the event handler which will be called diff --git a/modules/commands/debug.lua b/modules/commands/debug.lua index f0be73ba..e29786a6 100644 --- a/modules/commands/debug.lua +++ b/modules/commands/debug.lua @@ -9,6 +9,6 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands --- Opens the debug pannel for viewing tables. -- @command debug Commands.new_command('debug','Opens the debug pannel for viewing tables.') -:register(function(player,raw) +:register(function(player) DebugView.open_dubug(player) end) \ No newline at end of file diff --git a/modules/gui/debug/event_view.lua b/modules/gui/debug/event_view.lua index bc372007..cae93e60 100644 --- a/modules/gui/debug/event_view.lua +++ b/modules/gui/debug/event_view.lua @@ -1,7 +1,7 @@ -local Event = require 'utils.event' --- @dep utils.event -local table = require 'utils.table' --- @dep utils.table -local Gui = require 'utils.gui' --- @dep utils.gui -local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model +local Event = require 'utils.event' +local table = require 'utils.table' +local Gui = require 'utils.gui' +local Model = require 'modules.gui.debug.model' local format = string.format local insert = table.insert @@ -19,13 +19,16 @@ local name_lookup = {} -- GUI names local checkbox_name = Gui.uid_name() +local filter_name = Gui.uid_name() +local clear_filter_name = Gui.uid_name() -- global tables local enabled = {} local last_events = {} global.debug_event_view = { enabled = enabled, - last_events = last_events + last_events = last_events, + filter = '' } function Public.on_open_debug() @@ -90,24 +93,73 @@ end table.sort(grid_builder) -function Public.show(container) - local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) - local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) - local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) - +local function redraw_event_table(gui_table, filter) for _, event_name in pairs(grid_builder) do - local index = events[event_name] - gui_table.add({type = 'flow'}).add { - name = checkbox_name, - type = 'checkbox', - state = enabled[index] or false, - caption = event_name - } + if filter == '' or event_name:find(filter) then + local index = events[event_name] + gui_table.add({type = 'flow'}).add { + name = checkbox_name, + type = 'checkbox', + state = enabled[index] or false, + caption = event_name + } + end end end +function Public.show(container) + local filter = global.debug_event_view.filter + + local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) + + local filter_flow = main_frame_flow.add({type = 'flow', direction = 'horizontal'}) + filter_flow.add({type = 'label', caption = 'filter'}) + local filter_textfield = filter_flow.add({type = 'textfield', name = filter_name, text = filter}) + local clear_button = filter_flow.add({type = 'button', name = clear_filter_name, caption = 'clear'}) + + local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) + local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) + + Gui.set_data(filter_textfield, gui_table) + Gui.set_data(clear_button, {gui_table = gui_table, filter_textfield = filter_textfield}) + + redraw_event_table(gui_table, filter) +end + Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed) +Gui.on_text_changed( + filter_name, + function(event) + local element = event.element + local gui_table = Gui.get_data(element) + + local filter = element.text:gsub(' ', '_') + + global.debug_event_view.filter = filter + element.text = filter + + gui_table.clear() + redraw_event_table(gui_table, filter) + end +) + +Gui.on_click( + clear_filter_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + local filter_textfield = data.filter_textfield + local gui_table = data.gui_table + + filter_textfield.text = '' + global.debug_event_view.filter = '' + + gui_table.clear() + redraw_event_table(gui_table, '') + end +) + -- Event registers (TODO: turn to removable hooks.. maybe) for name, id in pairs(events) do name_lookup[id] = name diff --git a/modules/gui/debug/expcore_gui_view.lua b/modules/gui/debug/expcore_gui_view.lua new file mode 100644 index 00000000..cf95e894 --- /dev/null +++ b/modules/gui/debug/expcore_gui_view.lua @@ -0,0 +1,128 @@ +local Gui = require 'utils.gui' --- @dep utils.gui +local ExpGui = require 'expcore.gui' --- @dep utils.global +local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model + +local dump = Model.dump +local dump_text = Model.dump_text +local concat = table.concat + +local Public = {} + +local header_name = Gui.uid_name() +local left_panel_name = Gui.uid_name() +local right_panel_name = Gui.uid_name() +local input_text_box_name = Gui.uid_name() +local refresh_name = Gui.uid_name() + +Public.name = 'Elements' + +function Public.show(container) + local main_flow = container.add {type = 'flow', direction = 'horizontal'} + + local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name} + local left_panel_style = left_panel.style + left_panel_style.width = 300 + + for element_id, file_path in pairs(ExpGui.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = element_id..' - '..file_path} + Gui.set_data(header, element_id) + end + + local right_flow = main_flow.add {type = 'flow', direction = 'vertical'} + + local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'} + + local input_text_box = right_top_flow.add {type = 'text-box', name = input_text_box_name} + local input_text_box_style = input_text_box.style + input_text_box_style.horizontally_stretchable = true + input_text_box_style.height = 32 + input_text_box_style.maximal_width = 1000 + + local refresh_button = + right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'} + local refresh_button_style = refresh_button.style + refresh_button_style.width = 32 + refresh_button_style.height = 32 + + local right_panel = right_flow.add {type = 'text-box', name = right_panel_name} + right_panel.read_only = true + right_panel.selectable = true + + local right_panel_style = right_panel.style + right_panel_style.vertically_stretchable = true + right_panel_style.horizontally_stretchable = true + right_panel_style.maximal_width = 1000 + right_panel_style.maximal_height = 1000 + + local data = { + right_panel = right_panel, + input_text_box = input_text_box, + selected_header = nil + } + + Gui.set_data(input_text_box, data) + Gui.set_data(left_panel, data) + Gui.set_data(refresh_button, data) +end + +Gui.on_click( + header_name, + function(event) + local element = event.element + local element_id = Gui.get_data(element) + + local left_panel = element.parent.parent + local data = Gui.get_data(left_panel) + local right_panel = data.right_panel + local selected_header = data.selected_header + local input_text_box = data.input_text_box + + if selected_header then + selected_header.style.font_color = Color.white + end + + element.style.font_color = Color.orange + data.selected_header = element + + input_text_box.text = concat {'Gui.defines[', element_id, ']'} + input_text_box.style.font_color = Color.black + + local content = dump(ExpGui.debug_info[element_id]) or 'nil' + right_panel.text = content + end +) + +local function update_dump(text_input, data, player) + local suc, ouput = dump_text(text_input.text, player) + if not suc then + text_input.style.font_color = Color.red + else + text_input.style.font_color = Color.black + data.right_panel.text = ouput + end +end + +Gui.on_text_changed( + input_text_box_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + update_dump(element, data, event.player) + end +) + +Gui.on_click( + refresh_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + local input_text_box = data.input_text_box + + update_dump(input_text_box, data, event.player) + end +) + +return Public diff --git a/modules/gui/debug/expcore_store_view.lua b/modules/gui/debug/expcore_store_view.lua index 2d115992..300acc2d 100644 --- a/modules/gui/debug/expcore_store_view.lua +++ b/modules/gui/debug/expcore_store_view.lua @@ -24,8 +24,8 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - for store_id, token_name in pairs(Store.file_paths) do - local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..token_name} + for store_id, file_path in pairs(Store.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..file_path} Gui.set_data(header, store_id) end diff --git a/modules/gui/debug/main_view.lua b/modules/gui/debug/main_view.lua index 3c286a46..9807329c 100644 --- a/modules/gui/debug/main_view.lua +++ b/modules/gui/debug/main_view.lua @@ -6,6 +6,7 @@ local Public = {} local pages = { require 'modules.gui.debug.redmew_global_view', require 'modules.gui.debug.expcore_store_view', + require 'modules.gui.debug.expcore_gui_view', require 'modules.gui.debug.global_view', require 'modules.gui.debug.package_view', require 'modules.gui.debug._g_view', @@ -31,7 +32,7 @@ function Public.open_dubug(player) return end - frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3001', direction = 'vertical'} + frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3002', direction = 'vertical'} local frame_style = frame.style frame_style.height = 600 frame_style.width = 900 diff --git a/utils/gui.lua b/utils/gui.lua index 764037e0..36fc1d61 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -1,11 +1,7 @@ -local Token = require 'utils.token' --- @dep utils.token -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local mod_gui = require 'mod-gui' --- @dep mod-gui +local ExpGui = require 'expcore.gui' --- @dep expcore.gui local Gui = {} - local data = {} Global.register( @@ -15,12 +11,9 @@ Global.register( end ) -local top_elements = {} -local on_visible_handlers = {} -local on_pre_hidden_handlers = {} - function Gui.uid_name() - return tostring(Token.uid()) + local new_element = ExpGui.element() + return new_element.name end -- Associates data with the LuaGuiElement. If data is nil then removes the data @@ -75,219 +68,62 @@ function Gui.clear(element) element.clear() end -local function handler_factory(event_id) - local handlers - - local function on_event(event) - local element = event.element - if not element or not element.valid then - return - end - - local handler = handlers[element.name] - if not handler then - return - end - - local player = Game.get_player_by_index(event.player_index) - if not player or not player.valid then - return - end - event.player = player - - handler(event) - end - +local function handler_factory(event_name) return function(element_name, handler) - if not handlers then - handlers = {} - Event.add(event_id, on_event) - end - - handlers[element_name] = handler + local element = ExpGui.defines[element_name] + if not element then return end + element[event_name](element,function(_,_,event) + handler(event) + end) end end -local function custom_handler_factory(handlers) - return function(element_name, handler) - handlers[element_name] = handler - end -end - -local function custom_raise(handlers, element, player) - local handler = handlers[element.name] - if not handler then - return - end - - handler({element = element, player = player}) -end - -- Register a handler for the on_gui_checked_state_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_checked_state_changed = handler_factory(defines.events.on_gui_checked_state_changed) +Gui.on_checked_state_changed = handler_factory('on_checked_changed') -- Register a handler for the on_gui_click event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_click = handler_factory(defines.events.on_gui_click) +Gui.on_click = handler_factory('on_click') -- Register a handler for the on_gui_closed event for a custom LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_custom_close = handler_factory(defines.events.on_gui_closed) +Gui.on_custom_close = handler_factory('on_closed') -- Register a handler for the on_gui_elem_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_elem_changed = handler_factory(defines.events.on_gui_elem_changed) +Gui.on_elem_changed = handler_factory('on_elem_changed') -- Register a handler for the on_gui_selection_state_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_selection_state_changed = handler_factory(defines.events.on_gui_selection_state_changed) +Gui.on_selection_state_changed = handler_factory('on_selection_changed') -- Register a handler for the on_gui_text_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_text_changed = handler_factory(defines.events.on_gui_text_changed) +Gui.on_text_changed = handler_factory('on_text_changed') -- Register a handler for the on_gui_value_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_value_changed = handler_factory(defines.events.on_gui_value_changed) - --- Register a handler for when the player shows the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- Can only have one handler per element name. --- Guarantees that the element and the player are valid when calling the handler. --- Adds a player field to the event table. -Gui.on_player_show_top = custom_handler_factory(on_visible_handlers) - --- Register a handler for when the player hides the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- Can only have one handler per element name. --- Guarantees that the element and the player are valid when calling the handler. --- Adds a player field to the event table. -Gui.on_pre_player_hide_top = custom_handler_factory(on_pre_hidden_handlers) - ---- Allows the player to show / hide this element. --- The element must be in Gui.get_top_element_flow(player) --- This function must be called in the control stage, i.e not inside an event. --- @param element_name This name must be globally unique. -function Gui.allow_player_to_toggle_top_element_visibility(element_name) - if _LIFECYCLE ~= _STAGE.control then - error('can only be called during the control stage', 2) - end - top_elements[#top_elements + 1] = element_name -end +Gui.on_value_changed = handler_factory('on_value_changed') --- Returns the flow where top elements can be added and will be effected by google visibility -- For the toggle to work it must be registed with Gui.allow_player_to_toggle_top_element_visibility(element_name) -- @tparam LuaPlayer player pointer to the player who has the gui -- @treturn LuaGuiElement the top element flow -function Gui.get_top_element_flow(player) - player = Game.get_player_from_any(player) - return mod_gui.get_button_flow(player) -end - -local toggle_button_name = Gui.uid_name() -Gui.top_toggle_button_name = toggle_button_name - -Event.add( - defines.events.on_player_created, - function(event) - local player = Game.get_player_by_index(event.player_index) - - if not player or not player.valid then - return - end - - local top = Gui.get_top_element_flow(player) - - local b = top.add { - type = 'button', - name = toggle_button_name, - style = mod_gui.button_style, - caption = '<', - tooltip = {'gui_util.button_tooltip'} - } - local style = b.style - style.width = 18 - style.height = 36 - style.left_padding = 0 - style.top_padding = 0 - style.right_padding = 0 - style.bottom_padding = 0 - style.font = 'default-small-bold' - end -) - -Gui.on_click( - toggle_button_name, - function(event) - local button = event.element - local player = event.player - local top = Gui.get_top_element_flow(player) - - if button.caption == '<' then - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if ele.visible then - custom_raise(on_pre_hidden_handlers, ele, player) - ele.visible = false - end - end - end - - button.caption = '>' - button.style.height = 24 - else - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if not ele.visible then - ele.visible = true - custom_raise(on_visible_handlers, ele, player) - end - end - end - - button.caption = '<' - button.style.height = 36 - end - end -) - -if _DEBUG then - local concat = table.concat - - local names = {} - Gui.names = names - - function Gui.uid_name() - local info = debug.getinfo(2, 'Sl') - local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - local line = info.currentline - - local token = tostring(Token.uid()) - - local name = concat {token, ' - ', filepath, ':line:', line} - names[token] = name - - return token - end -end +Gui.get_top_element_flow = ExpGui.get_top_flow return Gui \ No newline at end of file From 105f53f629ee16598d34c60f4317e6b839bb4fd9 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Fri, 21 Feb 2020 23:21:06 +0100 Subject: [PATCH 10/21] Fixed warp button init --- modules/gui/warp-list.lua | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index e51e01c3..66626780 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -436,16 +436,7 @@ end) --- Button on the top flow used to toggle the warp list container -- @element warp_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'item/'..config.default_icon, - tooltip = {'warp-list.main-tooltip',config.standard_proximity_radius}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) :on_click(function(player,_,_) From bcde7943add47ffea8c0894b5b6e462f238282c0 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 23 Feb 2020 23:39:09 +0000 Subject: [PATCH 11/21] Split gui core into multiple files --- expcore/gui.lua | 920 +------------------------------ expcore/gui/core_defines.lua | 87 +++ expcore/gui/defines.lua | 218 ++++++++ expcore/gui/helper_functions.lua | 91 +++ expcore/gui/left_flow.lua | 180 ++++++ expcore/gui/prototype.lua | 352 ++++++++++++ expcore/gui/require.lua | 8 + expcore/gui/top_flow.lua | 99 ++++ 8 files changed, 1036 insertions(+), 919 deletions(-) create mode 100644 expcore/gui/core_defines.lua create mode 100644 expcore/gui/defines.lua create mode 100644 expcore/gui/helper_functions.lua create mode 100644 expcore/gui/left_flow.lua create mode 100644 expcore/gui/prototype.lua create mode 100644 expcore/gui/require.lua create mode 100644 expcore/gui/top_flow.lua diff --git a/expcore/gui.lua b/expcore/gui.lua index de0cd8f9..eaa22047 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -1,919 +1 @@ ---[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers -@core Gui -@alias Gui - -@usage-- Defining a button that prints the player's name -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button with a custom style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button using a custom function -local example_flow_with_button = -Gui.element(function(event_trigger,parent) - -- Add the flow the button is in - local flow = - parent.add{ - name = 'example_flow', - type = 'flow' - } - - -- Get the players name - local player = game.players[parent.player_index] - local player_name = player.name - - -- Add the button - local element = - flow.add{ - name = event_trigger, - type = 'button', - caption = 'Example Button: '..player_name - } - - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100] - style.font_color = player.color - - -- Return the element - return element -end) -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Drawing an element -local exmple_button_element = example_button(parent) -local example_flow_with_button = example_flow_with_button(parent) - -]] - -local Event = require 'utils.event' --- @dep utils.event -local mod_gui = require 'mod-gui' --- @dep mod-gui - -local Gui = { - --- The current highest uid that is being used, will not increase during runtime - -- @field uid - uid = 0, - --- Contains the uids of the elements that will show on the top flow and the auth function - -- @table top_elements - top_elements = {}, - --- Contains the uids of the elements that will show on the left flow and the open on join function - -- @table left_elements - left_elements = {}, - --- Table of all the elements which have been registed with the draw function and event handlers - -- @table defines - defines = {}, - --- An index used for debuging to find the file where different elements where registered - -- @table file_paths - file_paths = {}, - --- An index used for debuging to show the raw data used to define an element - -- @table debug_info - debug_info = {}, - --- The element prototype which is returned from Gui.element - -- @table _prototype_element - _prototype_element = {}, - --- The prototype metatable applied to new element defines - -- @table _mt_element - _mt_element = { - __call = function(self,parent,...) - local element = self._draw(self.name,parent,...) - if self._style then self._style(element.style,element,...) end - return element - end - } -} - -Gui._mt_element.__index = Gui._prototype_element - ---- Element Define. --- @section elementDefine - ---[[-- Base function used to define new elements, can be used with a table or with a function -@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element - -@usage-- Defining an element with a table -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} - -@usage-- Defining an element with a function -local example_flow_with_button = -Gui.element(function(event_trigger,parent,...) - -- Add the flow the button is in - local flow = - parent.add{ - name = 'example_flow', - type = 'flow' - } - - -- Add the button - local element = - flow.add{ - name = event_trigger, - type = 'button', - caption = 'Example Button' - } - - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100 - - -- Return the element - return element -end) - -]] -function Gui.element(element_define) - -- Set the metatable to allow access to register events - local element = setmetatable({}, Gui._mt_element) - - -- Increment the uid counter - local uid = Gui.uid + 1 - Gui.uid = uid - local name = tostring(uid) - element.name = name - Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } - - -- Add the defination function - if type(element_define) == 'table' then - Gui.debug_info[name].draw = element_define - element_define.name = name - element._draw = function(_,parent) - return parent.add(element_define) - end - else - Gui.debug_info[name].draw = 'Function' - element._draw = element_define - end - - -- Add the define to the base module - local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - Gui.file_paths[name] = file_path - Gui.defines[name] = element - - -- Return the element so event handers can be accessed - return element -end - ---[[-- Extension of Gui.element when using the table method, values applied after the element is drawn -@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element - -@usage-- Setting the height and width of the example button -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} - -@usage-- Using a function to set the style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style(function(style,element,...) - local player = game.players[element.player_index] - style.height = 25 - style.width = 100 - style.font_color = player.color -end) - -]] -function Gui._prototype_element:style(style_define) - -- Add the defination function - if type(style_define) == 'table' then - Gui.debug_info[self.name].style = style_define - self._style = function(style) - for key,value in pairs(style_define) do - style[key] = value - end - end - else - Gui.debug_info[self.name].style = 'Function' - self._style = style_define - end - - -- Return the element so event handers can be accessed - return self -end - ---[[-- Adds an element to be drawn to the top flow when a player joins -@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible -@treturn table the new element define that is used to register events to this element - -@usage-- Adding the example button -example_button:add_to_top_flow(function(player) - -- example button will only show when game time is less than 1 minute - return player.online_time < 3600 -end) - -]] -function Gui._prototype_element:add_to_top_flow(authenticator) - Gui.top_elements[self.name] = authenticator or true - return self -end - ---[[-- Adds an element to be drawn to the left flow when a player joins -@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible -@treturn table the new element define that is used to register events to this element - -@usage-- Adding the example button -example_flow_with_button:add_to_left_flow(true) - -]] -function Gui._prototype_element:add_to_left_flow(open_on_join) - Gui.left_elements[self.name] = open_on_join or false - return self -end - --- This function is called for event event -local function general_event_handler(event) - -- Check the element is valid - local element = event.element - if not element or not element.valid then - return - end - - -- Get the event handler for this element - local handlers = Gui.defines[element.name] - local handler = handlers and handlers[event.name] - if not handler then - return - end - - -- Get the player for this event - local player = game.players[event.player_index] - if not player or not player.valid then - return - end - event.player = player - - local success, err = pcall(handler,player,element,event) - if not success then - error('There as been an error with an event handler for a gui element:\n\t'..err) - end -end - --- This function returns the event handler adder and registeres the general handler -local function event_handler_factory(event_name) - Event.add(event_name, general_event_handler) - - return function(self,handler) - table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) - self[event_name] = handler - return self - end -end - ---- Element Events. --- @section elementEvents - ---- Called when the player opens a GUI. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) - ---- Called when the player closes the GUI they have open. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) - ---- Called when LuaGuiElement is clicked. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) - ---- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) - ---- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) - ---- Called when LuaGuiElement element value is changed (related to choose element buttons). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) - ---- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) - ---- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) - ---- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) - ---- Called when LuaGuiElement switch state is changed (related to switches). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) - ---- Called when LuaGuiElement text is changed by the player. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) - ---- Called when LuaGuiElement slider value is changed (related to the slider element). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) - ---- Top Flow. --- @section topFlow - ---- The style that should be used for buttons on the top flow --- @field Gui.top_flow_button_style -Gui.top_flow_button_style = mod_gui.button_style - ---[[-- Gets the flow which contains the elements for the top flow -@function Gui.get_top_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for -@treturn LuaGuiElement the top element flow - -@usage-- Geting your top element flow -local top_flow = Gui.get_top_flow(game.player) - -]] -Gui.get_top_flow = mod_gui.get_button_flow - ---- Button which toggles the top flow elements, shows inside top flow --- @element hide_top_flow -local hide_top_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/preset', - style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - padding = -2, - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - ---- Button which toggles the top flow elements, shows inside left flow --- @element show_top_flow -local show_top_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/preset', - style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - padding = -2, - width = 18, - height = 20 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - ---[[-- Updates the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to update the flow for - -@usage-- Update your flow -Gui.update_top_flow(game.player) - -]] -function Gui.update_top_flow(player) - local top_flow = Gui.get_top_flow(player) - local hide_button = top_flow[hide_top_flow.name] - local is_visible = hide_button.visible - - -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do - -- Ensure the element exists - local element = top_flow[name] - if not element then - element = Gui.defines[name](top_flow) - end - - -- Set the visible state - element.visible = is_visible and authenticator(player) or false - end -end - ---[[-- Toggles the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to toggle the flow for -@tparam[opt] boolean state if given then the state will be set to this state -@treturn boolean the new visible state of the top flow - -@usage-- Toggle your flow -Gui.toggle_top_flow(game.player) - -@usage-- Open your top flow -Gui.toggle_top_flow(game.player,true) - -]] -function Gui.toggle_top_flow(player,state) - -- Get the top flow and hide button - local top_flow = Gui.get_top_flow(player) - if state == nil then state = not top_flow.visible end - - -- Change the visiblty of the flow - local left_flow = Gui.get_left_flow(player) - local show_button = left_flow.gui_core_buttons[show_top_flow.name] - show_button.visible = not state - top_flow.visible = state - - return state -end - ---- Left Flow. --- @section leftFlow - ---[[-- Gets the flow which contains the elements for the left flow -@function Gui.get_left_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for -@treturn LuaGuiElement the left element flow - -@usage-- Geting your left element flow -local left_flow = Gui.get_left_flow(game.player) - -]] -Gui.get_left_flow = mod_gui.get_frame_flow - ---- Button which hides the elements in the left flow --- @element hide_left_flow -local hide_left_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/close_black', - style = 'tool_button', - tooltip = {'expcore-gui.left-button-tooltip'} -} -:style{ - padding = -3, - width = 18, - height = 20 -} -:on_click(function(player,_,_) - Gui.hide_left_flow(player) -end) - ---[[-- Button which can be used to toggle a left element, placed on the top flow -@tparam string sprite the sprite that you want to use on the button -@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have -@tparam table element_define the element define that you want to be toggled on the left flow -@tparam[opt] function authenticator used to decide if the button should be visible to a player - -@usage-- Add a button to toggle a left element -local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) - return player.admin -end) - -]] -function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) - return Gui.element{ - type = 'sprite-button', - sprite = sprite, - tooltip = tooltip, - style = Gui.top_flow_button_style - } - :style{ - padding = -2 - } - :add_to_top_flow(authenticator) - :on_click(function(player,_,_) - Gui.toggle_left_element(player, element_define) - end) -end - ---[[-- Hides all left elements for a player -@tparam LuaPlayer player the player to hide the elements for - -@usage-- Hide your left elements -Gui.hide_left_flow(game.player) - -]] -function Gui.hide_left_flow(player) - local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] - - -- Set the visible state of all elements in the flow - hide_button.visible = false - for name,_ in pairs(Gui.left_elements) do - left_flow[name].visible = false - end -end - ---[[-- Get the element define that is in the left flow -@tparam LuaPlayer player the player that you want tog et the element for -@tparam table element_define the element that you want to get for the player -@treturn LuaGuiElement the gui element linked to this define in the left flow - -@usage-- Get your left element -local frame = Gui.get_left_element(game.player,example_flow_with_button) - -]] -function Gui.get_left_element(player,element_define) - local left_flow = Gui.get_left_flow(player) - return left_flow[element_define.name] -end - ---[[-- Toggles the visible state of a left element for a player -@tparam LuaPlayer player the player that you want to toggle the element for -@tparam table element_define the element that you want to toggle for the player -@tparam[opt] boolean state if given then the state will be set to this state -@treturn boolean the new visible state of the element - -@usage-- Toggle your example button -Gui.toggle_top_flow(game.player,example_flow_with_button) - -@usage-- Open your example button -Gui.toggle_top_flow(game.player,example_flow_with_button,true) - -]] -function Gui.toggle_left_element(player,element_define,state) - local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] - - -- Set the visible state - local element = left_flow[element_define.name] - if state == nil then state = not element.visible end - element.visible = state - - -- Check if the hide button should be visible - local show_hide_button = false - for name,_ in pairs(Gui.left_elements) do - if left_flow[name].visible then - show_hide_button = true - break - end - end - hide_button.visible = show_hide_button - - return state -end - --- Draw the two flows when a player joins -Event.add(defines.events.on_player_created,function(event) - local player = game.players[event.player_index] - - -- Draw the top flow - local top_flow = Gui.get_top_flow(player) - hide_top_flow(top_flow) - Gui.update_top_flow(player) - - -- Draw the left flow - local left_flow = Gui.get_left_flow(player) - local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } - local show_top = show_top_flow(button_flow) - local hide_left = hide_left_flow(button_flow) - show_top.visible = false - - -- Draw the elements on the left flow - local show_hide_left = false - for name,open_on_join in pairs(Gui.left_elements) do - local left_element = Gui.defines[name](left_flow) - - -- Check if the element should be visible - local visible = type(open_on_join) == 'boolean' and open_on_join or false - if type(open_on_join) == 'function' then - local success, err = pcall(open_on_join, player) - if not success then - error('There as been an error with an open on join hander for a gui element:\n\t'..err) - end - visible = err - end - - left_element.visible = visible - if visible then - show_hide_left = true - end - end - - hide_left.visible = show_hide_left -end) - ---- Helper Functions. --- @section helperFunctions - ---[[-- Get the player that owns a gui element -@tparam LuaGuiElement element the element that you want to get the owner of -@treturn LuaPlayer the player that owns this element - -@usage-- Geting the owner of an element -local player = Gui.get_player_from_element(element) - -]] -function Gui.get_player_from_element(element) - if not element or not element.valid then return end - return game.players[element.player_index] -end - ---[[-- Will toggle the enabled state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set -@treturn boolean the new enabled state that the element has - -@usage-- Toggling the the enabled state -local new_enabled_state = Gui.toggle_enabled_state(element) - -]] -function Gui.toggle_enabled_state(element,state) - if not element or not element.valid then return end - if state == nil then state = not element.enabled end - element.enabled = state - return state -end - ---[[-- Will toggle the visible state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set -@treturn boolean the new visible state that the element has - -@usage-- Toggling the the visible state -local new_visible_state = Gui.toggle_visible_state(element) - -]] -function Gui.toggle_visible_state(element,state) - if not element or not element.valid then return end - if state == nil then state = not element.visible end - element.visible = state - return state -end - ---[[-- Destory a gui element without causing any errors, likly if the element may have already been removed -@tparam LuaGuiElement element the element that you want to remove -@treturn boolean true if the element was valid and has been removed - -@usage-- Likely use case for element not existing -Gui.destroy_if_valid(element[child_name]) - -]] -function Gui.destroy_if_valid(element) - if not element or not element.valid then return false end - element.destroy() - return true -end - ---[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button -@tparam number size the size that you want the button to be -@tparam[opt=-2] number padding the padding that you want on the sprite -@tparam[opt] table style any extra style settings that you want to have -@treturn table the style table to be used with element_define:style() - -@usage-- Adding a sprite button with size 20 -local button = -Gui.element{ - type = 'sprite-button', - sprite = 'entity/inserter' -} -:style(Gui.sprite_style(20)) - -]] -function Gui.sprite_style(size,padding,style) - style = style or {} - style.padding = padding or -2 - style.height = size - style.width = size - return style -end - ---[[-- Draw a flow that has custom element alignments, default is right align -@element Gui.alignment -@tparam LuaGuiElement parent the parent element that the alignment flow will be added to -@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow -@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow -@tparam[opt='alignment'] string name the name of the alignment flow -@treturn LuaGuiElement the alignment flow that was created - -@usage-- Adding a right align flow -local alignment = Gui.alignment(element,'example_right_alignment') - -@usage-- Adding a horizontal center and top align flow -local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') - -]] -Gui.alignment = -Gui.element(function(_,parent,_,_,name) - return parent.add{ - name = name or 'alignment', - type = 'flow', - } -end) -:style(function(style,_,horizontal_align,vertical_align,_) - style.padding = {1,2} - style.vertical_align = vertical_align or 'center' - style.horizontal_align = horizontal_align or 'right' - style.vertically_stretchable = style.vertical_align ~= 'center' - style.horizontally_stretchable = style.horizontal_align ~= 'center' -end) - ---[[-- Draw a scroll pane that has a table inside of it -@element Gui.scroll_table -@tparam LuaGuiElement parent the parent element that the scroll table will be added to -@tparam number height the maximum height for the scroll pane -@tparam number column_count the number of columns that the table will have -@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' -@treturn LuaGuiElement the table that was created - -@usage-- Adding a scroll table with max height of 200 and column count of 3 -local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) - -]] -Gui.scroll_table = -Gui.element(function(_,parent,_,column_count,name) - -- Draw the scroll - local scroll_pane = - parent.add{ - name = name or 'scroll', - type = 'scroll-pane', - direction = 'vertical', - horizontal_scroll_policy = 'never', - vertical_scroll_policy = 'auto', - style = 'scroll_pane_under_subheader' - } - - -- Draw the table - local scroll_table = - scroll_pane.add{ - type = 'table', - name = 'table', - column_count = column_count - } - - -- Return the scroll table - return scroll_table -end) -:style(function(style,element,height,_,_) - -- Change the style of the scroll - local scroll_style = element.parent.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true - - -- Change the style of the table - style.padding = 0 - style.cell_padding = 0 - style.vertical_align = 'center' - style.horizontally_stretchable = true -end) - ---[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the header will be added to -@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header -@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' -@treturn LuaGuiElement either the header or the header alignment if add_alignment is true - -@usage-- Adding a custom header with a label -local header_alignment = Gui.header( - element, - 'Example Caption', - 'Example Tooltip', - true -) - -]] -Gui.header = -Gui.element(function(_,parent,caption,tooltip,add_alignment,name) - -- Draw the header - local header = - parent.add{ - name = name or 'header', - type = 'frame', - style = 'subheader_frame' - } - - -- Change the style of the header - local style = header.style - style.padding = {2,4} - style.use_header_filler = false - style.horizontally_stretchable = true - - -- Draw the caption label - if caption then - header.add{ - name = 'header_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } - end - - -- Return either the header or the added alignment - return add_alignment and Gui.alignment(header) or header -end) - ---[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the footer will be added to -@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer -@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' -@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true - -@usage-- Adding a custom footer with a label -local header_alignment = Gui.footer( - element, - 'Example Caption', - 'Example Tooltip', - true -) - -]] -Gui.footer = -Gui.element(function(_,parent,caption,tooltip,add_alignment,name) - -- Draw the header - local footer = - parent.add{ - name = name or 'footer', - type = 'frame', - style = 'subfooter_frame' - } - - -- Change the style of the footer - local style = footer.style - style.padding = {2,4} - style.use_header_filler = false - style.horizontally_stretchable = true - - -- Draw the caption label - if caption then - footer.add{ - name = 'footer_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } - end - - -- Return either the footer or the added alignment - return add_alignment and Gui.alignment(footer) or footer -end) - ---[[-- Used for left frame to add a nice boarder to them and contain them -@element Gui.container -@tparam LuaGuiElement parent the parent element that the container will be added to -@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame -@tparam number width the minimal width that the frame will have - -@usage-- Adding a container as a base -local container = Gui.container(parent,'my_container',200) - -]] -Gui.container = -Gui.element(function(_,parent,name,_) - -- Draw the external container - local frame = - parent.add{ - name = name, - type = 'frame' - } - - -- Return the container - return frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } -end) -:style(function(style,element,_,width) - style.vertically_stretchable = false - local frame_style = element.parent.style - frame_style.padding = 2 - frame_style.minimal_width = width -end) - --- Module return -return Gui \ No newline at end of file +return require 'expcore.gui.require' \ No newline at end of file diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua new file mode 100644 index 00000000..5c26bea7 --- /dev/null +++ b/expcore/gui/core_defines.lua @@ -0,0 +1,87 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local Event = require 'utils.event' --- @dep utils.event + +--- Core Defines. +-- @section coreDefines + +--- Button which toggles the top flow elements, shows inside top flow +-- @element hide_top_flow +local hide_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) +Gui.core_defines.hide_top_flow = hide_top_flow + +--- Button which toggles the top flow elements, shows inside left flow +-- @element show_top_flow +local show_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) +Gui.core_defines.show_top_flow = show_top_flow + +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) +Gui.core_defines.hide_left_flow = hide_left_flow + +--- Draw the core elements when a player joins the game +Event.add(defines.events.on_player_created,function(event) + local player = game.players[event.player_index] + + -- Draw the top flow + local top_flow = Gui.get_top_flow(player) + hide_top_flow(top_flow) + Gui.update_top_flow(player) + + -- Draw the left flow + local left_flow = Gui.get_left_flow(player) + local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } + local show_top = show_top_flow(button_flow) + local hide_left = hide_left_flow(button_flow) + show_top.visible = false + hide_left.visible = false + Gui.draw_left_flow(player) + +end) \ No newline at end of file diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua new file mode 100644 index 00000000..db52d8ca --- /dev/null +++ b/expcore/gui/defines.lua @@ -0,0 +1,218 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' + +--[[-- Draw a flow that has custom element alignments, default is right align +@element Gui.alignment +@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow +@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow +@tparam[opt='alignment'] string name the name of the alignment flow +@treturn LuaGuiElement the alignment flow that was created + +@usage-- Adding a right align flow +local alignment = Gui.alignment(element,'example_right_alignment') + +@usage-- Adding a horizontal center and top align flow +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') + +]] +Gui.alignment = +Gui.element(function(_,parent,_,_,name) + return parent.add{ + name = name or 'alignment', + type = 'flow', + } +end) +:style(function(style,_,horizontal_align,vertical_align,_) + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' +end) + +--[[-- Draw a scroll pane that has a table inside of it +@element Gui.scroll_table +@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam number height the maximum height for the scroll pane +@tparam number column_count the number of columns that the table will have +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@treturn LuaGuiElement the table that was created + +@usage-- Adding a scroll table with max height of 200 and column count of 3 +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) + +]] +Gui.scroll_table = +Gui.element(function(_,parent,_,column_count,name) + -- Draw the scroll + local scroll_pane = + parent.add{ + name = name or 'scroll', + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto', + style = 'scroll_pane_under_subheader' + } + + -- Draw the table + local scroll_table = + scroll_pane.add{ + type = 'table', + name = 'table', + column_count = column_count + } + + -- Return the scroll table + return scroll_table +end) +:style(function(style,element,height,_,_) + -- Change the style of the scroll + local scroll_style = element.parent.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Change the style of the table + style.padding = 0 + style.cell_padding = 0 + style.vertical_align = 'center' + style.horizontally_stretchable = true +end) + +--[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the header or the header alignment if add_alignment is true + +@usage-- Adding a custom header with a label +local header_alignment = Gui.header( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.header = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local header = + parent.add{ + name = name or 'header', + type = 'frame', + style = 'subheader_frame' + } + + -- Change the style of the header + local style = header.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the header or the added alignment + return add_alignment and Gui.alignment(header) or header +end) + +--[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the footer will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true + +@usage-- Adding a custom footer with a label +local header_alignment = Gui.footer( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.footer = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local footer = + parent.add{ + name = name or 'footer', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the footer + local style = footer.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + footer.add{ + name = 'footer_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the footer or the added alignment + return add_alignment and Gui.alignment(footer) or footer +end) + +--[[-- Used for left frame to add a nice boarder to them and contain them +@element Gui.container +@tparam LuaGuiElement parent the parent element that the container will be added to +@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam number width the minimal width that the frame will have + +@usage-- Adding a container as a base +local container = Gui.container(parent,'my_container',200) + +]] +Gui.container = +Gui.element(function(_,parent,name,_) + -- Draw the external container + local frame = + parent.add{ + name = name, + type = 'frame' + } + + -- Return the container + return frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } +end) +:style(function(style,element,_,width) + style.vertically_stretchable = false + local frame_style = element.parent.style + frame_style.padding = 2 + frame_style.minimal_width = width +end) \ No newline at end of file diff --git a/expcore/gui/helper_functions.lua b/expcore/gui/helper_functions.lua new file mode 100644 index 00000000..22106718 --- /dev/null +++ b/expcore/gui/helper_functions.lua @@ -0,0 +1,91 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' + +--- Helper Functions. +-- @section helperFunctions + +--[[-- Get the player that owns a gui element +@tparam LuaGuiElement element the element that you want to get the owner of +@treturn LuaPlayer the player that owns this element + +@usage-- Geting the owner of an element +local player = Gui.get_player_from_element(element) + +]] +function Gui.get_player_from_element(element) + if not element or not element.valid then return end + return game.players[element.player_index] +end + +--[[-- Will toggle the enabled state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new enabled state that the element has + +@usage-- Toggling the the enabled state +local new_enabled_state = Gui.toggle_enabled_state(element) + +]] +function Gui.toggle_enabled_state(element,state) + if not element or not element.valid then return end + if state == nil then state = not element.enabled end + element.enabled = state + return state +end + +--[[-- Will toggle the visible state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new visible state that the element has + +@usage-- Toggling the the visible state +local new_visible_state = Gui.toggle_visible_state(element) + +]] +function Gui.toggle_visible_state(element,state) + if not element or not element.valid then return end + if state == nil then state = not element.visible end + element.visible = state + return state +end + +--[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +@tparam LuaGuiElement element the element that you want to remove +@treturn boolean true if the element was valid and has been removed + +@usage-- Likely use case for element not existing +Gui.destroy_if_valid(element[child_name]) + +]] +function Gui.destroy_if_valid(element) + if not element or not element.valid then return false end + element.destroy() + return true +end + +--[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +@tparam number size the size that you want the button to be +@tparam[opt=-2] number padding the padding that you want on the sprite +@tparam[opt] table style any extra style settings that you want to have +@treturn table the style table to be used with element_define:style() + +@usage-- Adding a sprite button with size 20 +local button = +Gui.element{ + type = 'sprite-button', + sprite = 'entity/inserter' +} +:style(Gui.sprite_style(20)) + +]] +function Gui.sprite_style(size,padding,style) + style = style or {} + style.padding = padding or -2 + style.height = size + style.width = size + return style +end \ No newline at end of file diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua new file mode 100644 index 00000000..e21a10c1 --- /dev/null +++ b/expcore/gui/left_flow.lua @@ -0,0 +1,180 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local mod_gui = require 'mod-gui' --- @dep mod-gui + +local hide_left_flow = Gui.core_defines.hide_left_flow.name + +--- Left Flow. +-- @section leftFlow + +--- Contains the uids of the elements that will show on the left flow and the open on join function +-- @table left_elements +Gui.left_elements = {} + +--[[-- Gets the flow which contains the elements for the left flow +@function Gui.get_left_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the left element flow + +@usage-- Geting your left element flow +local left_flow = Gui.get_left_flow(game.player) + +]] +Gui.get_left_flow = mod_gui.get_frame_flow + +--[[-- Adds an element to be drawn to the left flow when a player joins +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +@treturn table the new element define that is used to register events to this element + +@usage-- Adding the example button +example_flow_with_button:add_to_left_flow(true) + +]] +function Gui._prototype_element:add_to_left_flow(open_on_join) + Gui.left_elements[self.name] = open_on_join or false + return self +end + +--[[-- Button which can be used to toggle a left element, placed on the top flow +@tparam string sprite the sprite that you want to use on the button +@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have +@tparam table element_define the element define that you want to be toggled on the left flow +@tparam[opt] function authenticator used to decide if the button should be visible to a player + +@usage-- Add a button to toggle a left element +local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) + return player.admin +end) + +]] +function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) + return Gui.element{ + type = 'sprite-button', + sprite = sprite, + tooltip = tooltip, + style = Gui.top_flow_button_style + } + :style{ + padding = -2 + } + :add_to_top_flow(authenticator) + :on_click(function(player,_,_) + Gui.toggle_left_element(player, element_define) + end) +end + +--[[-- Draw all the left elements onto the left flow, internal use only +@tparam LuaPlayer player the player that you want to draw the elements for + +@usage Draw all the left elements +Gui.draw_left_flow(player) + +]] +function Gui.draw_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + local show_hide_button = false + + for name, open_on_join in pairs(Gui.left_elements) do + -- Draw the element to the left flow + local left_element = Gui.defines[name](left_flow) + + -- Check if it should be open by default + local visible = type(open_on_join) == 'boolean' and open_on_join or false + if type(open_on_join) == 'function' then + local success, err = pcall(open_on_join, player) + if not success then + error('There as been an error with an open on join hander for a gui element:\n\t'..err) + end + visible = err + end + + -- Set the visible state of the element + left_element.visible = visible + show_hide_button = show_hide_button or visible + end + + hide_button.visible = show_hide_button +end + +--[[-- Update the visible state of the hide left button, also draw left elements if not present +@tparam LuaPlayer player the player to update the left flow for +@treturn boolean true if any left element is visible + +@usage Check if any left elements are visible +local visible = Gui.update_left_flow(player) + +]] +function Gui.update_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + for name, _ in pairs(Gui.left_elements) do + local left_element = left_flow[name] + if left_element.visible then + hide_button.visible = true + return true + end + end + return false +end + +--[[-- Hides all left elements for a player +@tparam LuaPlayer player the player to hide the elements for + +@usage-- Hide your left elements +Gui.hide_left_flow(game.player) + +]] +function Gui.hide_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + + -- Set the visible state of all elements in the flow + hide_button.visible = false + for name,_ in pairs(Gui.left_elements) do + left_flow[name].visible = false + end +end + +--[[-- Get the element define that is in the left flow +@tparam LuaPlayer player the player that you want tog et the element for +@tparam table element_define the element that you want to get for the player +@treturn LuaGuiElement the gui element linked to this define in the left flow + +@usage-- Get your left element +local frame = Gui.get_left_element(game.player,example_flow_with_button) + +]] +function Gui.get_left_element(player,element_define) + local left_flow = Gui.get_left_flow(player) + return left_flow[element_define.name] +end + +--[[-- Toggles the visible state of a left element for a player +@tparam LuaPlayer player the player that you want to toggle the element for +@tparam table element_define the element that you want to toggle for the player +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the element + +@usage-- Toggle your example button +Gui.toggle_top_flow(game.player,example_flow_with_button) + +@usage-- Open your example button +Gui.toggle_top_flow(game.player,example_flow_with_button,true) + +]] +function Gui.toggle_left_element(player,element_define,state) + local left_flow = Gui.get_left_flow(player) + + -- Set the visible state + local element = left_flow[element_define.name] + if state == nil then state = not element.visible end + element.visible = state + Gui.update_left_flow(player) + + return state +end \ No newline at end of file diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua new file mode 100644 index 00000000..75365bd1 --- /dev/null +++ b/expcore/gui/prototype.lua @@ -0,0 +1,352 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@core Gui +@alias Gui + +@usage-- Defining a button that prints the player's name +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button with a custom style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button using a custom function +local example_flow_with_button = +Gui.element(function(event_trigger,parent) + -- Add the flow the button is in + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + -- Get the players name + local player = game.players[parent.player_index] + local player_name = player.name + + -- Add the button + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button: '..player_name + } + + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100] + style.font_color = player.color + + -- Return the element + return element +end) +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Drawing an element +local exmple_button_element = example_button(parent) +local example_flow_with_button = example_flow_with_button(parent) + +]] + +local Event = require 'utils.event' --- @dep utils.event + +local Gui = { + --- The current highest uid that is being used, will not increase during runtime + -- @field uid + uid = 0, + --- An index of the element deinfes which are used by the core gui system + -- @table core_defines + core_defines = {}, + --- Table of all the elements which have been registed with the draw function and event handlers + -- @table defines + defines = {}, + --- Table of all custom events that are used by element defines, used to avoid conflicts + -- @table events + events = {}, + --- An index used for debuging to find the file where different elements where registered + -- @table file_paths + file_paths = {}, + --- An index used for debuging to show more data on element defines + -- @table debug_info + debug_info = {}, + --- The element prototype which is returned from Gui.element + -- @table _prototype_element + _prototype_element = {}, + --- The prototype metatable applied to new element defines + -- @table _mt_element + _mt_element = { + __call = function(self,parent,...) + local element = self._draw(self.name,parent,...) + if self._style then self._style(element.style,element,...) end + return element + end + } +} + +Gui._mt_element.__index = Gui._prototype_element + +--- Element Define. +-- @section elementDefine + +--[[-- Base function used to define new elements, can be used with a table or with a function +@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Defining an element with a table +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} + +@usage-- Defining an element with a function +local example_flow_with_button = +Gui.element(function(event_trigger,parent,...) + -- Add the flow the button is in + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + -- Add the button + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } + + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100 + + -- Return the element + return element +end) + +]] +function Gui.element(element_define) + -- Set the metatable to allow access to register events + local element = setmetatable({}, Gui._mt_element) + + -- Increment the uid counter + local uid = Gui.uid + 1 + Gui.uid = uid + local name = tostring(uid) + element.name = name + Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } + + -- Add the defination function + if type(element_define) == 'table' then + Gui.debug_info[name].draw = element_define + element_define.name = name + element._draw = function(_,parent) + return parent.add(element_define) + end + else + Gui.debug_info[name].draw = 'Function' + element._draw = element_define + end + + -- Add the define to the base module + local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) + Gui.file_paths[name] = file_path + Gui.defines[name] = element + + -- Return the element so event handers can be accessed + return element +end + +--[[-- Extension of Gui.element when using the table method, values applied after the element is drawn +@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Setting the height and width of the example button +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} + +@usage-- Using a function to set the style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style(function(style,element,...) + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color +end) + +]] +function Gui._prototype_element:style(style_define) + -- Add the defination function + if type(style_define) == 'table' then + Gui.debug_info[self.name].style = style_define + self._style = function(style) + for key,value in pairs(style_define) do + style[key] = value + end + end + else + Gui.debug_info[self.name].style = 'Function' + self._style = style_define + end + + -- Return the element so event handers can be accessed + return self +end + +--[[-- Set the handler to be called on a custom event, only one handler can be used +@tparam string event_name the name of the event you want to handler to be called on +@tparam function handler the handler that you want to be called when the event is raised +@treturn table the element define so more handleres can be registered + +@usage Print the player name when my_custom_event is raised +element_deinfe:on_custom_event('my_custom_event', function(event) + event.player.print(player.name) +end) + +]] +function Gui._prototype_element:on_custom_event(event_name,handler) + table.insert(Gui.debug_info[self.name].events,event_name) + Gui.events[event_name] = event_name + self[event_name] = handler + return self +end + +--[[-- Raise the handler which is attached to any event; external use should be limited to custom events +@tparam table event the event table bassed to the handler, must include fields: name, element + +@usage Raising a custom event +element_define:raise_custom_event{ + name = 'my_custom_event', + element = element +} + +]] +function Gui._prototype_element:raise_custom_event(event) + -- Check the element is valid + local element = event.element + if not element or not element.valid then + return + end + + -- Get the event handler for this element + local handler = self[event.name] + if not handler then + return + end + + -- Get the player for this event + local player_index = event.player_index or element.player_index + local player = game.players[player_index] + if not player or not player.valid then + return + end + event.player = player + + local success, err = pcall(handler,player,element,event) + if not success then + error('There as been an error with an event handler for a gui element:\n\t'..err) + end +end + +-- This function is used to register a link between element define events and the events in the factorio api +local function event_handler_factory(event_name) + Event.add(event_name, function(event) + local element = event.element + if not element or not element.valid then return end + local element_define = Gui.defines[element.name] + element_define:raise_custom_event(event) + end) + + return function(self,handler) + table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) + self[event_name] = handler + return self + end +end + +--- Element Events. +-- @section elementEvents + +--- Called when the player opens a GUI. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) + +--- Called when the player closes the GUI they have open. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) + +--- Called when LuaGuiElement is clicked. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) + +--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) + +--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) + +--- Called when LuaGuiElement element value is changed (related to choose element buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) + +--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) + +--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) + +--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) + +--- Called when LuaGuiElement switch state is changed (related to switches). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) + +--- Called when LuaGuiElement text is changed by the player. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) + +--- Called when LuaGuiElement slider value is changed (related to the slider element). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) + +-- Module return +return Gui \ No newline at end of file diff --git a/expcore/gui/require.lua b/expcore/gui/require.lua new file mode 100644 index 00000000..26fcf0d6 --- /dev/null +++ b/expcore/gui/require.lua @@ -0,0 +1,8 @@ +local Gui = require 'expcore.gui.prototype' +require 'expcore.gui.core_defines' +require 'expcore.gui.top_flow' +require 'expcore.gui.left_flow' +require 'expcore.gui.helper_functions' +require 'expcore.gui.defines' + +return Gui \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua new file mode 100644 index 00000000..b35eb2b0 --- /dev/null +++ b/expcore/gui/top_flow.lua @@ -0,0 +1,99 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local mod_gui = require 'mod-gui' --- @dep mod-gui + +local hide_top_flow = Gui.core_defines.hide_top_flow.name +local show_top_flow = Gui.core_defines.show_top_flow.name + +--- Top Flow. +-- @section topFlow + +--- Contains the uids of the elements that will show on the top flow and the auth function +-- @table top_elements +Gui.top_elements = {} + +--- The style that should be used for buttons on the top flow +-- @field Gui.top_flow_button_style +Gui.top_flow_button_style = mod_gui.button_style + +--[[-- Gets the flow which contains the elements for the top flow +@function Gui.get_top_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the top element flow + +@usage-- Geting your top element flow +local top_flow = Gui.get_top_flow(game.player) + +]] +Gui.get_top_flow = mod_gui.get_button_flow + +--[[-- Adds an element to be drawn to the top flow when a player joins +@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible +@treturn table the new element define that is used to register events to this element + +@usage-- Adding the example button +example_button:add_to_top_flow(function(player) + -- example button will only show when game time is less than 1 minute + return player.online_time < 3600 +end) + +]] +function Gui._prototype_element:add_to_top_flow(authenticator) + Gui.top_elements[self.name] = authenticator or true + return self +end + +--[[-- Updates the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to update the flow for + +@usage-- Update your flow +Gui.update_top_flow(game.player) + +]] +function Gui.update_top_flow(player) + local top_flow = Gui.get_top_flow(player) + local hide_button = top_flow[hide_top_flow] + local is_visible = hide_button.visible + + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + -- Ensure the element exists + local element = top_flow[name] + if not element then + element = Gui.defines[name](top_flow) + end + + -- Set the visible state + element.visible = is_visible and authenticator(player) or false + end +end + +--[[-- Toggles the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to toggle the flow for +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the top flow + +@usage-- Toggle your flow +Gui.toggle_top_flow(game.player) + +@usage-- Open your top flow +Gui.toggle_top_flow(game.player,true) + +]] +function Gui.toggle_top_flow(player,state) + -- Get the top flow and hide button + local top_flow = Gui.get_top_flow(player) + if state == nil then state = not top_flow.visible end + + -- Change the visiblty of the flow + local left_flow = Gui.get_left_flow(player) + local show_button = left_flow.gui_core_buttons[show_top_flow] + show_button.visible = not state + top_flow.visible = state + + return state +end \ No newline at end of file From 0db55650240c1bf120849588e979d552a2f03e9b Mon Sep 17 00:00:00 2001 From: badgamernl Date: Mon, 24 Feb 2020 23:35:25 +0100 Subject: [PATCH 12/21] Added ability to chain raise_custom_event --- expcore/gui/prototype.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 75365bd1..21f26033 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -246,6 +246,7 @@ end --[[-- Raise the handler which is attached to any event; external use should be limited to custom events @tparam table event the event table bassed to the handler, must include fields: name, element +@treturn table the element define so more events can be raised @usage Raising a custom event element_define:raise_custom_event{ @@ -258,20 +259,20 @@ function Gui._prototype_element:raise_custom_event(event) -- Check the element is valid local element = event.element if not element or not element.valid then - return + return self end -- Get the event handler for this element local handler = self[event.name] if not handler then - return + return self end -- Get the player for this event local player_index = event.player_index or element.player_index local player = game.players[player_index] if not player or not player.valid then - return + return self end event.player = player @@ -279,6 +280,7 @@ function Gui._prototype_element:raise_custom_event(event) if not success then error('There as been an error with an event handler for a gui element:\n\t'..err) end + return self end -- This function is used to register a link between element define events and the events in the factorio api From 1273de4e86a2e1b39925d55a360417ddfbc150bc Mon Sep 17 00:00:00 2001 From: badgamernl Date: Mon, 24 Feb 2020 23:43:41 +0100 Subject: [PATCH 13/21] Added custom event on_visibility_changed_by_click Fixed warp flow issue because of this --- expcore/gui/left_flow.lua | 51 ++++++++++++++++++++++++++++++++++++--- expcore/gui/prototype.lua | 7 ++++++ modules/gui/warp-list.lua | 7 +++--- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index e21a10c1..64243932 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -52,7 +52,7 @@ end) ]] function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) - return Gui.element{ + local button = Gui.element{ type = 'sprite-button', sprite = sprite, tooltip = tooltip, @@ -62,9 +62,26 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) padding = -2 } :add_to_top_flow(authenticator) - :on_click(function(player,_,_) - Gui.toggle_left_element(player, element_define) + + -- Add on_click handler to handle click events comming from the player + button:on_click(function(player,_,_) + local top_flow = Gui.get_top_flow(player) + local element = top_flow[button.name] + local visibility_state = Gui.toggle_left_element(player, element_define) + + -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking + -- Used in warp gui to handle the keep open logic + button:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = element, + state = visibility_state + } end) + + -- Add property to the left flow element with the name of the button + -- This is for the ability to reverse lookup the button from the left flow element + element_define.toolbar_button = button.name + return button end --[[-- Draw all the left elements onto the left flow, internal use only @@ -137,6 +154,34 @@ function Gui.hide_left_flow(player) hide_button.visible = false for name,_ in pairs(Gui.left_elements) do left_flow[name].visible = false + + -- Get the assosiated element define + local element_define = Gui.defines[name] + local top_flow = Gui.get_top_flow(player) + + -- Check if the the element has a button attached + if not element_define.toolbar_button then + goto hide_left_flow_end + end + + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if not button then + goto hide_left_flow_end + end + + -- Get the button define from the reverse lookup on the element + local button_define = Gui.defines[element_define.toolbar_button] + + -- Raise the custom event if all of the top checks have passed + button_define:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = button, + state = false + } + + -- Label for the end of the loop + ::hide_left_flow_end:: end end diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 21f26033..aedcf736 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -350,5 +350,12 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) +--- Element Events. +-- @section customEvents +Gui.events = { + -- Triggered when a user changed the visibility of a left flow element by clicking a button + on_visibility_changed_by_click = 'on_visibility_changed_by_click' +} + -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 66626780..7f63395c 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,9 +439,10 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_click(function(player,_,_) - local visible_state = Gui.toggle_left_element(player, warp_list_container) - keep_gui_open[player.name] = visible_state +:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) + local state = event.state -- true if visible, false if invisible + -- Set gui keep open state for player that clicked the button + keep_gui_open[player.name] = state end) --- When the name of a warp is updated this is triggered From 3aa77227ca9d9ab17d3eef9962c84055e27b1263 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:35:55 +0100 Subject: [PATCH 14/21] Removed goto usage --- expcore/gui/left_flow.lua | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 64243932..74003f15 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -160,28 +160,20 @@ function Gui.hide_left_flow(player) local top_flow = Gui.get_top_flow(player) -- Check if the the element has a button attached - if not element_define.toolbar_button then - goto hide_left_flow_end + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Get the button define from the reverse lookup on the element + local button_define = Gui.defines[element_define.toolbar_button] + -- Raise the custom event if all of the top checks have passed + button_define:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = button, + state = false + } + end end - - -- Check if the topflow contains the button - local button = top_flow[element_define.toolbar_button] - if not button then - goto hide_left_flow_end - end - - -- Get the button define from the reverse lookup on the element - local button_define = Gui.defines[element_define.toolbar_button] - - -- Raise the custom event if all of the top checks have passed - button_define:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, - element = button, - state = false - } - - -- Label for the end of the loop - ::hide_left_flow_end:: end end From efd9c7b609f64c1d4ae23f090337eb16d2cfa1ec Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:41:18 +0100 Subject: [PATCH 15/21] Renamed Gui.event to Gui.custom_event --- expcore/gui/left_flow.lua | 4 ++-- expcore/gui/prototype.lua | 4 ++-- modules/gui/warp-list.lua | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 74003f15..255823c5 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -72,7 +72,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking -- Used in warp gui to handle the keep open logic button:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, + name = Gui.custom_events.on_visibility_changed_by_click, element = element, state = visibility_state } @@ -168,7 +168,7 @@ function Gui.hide_left_flow(player) local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed button_define:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, + name = Gui.custom_events.on_visibility_changed_by_click, element = button, state = false } diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index aedcf736..6e7e6c5f 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -350,9 +350,9 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) ---- Element Events. +--- Custom element events. -- @section customEvents -Gui.events = { +Gui.custom_event = { -- Triggered when a user changed the visibility of a left flow element by clicking a button on_visibility_changed_by_click = 'on_visibility_changed_by_click' } diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 7f63395c..5e24af6c 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,7 +439,7 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) +:on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) local state = event.state -- true if visible, false if invisible -- Set gui keep open state for player that clicked the button keep_gui_open[player.name] = state From 8e9325fc0cf96dac9825a404796ed3d4283f1da6 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:42:33 +0100 Subject: [PATCH 16/21] Changed keep open to be a one liner --- modules/gui/warp-list.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 5e24af6c..b6954687 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -440,9 +440,8 @@ Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',c return Roles.player_allowed(player,'gui/warp-list') end) :on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) - local state = event.state -- true if visible, false if invisible - -- Set gui keep open state for player that clicked the button - keep_gui_open[player.name] = state + -- Set gui keep open state for player that clicked the button: true if visible, false if invisible + keep_gui_open[player.name] = event.state end) --- When the name of a warp is updated this is triggered From 2d90d1dcdd3071c7820a0083f006e4f5b5e61dde Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:49:57 +0100 Subject: [PATCH 17/21] Rerenamed events --- expcore/gui/left_flow.lua | 4 ++-- expcore/gui/prototype.lua | 7 +++---- modules/gui/warp-list.lua | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 255823c5..74003f15 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -72,7 +72,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking -- Used in warp gui to handle the keep open logic button:raise_custom_event{ - name = Gui.custom_events.on_visibility_changed_by_click, + name = Gui.events.on_visibility_changed_by_click, element = element, state = visibility_state } @@ -168,7 +168,7 @@ function Gui.hide_left_flow(player) local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed button_define:raise_custom_event{ - name = Gui.custom_events.on_visibility_changed_by_click, + name = Gui.events.on_visibility_changed_by_click, element = button, state = false } diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 6e7e6c5f..b307da02 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -352,10 +352,9 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Custom element events. -- @section customEvents -Gui.custom_event = { - -- Triggered when a user changed the visibility of a left flow element by clicking a button - on_visibility_changed_by_click = 'on_visibility_changed_by_click' -} + +-- Triggered when a user changed the visibility of a left flow element by clicking a button +Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index b6954687..595a3ba2 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,7 +439,7 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) +:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) -- Set gui keep open state for player that clicked the button: true if visible, false if invisible keep_gui_open[player.name] = event.state end) From 76f86b7a970e34dccefafd71deb207bca5581e7b Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 01:36:40 +0100 Subject: [PATCH 18/21] Added toolbar button color for open flows * Added top flow button style `Gui.top_flow_button_visible_style` * Added function to style toolbar buttons `Gui.left_toolbar_button_style` * Modified code to call the toolbar button style function --- expcore/gui/left_flow.lua | 50 +++++++++++++++++++++++++++++++++++++++ expcore/gui/top_flow.lua | 4 ++++ 2 files changed, 54 insertions(+) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 74003f15..53c37394 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -39,6 +39,28 @@ function Gui._prototype_element:add_to_left_flow(open_on_join) return self end +--[[-- Styles the top flow button depending on the state given +@tparam LuaGuiElement the button element to style +@tparam boolean state The state the button is in + +@usage-- Sets the button to the visible style +Gui.left_toolbar_button_style(button, true) + +@usage-- Sets the button to the hidden style +Gui.left_toolbar_button_style(button, false) + +]] +function Gui.left_toolbar_button_style(button, state) + if state then + button.style = Gui.top_flow_button_visible_style + else + button.style = Gui.top_flow_button_style + end + button.style.minimal_width = 36 + button.style.height = 36 + button.style.padding = -2 +end + --[[-- Button which can be used to toggle a left element, placed on the top flow @tparam string sprite the sprite that you want to use on the button @tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have @@ -59,6 +81,8 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) style = Gui.top_flow_button_style } :style{ + minimal_width = 36, + height = 36, padding = -2 } :add_to_top_flow(authenticator) @@ -113,6 +137,20 @@ function Gui.draw_left_flow(player) -- Set the visible state of the element left_element.visible = visible show_hide_button = show_hide_button or visible + + -- Get the assosiated element define + local element_define = Gui.defines[name] + local top_flow = Gui.get_top_flow(player) + + -- Check if the the element has a button attached + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Style the button + Gui.left_toolbar_button_style(button, visible) + end + end end hide_button.visible = show_hide_button @@ -164,6 +202,8 @@ function Gui.hide_left_flow(player) -- Check if the topflow contains the button local button = top_flow[element_define.toolbar_button] if button then + -- Style the button + Gui.left_toolbar_button_style(button, false) -- Get the button define from the reverse lookup on the element local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed @@ -206,6 +246,7 @@ Gui.toggle_top_flow(game.player,example_flow_with_button,true) ]] function Gui.toggle_left_element(player,element_define,state) local left_flow = Gui.get_left_flow(player) + local top_flow = Gui.get_top_flow(player) -- Set the visible state local element = left_flow[element_define.name] @@ -213,5 +254,14 @@ function Gui.toggle_left_element(player,element_define,state) element.visible = state Gui.update_left_flow(player) + -- Check if the the element has a button attached + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Style the button + Gui.left_toolbar_button_style(button, state) + end + end return state end \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index b35eb2b0..f4d5de9f 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -20,6 +20,10 @@ Gui.top_elements = {} -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style +--- The style that should be used for buttons on the top flow where the flow it opens is visible +-- @field Gui.top_flow_button_visible_style +Gui.top_flow_button_visible_style = 'menu_button_continue' + --[[-- Gets the flow which contains the elements for the top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for From c2c535848d9170651a79eb8a92dffe4ffdc0b5cd Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 17 Mar 2020 22:36:52 +0000 Subject: [PATCH 19/21] Cleaned core gui files --- expcore/gui/core_defines.lua | 8 +- expcore/gui/defines.lua | 82 +++++------ expcore/gui/helper_functions.lua | 18 +-- expcore/gui/left_flow.lua | 58 ++++---- expcore/gui/prototype.lua | 228 +++++++++++++++++++------------ expcore/gui/top_flow.lua | 37 ++--- modules/gui/player-list.lua | 2 +- modules/gui/rocket-info.lua | 4 +- modules/gui/science-info.lua | 2 +- modules/gui/task-list.lua | 2 +- modules/gui/warp-list.lua | 2 +- 11 files changed, 250 insertions(+), 193 deletions(-) diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua index 5c26bea7..8ae38fbe 100644 --- a/expcore/gui/core_defines.lua +++ b/expcore/gui/core_defines.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Gui defines that are used internally by the gui system @module Gui ]] @@ -9,7 +9,7 @@ local Event = require 'utils.event' --- @dep utils.event --- Core Defines. -- @section coreDefines ---- Button which toggles the top flow elements, shows inside top flow +--- Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible -- @element hide_top_flow local hide_top_flow = Gui.element{ @@ -28,7 +28,7 @@ Gui.element{ end) Gui.core_defines.hide_top_flow = hide_top_flow ---- Button which toggles the top flow elements, shows inside left flow +--- Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden -- @element show_top_flow local show_top_flow = Gui.element{ @@ -47,7 +47,7 @@ Gui.element{ end) Gui.core_defines.show_top_flow = show_top_flow ---- Button which hides the elements in the left flow +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible -- @element hide_left_flow local hide_left_flow = Gui.element{ diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua index db52d8ca..d062078c 100644 --- a/expcore/gui/defines.lua +++ b/expcore/gui/defines.lua @@ -1,16 +1,19 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Common defines that are used by other modules, non of these are used internally @module Gui ]] local Gui = require 'expcore.gui.prototype' ---[[-- Draw a flow that has custom element alignments, default is right align +--- Defines. +-- @section defines + +--[[-- Draw a flow used to align its child elements, default is right align @element Gui.alignment -@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam LuaGuiElement parent the parent element to which the alignment will be added +@tparam[opt='alignment'] string name the name of the alignment flow which is added @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow @tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow -@tparam[opt='alignment'] string name the name of the alignment flow @treturn LuaGuiElement the alignment flow that was created @usage-- Adding a right align flow @@ -21,13 +24,13 @@ local alignment = Gui.alignment(element,'example_center_top_alignment','center', ]] Gui.alignment = -Gui.element(function(_,parent,_,_,name) +Gui.element(function(_,parent,name,_,_) return parent.add{ name = name or 'alignment', type = 'flow', } end) -:style(function(style,_,horizontal_align,vertical_align,_) +:style(function(style,_,_,horizontal_align,vertical_align) style.padding = {1,2} style.vertical_align = vertical_align or 'center' style.horizontal_align = horizontal_align or 'right' @@ -37,18 +40,18 @@ end) --[[-- Draw a scroll pane that has a table inside of it @element Gui.scroll_table -@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam LuaGuiElement parent the parent element to which the scroll table will be added @tparam number height the maximum height for the scroll pane @tparam number column_count the number of columns that the table will have -@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called "table" @treturn LuaGuiElement the table that was created @usage-- Adding a scroll table with max height of 200 and column count of 3 -local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) +local scroll_table = Gui.scroll_table(element,200,3) ]] Gui.scroll_table = -Gui.element(function(_,parent,_,column_count,name) +Gui.element(function(_,parent,height,column_count,name) -- Draw the scroll local scroll_pane = parent.add{ @@ -60,6 +63,12 @@ Gui.element(function(_,parent,_,column_count,name) style = 'scroll_pane_under_subheader' } + -- Set the style of the scroll pane + local scroll_style = scroll_pane.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + -- Draw the table local scroll_table = scroll_pane.add{ @@ -71,35 +80,27 @@ Gui.element(function(_,parent,_,column_count,name) -- Return the scroll table return scroll_table end) -:style(function(style,element,height,_,_) - -- Change the style of the scroll - local scroll_style = element.parent.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true +:style{ + padding = 0, + cell_padding = 0, + vertical_align = 'center', + horizontally_stretchable = true +} - -- Change the style of the table - style.padding = 0 - style.cell_padding = 0 - style.vertical_align = 'center' - style.horizontally_stretchable = true -end) - ---[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +--[[-- Used to add a frame with the header style, has the option for a right alignment flow for buttons @element Gui.header -@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam LuaGuiElement parent the parent element to which the header will be added @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the header +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called "alignment" @treturn LuaGuiElement either the header or the header alignment if add_alignment is true @usage-- Adding a custom header with a label -local header_alignment = Gui.header( +local header = Gui.header( element, 'Example Caption', - 'Example Tooltip', - true + 'Example Tooltip' ) ]] @@ -134,21 +135,20 @@ Gui.element(function(_,parent,caption,tooltip,add_alignment,name) return add_alignment and Gui.alignment(header) or header end) ---[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the footer will be added to +--[[-- Used to add a frame with the footer style, has the option for a right alignment flow for buttons +@element Gui.footer +@tparam LuaGuiElement parent the parent element to which the footer will be added @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the footer +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called "alignment" @treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true @usage-- Adding a custom footer with a label -local header_alignment = Gui.footer( +local footer = Gui.footer( element, 'Example Caption', - 'Example Tooltip', - true + 'Example Tooltip' ) ]] @@ -183,10 +183,10 @@ Gui.element(function(_,parent,caption,tooltip,add_alignment,name) return add_alignment and Gui.alignment(footer) or footer end) ---[[-- Used for left frame to add a nice boarder to them and contain them +--[[-- Used for left frames to give them a nice boarder @element Gui.container -@tparam LuaGuiElement parent the parent element that the container will be added to -@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam LuaGuiElement parent the parent element to which the container will be added +@tparam string name the name that you want to give to the outer frame, often just event_trigger @tparam number width the minimal width that the frame will have @usage-- Adding a container as a base diff --git a/expcore/gui/helper_functions.lua b/expcore/gui/helper_functions.lua index 22106718..c303fb15 100644 --- a/expcore/gui/helper_functions.lua +++ b/expcore/gui/helper_functions.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Functions used to help with the use of guis @module Gui ]] @@ -9,7 +9,7 @@ local Gui = require 'expcore.gui.prototype' -- @section helperFunctions --[[-- Get the player that owns a gui element -@tparam LuaGuiElement element the element that you want to get the owner of +@tparam LuaGuiElement element the element to get the owner of @treturn LuaPlayer the player that owns this element @usage-- Geting the owner of an element @@ -22,8 +22,8 @@ function Gui.get_player_from_element(element) end --[[-- Will toggle the enabled state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set +@tparam LuaGuiElement element the element to toggle/set the enabled state of +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new enabled state that the element has @usage-- Toggling the the enabled state @@ -38,8 +38,8 @@ function Gui.toggle_enabled_state(element,state) end --[[-- Will toggle the visible state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set +@tparam LuaGuiElement element the element to toggle/set the visible state of +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new visible state that the element has @usage-- Toggling the the visible state @@ -53,11 +53,11 @@ function Gui.toggle_visible_state(element,state) return state end ---[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +--[[-- Destory a gui element without causing any errors, often because the element was already removed @tparam LuaGuiElement element the element that you want to remove @treturn boolean true if the element was valid and has been removed -@usage-- Likely use case for element not existing +@usage-- Remove a child element if it exists Gui.destroy_if_valid(element[child_name]) ]] @@ -67,7 +67,7 @@ function Gui.destroy_if_valid(element) return true end ---[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +--[[-- Returns a table to be used as the style for a sprite buttons, produces a sqaure button @tparam number size the size that you want the button to be @tparam[opt=-2] number padding the padding that you want on the sprite @tparam[opt] table style any extra style settings that you want to have diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 53c37394..cbe83bfa 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -11,23 +11,26 @@ local hide_left_flow = Gui.core_defines.hide_left_flow.name --- Left Flow. -- @section leftFlow ---- Contains the uids of the elements that will show on the left flow and the open on join function +-- Triggered when a user changed the visibility of a left flow element by clicking a button +Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' + +--- Contains the uids of the elements that will shown on the left flow and their join functions -- @table left_elements Gui.left_elements = {} ---[[-- Gets the flow which contains the elements for the left flow +--[[-- Gets the flow refered to as the left flow, each player has one left flow @function Gui.get_left_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for +@tparam LuaPlayer player the player that you want to get the left flow for @treturn LuaGuiElement the left element flow -@usage-- Geting your left element flow +@usage-- Geting your left flow local left_flow = Gui.get_left_flow(game.player) ]] Gui.get_left_flow = mod_gui.get_frame_flow ---[[-- Adds an element to be drawn to the left flow when a player joins -@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +--[[-- Sets an element define to be drawn to the left flow when a player joins, includes optional check +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element should be visible @treturn table the new element define that is used to register events to this element @usage-- Adding the example button @@ -39,7 +42,7 @@ function Gui._prototype_element:add_to_left_flow(open_on_join) return self end ---[[-- Styles the top flow button depending on the state given +--[[-- Styles a top flow button depending on the state given @tparam LuaGuiElement the button element to style @tparam boolean state The state the button is in @@ -61,14 +64,15 @@ function Gui.left_toolbar_button_style(button, state) button.style.padding = -2 end ---[[-- Button which can be used to toggle a left element, placed on the top flow +--[[-- Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow @tparam string sprite the sprite that you want to use on the button @tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have -@tparam table element_define the element define that you want to be toggled on the left flow +@tparam table element_define the element define that you want to have toggled by this button, define must exist on the left flow @tparam[opt] function authenticator used to decide if the button should be visible to a player @usage-- Add a button to toggle a left element -local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) +local toolbar_button = +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', example_flow_with_button, function(player) return player.admin end) @@ -108,7 +112,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) return button end ---[[-- Draw all the left elements onto the left flow, internal use only +--[[-- Draw all the left elements onto the left flow, internal use only with on join @tparam LuaPlayer player the player that you want to draw the elements for @usage Draw all the left elements @@ -156,11 +160,11 @@ function Gui.draw_left_flow(player) hide_button.visible = show_hide_button end ---[[-- Update the visible state of the hide left button, also draw left elements if not present +--[[-- Update the visible state of the hide button, can be used to check if any frames are visible @tparam LuaPlayer player the player to update the left flow for @treturn boolean true if any left element is visible -@usage Check if any left elements are visible +@usage-- Check if any left elements are visible local visible = Gui.update_left_flow(player) ]] @@ -185,6 +189,7 @@ Gui.hide_left_flow(game.player) ]] function Gui.hide_left_flow(player) + local top_flow = Gui.get_top_flow(player) local left_flow = Gui.get_left_flow(player) local hide_button = left_flow.gui_core_buttons[hide_left_flow] @@ -193,11 +198,8 @@ function Gui.hide_left_flow(player) for name,_ in pairs(Gui.left_elements) do left_flow[name].visible = false - -- Get the assosiated element define + -- Check if the the element has a toobar button attached local element_define = Gui.defines[name] - local top_flow = Gui.get_top_flow(player) - - -- Check if the the element has a button attached if element_define.toolbar_button then -- Check if the topflow contains the button local button = top_flow[element_define.toolbar_button] @@ -217,13 +219,13 @@ function Gui.hide_left_flow(player) end end ---[[-- Get the element define that is in the left flow -@tparam LuaPlayer player the player that you want tog et the element for -@tparam table element_define the element that you want to get for the player -@treturn LuaGuiElement the gui element linked to this define in the left flow +--[[-- Get the element define that is in the left flow, use in events without an element refrence +@tparam LuaPlayer player the player that you want to get the element for +@tparam table element_define the element that you want to get +@treturn LuaGuiElement the gui element linked to this define for this player @usage-- Get your left element -local frame = Gui.get_left_element(game.player,example_flow_with_button) +local frame = Gui.get_left_element(game.player, example_flow_with_button) ]] function Gui.get_left_element(player,element_define) @@ -231,17 +233,17 @@ function Gui.get_left_element(player,element_define) return left_flow[element_define.name] end ---[[-- Toggles the visible state of a left element for a player +--[[-- Toggles the visible state of a left element for a given player, can be used to set the visible state @tparam LuaPlayer player the player that you want to toggle the element for -@tparam table element_define the element that you want to toggle for the player -@tparam[opt] boolean state if given then the state will be set to this state +@tparam table element_define the element that you want to toggle +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new visible state of the element @usage-- Toggle your example button -Gui.toggle_top_flow(game.player,example_flow_with_button) +Gui.toggle_top_flow(game.player, example_flow_with_button) -@usage-- Open your example button -Gui.toggle_top_flow(game.player,example_flow_with_button,true) +@usage-- Show your example button +Gui.toggle_top_flow(game.player, example_flow_with_button, true) ]] function Gui.toggle_left_element(player,element_define,state) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index b307da02..3c648c31 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -1,95 +1,148 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Used to simplify gui creation using factory functions called element defines @core Gui @alias Gui -@usage-- Defining a button that prints the player's name +@usage-- To draw your element you only need to call the factory function +-- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element +local example_button_element = example_button(parent_element) + +@usage-- Making a factory function for a button with the caption "Example Button" +-- This method has all the same features as LuaGuiElement.add local example_button = Gui.element{ type = 'button', caption = 'Example Button' } -:on_click(function(player,element,event) - player.print(player.name) -end) -@usage-- Defining a button with a custom style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button using a custom function +@usage-- Making a factory function for a button which is contained within a flow +-- This method is for when you still want to register event handlers but cant use the table method local example_flow_with_button = -Gui.element(function(event_trigger,parent) - -- Add the flow the button is in +Gui.element(function(event_trigger,parent,...) + -- ... shows that all other arguments from the factory call are passed to this function + -- Here we are adding a flow which we will then later add a button to local flow = - parent.add{ + parent.add{ -- paraent is the element which is passed to the factory function name = 'example_flow', type = 'flow' } - -- Get the players name - local player = game.players[parent.player_index] - local player_name = player.name - - -- Add the button + -- Now we add the button to the flow that we created earlier local element = flow.add{ - name = event_trigger, + name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers type = 'button', - caption = 'Example Button: '..player_name + caption = 'Example Button' } - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100] - style.font_color = player.color - - -- Return the element + -- You must return a new element, this is so styles can be applied and returned to the caller + -- You may return any of your elements that you added, consider the context in which it will be used for which should be returned return element end) -:on_click(function(player,element,event) - player.print(player.name) + +@usage-- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style{ + height = 25, -- same as element.style.height = 25 + width = 100 -- same as element.style.width = 25 +} + +@usage-- Styles can also have a custom function when the style is dynamic and depends on other factors +-- Use this method if your style is dynamic and depends on other factors +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style(function(style,element,...) + -- style is the current style object for the elemenent + -- element is the element that is being changed + -- ... shows that all other arguments from the factory call are passed to this function + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color end) -@usage-- Drawing an element -local exmple_button_element = example_button(parent) -local example_flow_with_button = example_flow_with_button(parent) +@usage-- You are able to register event handlers to your elements, these can be factorio events or custom ones +-- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(player,element,event) + -- player is the player who interacted with the element to cause the event + -- element is a refrence to the element which caused the event + -- event is a raw refrence to the event data if player and element are not enough + player.print('Clicked: '..element.name) +end) + +@usage-- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element) +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) + +@usage-- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align) +-- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above +Gui.alignment = +Gui.element(function(_,parent,name,_,_) + return parent.add{ + name = name or 'alignment', + type = 'flow', + } +end) +:style(function(style,_,_,horizontal_align,vertical_align) + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' +end) ]] local Event = require 'utils.event' --- @dep utils.event local Gui = { - --- The current highest uid that is being used, will not increase during runtime + --- The current highest uid that is being used by a define, will not increase during runtime -- @field uid uid = 0, - --- An index of the element deinfes which are used by the core gui system - -- @table core_defines - core_defines = {}, - --- Table of all the elements which have been registed with the draw function and event handlers - -- @table defines - defines = {}, - --- Table of all custom events that are used by element defines, used to avoid conflicts + --- String indexed table used to avoid conflict with custom event names, similar to how defines.events works -- @table events events = {}, - --- An index used for debuging to find the file where different elements where registered + --- Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime + -- @table defines + defines = {}, + --- An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence + -- @table core_defines + core_defines = {}, + --- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging -- @table file_paths file_paths = {}, - --- An index used for debuging to show more data on element defines + --- Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them -- @table debug_info debug_info = {}, - --- The element prototype which is returned from Gui.element + --- The prototype used to store the functions of an element define -- @table _prototype_element _prototype_element = {}, --- The prototype metatable applied to new element defines @@ -108,28 +161,33 @@ Gui._mt_element.__index = Gui._prototype_element --- Element Define. -- @section elementDefine ---[[-- Base function used to define new elements, can be used with a table or with a function -@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element +--[[-- Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function +@tparam ?table|function element_define the define information for the gui element, same data as LuaGuiElement.add, or a custom function may be used +@treturn table the new element define, this can be considered a factory for the element which can be called to draw the element to any other element -@usage-- Defining an element with a table +@usage-- Using element defines like LuaGuiElement.add +-- This returns a factory function to draw a button with the caption "Example Button" local example_button = Gui.element{ type = 'button', caption = 'Example Button' } -@usage-- Defining an element with a function +@usage-- Using element defines with a custom factory function +-- This method can be used if you still want to be able register event handlers but it is too complex to be compatible with LuaGuiElement.add local example_flow_with_button = Gui.element(function(event_trigger,parent,...) - -- Add the flow the button is in + -- ... shows that all other arguments from the factory call are passed to this function + -- parent is the element which was passed to the factory function where you should add your new element + -- here we are adding a flow which we will then later add a button to local flow = parent.add{ name = 'example_flow', type = 'flow' } - -- Add the button + -- event_trigger should be the name of any elements you want to trigger your event handlers, such as on_click or on_state_changed + -- now we add the button to the flow that we created earlier local element = flow.add{ name = event_trigger, @@ -137,12 +195,8 @@ Gui.element(function(event_trigger,parent,...) caption = 'Example Button' } - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100 - - -- Return the element + -- you must return your new element, this is so styles can be applied and returned to the caller + -- you may return any of your elements that you add, consider the context in which it will be used for what should be returned return element end) @@ -179,28 +233,34 @@ function Gui.element(element_define) return element end ---[[-- Extension of Gui.element when using the table method, values applied after the element is drawn -@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element +--[[-- Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function +@tparam ?table|function style_define style table where each key and value pair is treated like LuaGuiElement.style[key] = value, a custom function can be used +@treturn table the element define is returned to allow for event handlers to be registered -@usage-- Setting the height and width of the example button +@usage-- Using the table method of setting the style local example_button = Gui.element{ type = 'button', - caption = 'Example Button' + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here } :style{ - height = 25, - width = 100 + height = 25, -- same as element.style.height = 25 + width = 100 -- same as element.style.width = 25 } -@usage-- Using a function to set the style +@usage-- Using the function method to set the style +-- Use this method if your style is dynamic and depends on other factors local example_button = Gui.element{ type = 'button', - caption = 'Example Button' + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here } :style(function(style,element,...) + -- style is the current style object for the elemenent + -- element is the element that is being changed + -- ... shows that all other arguments from the factory call are passed to this function local player = game.players[element.player_index] style.height = 25 style.width = 100 @@ -226,12 +286,12 @@ function Gui._prototype_element:style(style_define) return self end ---[[-- Set the handler to be called on a custom event, only one handler can be used -@tparam string event_name the name of the event you want to handler to be called on +--[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element +@tparam string event_name the name of the event you want to handler to be called on, often from Gui.events @tparam function handler the handler that you want to be called when the event is raised @treturn table the element define so more handleres can be registered -@usage Print the player name when my_custom_event is raised +@usage-- Register a handler to "my_custom_event" for this element element_deinfe:on_custom_event('my_custom_event', function(event) event.player.print(player.name) end) @@ -244,8 +304,8 @@ function Gui._prototype_element:on_custom_event(event_name,handler) return self end ---[[-- Raise the handler which is attached to any event; external use should be limited to custom events -@tparam table event the event table bassed to the handler, must include fields: name, element +--[[-- Raise the handler which is attached to an event; external use should be limited to custom events +@tparam table event the event table passed to the handler, must contain fields: name, element @treturn table the element define so more events can be raised @usage Raising a custom event @@ -283,7 +343,7 @@ function Gui._prototype_element:raise_custom_event(event) return self end --- This function is used to register a link between element define events and the events in the factorio api +-- This function is used to link element define events and the events from the factorio api local function event_handler_factory(event_name) Event.add(event_name, function(event) local element = event.element @@ -350,11 +410,5 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) ---- Custom element events. --- @section customEvents - --- Triggered when a user changed the visibility of a left flow element by clicking a button -Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' - -- Module return return Gui \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index f4d5de9f..d9291d0f 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Controls the elements on the top flow @module Gui ]] @@ -12,7 +12,7 @@ local show_top_flow = Gui.core_defines.show_top_flow.name --- Top Flow. -- @section topFlow ---- Contains the uids of the elements that will show on the top flow and the auth function +--- Contains the uids of the elements that will shown on the top flow and their auth functions -- @table top_elements Gui.top_elements = {} @@ -20,29 +20,30 @@ Gui.top_elements = {} -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style ---- The style that should be used for buttons on the top flow where the flow it opens is visible +--- The style that should be used for buttons on the top flow when their flow is visible -- @field Gui.top_flow_button_visible_style Gui.top_flow_button_visible_style = 'menu_button_continue' ---[[-- Gets the flow which contains the elements for the top flow +--[[-- Gets the flow refered to as the top flow, each player has one top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @treturn LuaGuiElement the top element flow -@usage-- Geting your top element flow +@usage-- Geting your top flow local top_flow = Gui.get_top_flow(game.player) ]] Gui.get_top_flow = mod_gui.get_button_flow ---[[-- Adds an element to be drawn to the top flow when a player joins -@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible -@treturn table the new element define that is used to register events to this element +--[[-- Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator +@tparam[opt] function authenticator called during toggle or update to decide weather the element should be visible +@treturn table the new element define to allow event handlers to be registered -@usage-- Adding the example button +@usage-- Adding an element to the top flow on join example_button:add_to_top_flow(function(player) - -- example button will only show when game time is less than 1 minute - return player.online_time < 3600 + -- example button will only be shown if the player is an admin + -- note button will not update its state when player.admin is changed Gui.update_top_flow must be called for this + return player.admin end) ]] @@ -51,10 +52,10 @@ function Gui._prototype_element:add_to_top_flow(authenticator) return self end ---[[-- Updates the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to update the flow for +--[[-- Updates the visible state of all the elements on the players top flow, uses authenticator +@tparam LuaPlayer player the player that you want to update the top flow for -@usage-- Update your flow +@usage-- Update your top flow Gui.update_top_flow(game.player) ]] @@ -64,7 +65,7 @@ function Gui.update_top_flow(player) local is_visible = hide_button.visible -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do + for name, authenticator in pairs(Gui.top_elements) do -- Ensure the element exists local element = top_flow[name] if not element then @@ -76,9 +77,9 @@ function Gui.update_top_flow(player) end end ---[[-- Toggles the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to toggle the flow for -@tparam[opt] boolean state if given then the state will be set to this state +--[[-- Toggles the visible state of all the elements on a players top flow, effects all elements +@tparam LuaPlayer player the player that you want to toggle the top flow for +@tparam[opt] boolean state if given then the state will be set to this @treturn boolean the new visible state of the top flow @usage-- Toggle your flow diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 13bb1c7c..8cf23eef 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -105,7 +105,7 @@ Gui.element(function(event_trigger,parent,player_data) player_name.style.font_color = player_data.chat_color -- Add the time played label - local alignment = Gui.alignment(parent,nil,nil,'player-time-'..player_data.index) + local alignment = Gui.alignment(parent,'player-time-'..player_data.index) local time_label = alignment.add{ name = 'label', type = 'label', diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index b2490ed3..cc904c87 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -55,7 +55,7 @@ Gui.element(function(_,parent,label_data) name_label.style.padding = {0,2} --- Right aligned label to store the data - local alignment = Gui.alignment(parent,nil,nil,data_fullname) + local alignment = Gui.alignment(parent,data_fullname) local element = alignment.add{ type = 'label', @@ -302,7 +302,7 @@ Gui.element(function(_,parent,silo_data) silo_cords(parent,silo_data) -- Add a progress label - local alignment = Gui.alignment(parent,nil,nil,silo_name) + local alignment = Gui.alignment(parent,silo_name) local element = alignment.add{ type = 'label', diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 0fd224fb..36d4d947 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -23,7 +23,7 @@ Gui.element(function(_,parent,production_label_data) local color = production_label_data.color -- Add an alignment for the number - local alignment = Gui.alignment(parent,nil,nil,name) + local alignment = Gui.alignment(parent,name) -- Add the main value label local element = diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index b1ef31e4..372555cf 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -118,7 +118,7 @@ Gui.element(function(_,parent,task_id) task_flow.style.padding = 0 -- Add the two edit buttons outside the task flow - local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) + local edit_flow = Gui.alignment(parent,'edit-'..task_id) edit_task(edit_flow) discard_task(edit_flow) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 595a3ba2..1bf8b95b 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -137,7 +137,7 @@ Gui.element(function(_,parent,warp_id) warp_flow.style.padding = 0 -- Add the two edit buttons outside the warp flow - local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..warp_id) + local edit_flow = Gui.alignment(parent,'edit-'..warp_id) edit_warp(edit_flow) discard_warp(edit_flow) From 60467a71909a808b1b0690c0acc8f73281852cbe Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 18 Mar 2020 21:19:54 +0000 Subject: [PATCH 20/21] Cleaned gui modules --- expcore/gui/left_flow.lua | 1 + modules/gui/player-list.lua | 8 +- modules/gui/rocket-info.lua | 293 ++++++++++++++++++------------------ modules/gui/task-list.lua | 2 +- modules/gui/warp-list.lua | 3 +- 5 files changed, 155 insertions(+), 152 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index cbe83bfa..f41d8419 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -178,6 +178,7 @@ function Gui.update_left_flow(player) return true end end + hide_button.visible = false return false end diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 8cf23eef..0c460eb7 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -1,5 +1,5 @@ --[[-- Gui Module - Player List - - Adds a player list to show names and play time; also includes action buttons which can apply to players + - Adds a player list to show names and play time; also includes action buttons which can preform actions to players @gui Player-List @alias player_list ]] @@ -60,7 +60,7 @@ Gui.element{ style = 'shortcut_bar_button_red' } :style(Gui.sprite_style(30,-1,{ top_margin = -1, right_margin = -1 })) -:on_click(function(player,element) +:on_click(function(player,_) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) end) @@ -170,7 +170,7 @@ Gui.element(function(_,parent) end) --- Updates the visible state of the action bar buttons -local function update_action_bar_buttons(element) +local function update_action_bar(element) local player = Gui.get_player_from_element(element) local selected_player_name = Store.get(selected_player_store,player) @@ -389,7 +389,7 @@ Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table - update_action_bar_buttons(frame.container.action_bar) + update_action_bar(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do local element = scroll_table[next_player.name][open_action_bar.name] local style = 'frame_button' diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index cc904c87..f2384a21 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -37,151 +37,6 @@ local function check_player_permissions(player,action) return true end ---- Data label which contains a name and a value label pair --- @element data_label -local data_label = -Gui.element(function(_,parent,label_data) - local data_name = label_data.name - local data_subname = label_data.subname - local data_fullname = data_subname and data_name..data_subname or data_name - - -- Add the name label - local name_label = parent.add{ - type = 'label', - name = data_fullname..'-label', - caption = {'rocket-info.data-caption-'..data_name,data_subname}, - tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} - } - name_label.style.padding = {0,2} - - --- Right aligned label to store the data - local alignment = Gui.alignment(parent,data_fullname) - local element = - alignment.add{ - type = 'label', - name = 'label', - caption = label_data.value, - tooltip = label_data.tooltip - } - element.style.padding = {0,2} - - return element -end) - -local function update_data_labels(parent,data_label_data) - for _, label_data in ipairs(data_label_data) do - local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name - if not parent[data_name] then - data_label(parent,label_data) - else - local data_label_element = parent[data_name].label - data_label_element.tooltip = label_data.tooltip - data_label_element.caption = label_data.value - end - end -end - ---- Gets the label data for all the different stats -local function get_stats_data(force_name) - local force_rockets = Rockets.get_rocket_count(force_name) - local stats = Rockets.get_stats(force_name) - local stats_data = {} - - -- Format the first launch data - if config.stats.show_first_rocket then - local value = stats.first_launch or 0 - table.insert(stats_data,{ - name = 'first-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format the last launch data - if config.stats.show_last_rocket then - local value = stats.last_launch or 0 - table.insert(stats_data,{ - name = 'last-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format fastest launch data - if config.stats.show_fastest_rocket then - local value = stats.fastest_launch or 0 - table.insert(stats_data,{ - name = 'fastest-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format total rocket data - if config.stats.show_total_rockets then - local total_rockets = Rockets.get_game_rocket_count() - total_rockets = total_rockets == 0 and 1 or total_rockets - local percentage = math.round(force_rockets/total_rockets,3)*100 - table.insert(stats_data,{ - name = 'total-rockets', - value = force_rockets, - tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} - }) - end - - -- Format game avg data - if config.stats.show_game_avg then - local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 - table.insert(stats_data,{ - name = 'avg-launch', - value = time_formats.caption(avg), - tooltip = time_formats.tooltip(avg) - }) - end - - -- Format rolling avg data - for _,avg_over in pairs(config.stats.rolling_avg) do - local avg = Rockets.get_rolling_average(force_name,avg_over) - table.insert(stats_data,{ - name = 'avg-launch-n', - subname = avg_over, - value = time_formats.caption(avg), - tooltip = time_formats.tooltip(avg) - }) - end - - -- Return formated data - return stats_data -end - ---- Gets the label data for the milestones -local function get_milestone_data(force_name) - local force_rockets = Rockets.get_rocket_count(force_name) - local milestone_data = {} - - for _,milestone in ipairs(config.milestones) do - if milestone <= force_rockets then - local time = Rockets.get_rocket_time(force_name,milestone) - table.insert(milestone_data,{ - name = 'milestone-n', - subname = milestone, - value = time_formats.caption_hours(time), - tooltip = time_formats.tooltip_hours(time) - }) - else - table.insert(milestone_data,{ - name = 'milestone-n', - subname = milestone, - value = {'rocket-info.data-caption-milestone-next'}, - tooltip = {'rocket-info.data-tooltip-milestone-next'} - }) - break - end - end - - return milestone_data -end - --- Button to toggle the auto launch on a rocket silo -- @elemeent toggle_launch local toggle_launch = @@ -191,7 +46,7 @@ Gui.element{ tooltip = {'rocket-info.toggle-rocket-tooltip'} } :style(Gui.sprite_style(16)) -:on_click(function(player,element,_) +:on_click(function(_,element,_) local rocket_silo_name = element.parent.name:sub(8) local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) if rocket_silo.auto_launch then @@ -315,6 +170,51 @@ Gui.element(function(_,parent,silo_data) return element end) +--- Data label which contains a name and a value label pair +-- @element data_label +local data_label = +Gui.element(function(_,parent,label_data) + local data_name = label_data.name + local data_subname = label_data.subname + local data_fullname = data_subname and data_name..data_subname or data_name + + -- Add the name label + local name_label = parent.add{ + type = 'label', + name = data_fullname..'-label', + caption = {'rocket-info.data-caption-'..data_name,data_subname}, + tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} + } + name_label.style.padding = {0,2} + + --- Right aligned label to store the data + local alignment = Gui.alignment(parent,data_fullname) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = label_data.value, + tooltip = label_data.tooltip + } + element.style.padding = {0,2} + + return element +end) + +-- Used to update the captions and tooltips on the data labels +local function update_data_labels(parent,data_label_data) + for _, label_data in ipairs(data_label_data) do + local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name + if not parent[data_name] then + data_label(parent,label_data) + else + local data_label_element = parent[data_name].label + data_label_element.tooltip = label_data.tooltip + data_label_element.caption = label_data.value + end + end +end + local function get_progress_data(force_name) local force_silos = Rockets.get_silos(force_name) local progress_data = {} @@ -417,6 +317,107 @@ local function update_build_progress(parent,progress_data) if show_message then parent.no_silos.visible = true end end +--- Gets the label data for all the different stats +local function get_stats_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local stats = Rockets.get_stats(force_name) + local stats_data = {} + + -- Format the first launch data + if config.stats.show_first_rocket then + local value = stats.first_launch or 0 + table.insert(stats_data,{ + name = 'first-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format the last launch data + if config.stats.show_last_rocket then + local value = stats.last_launch or 0 + table.insert(stats_data,{ + name = 'last-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format fastest launch data + if config.stats.show_fastest_rocket then + local value = stats.fastest_launch or 0 + table.insert(stats_data,{ + name = 'fastest-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format total rocket data + if config.stats.show_total_rockets then + local total_rockets = Rockets.get_game_rocket_count() + total_rockets = total_rockets == 0 and 1 or total_rockets + local percentage = math.round(force_rockets/total_rockets,3)*100 + table.insert(stats_data,{ + name = 'total-rockets', + value = force_rockets, + tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} + }) + end + + -- Format game avg data + if config.stats.show_game_avg then + local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 + table.insert(stats_data,{ + name = 'avg-launch', + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Format rolling avg data + for _,avg_over in pairs(config.stats.rolling_avg) do + local avg = Rockets.get_rolling_average(force_name,avg_over) + table.insert(stats_data,{ + name = 'avg-launch-n', + subname = avg_over, + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Return formated data + return stats_data +end + +--- Gets the label data for the milestones +local function get_milestone_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local milestone_data = {} + + for _,milestone in ipairs(config.milestones) do + if milestone <= force_rockets then + local time = Rockets.get_rocket_time(force_name,milestone) + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = time_formats.caption_hours(time), + tooltip = time_formats.tooltip_hours(time) + }) + else + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = {'rocket-info.data-caption-milestone-next'}, + tooltip = {'rocket-info.data-tooltip-milestone-next'} + }) + break + end + end + + return milestone_data +end + -- Button to toggle a section dropdown -- @element toggle_section local toggle_section = diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 372555cf..b8b260b0 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -1,5 +1,5 @@ --[[-- Gui Module - Task List - - Adds a task list to the game which players can add remove and edit items on + - Adds a task list to the game which players can add, remove and edit items on @gui Task-List @alias task_list ]] diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 1bf8b95b..de92d42e 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -79,7 +79,7 @@ Gui.element{ style = 'tool_button' } :style(Styles.sprite20) -:on_click(function(player,element) +:on_click(function(player,_) -- Add the new warp local force_name = player.force.name local surface = player.surface @@ -263,6 +263,7 @@ Gui.element(function(event_trigger,parent,warp) end) :style(Styles.sprite32) :on_click(function(player,element,_) + if element.type == 'choose-elem-button' then return end local warp_id = element.parent.caption Warps.teleport_player(warp_id,player) From a2dec8f16ca50f4f874123a7d491f917369c59eb Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 18 Mar 2020 21:37:29 +0000 Subject: [PATCH 21/21] Removed unused config value --- config/roles.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/roles.lua b/config/roles.lua index 8bc10b92..603191b6 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -217,9 +217,7 @@ local default = Roles.new_role('Guest','') 'gui/rocket-info', 'gui/science-info', 'gui/task-list', - 'gui/warp-list', - 'gui/warp-list/apply-cooldown', - 'gui/warp-list/apply-proximity', + 'gui/warp-list' } --- Jail role