From 003cd6c801d11b3101fe47b2aa6565af4ab93768 Mon Sep 17 00:00:00 2001
From: SimonFlapse <signup@simonflarup.dk>
Date: Sun, 9 Jun 2019 16:39:21 +0200
Subject: [PATCH] Added a radio to browse sounds

---
 config.lua             |   4 +
 control.lua            |   3 +
 features/gui/radio.lua | 218 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 225 insertions(+)
 create mode 100644 features/gui/radio.lua

diff --git a/config.lua b/config.lua
index 3115ec79..9bf46a7b 100644
--- a/config.lua
+++ b/config.lua
@@ -311,6 +311,10 @@ global.config = {
     rich_text_gui = {
         enabled = true
     },
+    -- adds a command to open a gui that can play sounds from a list
+    radio = {
+        enabled = false
+    },
     -- adds a camera to watch another player
     camera = {
         enabled = true
diff --git a/control.lua b/control.lua
index ff9222d5..12fd32c1 100644
--- a/control.lua
+++ b/control.lua
@@ -135,6 +135,9 @@ end
 if config.rich_text_gui.enabled then
     require 'features.gui.rich_text'
 end
+if config.radio.enabled or _DEBUG then
+    require 'features.gui.radio'
+end
 if config.redmew_settings.enabled then
     require 'features.gui.redmew_settings'
 end
diff --git a/features/gui/radio.lua b/features/gui/radio.lua
new file mode 100644
index 00000000..87389183
--- /dev/null
+++ b/features/gui/radio.lua
@@ -0,0 +1,218 @@
+local Gui = require 'utils.gui'
+local Command = require 'utils.command'
+local Event = require 'utils.event'
+
+local main_button_name = Gui.uid_name()
+local radio_frame = Gui.uid_name()
+local close_radio = Gui.uid_name()
+local play_sound = Gui.uid_name()
+
+local sounds = {
+    ['ambient'] = {
+        'after-the-crash',
+        'automation',
+        'resource-deficiency',
+        'are-we-alone',
+        'beyond-factory-outskirts',
+        'censeqs-discrepancy',
+        'efficiency-program',
+        'expansion',
+        'the-search-for-iron',
+        'gathering-horizon',
+        'research-and-minerals',
+        'solar-intervention',
+        'the-oil-industry',
+        'the-right-tools',
+        'pollution',
+        'turbine-dynamics',
+        'sentient',
+        'anomaly',
+        'first-light',
+        'transmit',
+        'swell-pad',
+        'world-ambience-1',
+        'world-ambience-2',
+        'world-ambience-3',
+        'world-ambience-4',
+        'world-ambience-5',
+        'world-ambience-6'
+    },
+    ['default'] = {
+        'worm-sends-biters',
+        'mainframe-activated',
+        'car-repaired'
+    },
+    ['utility'] = {
+        'achievement_unlocked',
+        'alert_destroyed',
+        'armor_insert',
+        'armor_remove',
+        'axe_fighting',
+        'axe_mining_ore',
+        'build_big',
+        'build_medium',
+        'build_small',
+        'cannot_build',
+        'console_message',
+        'crafting_finished',
+        'deconstruct_big',
+        'deconstruct_medium',
+        'deconstruct_small',
+        'default_manual_repair',
+        'game_lost',
+        'game_won',
+        'gui_click',
+        'inventory_move',
+        'list_box_click',
+        'metal_walking_sound',
+        'mining_wood',
+        'new_objective',
+        'research_completed',
+        'scenario_message',
+        'tutorial_notice',
+        'wire_connect_pole',
+        'wire_disconnect',
+        'wire_pickup'
+    }
+}
+
+local function draw_radio(event)
+    local frame_caption
+
+    frame_caption = 'Radio'
+    local player = event.player
+    local center = player.gui.center
+
+    local frame = center[radio_frame]
+    if frame then
+        Gui.remove_data_recursively(frame)
+        frame.destroy()
+        return
+    end
+
+    frame = center.add {type = 'frame', name = radio_frame, caption = frame_caption, direction = 'vertical'}
+    local scroll_pane =
+        frame.add {
+        type = 'scroll-pane',
+        vertical_scroll_policy = 'auto-and-reserve-space',
+        horizontal_scroll_policy = 'never'
+    }
+
+    local main_table = scroll_pane.add {type = 'table', column_count = 4}
+
+    for type, sound in pairs(sounds) do
+        for i = 1, #sound do
+            local name = (type == 'default') and sound[i] or type .. '/' .. sound[i]
+            main_table.add {type = 'label', caption = type .. '/' .. sound[i]}
+            main_table.add {type = 'button', name = 'radio_play:' .. name, caption = 'Play'}
+        end
+    end
+
+    local information_pane =
+        frame.add {
+        type = 'scroll-pane',
+        vertical_scroll_policy = 'auto-and-reserve-space',
+        horizontal_scroll_policy = 'never'
+    }
+    information_pane.style.horizontally_stretchable = true
+    information_pane.style.horizontal_align = 'center'
+
+    local text =
+        [[
+        Other types:
+        syntax = <type>/<entity>
+        "tile-walking" - for example "tile-walking/concrete"
+        "tile-build"
+        "tile-mined"
+        "entity-build" - for example "entity-build/wooden-chest"
+        "entity-mined"
+        "entity-vehicle_impact"
+        "entity-open"
+        "entity-close"
+    ]]
+    local information = information_pane.add {type = 'text-box', text = text}
+    information.style.horizontally_stretchable = true
+    information.style.vertically_stretchable = true
+    information.style.minimal_height = 200
+    information.style.minimal_width = 400
+
+    local bottom_flow = frame.add {type = 'flow', direction = 'horizontal'}
+
+    local left_flow = bottom_flow.add {type = 'flow', direction = 'horizontal'}
+    left_flow.style.horizontal_align = 'left'
+    left_flow.style.horizontally_stretchable = true
+
+    local close_button = left_flow.add {type = 'button', name = close_radio, caption = 'Close'}
+    Gui.set_data(close_button, frame)
+
+    local data = {}
+    Gui.set_data(frame, data)
+
+    player.opened = frame
+end
+
+Gui.on_click(main_button_name, draw_radio)
+
+Gui.on_click(
+    close_radio,
+    function(event)
+        local frame = Gui.get_data(event.element)
+
+        Gui.remove_data_recursively(frame)
+        frame.destroy()
+    end
+)
+
+Gui.on_click(
+    play_sound,
+    function(_)
+        game.print('Play_sound')
+    end
+)
+
+Gui.on_custom_close(
+    radio_frame,
+    function(event)
+        local element = event.element
+        Gui.remove_data_recursively(element)
+        element.destroy()
+    end
+)
+
+local function radio_command(_, player)
+    if player and player.valid then
+        local event = {player = player}
+        draw_radio(event)
+    end
+end
+
+Command.add(
+    'radio',
+    {
+        description = 'Opens radio gui',
+        capture_excess_arguments = false,
+        allowed_by_server = false
+    },
+    radio_command
+)
+
+local function handler(event)
+    local element = event.element
+    if not element or not element.valid then
+        return
+    end
+    local name = element.name
+    local subname = string.sub(name, 1, 11)
+    if subname == 'radio_play:' then
+        local path = string.sub(name, 12)
+        local player = game.get_player(event.player_index)
+        if (game.is_valid_sound_path(path)) then
+            player.play_sound {path = path}
+            return
+        else
+            player.print('Unable to play sound: ' .. path)
+        end
+    end
+end
+
+Event.add(defines.events.on_gui_click, handler)