--[[-- 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 }