Skip to content

Commit

Permalink
tgui: Jukebox (tgstation#52014)
Browse files Browse the repository at this point in the history
* Jukebox TGUI

* Line endings

* Review fixes
  • Loading branch information
Arkatos1 authored Jul 6, 2020
1 parent ff5d028 commit ae46de5
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 40 deletions.
107 changes: 68 additions & 39 deletions code/game/machinery/dance_machine.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
verb_say = "states"
density = TRUE
req_access = list(ACCESS_BAR)
ui_x = 370
ui_y = 313
var/active = FALSE
var/list/rangers = list()
var/stop = 0
var/list/songs = list()
var/datum/track/selection = null
/// Volume of the songs played
var/volume = 100

/obj/machinery/jukebox/disco
name = "radiant dance machine mark IV"
Expand Down Expand Up @@ -82,40 +86,54 @@
else
icon_state = "[initial(icon_state)]"

/obj/machinery/jukebox/ui_interact(mob/user)
. = ..()
if(!user.canUseTopic(src, !issilicon(user)))
return
if (!anchored)
/obj/machinery/jukebox/ui_status(mob/user)
if(!anchored)
to_chat(user,"<span class='warning'>This device must be anchored by a wrench!</span>")
return
if(!allowed(user))
return UI_CLOSE
if(!allowed(user) && !isobserver(user))
to_chat(user,"<span class='warning'>Error: Access Denied.</span>")
user.playsound_local(src,'sound/misc/compiler-failure.ogg', 25, 1)
return
if(!songs.len)
user.playsound_local(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
return UI_CLOSE
if(!songs.len && !isobserver(user))
to_chat(user,"<span class='warning'>Error: No music tracks have been authorized for your station. Petition Central Command to resolve this issue.</span>")
playsound(src,'sound/misc/compiler-failure.ogg', 25, TRUE)
return
var/list/dat = list()
dat +="<div class='statusDisplay' style='text-align:center'>"
dat += "<b><A href='?src=[REF(src)];action=toggle'>[!active ? "BREAK IT DOWN" : "SHUT IT DOWN"]<b></A><br>"
dat += "</div><br>"
dat += "<A href='?src=[REF(src)];action=select'> Select Track</A><br>"
dat += "Track Selected: [selection.song_name]<br>"
dat += "Track Length: [DisplayTimeText(selection.song_length)]<br><br>"
var/datum/browser/popup = new(user, "vending", "[name]", 400, 350)
popup.set_content(dat.Join())
popup.open()


/obj/machinery/jukebox/Topic(href, href_list)
if(..())
playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
return UI_CLOSE
return ..()

/obj/machinery/jukebox/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "Jukebox", name, ui_x, ui_y, master_ui, state)
ui.open()

/obj/machinery/jukebox/ui_data(mob/user)
var/list/data = list()
data["active"] = active
data["songs"] = list()
for(var/datum/track/S in songs)
var/list/track_data = list(
name = S.song_name
)
data["songs"] += list(track_data)
data["track_selected"] = null
data["track_length"] = null
data["track_beat"] = null
if(selection)
data["track_selected"] = selection.song_name
data["track_length"] = DisplayTimeText(selection.song_length)
data["track_beat"] = selection.song_beat
data["volume"] = volume
return data

/obj/machinery/jukebox/ui_act(action, list/params)
. = ..()
if(.)
return
add_fingerprint(usr)
switch(href_list["action"])

switch(action)
if("toggle")
if (QDELETED(src))
if(QDELETED(src))
return
if(!active)
if(stop > world.time)
Expand All @@ -124,23 +142,36 @@
return
activate_music()
START_PROCESSING(SSobj, src)
updateUsrDialog()
else if(active)
return TRUE
else
stop = 0
updateUsrDialog()
if("select")
return TRUE
if("select_track")
if(active)
to_chat(usr, "<span class='warning'>Error: You cannot change the song until the current one is over.</span>")
return

var/list/available = list()
for(var/datum/track/S in songs)
available[S.song_name] = S
var/selected = input(usr, "Choose your song", "Track:") as null|anything in sortList(available)
var/selected = params["track"]
if(QDELETED(src) || !selected || !istype(available[selected], /datum/track))
return
selection = available[selected]
updateUsrDialog()
return TRUE
if("set_volume")
var/new_volume = params["volume"]
if(new_volume == "reset")
volume = initial(volume)
return TRUE
else if(new_volume == "min")
volume = 0
return TRUE
else if(new_volume == "max")
volume = 100
return TRUE
else if(text2num(new_volume) != null)
volume = text2num(new_volume)
return TRUE

/obj/machinery/jukebox/proc/activate_music()
active = TRUE
Expand Down Expand Up @@ -368,7 +399,6 @@
sleep(1)
M.lying_fix()


/obj/machinery/jukebox/disco/proc/dance4(var/mob/living/M)
var/speed = rand(1,3)
set waitfor = 0
Expand Down Expand Up @@ -441,7 +471,7 @@
continue
if(!(M in rangers))
rangers[M] = TRUE
M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played)
M.playsound_local(get_turf(M), null, volume, channel = CHANNEL_JUKEBOX, S = song_played)
for(var/mob/L in rangers)
if(get_dist(src,L) > 10)
rangers -= L
Expand All @@ -456,7 +486,6 @@
update_icon()
stop = world.time + 100


/obj/machinery/jukebox/disco/process()
. = ..()
if(active)
Expand Down
107 changes: 107 additions & 0 deletions tgui/packages/tgui/interfaces/Jukebox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { sortBy } from 'common/collections';
import { flow } from 'common/fp';
import { useBackend } from '../backend';
import { Box, Button, Dropdown, Section, Knob, LabeledControls, LabeledList } from '../components';
import { Window } from '../layouts';

export const Jukebox = (props, context) => {
const { act, data } = useBackend(context);
const {
active,
track_selected,
track_length,
track_beat,
volume,
} = data;
const songs = flow([
sortBy(
song => song.name),
])(data.songs || []);
return (
<Window>
<Window.Content>
<Section
title="Song Player"
buttons={(
<Button
icon={active ? 'pause' : 'play'}
content={active ? 'Stop' : 'Play'}
selected={active}
onClick={() => act('toggle')} />
)}>
<LabeledList>
<LabeledList.Item label="Track Selected">
<Dropdown
overflow-y="scroll"
width="240px"
options={songs.map(song => song.name)}
disabled={active}
selected={track_selected || "Select a Track"}
onSelected={value => act('select_track', {
track: value,
})} />
</LabeledList.Item>
<LabeledList.Item label="Track Length">
{track_selected ? track_length : "No Track Selected"}
</LabeledList.Item>
<LabeledList.Item label="Track Beat">
{track_selected ? track_beat : "No Track Selected"}
{track_beat === 1 ? " beat" : " beats"}
</LabeledList.Item>
</LabeledList>
</Section>
<Section title="Machine Settings">
<LabeledControls justify="center">
<LabeledControls.Item label="Volume">
<Box position="relative">
<Knob
size={3.2}
color={volume >= 50 ? 'red' : 'green'}
value={volume}
unit="%"
minValue={0}
maxValue={100}
step={1}
stepPixelSize={1}
disabled={active}
onDrag={(e, value) => act('set_volume', {
volume: value,
})} />
<Button
fluid
position="absolute"
top="-2px"
right="-22px"
color="transparent"
icon="fast-backward"
onClick={() => act('set_volume', {
volume: "min",
})} />
<Button
fluid
position="absolute"
top="16px"
right="-22px"
color="transparent"
icon="fast-forward"
onClick={() => act('set_volume', {
volume: "max",
})} />
<Button
fluid
position="absolute"
top="34px"
right="-22px"
color="transparent"
icon="undo"
onClick={() => act('set_volume', {
volume: "reset",
})} />
</Box>
</LabeledControls.Item>
</LabeledControls>
</Section>
</Window.Content>
</Window>
);
};
2 changes: 1 addition & 1 deletion tgui/packages/tgui/public/tgui.bundle.js

Large diffs are not rendered by default.

0 comments on commit ae46de5

Please sign in to comment.