diff --git a/expcore/Gui/buttons.lua b/expcore/Gui/buttons.lua index d2462ae4..77015cde 100644 --- a/expcore/Gui/buttons.lua +++ b/expcore/Gui/buttons.lua @@ -5,16 +5,16 @@ local Gui = require './core' local Button = { config={}, clean_names={}, - _prototype=Gui._extend_prototype{ - on_click = Gui._new_event_adder('on_click'), - on_left_click = Gui._new_event_adder('on_left_click'), - on_right_click = Gui._new_event_adder('on_right_click'), + _prototype=Gui._prototype_factory{ + on_click = Gui._event_factory('on_click'), + on_left_click = Gui._event_factory('on_left_click'), + on_right_click = Gui._event_factory('on_right_click'), } } function Button.new_button(name) - local self = Gui._new_define(Button._prototype) + local self = Gui._define_factory(Button._prototype) self.draw_data.type = 'button' self.draw_data.style = mod_gui.button_style diff --git a/expcore/Gui/checkboxs.lua b/expcore/Gui/checkboxs.lua index 32e40454..61930283 100644 --- a/expcore/Gui/checkboxs.lua +++ b/expcore/Gui/checkboxs.lua @@ -3,9 +3,9 @@ local Store = require 'expcore.store' local Game = require 'utils.game' local function event_call(self,element,value) - if self.events.on_state_change then + if self.events.on_change then local player = Game.get_player_by_index(element.player_index) - self.events.on_state_change(player,element,value) + self.events.on_change(player,element,value) end end @@ -17,21 +17,21 @@ end local Checkbox = { option_sets={}, option_categorize={}, - _prototype_checkbox=Gui._extend_prototype{ - on_state_change = Gui._new_event_adder('on_state_change'), - add_store = Gui._new_store_adder(store_call), - add_sync_store = Gui._new_sync_store_adder(store_call) + _prototype_checkbox=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) }, - _prototype_radiobutton=Gui._extend_prototype{ - on_state_change = Gui._new_event_adder('on_state_change'), - add_store = Gui._new_store_adder(store_call), - add_sync_store = Gui._new_sync_store_adder(store_call) + _prototype_radiobutton=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) } } function Checkbox.new_checkbox(name) - local self = Gui._new_define(Checkbox._prototype_checkbox) + local self = Gui._define_factory(Checkbox._prototype_checkbox) self.draw_data.type = 'checkbox' self.draw_data.state = false @@ -161,4 +161,16 @@ function Checkbox.new_option_set(name,callback,categorize) return name end +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 + return Checkbox \ No newline at end of file diff --git a/expcore/Gui/core.lua b/expcore/Gui/core.lua index 5680ae26..ff35f5e2 100644 --- a/expcore/Gui/core.lua +++ b/expcore/Gui/core.lua @@ -12,14 +12,14 @@ Global.register(Gui.instances,function(tbl) Gui.instances = tbl end) -function Gui._extend_prototype(tbl) +function Gui._prototype_factory(tbl) for k,v in pairs(Gui._prototype) do if not tbl[k] then tbl[k] = v end end return tbl end -function Gui._new_event_adder(name) +function Gui._event_factory(name) return function(self,callback) if type(callback) ~= 'function' then return error('Event callback must be a function',2) @@ -30,7 +30,7 @@ function Gui._new_event_adder(name) end end -function Gui._new_store_adder(callback) +function Gui._store_factory(callback) return function(self,categorize) if self.store then return end @@ -57,7 +57,7 @@ function Gui._new_store_adder(callback) end end -function Gui._new_sync_store_adder(callback) +function Gui._sync_store_factory(callback) return function(self,location,categorize) if self.store then return end @@ -88,7 +88,7 @@ function Gui._new_sync_store_adder(callback) end end -function Gui._new_define(prototype) +function Gui._define_factory(prototype) local uid = Gui.uid_name() local define = setmetatable({ name=uid, @@ -113,9 +113,13 @@ end --- Sets an alias to the uid function Gui._prototype:debug_name(name) - self.debug_name = name - Gui.names[name] = self.name - Gui.names[self.name] = name + if name then + self.debug_name = name + Gui.names[name] = self.name + Gui.names[self.name] = name + else + return self.debug_name + end return self end diff --git a/expcore/Gui/dropdown.lua b/expcore/Gui/dropdown.lua index b0690192..38761584 100644 --- a/expcore/Gui/dropdown.lua +++ b/expcore/Gui/dropdown.lua @@ -4,8 +4,8 @@ local Game = require 'utils.game' local function event_call(define,element,value) local player = Game.get_player_by_index(element.player_index) - if define.events.on_selection then - define.events.on_selection(player,element,value) + if define.events.on_change then + define.events.on_change(player,element,value) end if define.option_callbacks and define.option_callbacks[value] then @@ -20,16 +20,16 @@ local function store_call(self,element,value) end local Dropdown = { - _prototype=Gui._extend_prototype{ - on_selection = Gui._new_event_adder('on_selection'), - add_store = Gui._new_store_adder(store_call), - add_sync_store = Gui._new_sync_store_adder(store_call) + _prototype=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) } } function Dropdown.new_dropdown(name) - local self = Gui._new_define(Dropdown._prototype) + local self = Gui._define_factory(Dropdown._prototype) self.draw_data.type = 'drop-down' if name then @@ -40,9 +40,11 @@ function Dropdown.new_dropdown(name) if self.dynamic_options then local player = Game.get_player_by_index(element.player_index) local dynamic_options = self.dynamic_options(player,element) + local items = element.items for _,v in pairs(dynamic_options) do - element.add_item(v) + table.insert(items,v) end + element.items = items end if self.store then diff --git a/expcore/Gui/elem-button.lua b/expcore/Gui/elem-button.lua new file mode 100644 index 00000000..e6ad8586 --- /dev/null +++ b/expcore/Gui/elem-button.lua @@ -0,0 +1,80 @@ +local Gui = require './core' +local Game = require 'utils.game' + +local function event_call(define,element,value) + local player = Game.get_player_by_index(element.player_index) + + if define.events.on_change then + define.events.on_change(player,element,value) + end + +end + +local function store_call(self,element,value) + element.elem_value = value + event_call(self,element,value) +end + +local ElemButton = { + _prototype=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) + } +} + +function ElemButton.new_elem_button(name) + + local self = Gui._define_factory(ElemButton._prototype) + self.draw_data.type = 'choose-elem-button' + + if name then + self:debug_name(name) + end + + self.post_draw = function(element) + local player = Game.get_player_by_index(element.player_index) + + if type(self.default) == 'function' then + element.elem_value = self.default(player,element) + end + + if self.store then + local category = self.categorize and self.categorize(element) or nil + local value = self:get_store(category) + 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 + local category = self.categorize and self.categorize(element) or value + self:set_store(category,value) + + else + event_call(self,element,value) + + end + + end) + + return self +end + +function ElemButton._prototype:set_type(type) + self.draw_data.elem_type = type + return self +end + +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/slider.lua b/expcore/Gui/slider.lua index 291c1511..3c37c6cc 100644 --- a/expcore/Gui/slider.lua +++ b/expcore/Gui/slider.lua @@ -11,7 +11,7 @@ local function get_labels(define,element) local categorize = define.categorize or not define.store and cat local category = categorize and categorize(element) or nil - local instances = Gui.get_labels({ + local instances = Gui.get_instances({ name=name, categorize=categorize },category) @@ -53,16 +53,16 @@ local function store_call(self,element,value) end local Slider = { - _prototype=Gui._extend_prototype{ - on_change = Gui._new_event_adder('on_change'), - add_store = Gui._new_store_adder(store_call), - add_sync_store = Gui._new_sync_store_adder(store_call) + _prototype=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) } } function Slider.new_slider(name) - local self = Gui._new_define(Slider._prototype) + local self = Gui._define_factory(Slider._prototype) self.draw_data.type = 'slider' if name then @@ -145,8 +145,8 @@ function Slider._prototype:draw_label(element) if not Gui.instances[name] then Gui.instances[name] = {} end - local instances = get_labels(self,element) - table.insert(instances,new_element) + local labels = get_labels(self,element) + table.insert(labels,new_element) return new_element end diff --git a/expcore/Gui/test.lua b/expcore/Gui/test.lua index 4b2bac18..dbce8463 100644 --- a/expcore/Gui/test.lua +++ b/expcore/Gui/test.lua @@ -1,8 +1,10 @@ +--- This file creates a teste gui that is used to test every input method +-- note that this does not cover every permutation only features in indepentance +-- for example store in most cases is just by player name, but other store methods are tested with checkbox local Gui = require 'expcore.gui' local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_colour','table_keys') local Colors = require 'resources.color_presets' local Game = require 'utils.game' -local clean_stack_trace = ext_require('modules.commands.interface','clean_stack_trace') local tests = {} @@ -11,6 +13,14 @@ local function categozie_by_player(element) return player.name end +--[[ + Toolbar Tests + > No display - Toolbar button with no display + > With caption - Toolbar button with a caption display + > With icons - Toolbar button with an icon + > Main test gui - Main test gui triggers all other tests +]] + Gui.new_toolbar_button('click-1') :set_post_authenticator(function(player,button_name) return global.click_one @@ -44,246 +54,507 @@ Gui.new_toolbar_button('gui-test-open') end) :on_click(function(player,_element,event) if player.gui.center.TestGui then player.gui.center.TestGui.destroy() return end - local frame = player.gui.center.add{type='frame',caption='Gui Test',name='TestGui'} - frame = frame.add{type='table',column_count=5} - for key,element in pairs(tests) do - local test_function = type(element) == 'function' and element or element.draw_to - local success,err = pcall(test_function,element,frame) - if success then - player.print('Drawing: '..key..format_chat_colour(' SUCCESS',Colors.green)) - else - player.print('Drawing: '..key..format_chat_colour(' FAIL',Colors.red)..' '..clean_stack_trace(err)) + + local frame = player.gui.center.add{ + type='frame', + caption='Gui Test', + name='TestGui' + } + + 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) -tests['Button no display'] = Gui.new_button('test button no display') +--[[ + 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,event) 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) -tests['Button caption'] = Gui.new_button('test button caption') +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,event) - player.print('Button caption') + player.print('Button with caption') end) -tests['Button icon'] = Gui.new_button('test button icon') +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,event) - player.print('Button icon') + player.print('Button with icons') end) -tests['Button auth'] = Gui.new_button('test button auth') +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,event) - player.print('Button auth') + player.print('Button with auth') end) -tests['Checkbox local'] = Gui.new_checkbox('test checkbox local') +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_state_change(function(player,element,state) +:on_change(function(player,element,state) player.print('Checkbox local: '..tostring(state)) end) -tests['Checkbox store game'] = Gui.new_checkbox('test checkbox store game') +local checkbox_game = +Gui.new_checkbox('test-checkbox-store-game') +:set_tooltip('Checkbox store game') :set_caption('Checkbox Store Game') :add_store() -:on_state_change(function(player,element,state) +:on_change(function(player,element,state) player.print('Checkbox store game: '..tostring(state)) end) -tests['Checkbox store player'] = Gui.new_checkbox('test checkbox store player') -:set_caption('Checkbox Store Player') -:add_store(categozie_by_player) -:on_state_change(function(player,element,state) - player.print('Checkbox store player: '..tostring(state)) -end) - -tests['Checkbox store force'] = Gui.new_checkbox('test checkbox store force') +local checkbox_force = +Gui.new_checkbox('test-checkbox-store-force') +:set_tooltip('Checkboc store force') :set_caption('Checkbox Store Force') :add_store(function(element) local player = Game.get_player_by_index(element.player_index) return player.force.name end) -:on_state_change(function(player,element,state) +:on_change(function(player,element,state) player.print('Checkbox store force: '..tostring(state)) end) -tests['Radiobutton local'] = Gui.new_radiobutton('test radiobutton local') +local checkbox_player = +Gui.new_checkbox('test-checkbox-store-player') +:set_tooltip('Checkbox store player') +:set_caption('Checkbox Store Player') +:add_store(categozie_by_player) +:on_change(function(player,element,state) + player.print('Checkbox store player: '..tostring(state)) +end) + +tests.Checkboxs = { + ['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_state_change(function(player,element,state) +:on_change(function(player,element,state) player.print('Radiobutton local: '..tostring(state)) end) -tests['Radiobutton store player'] = Gui.new_radiobutton('test radiobutton store player') -:set_caption('Radiobutton Store Player') +local radiobutton_player = +Gui.new_radiobutton('test-radiobutton-store') +:set_tooltip('Radiobutton store') +:set_caption('Radiobutton Store') :add_store(categozie_by_player) -:on_state_change(function(player,element,state) - player.print('Radiobutton store player: '..tostring(state)) +:on_change(function(player,element,state) + player.print('Radiobutton store: '..tostring(state)) end) -local test_option_set = Gui.new_radiobutton_option_set('gui.test.share',function(value,category) +local radiobutton_option_set = +Gui.new_radiobutton_option_set('gui.test.share',function(value,category) game.print('Radiobutton option set for: '..category..' is now: '..tostring(value)) end,categozie_by_player) -tests['Radiobutton option one'] = Gui.new_radiobutton('test radiobutton option one') +local radiobutton_option_one = +Gui.new_radiobutton('test-radiobutton-option-one') +:set_tooltip('Radiobutton option set') :set_caption('Radiobutton Option One') -:add_as_option(test_option_set,'One') -:on_state_change(function(player,element,state) +:add_as_option(radiobutton_option_set,'One') +:on_change(function(player,element,state) player.print('Radiobutton option one: '..tostring(state)) end) -tests['Radiobutton option two'] = Gui.new_radiobutton('test radiobutton option two') +local radiobutton_option_two = +Gui.new_radiobutton('test-radiobutton-option-two') +:set_tooltip('Radiobutton option set') :set_caption('Radiobutton Option Two') -:add_as_option(test_option_set,'Two') -:on_state_change(function(player,element,state) +:add_as_option(radiobutton_option_set,'Two') +:on_change(function(player,element,state) player.print('Radiobutton option two: '..tostring(state)) end) -tests['Radiobutton option three'] = Gui.new_radiobutton('test radiobutton option three') +local radiobutton_option_three = +Gui.new_radiobutton('test-radiobutton-option-three') +:set_tooltip('Radiobutton option set') :set_caption('Radiobutton Option Three') -:add_as_option(test_option_set,'Three') -:on_state_change(function(player,element,state) +:add_as_option(radiobutton_option_set,'Three') +:on_change(function(player,element,state) player.print('Radiobutton option three: '..tostring(state)) end) -tests['Dropdown local static general'] = Gui.new_dropdown('test dropdown local static general') -:set_tooltip('Dropdown Local Static General') +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_selection(function(player,element,value) +:on_change(function(player,element,value) player.print('Dropdown local static general: '..tostring(value)) end) -tests['Dropdown player static general'] = Gui.new_dropdown('test dropdown player static general') -:set_tooltip('Dropdown Player Static General') +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(categozie_by_player) -:on_selection(function(player,element,value) - player.print('Dropdown player static general: '..tostring(value)) +:on_change(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 -tests['Dropdown local static case'] = Gui.new_dropdown('test dropdown local static case') -:set_tooltip('Dropdown Local Static Case') + +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_selection(function(player,element,value) +:on_change(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 player static case (case): '..tostring(value)) + player.print('Dropdown store static case (case): '..tostring(value)) end -tests['Dropdown player static case'] = Gui.new_dropdown('test dropdown player static case') -:set_tooltip('Dropdown Player Static Case') + +local dropdown_player_static_case = +Gui.new_dropdown('test-dropdown-store-static-case') +:set_tooltip('Dropdown store static case') :add_store(categozie_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_selection(function(player,element,value) - player.print('Dropdown player static case (general): '..tostring(value)) +:on_change(function(player,element,value) + player.print('Dropdown store static case (general): '..tostring(value)) end) -tests['Dropdown local dynamic general'] = Gui.new_dropdown('test dropdown local dynamic general') -:set_tooltip('Dropdown Local Dynamic General') +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_selection(function(player,element,value) - player.print('Dropdown local dynamic general: '..tostring(value)) +:on_change(function(player,element,value) + player.print('Dropdown local dynamic: '..tostring(value)) end) -tests['Dropdown player dynamic general'] = Gui.new_dropdown('test dropdown player dynamic general') -:set_tooltip('Dropdown Player Dynamic General') +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(categozie_by_player) -:on_selection(function(player,element,value) - player.print('Dropdown player dynamic general: '..tostring(value)) +:on_change(function(player,element,value) + player.print('Dropdown store dynamic: '..tostring(value)) end) -tests['List box local static general'] = Gui.new_list_box('test list box local static general') -:set_tooltip('List Box Local Static General') +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_selection(function(player,element,value) - player.print('Dropdown local static general: '..tostring(value)) +:on_change(function(player,element,value) + player.print('Dropdown local: '..tostring(value)) end) -tests['List box player static general'] = Gui.new_list_box('test list box player static general') -:set_tooltip('List Box Player Static General') +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(categozie_by_player) -:on_selection(function(player,element,value) - player.print('Dropdown player static general: '..tostring(value)) +:on_change(function(player,element,value) + player.print('Dropdown store: '..tostring(value)) end) -tests['Slider local default'] = Gui.new_slider('test slider local default') -:set_tooltip('Silder Local Default') +tests["List Boxs"] = { + ['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('Silder local default') :on_change(function(player,element,value,percent) - player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -tests['Slider player default'] = Gui.new_slider('test slider player default') -:set_tooltip('Silder Player Default') +local slider_player_default = +Gui.new_slider('test-slider-store-default') +:set_tooltip('Silder store default') :add_store(categozie_by_player) :on_change(function(player,element,value,percent) - player.print('Slider player default: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider store default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -tests['Slider static range'] = Gui.new_slider('test slider static range') -:set_tooltip('Silder Static Range') +local slider_static = +Gui.new_slider('test-slider-static-range') +:set_tooltip('Silder static range') :set_range(5,50) :on_change(function(player,element,value,percent) - player.print('Slider static range: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider static range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -tests['Slider dynamic range'] = Gui.new_slider('test slider dynamic range') -:set_tooltip('Silder Dynamic Range') +local slider_dynamic = +Gui.new_slider('test-slider-dynamic-range') +:set_tooltip('Silder dynamic range') :set_range(function(player,element) return player.index - 5 end,function(player,element) return player.index + 4 end) :on_change(function(player,element,value,percent) - player.print('Slider static range: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider dynamic range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -local label_slider = Gui.new_slider('test slider local lable') -:set_tooltip('Silder Local label') +local label_slider_local = +Gui.new_slider('test-slider-local-label') +:set_tooltip('Silder local label') :enable_auto_draw_label() :on_change(function(player,element,value,percent) - player.print('Slider local label: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider local label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -tests['Slider local label'] = function(self,frame) - local flow = frame.add{type='flow'} - label_slider:draw_to(flow) -end - -local label_slider_player = Gui.new_slider('test slider player lable') -:set_tooltip('Silder Player label') +local label_slider_player = +Gui.new_slider('test-slider-store-label') +:set_tooltip('Silder store label') :enable_auto_draw_label() :add_store(categozie_by_player) :on_change(function(player,element,value,percent) - player.print('Slider player label: '..tostring(math.round(value))..' '..tostring(math.round(percent,2))) + player.print('Slider store label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) end) -tests['Slider player label'] = function(self,frame) - local flow = frame.add{type='flow'} - label_slider_player:draw_to(flow) -end \ No newline at end of file +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_change(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(categozie_by_player) +:on_change(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_change(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_change(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_change(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_change(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_change(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(categozie_by_player) +:on_change(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 +} \ No newline at end of file diff --git a/expcore/Gui/text.lua b/expcore/Gui/text.lua new file mode 100644 index 00000000..0eb36340 --- /dev/null +++ b/expcore/Gui/text.lua @@ -0,0 +1,115 @@ +local Gui = require './core' +local Game = require 'utils.game' + +local function event_call(define,element,value) + local player = Game.get_player_by_index(element.player_index) + + if define.events.on_change then + define.events.on_change(player,element,value) + end + +end + +local function store_call(self,element,value) + element.text = value + event_call(self,element,value) +end + +local Text = { + _prototype_field=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) + }, + _prototype_box=Gui._prototype_factory{ + on_change = Gui._event_factory('on_change'), + add_store = Gui._store_factory(store_call), + add_sync_store = Gui._sync_store_factory(store_call) + } +} + +function Text.new_text_field(name) + + local self = Gui._define_factory(Text._prototype_field) + self.draw_data.type = 'textfield' + + if name then + self:debug_name(name) + end + + self.post_draw = function(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 category = self.categorize and self.categorize(element) or nil + local value = self:get_store(category) + 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 + local category = self.categorize and self.categorize(element) or value + self:set_store(category,value) + + else + event_call(self,element,value) + + end + + end) + + return self +end + +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 + +function Text._prototype_box:set_selectable(state) + if state == false then + self.selectable = false + else + self.selectable = true + end + return self +end + +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 + +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.lua b/expcore/gui.lua index 0927f5bc..7c45d4d3 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -15,6 +15,7 @@ local Checkbox = require('./gui/checkboxs') 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 local Dropdown = require('./gui/dropdown') @@ -26,4 +27,13 @@ local Slider = require('./gui/slider') Gui.new_slider = Slider.new_slider Gui.classes.slider = Slider +local Text = require('./gui/text') +Gui.new_text_filed = Text.new_text_field +Gui.new_text_box = Text.new_text_box +Gui.classes.text = Text + +local ElemButton = require('./gui/elem-button') +Gui.new_elem_button = ElemButton.new_elem_button +Gui.classes.elem_button = ElemButton + return Gui \ No newline at end of file diff --git a/expcore/store.lua b/expcore/store.lua index 7436ec9f..f391dbd2 100644 --- a/expcore/store.lua +++ b/expcore/store.lua @@ -77,7 +77,8 @@ >>>> Alternative method Some people may prefer to use a varible rather than a string for formating reasons here is an example. Also for any times when - there will be little external input Store.uid_location() can be used to generate non conflicting locations. + there will be little external input Store.uid_location() can be used to generate non conflicting locations, use of register_synced will + still require a name other wise there may be mirgration issuses. local store_game_speed = Store.uid_location()