From 4b3459f20f697e0e37aecc6bc1387f8ecefc3e86 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 14 May 2019 20:04:31 +0100 Subject: [PATCH] Added Sliders --- expcore/Gui/core.lua | 2 +- expcore/Gui/dropdown.lua | 4 +- expcore/Gui/slider.lua | 143 +++++++++++++++++++++++++++++++++++++++ expcore/Gui/test.lua | 62 ++++++++++++++++- expcore/Gui/toolbar.lua | 3 +- expcore/gui.lua | 4 ++ utils/gui.lua | 1 + 7 files changed, 211 insertions(+), 8 deletions(-) create mode 100644 expcore/Gui/slider.lua diff --git a/expcore/Gui/core.lua b/expcore/Gui/core.lua index 73612f02..823bbaec 100644 --- a/expcore/Gui/core.lua +++ b/expcore/Gui/core.lua @@ -33,7 +33,6 @@ function Gui.get_instances(self,category) return instances end - function Gui._extend_prototype(tbl) for k,v in pairs(Gui._prototype) do if not tbl[k] then tbl[k] = v end @@ -105,6 +104,7 @@ end function Gui._prototype:debug_name(name) self.debug_name = name Gui.names[name] = self.name + Gui.names[self.name] = name return self end diff --git a/expcore/Gui/dropdown.lua b/expcore/Gui/dropdown.lua index 764af040..697a63f1 100644 --- a/expcore/Gui/dropdown.lua +++ b/expcore/Gui/dropdown.lua @@ -31,11 +31,9 @@ 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 - table.insert(items,v) + element.add_item(v) end - element.items = items end if self.store then local category = self.categorize and self.categorize(element) or nil diff --git a/expcore/Gui/slider.lua b/expcore/Gui/slider.lua new file mode 100644 index 00000000..3c207860 --- /dev/null +++ b/expcore/Gui/slider.lua @@ -0,0 +1,143 @@ +local Gui = require './core' +local Game = require 'utils.game' + +local function get_instances(define,element) + local function cat(e) + return e.player_index + end + + local name = define.name..'-label' + if not Gui.instances[name] then return end + + local categorize = define.categorize or not define.store and cat + local category = categorize and categorize(element) or nil + local instances = Gui.get_instances({ + name=name, + categorize=categorize + },category) + + return instances +end + +local function update_instances(define,element) + local instances = get_instances(define,element) + local value = element.slider_value + if instances then + for k,instance in pairs(instances) do + if instance and instance.valid then + instance.caption = tostring(math.round(value,2)) + else + instances[k]=nil + end + end + end +end + +local Slider = { + _prototype=Gui._extend_prototype{ + on_change = Gui._new_event_adder('on_change'), + add_store = Gui._new_store_adder(function(self,element,value) + element.slider_value = value + 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 + local player = Game.get_player_by_index(element.player_index) + if self.events.on_change then + self.events.on_change(player,element,value,percent) + end + update_instances(self,element) + end) + } +} + +function Slider.new_slider(name) + + local self = Gui._new_define(Slider._prototype) + self.draw_data.type = 'slider' + + if name then + self:debug_name(name) + end + + self.post_draw = function(element) + local player = Game.get_player_by_index(element.player_index) + 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 category = self.categorize and self.categorize(element) or nil + local value = self:get_store(category) + 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 + 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 + local category = self.categorize and self.categorize(element) or value + + if self.store then + self:set_store(category,value) + + elseif self.events.on_change then + self.events.on_change(event.player,element,value,percent) + update_instances(self,element) + end + + end) + + return self +end + +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 + +function Slider._prototype:draw_label(element) + local name = self.name..'-label' + if element[name] then return end + local value = 0 + if self.store then + local category = self.categorize and self.categorize(element) or value + value = self:get_store(category) or 0 + end + local new_element = element.add{ + name=name, + type='label', + caption=tostring(math.round(value,2)) + } + if not Gui.instances[name] then Gui.instances[name] = {} end + local instances = get_instances(self,element) + table.insert(instances,new_element) + return new_element +end + +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/test.lua b/expcore/Gui/test.lua index 40562c3a..4b2bac18 100644 --- a/expcore/Gui/test.lua +++ b/expcore/Gui/test.lua @@ -3,7 +3,6 @@ local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_ local Colors = require 'resources.color_presets' local Game = require 'utils.game' local clean_stack_trace = ext_require('modules.commands.interface','clean_stack_trace') -local Store = require 'expcore.store' local tests = {} @@ -48,7 +47,8 @@ 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 success,err = pcall(element.draw_to,element,frame) + 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 @@ -230,4 +230,60 @@ tests['List box player static general'] = Gui.new_list_box('test list box player :add_store(categozie_by_player) :on_selection(function(player,element,value) player.print('Dropdown player static general: '..tostring(value)) -end) \ No newline at end of file +end) + +tests['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))) +end) + +tests['Slider player default'] = Gui.new_slider('test slider player default') +:set_tooltip('Silder Player 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))) +end) + +tests['Slider static range'] = 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))) +end) + +tests['Slider dynamic range'] = 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))) +end) + +local label_slider = Gui.new_slider('test slider local lable') +: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))) +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') +: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))) +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 diff --git a/expcore/Gui/toolbar.lua b/expcore/Gui/toolbar.lua index ebc7033f..094973c6 100644 --- a/expcore/Gui/toolbar.lua +++ b/expcore/Gui/toolbar.lua @@ -32,12 +32,13 @@ end 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.clean_name or button.name) then - element.visible = true + element.visible = visible element.enabled = true else element.visible = false diff --git a/expcore/gui.lua b/expcore/gui.lua index d1343106..0927f5bc 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -22,4 +22,8 @@ Gui.new_dropdown = Dropdown.new_dropdown Gui.new_list_box = Dropdown.new_list_box Gui.classes.dropdown = Dropdown +local Slider = require('./gui/slider') +Gui.new_slider = Slider.new_slider +Gui.classes.slider = Slider + return Gui \ No newline at end of file diff --git a/utils/gui.lua b/utils/gui.lua index 7de4b60a..8a765dff 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -200,6 +200,7 @@ function Gui.get_top_element_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,