2019-03-03 22:37:50 +02:00
|
|
|
local Gui = require 'utils.gui'
|
|
|
|
local Event = require 'utils.event'
|
|
|
|
local Toast = require 'features.gui.toast'
|
|
|
|
local Settings = require 'utils.redmew_settings'
|
|
|
|
local Color = require 'resources.color_presets'
|
|
|
|
local pairs = pairs
|
|
|
|
|
|
|
|
local main_button_name = Gui.uid_name()
|
|
|
|
local save_changes_button_name = Gui.uid_name()
|
|
|
|
local main_frame_name = Gui.uid_name()
|
|
|
|
|
|
|
|
local Public = {}
|
|
|
|
|
|
|
|
local function player_created(event)
|
2019-05-26 11:40:04 +02:00
|
|
|
local player = game.get_player(event.player_index)
|
2019-03-03 22:37:50 +02:00
|
|
|
if not player or not player.valid then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-08-03 18:31:10 +02:00
|
|
|
Gui.add_top_element(player,
|
2019-06-21 11:56:37 +02:00
|
|
|
{
|
|
|
|
type = 'sprite-button',
|
|
|
|
name = main_button_name,
|
|
|
|
sprite = 'item/iron-gear-wheel',
|
|
|
|
tooltip = {'redmew_settings_gui.tooltip'}
|
|
|
|
}
|
|
|
|
)
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function player_joined(event)
|
2019-05-26 11:40:04 +02:00
|
|
|
local player = game.get_player(event.player_index)
|
2019-03-03 22:37:50 +02:00
|
|
|
if not player or not player.valid then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-05-26 14:44:18 +02:00
|
|
|
local main_frame = player.gui.center[main_frame_name]
|
|
|
|
|
2020-09-14 22:14:15 +02:00
|
|
|
if main_frame and main_frame.valid then
|
2024-08-03 18:31:10 +02:00
|
|
|
Gui.destroy(main_frame)
|
2019-05-26 14:44:18 +02:00
|
|
|
end
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function get_element_value(element)
|
|
|
|
if element.type == 'text-box' then
|
|
|
|
return element.text
|
|
|
|
end
|
|
|
|
if element.type == 'slider' then
|
|
|
|
return element.slider_value
|
|
|
|
end
|
|
|
|
if element.type == 'checkbox' then
|
|
|
|
return element.state
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-05-26 20:15:05 +02:00
|
|
|
local function set_element_value(element, value)
|
|
|
|
if element.type == 'text-box' then
|
2020-11-24 19:44:31 +02:00
|
|
|
element.text = tostring(value)
|
2019-05-26 20:15:05 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
if element.type == 'slider' then
|
|
|
|
element.slider_value = value
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if element.type == 'checkbox' then
|
|
|
|
element.state = value
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-03 22:37:50 +02:00
|
|
|
local function create_input_element(frame, type, value)
|
|
|
|
if type == 'fraction' then
|
|
|
|
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
|
|
|
|
end
|
|
|
|
if type == 'boolean' then
|
|
|
|
return frame.add({type = 'checkbox', state = value})
|
|
|
|
end
|
|
|
|
|
|
|
|
-- ensure something is always added to prevent errors
|
2020-11-24 19:44:31 +02:00
|
|
|
return frame.add({type = 'text-box', text = tostring(value)})
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function draw_main_frame(center, player)
|
|
|
|
local settings = Settings.get_setting_metadata()
|
2019-06-21 11:56:37 +02:00
|
|
|
local settings_frame =
|
|
|
|
center.add(
|
|
|
|
{
|
|
|
|
type = 'frame',
|
|
|
|
name = main_frame_name,
|
|
|
|
direction = 'vertical',
|
|
|
|
caption = {'redmew_settings_gui.frame_title'}
|
|
|
|
}
|
|
|
|
)
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
local settings_frame_style = settings_frame.style
|
2020-12-27 09:42:02 +02:00
|
|
|
settings_frame_style.width = 500
|
2019-03-03 22:37:50 +02:00
|
|
|
|
2019-05-27 23:04:32 +02:00
|
|
|
local info_text = settings_frame.add({type = 'label', caption = {'redmew_settings_gui.setting_info'}})
|
|
|
|
local info_text_style = info_text.style
|
|
|
|
info_text_style.single_line = false
|
|
|
|
info_text_style.bottom_padding = 5
|
|
|
|
info_text_style.left_padding = 5
|
|
|
|
info_text_style.right_padding = 5
|
|
|
|
info_text_style.top_padding = 5
|
|
|
|
info_text_style.width = 370
|
|
|
|
|
2019-03-03 22:37:50 +02:00
|
|
|
local scroll_pane = settings_frame.add({type = 'scroll-pane'})
|
|
|
|
local scroll_style = scroll_pane.style
|
2019-03-04 21:34:44 +02:00
|
|
|
scroll_style.vertically_squashable = true
|
2019-03-03 22:37:50 +02:00
|
|
|
scroll_style.maximal_height = 800
|
|
|
|
scroll_style.bottom_padding = 5
|
|
|
|
scroll_style.left_padding = 5
|
|
|
|
scroll_style.right_padding = 5
|
|
|
|
scroll_style.top_padding = 5
|
|
|
|
|
|
|
|
local setting_grid = scroll_pane.add({type = 'table', column_count = 2})
|
|
|
|
local player_index = player.index
|
|
|
|
|
|
|
|
local data = {}
|
|
|
|
|
|
|
|
for name, setting in pairs(settings) do
|
2019-06-21 11:56:37 +02:00
|
|
|
local label =
|
|
|
|
setting_grid.add(
|
|
|
|
{
|
|
|
|
type = 'label',
|
|
|
|
caption = setting.locale_string
|
|
|
|
}
|
|
|
|
)
|
2019-05-27 23:04:32 +02:00
|
|
|
|
|
|
|
local label_style = label.style
|
|
|
|
label_style.horizontally_stretchable = true
|
|
|
|
label_style.height = 35
|
|
|
|
label_style.vertical_align = 'center'
|
2019-03-03 22:37:50 +02:00
|
|
|
|
2019-05-28 21:04:30 +02:00
|
|
|
local value = Settings.toScalar(name, Settings.get(player_index, name))
|
2019-05-27 23:04:32 +02:00
|
|
|
local input_container = setting_grid.add({type = 'flow'})
|
|
|
|
local input_container_style = input_container.style
|
|
|
|
input_container_style.height = 35
|
|
|
|
input_container_style.vertical_align = 'center'
|
|
|
|
local input = create_input_element(input_container, setting.type, value)
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
data[name] = {
|
|
|
|
label = label,
|
|
|
|
input = input,
|
2019-06-21 11:56:37 +02:00
|
|
|
previous_value = value
|
2019-03-03 22:37:50 +02:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
local bottom_flow = settings_frame.add({type = 'flow', direction = 'horizontal'})
|
|
|
|
|
|
|
|
local left_flow = bottom_flow.add({type = 'flow'})
|
|
|
|
left_flow.style.horizontal_align = 'left'
|
|
|
|
left_flow.style.horizontally_stretchable = true
|
|
|
|
|
2019-06-21 11:56:37 +02:00
|
|
|
local close_button =
|
|
|
|
left_flow.add({type = 'button', name = main_button_name, caption = {'redmew_settings_gui.button_cancel'}})
|
2019-03-03 22:37:50 +02:00
|
|
|
close_button.style = 'back_button'
|
|
|
|
|
|
|
|
local right_flow = bottom_flow.add({type = 'flow'})
|
|
|
|
right_flow.style.horizontal_align = 'right'
|
|
|
|
|
2019-06-21 11:56:37 +02:00
|
|
|
local save_button =
|
|
|
|
right_flow.add(
|
|
|
|
{type = 'button', name = save_changes_button_name, caption = {'redmew_settings_gui.button_save_changes'}}
|
|
|
|
)
|
2019-03-03 22:37:50 +02:00
|
|
|
save_button.style = 'confirm_button'
|
|
|
|
|
|
|
|
Gui.set_data(save_button, data)
|
2019-05-26 20:15:05 +02:00
|
|
|
Gui.set_data(settings_frame, data)
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
player.opened = settings_frame
|
|
|
|
end
|
|
|
|
|
|
|
|
local function toggle(event)
|
|
|
|
local player = event.player
|
2019-06-20 13:39:18 +02:00
|
|
|
local gui = player.gui
|
|
|
|
local center = gui.center
|
2019-03-03 22:37:50 +02:00
|
|
|
local main_frame = center[main_frame_name]
|
2024-08-03 18:31:10 +02:00
|
|
|
local main_button = Gui.get_top_element(player, main_button_name)
|
|
|
|
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
if main_frame then
|
2024-08-03 18:31:10 +02:00
|
|
|
main_button.toggled = false
|
|
|
|
Gui.destroy(main_frame)
|
2019-03-03 22:37:50 +02:00
|
|
|
else
|
|
|
|
draw_main_frame(center, player)
|
2024-08-03 18:31:10 +02:00
|
|
|
main_button.toggled = true
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function save_changes(event)
|
|
|
|
local data = Gui.get_data(event.element)
|
|
|
|
local player_index = event.player_index
|
|
|
|
local player = event.player
|
|
|
|
|
|
|
|
local errors_count = 0
|
|
|
|
local values = {}
|
|
|
|
|
|
|
|
for name, element_data in pairs(data) do
|
|
|
|
local input = element_data.input
|
|
|
|
local label = element_data.label
|
|
|
|
local value = get_element_value(input)
|
|
|
|
local validated = Settings.validate(name, value)
|
|
|
|
|
|
|
|
if nil ~= validated then
|
|
|
|
errors_count = errors_count + 1
|
|
|
|
label.style.font_color = Color.red
|
|
|
|
label.tooltip = validated
|
|
|
|
label.parent.tooltip = validated
|
|
|
|
input.tooltip = validated
|
|
|
|
input.parent.tooltip = validated
|
|
|
|
else
|
|
|
|
label.style.font_color = Color.white
|
|
|
|
label.tooltip = ''
|
|
|
|
label.parent.tooltip = ''
|
|
|
|
input.tooltip = ''
|
|
|
|
input.parent.tooltip = ''
|
|
|
|
end
|
|
|
|
values[name] = value
|
|
|
|
end
|
|
|
|
|
|
|
|
if errors_count > 0 then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-05-26 18:54:45 +02:00
|
|
|
for name, value in pairs(values) do
|
2019-03-03 22:37:50 +02:00
|
|
|
Settings.set(player_index, name, value)
|
|
|
|
end
|
|
|
|
|
2019-03-04 08:51:57 +02:00
|
|
|
Toast.toast_player(player, 5, {'redmew_settings_gui.save_success_toast_message'})
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
local main_frame = player.gui.center[main_frame_name]
|
|
|
|
|
|
|
|
if main_frame then
|
2024-08-03 18:31:10 +02:00
|
|
|
Gui.destroy(main_frame)
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
2024-08-03 18:31:10 +02:00
|
|
|
|
|
|
|
local main_button = Gui.get_top_element(player, main_button_name)
|
|
|
|
main_button.toggled = false
|
2019-03-03 22:37:50 +02:00
|
|
|
end
|
|
|
|
|
2019-05-26 20:15:05 +02:00
|
|
|
local function setting_set(event)
|
2019-05-27 16:01:48 +02:00
|
|
|
if not event.value_changed then
|
2019-05-26 20:15:05 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-05-27 16:01:48 +02:00
|
|
|
local player = game.get_player(event.player_index)
|
2019-05-26 20:15:05 +02:00
|
|
|
if not player or not player.valid then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local main_frame = player.gui.center[main_frame_name]
|
|
|
|
if not main_frame or not main_frame.valid then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local data = Gui.get_data(main_frame)
|
|
|
|
if not data then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-05-28 21:04:30 +02:00
|
|
|
local setting_name = event.setting_name
|
|
|
|
local element_data = data[setting_name]
|
2019-05-26 20:15:05 +02:00
|
|
|
|
|
|
|
if not element_data then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local input = element_data.input
|
|
|
|
if not input or not input.valid then
|
|
|
|
-- for some reason it has been removed already
|
|
|
|
return
|
|
|
|
end
|
2019-05-28 21:04:30 +02:00
|
|
|
set_element_value(input, Settings.toScalar(setting_name, event.new_value))
|
|
|
|
element_data.previous_value = Settings.toScalar(setting_name, event.old_value)
|
2019-05-26 18:54:45 +02:00
|
|
|
end
|
|
|
|
|
2019-06-21 11:56:37 +02:00
|
|
|
Gui.on_custom_close(
|
|
|
|
main_frame_name,
|
|
|
|
function(event)
|
2024-08-03 18:31:10 +02:00
|
|
|
Gui.destroy(event.element)
|
2019-06-21 11:56:37 +02:00
|
|
|
end
|
|
|
|
)
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
Gui.allow_player_to_toggle_top_element_visibility(main_button_name)
|
|
|
|
|
|
|
|
Gui.on_click(main_button_name, toggle)
|
|
|
|
Gui.on_click(save_changes_button_name, save_changes)
|
|
|
|
Event.add(defines.events.on_player_created, player_created)
|
|
|
|
Event.add(defines.events.on_player_joined_game, player_joined)
|
2019-05-26 20:15:05 +02:00
|
|
|
Event.add(Settings.events.on_setting_set, setting_set)
|
2019-03-03 22:37:50 +02:00
|
|
|
|
|
|
|
return Public
|