mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge branch 'master' into upstream-merge-13122
This commit is contained in:
326
code/modules/tgui/modules/admin/player_notes.dm
Normal file
326
code/modules/tgui/modules/admin/player_notes.dm
Normal file
@@ -0,0 +1,326 @@
|
||||
#define PLAYER_NOTES_ENTRIES_PER_PAGE 50
|
||||
|
||||
/datum/tgui_module/player_notes
|
||||
name = "Player Notes"
|
||||
tgui_id = "PlayerNotes"
|
||||
|
||||
var/ckeys = list()
|
||||
|
||||
var/current_filter = ""
|
||||
var/current_page = 1
|
||||
|
||||
var/number_pages = 0
|
||||
|
||||
/datum/tgui_module/player_notes/proc/filter_ckeys(var/page, var/filter)
|
||||
var/savefile/S=new("data/player_notes.sav")
|
||||
var/list/note_keys
|
||||
S >> note_keys
|
||||
if(!note_keys)
|
||||
to_chat(usr, "No notes found.")
|
||||
else
|
||||
note_keys = sortList(note_keys)
|
||||
|
||||
if(filter)
|
||||
var/list/results = list()
|
||||
var/regex/needle = regex(filter, "i")
|
||||
for(var/haystack in note_keys)
|
||||
if(needle.Find(haystack))
|
||||
results += haystack
|
||||
note_keys = results
|
||||
|
||||
// Display the notes on the current page
|
||||
number_pages = note_keys.len / PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
// Emulate CEILING(why does BYOND not have ceil, 1)
|
||||
if(number_pages != round(number_pages))
|
||||
number_pages = round(number_pages) + 1
|
||||
var/page_index = page - 1
|
||||
|
||||
if(page_index < 0 || page_index >= number_pages)
|
||||
to_chat(usr, "No keys found.")
|
||||
else
|
||||
var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1
|
||||
var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
upper_bound = min(upper_bound, note_keys.len)
|
||||
ckeys = list()
|
||||
for(var/index = lower_bound, index <= upper_bound, index++)
|
||||
ckeys += note_keys[index]
|
||||
|
||||
current_filter = filter
|
||||
|
||||
/datum/tgui_module/player_notes/proc/open_legacy()
|
||||
var/datum/admins/A = admin_datums[usr.ckey]
|
||||
A.PlayerNotesLegacy()
|
||||
|
||||
/datum/tgui_module/player_notes/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
|
||||
/datum/tgui_module/player_notes/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("__fallback")
|
||||
log_runtime(EXCEPTION("TGUI Fallback Triggered: \"[ui.user]\" tried to use/open \"[ui.title]/[ui.interface]\"! Trying to open legacy UI!"))
|
||||
open_legacy()
|
||||
|
||||
if("show_player_info")
|
||||
var/datum/tgui_module/player_notes_info/A = new(src)
|
||||
A.key = params["name"]
|
||||
A.tgui_interact(usr)
|
||||
|
||||
if("filter_player_notes")
|
||||
var/input = tgui_input_text(usr, "Filter string (case-insensitive regex)", "Player notes filter")
|
||||
current_filter = input
|
||||
|
||||
if("set_page")
|
||||
var/page = params["index"]
|
||||
current_page = page
|
||||
|
||||
if("clear_player_info_filter")
|
||||
current_filter = ""
|
||||
|
||||
if("open_legacy_ui")
|
||||
open_legacy()
|
||||
|
||||
/datum/tgui_module/player_notes/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
filter_ckeys(current_page, current_filter)
|
||||
data["ckeys"] = list()
|
||||
data["pages"] = number_pages + 1
|
||||
data["filter"] = current_filter
|
||||
|
||||
for(var/ckey in ckeys)
|
||||
data["ckeys"] += list(list(
|
||||
"name" = ckey
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
// PLAYER NOTES INFO
|
||||
/datum/tgui_module/player_notes_info
|
||||
name = "Player Notes Info"
|
||||
tgui_id = "PlayerNotesInfo"
|
||||
|
||||
var/key = null
|
||||
|
||||
/datum/tgui_module/player_notes_info/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
|
||||
/datum/tgui_module/player_notes_info/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("__fallback")
|
||||
var/datum/admins/A = admin_datums[usr.ckey]
|
||||
A.show_player_info_legacy(key)
|
||||
|
||||
if("add_player_info")
|
||||
var/key = params["ckey"]
|
||||
var/add = tgui_input_text(usr, "Write your comment below.", "Add Player Info", multiline = TRUE)
|
||||
if(!add) return
|
||||
|
||||
notes_add(key,add,usr)
|
||||
|
||||
if("remove_player_info")
|
||||
var/key = params["ckey"]
|
||||
var/index = params["index"]
|
||||
|
||||
notes_del(key, index)
|
||||
|
||||
/datum/tgui_module/player_notes_info/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(!key)
|
||||
return
|
||||
|
||||
var/p_age = "unknown"
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.ckey == key)
|
||||
p_age = C.player_age
|
||||
break
|
||||
|
||||
data["entries"] = list()
|
||||
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(infos)
|
||||
var/update_file = 0
|
||||
var/i = 0
|
||||
for(var/datum/player_info/I in infos)
|
||||
i += 1
|
||||
if(!I.timestamp)
|
||||
I.timestamp = "Pre-4/3/2012"
|
||||
update_file = 1
|
||||
if(!I.rank)
|
||||
I.rank = "N/A"
|
||||
update_file = 1
|
||||
|
||||
data["entries"] += list(list(
|
||||
"comment" = I.content,
|
||||
"author" = "[I.author] ([I.rank])",
|
||||
"date" = "[I.timestamp]"
|
||||
))
|
||||
if(update_file) info << infos
|
||||
|
||||
data["ckey"] = key
|
||||
data["age"] = p_age
|
||||
|
||||
return data
|
||||
|
||||
// ==== LEGACY UI ====
|
||||
|
||||
/datum/admins/proc/PlayerNotesLegacy()
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
PlayerNotesPageLegacy(1)
|
||||
|
||||
/datum/admins/proc/PlayerNotesFilterLegacy()
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
var/filter = tgui_input_text(usr, "Filter string (case-insensitive regex)", "Player notes filter")
|
||||
PlayerNotesPageLegacy(1, filter)
|
||||
|
||||
/datum/admins/proc/PlayerNotesPageLegacy(page, filter)
|
||||
var/dat = "<B>Player notes</B> - <a href='?src=\ref[src];notes_legacy=filter'>Apply Filter</a><HR>"
|
||||
var/savefile/S=new("data/player_notes.sav")
|
||||
var/list/note_keys
|
||||
S >> note_keys
|
||||
if(!note_keys)
|
||||
dat += "No notes found."
|
||||
else
|
||||
dat += "<table>"
|
||||
note_keys = sortList(note_keys)
|
||||
|
||||
if(filter)
|
||||
var/list/results = list()
|
||||
var/regex/needle = regex(filter, "i")
|
||||
for(var/haystack in note_keys)
|
||||
if(needle.Find(haystack))
|
||||
results += haystack
|
||||
note_keys = results
|
||||
|
||||
// Display the notes on the current page
|
||||
var/number_pages = note_keys.len / PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
// Emulate CEILING(why does BYOND not have ceil, 1)
|
||||
if(number_pages != round(number_pages))
|
||||
number_pages = round(number_pages) + 1
|
||||
var/page_index = page - 1
|
||||
|
||||
if(page_index < 0 || page_index >= number_pages)
|
||||
dat += "<tr><td>No keys found.</td></tr>"
|
||||
else
|
||||
var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1
|
||||
var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
upper_bound = min(upper_bound, note_keys.len)
|
||||
for(var/index = lower_bound, index <= upper_bound, index++)
|
||||
var/t = note_keys[index]
|
||||
dat += "<tr><td><a href='?src=\ref[src];notes_legacy=show;ckey=[t]'>[t]</a></td></tr>"
|
||||
|
||||
dat += "</table><hr>"
|
||||
|
||||
// Display a footer to select different pages
|
||||
for(var/index = 1, index <= number_pages, index++)
|
||||
if(index == page)
|
||||
dat += "<b>"
|
||||
dat += "<a href='?src=\ref[src];notes_legacy=list;index=[index];filter=[filter ? url_encode(filter) : 0]'>[index]</a> "
|
||||
if(index == page)
|
||||
dat += "</b>"
|
||||
|
||||
usr << browse(dat, "window=player_notes;size=400x400")
|
||||
|
||||
/datum/admins/proc/player_has_info_legacy(var/key as text)
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos || !infos.len) return 0
|
||||
else return 1
|
||||
|
||||
/datum/admins/proc/show_player_info_legacy(var/key as text)
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
var/dat = "<html><head><title>Info on [key]</title></head>"
|
||||
dat += "<body>"
|
||||
|
||||
var/p_age = "unknown"
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.ckey == key)
|
||||
p_age = C.player_age
|
||||
break
|
||||
dat +="<span style='color:#000000; font-weight: bold'>Player age: [p_age]</span><br>"
|
||||
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos)
|
||||
dat += "No information found on the given key.<br>"
|
||||
else
|
||||
var/update_file = 0
|
||||
var/i = 0
|
||||
for(var/datum/player_info/I in infos)
|
||||
i += 1
|
||||
if(!I.timestamp)
|
||||
I.timestamp = "Pre-4/3/2012"
|
||||
update_file = 1
|
||||
if(!I.rank)
|
||||
I.rank = "N/A"
|
||||
update_file = 1
|
||||
dat += "<font color=#008800>[I.content]</font> <i>by [I.author] ([I.rank])</i> on <i><font color=blue>[I.timestamp]</i></font> "
|
||||
if(I.author == usr.key || I.author == "Adminbot" || ishost(usr))
|
||||
dat += "<A href='?src=\ref[src];remove_player_info_legacy=[key];remove_index=[i]'>Remove</A>"
|
||||
dat += "<br><br>"
|
||||
if(update_file) info << infos
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];add_player_info_legacy=[key]'>Add Comment</A><br>"
|
||||
|
||||
dat += "</body></html>"
|
||||
usr << browse(dat, "window=adminplayerinfo;size=480x480")
|
||||
|
||||
/datum/admins/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if(href_list["add_player_info_legacy"])
|
||||
var/key = href_list["add_player_info_legacy"]
|
||||
var/add = sanitize(tgui_input_text(usr, "Add Player Info (Legacy)"))
|
||||
if(!add) return
|
||||
|
||||
notes_add(key,add,usr)
|
||||
show_player_info_legacy(key)
|
||||
|
||||
if(href_list["remove_player_info_legacy"])
|
||||
var/key = href_list["remove_player_info_legacy"]
|
||||
var/index = text2num(href_list["remove_index"])
|
||||
|
||||
notes_del(key, index)
|
||||
show_player_info_legacy(key)
|
||||
|
||||
if(href_list["notes_legacy"])
|
||||
var/ckey = href_list["ckey"]
|
||||
if(!ckey)
|
||||
var/mob/M = locate(href_list["mob"])
|
||||
if(ismob(M))
|
||||
ckey = M.ckey
|
||||
|
||||
switch(href_list["notes_legacy"])
|
||||
if("show")
|
||||
show_player_info_legacy(ckey)
|
||||
if("list")
|
||||
var/filter
|
||||
if(href_list["filter"] && href_list["filter"] != "0")
|
||||
filter = url_decode(href_list["filter"])
|
||||
PlayerNotesPageLegacy(text2num(href_list["index"]), filter)
|
||||
if("filter")
|
||||
PlayerNotesFilterLegacy()
|
||||
return
|
||||
@@ -75,7 +75,7 @@
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(H.dna)
|
||||
default = H.dna.b_type
|
||||
var/new_blood_type = sanitize(input(usr,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text)
|
||||
var/new_blood_type = sanitize(tgui_input_text(usr,"What blood type would you like to be written on this card?","Agent Card Blood Type",default))
|
||||
if(!isnull(new_blood_type) && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.blood_type = new_blood_type
|
||||
to_chat(usr, "<span class='notice'>Blood type changed to '[new_blood_type]'.</span>")
|
||||
@@ -86,7 +86,7 @@
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(H.dna)
|
||||
default = H.dna.unique_enzymes
|
||||
var/new_dna_hash = sanitize(input(usr,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text)
|
||||
var/new_dna_hash = sanitize(tgui_input_text(usr,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default))
|
||||
if(!isnull(new_dna_hash) && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.dna_hash = new_dna_hash
|
||||
to_chat(usr, "<span class='notice'>DNA hash changed to '[new_dna_hash]'.</span>")
|
||||
@@ -103,7 +103,7 @@
|
||||
to_chat(usr, "<span class='notice'>Fingerprint hash changed to '[new_fingerprint_hash]'.</span>")
|
||||
. = TRUE
|
||||
if("name")
|
||||
var/new_name = sanitizeName(input(usr,"What name would you like to put on this card?","Agent Card Name", S.registered_name) as null|text)
|
||||
var/new_name = sanitizeName(tgui_input_text(usr,"What name would you like to put on this card?","Agent Card Name", S.registered_name))
|
||||
if(!isnull(new_name) && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.registered_name = new_name
|
||||
S.update_name()
|
||||
@@ -114,7 +114,7 @@
|
||||
to_chat(usr, "<span class='notice'>Photo changed.</span>")
|
||||
. = TRUE
|
||||
if("sex")
|
||||
var/new_sex = sanitize(input(usr,"What sex would you like to put on this card?","Agent Card Sex", S.sex) as null|text)
|
||||
var/new_sex = sanitize(tgui_input_text(usr,"What sex would you like to put on this card?","Agent Card Sex", S.sex))
|
||||
if(!isnull(new_sex) && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.sex = new_sex
|
||||
to_chat(usr, "<span class='notice'>Sex changed to '[new_sex]'.</span>")
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
if(message_cooldown > world.time)
|
||||
to_chat(usr, "<span class='warning'>Please allow at least one minute to pass between announcements.</span>")
|
||||
return
|
||||
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|message
|
||||
var/input = tgui_input_text(usr, "Please write a message to announce to the station crew.", "Priority Announcement", multiline = TRUE)
|
||||
if(!input || message_cooldown > world.time || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX))
|
||||
return
|
||||
if(length(input) < COMM_MSGLEN_MINIMUM)
|
||||
@@ -337,10 +337,10 @@
|
||||
if(centcomm_message_cooldown > world.time)
|
||||
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
||||
return
|
||||
var/input = sanitize(input(usr, "Please choose a message to transmit to [using_map.boss_short] via quantum entanglement. \
|
||||
var/input = sanitize(tgui_input_text(usr, "Please choose a message to transmit to [using_map.boss_short] via quantum entanglement. \
|
||||
Please be aware that this process is very expensive, and abuse will lead to... termination. \
|
||||
Transmission does not guarantee a response. \
|
||||
There is a 30 second delay before you may send another message, be clear, full and concise.", "Central Command Quantum Messaging") as null|message)
|
||||
There is a 30 second delay before you may send another message, be clear, full and concise.", "Central Command Quantum Messaging", multiline = TRUE))
|
||||
if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX))
|
||||
return
|
||||
if(length(input) < COMM_CCMSGLEN_MINIMUM)
|
||||
@@ -358,7 +358,7 @@
|
||||
if(centcomm_message_cooldown > world.time)
|
||||
to_chat(usr, "Arrays recycling. Please stand by.")
|
||||
return
|
||||
var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", ""))
|
||||
var/input = sanitize(tgui_input_text(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", ""))
|
||||
if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX))
|
||||
return
|
||||
if(length(input) < COMM_CCMSGLEN_MINIMUM)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
switch(action)
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Gyrotron Control", gyro_tag) as null|text)
|
||||
var/new_ident = sanitize_text(tgui_input_text(usr, "Enter a new ident tag.", "Gyrotron Control", gyro_tag))
|
||||
if(new_ident)
|
||||
gyro_tag = new_ident
|
||||
return TRUE
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
/* HELM */
|
||||
if("add")
|
||||
var/datum/computer_file/data/waypoint/R = new()
|
||||
var/sec_name = input(usr, "Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
|
||||
var/sec_name = tgui_input_text(usr, "Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]")
|
||||
if(!sec_name)
|
||||
sec_name = "Sector #[known_sectors.len]"
|
||||
R.fields["name"] = sec_name
|
||||
@@ -319,8 +319,8 @@
|
||||
R.fields["x"] = linked.x
|
||||
R.fields["y"] = linked.y
|
||||
if("new")
|
||||
var/newx = input(usr, "Input new entry x coordinate", "Coordinate input", linked.x) as num
|
||||
var/newy = input(usr, "Input new entry y coordinate", "Coordinate input", linked.y) as num
|
||||
var/newx = tgui_input_number(usr, "Input new entry x coordinate", "Coordinate input", linked.x)
|
||||
var/newy = tgui_input_number(usr, "Input new entry y coordinate", "Coordinate input", linked.y)
|
||||
R.fields["x"] = CLAMP(newx, 1, world.maxx)
|
||||
R.fields["y"] = CLAMP(newy, 1, world.maxy)
|
||||
known_sectors[sec_name] = R
|
||||
@@ -335,12 +335,12 @@
|
||||
|
||||
if("setcoord")
|
||||
if(params["setx"])
|
||||
var/newx = input(usr, "Input new destiniation x coordinate", "Coordinate input", dx) as num|null
|
||||
var/newx = tgui_input_number(usr, "Input new destiniation x coordinate", "Coordinate input", dx)
|
||||
if(newx)
|
||||
dx = CLAMP(newx, 1, world.maxx)
|
||||
|
||||
if(params["sety"])
|
||||
var/newy = input(usr, "Input new destiniation y coordinate", "Coordinate input", dy) as num|null
|
||||
var/newy = tgui_input_number(usr, "Input new destiniation y coordinate", "Coordinate input", dy)
|
||||
if(newy)
|
||||
dy = CLAMP(newy, 1, world.maxy)
|
||||
. = TRUE
|
||||
@@ -356,13 +356,13 @@
|
||||
. = TRUE
|
||||
|
||||
if("speedlimit")
|
||||
var/newlimit = input(usr, "Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null
|
||||
var/newlimit = tgui_input_number(usr, "Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000)
|
||||
if(newlimit)
|
||||
speedlimit = CLAMP(newlimit/1000, 0, 100)
|
||||
. = TRUE
|
||||
|
||||
if("accellimit")
|
||||
var/newlimit = input(usr, "Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null
|
||||
var/newlimit = tgui_input_number(usr, "Input new acceleration limit", "Acceleration limit", accellimit*1000)
|
||||
if(newlimit)
|
||||
accellimit = max(newlimit/1000, 0)
|
||||
. = TRUE
|
||||
@@ -402,7 +402,7 @@
|
||||
. = TRUE
|
||||
|
||||
if("set_global_limit")
|
||||
var/newlim = input(usr, "Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num
|
||||
var/newlim = tgui_input_number(usr, "Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100, 100, 0)
|
||||
linked.thrust_limit = clamp(newlim/100, 0, 1)
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
E.set_thrust_limit(linked.thrust_limit)
|
||||
@@ -416,7 +416,7 @@
|
||||
|
||||
if("set_limit")
|
||||
var/datum/ship_engine/E = locate(params["engine"])
|
||||
var/newlim = input(usr, "Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
|
||||
var/newlim = tgui_input_number(usr, "Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit(), 100, 0)
|
||||
var/limit = clamp(newlim/100, 0, 1)
|
||||
if(istype(E))
|
||||
E.set_thrust_limit(limit)
|
||||
@@ -437,7 +437,7 @@
|
||||
/* END ENGINES */
|
||||
/* SENSORS */
|
||||
if("range")
|
||||
var/nrange = input(usr, "Set new sensors range", "Sensor range", sensors.range) as num|null
|
||||
var/nrange = tgui_input_number(usr, "Set new sensors range", "Sensor range", sensors.range)
|
||||
if(nrange)
|
||||
sensors.set_range(CLAMP(nrange, 1, world.view))
|
||||
. = TRUE
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
smes_data["RCON_tag"] = SMES.RCon_tag
|
||||
smeslist.Add(list(smes_data))
|
||||
|
||||
data["pages"] = number_pages
|
||||
data["pages"] = number_pages + 1
|
||||
data["current_page"] = current_page
|
||||
data["smes_info"] = sortByKey(smeslist, "RCON_tag")
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
return TRUE
|
||||
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Core Control", core_tag) as null|text)
|
||||
var/new_ident = sanitize_text(tgui_input_text(usr, "Enter a new ident tag.", "Core Control", core_tag))
|
||||
if(new_ident)
|
||||
core_tag = new_ident
|
||||
return TRUE
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
return TRUE
|
||||
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Gyrotron Control", fuel_tag) as null|text)
|
||||
var/new_ident = sanitize_text(tgui_input_text(usr, "Enter a new ident tag.", "Gyrotron Control", fuel_tag))
|
||||
if(new_ident)
|
||||
fuel_tag = new_ident
|
||||
|
||||
|
||||
@@ -32,8 +32,12 @@
|
||||
var/closing = FALSE
|
||||
/// The status/visibility of the UI.
|
||||
var/status = STATUS_INTERACTIVE
|
||||
/// Timed refreshing state
|
||||
var/refreshing = FALSE
|
||||
/// Topic state used to determine status/interactability.
|
||||
var/datum/tgui_state/state = null
|
||||
/// Rate limit client refreshes to prevent DoS.
|
||||
COOLDOWN_DECLARE(refresh_cooldown)
|
||||
/// The map z-level to display.
|
||||
var/map_z_level = 1
|
||||
/// The Parent UI
|
||||
@@ -176,11 +180,17 @@
|
||||
/datum/tgui/proc/send_full_update(custom_data, force)
|
||||
if(!user.client || !initialized || closing)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, refresh_cooldown))
|
||||
refreshing = TRUE
|
||||
addtimer(CALLBACK(src, .proc/send_full_update), TGUI_REFRESH_FULL_UPDATE_COOLDOWN, TIMER_UNIQUE)
|
||||
return
|
||||
refreshing = FALSE
|
||||
var/should_update_data = force || status >= STATUS_UPDATE
|
||||
window.send_message("update", get_payload(
|
||||
custom_data,
|
||||
with_data = should_update_data,
|
||||
with_static_data = TRUE))
|
||||
COOLDOWN_START(src, refresh_cooldown, TGUI_REFRESH_FULL_UPDATE_COOLDOWN)
|
||||
|
||||
/**
|
||||
* public
|
||||
@@ -211,6 +221,7 @@
|
||||
"title" = title,
|
||||
"status" = status,
|
||||
"interface" = interface,
|
||||
"refreshing" = refreshing,
|
||||
"map" = (using_map && using_map.path) ? using_map.path : "Unknown",
|
||||
"mapZLevel" = map_z_level,
|
||||
"window" = list(
|
||||
@@ -312,6 +323,9 @@
|
||||
return FALSE
|
||||
switch(type)
|
||||
if("ready")
|
||||
// Send a full update when the user manually refreshes the UI
|
||||
if(initialized)
|
||||
send_full_update()
|
||||
initialized = TRUE
|
||||
if("pingReply")
|
||||
initialized = TRUE
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/**
|
||||
* Creates a TGUI alert window and returns the user's response.
|
||||
*
|
||||
* This proc should be used to create alerts that the caller will wait for a response from.
|
||||
* Arguments:
|
||||
* * user - The user to show the alert to.
|
||||
* * message - The content of the alert, shown in the body of the TGUI window.
|
||||
* * title - The of the alert modal, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0)
|
||||
if (istext(buttons))
|
||||
stack_trace("tgui_alert() received text for buttons instead of list")
|
||||
return
|
||||
if (istext(user))
|
||||
stack_trace("tgui_alert() received text for user instead of list")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_alert/alert = new(user, message, title, buttons, timeout)
|
||||
alert.tgui_interact(user)
|
||||
alert.wait()
|
||||
if (alert)
|
||||
. = alert.choice
|
||||
qdel(alert)
|
||||
|
||||
/**
|
||||
* Creates an asynchronous TGUI alert window with an associated callback.
|
||||
*
|
||||
* This proc should be used to create alerts that invoke a callback with the user's chosen option.
|
||||
* Arguments:
|
||||
* * user - The user to show the alert to.
|
||||
* * message - The content of the alert, shown in the body of the TGUI window.
|
||||
* * title - The of the alert modal, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise.
|
||||
*/
|
||||
/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0)
|
||||
if (istext(buttons))
|
||||
stack_trace("tgui_alert() received text for buttons instead of list")
|
||||
return
|
||||
if (istext(user))
|
||||
stack_trace("tgui_alert() received text for user instead of list")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_alert/async/alert = new(user, message, title, buttons, callback, timeout)
|
||||
alert.tgui_interact(user)
|
||||
|
||||
/**
|
||||
* # tgui_modal
|
||||
*
|
||||
* Datum used for instantiating and using a TGUI-controlled modal that prompts the user with
|
||||
* a message and has buttons for responses.
|
||||
*/
|
||||
/datum/tgui_alert
|
||||
/// The title of the TGUI window
|
||||
var/title
|
||||
/// The textual body of the TGUI window
|
||||
var/message
|
||||
/// The list of buttons (responses) provided on the TGUI window
|
||||
var/list/buttons
|
||||
/// The button that the user has pressed, null if no selection has been made
|
||||
var/choice
|
||||
/// The time at which the tgui_modal was created, for displaying timeout progress.
|
||||
var/start_time
|
||||
/// The lifespan of the tgui_modal, after which the window will close and delete itself.
|
||||
var/timeout
|
||||
/// Boolean field describing if the tgui_modal was closed by the user.
|
||||
var/closed
|
||||
|
||||
/datum/tgui_alert/New(mob/user, message, title, list/buttons, timeout)
|
||||
src.title = title
|
||||
src.message = message
|
||||
src.buttons = buttons.Copy()
|
||||
if (timeout)
|
||||
src.timeout = timeout
|
||||
start_time = world.time
|
||||
QDEL_IN(src, timeout)
|
||||
|
||||
/datum/tgui_alert/Destroy(force, ...)
|
||||
SStgui.close_uis(src)
|
||||
QDEL_NULL(buttons)
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Waits for a user's response to the tgui_modal's prompt before returning. Returns early if
|
||||
* the window was closed by the user.
|
||||
*/
|
||||
/datum/tgui_alert/proc/wait()
|
||||
while (!choice && !closed && !QDELETED(src))
|
||||
stoplag(1)
|
||||
|
||||
/datum/tgui_alert/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AlertModal")
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_alert/tgui_close(mob/user)
|
||||
. = ..()
|
||||
closed = TRUE
|
||||
|
||||
/datum/tgui_alert/tgui_state(mob/user)
|
||||
return GLOB.tgui_always_state
|
||||
|
||||
/datum/tgui_alert/tgui_data(mob/user)
|
||||
. = list(
|
||||
"title" = title,
|
||||
"message" = message,
|
||||
"buttons" = buttons
|
||||
)
|
||||
|
||||
if(timeout)
|
||||
.["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS))
|
||||
|
||||
/datum/tgui_alert/tgui_act(action, list/params)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
switch(action)
|
||||
if("choose")
|
||||
if (!(params["choice"] in buttons))
|
||||
return
|
||||
set_choice(params["choice"])
|
||||
SStgui.close_uis(src)
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_alert/proc/set_choice(choice)
|
||||
src.choice = choice
|
||||
|
||||
/**
|
||||
* # async tgui_modal
|
||||
*
|
||||
* An asynchronous version of tgui_modal to be used with callbacks instead of waiting on user responses.
|
||||
*/
|
||||
/datum/tgui_alert/async
|
||||
/// The callback to be invoked by the tgui_modal upon having a choice made.
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_alert/async/New(mob/user, message, title, list/buttons, callback, timeout)
|
||||
..(user, message, title, buttons, timeout)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_alert/async/Destroy(force, ...)
|
||||
QDEL_NULL(callback)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_alert/async/set_choice(choice)
|
||||
. = ..()
|
||||
if(!isnull(src.choice))
|
||||
callback?.InvokeAsync(src.choice)
|
||||
|
||||
/datum/tgui_alert/async/wait()
|
||||
return
|
||||
@@ -1,205 +0,0 @@
|
||||
/**
|
||||
* Creates a TGUI input list window and returns the user's response.
|
||||
*
|
||||
* This proc should be used to create alerts that the caller will wait for a response from.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * default - The option with this value will be selected on first paint of the TGUI window.
|
||||
* * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_list(mob/user, message, title, list/buttons, default, timeout = 0)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_alert() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if(!length(buttons))
|
||||
return
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_list_input/input = new(user, message, title, buttons, default, timeout)
|
||||
input.tgui_interact(user)
|
||||
input.wait()
|
||||
if (input)
|
||||
. = input.choice
|
||||
qdel(input)
|
||||
|
||||
/**
|
||||
* Creates an asynchronous TGUI input list window with an associated callback.
|
||||
*
|
||||
* This proc should be used to create inputs that invoke a callback with the user's chosen option.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * default - The option with this value will be selected on first paint of the TGUI window.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_list_async(mob/user, message, title, list/buttons, default, datum/callback/callback, timeout = 60 SECONDS)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_alert() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if(!length(buttons))
|
||||
return
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_list_input/async/input = new(user, message, title, buttons, default, callback, timeout)
|
||||
input.tgui_interact(user)
|
||||
|
||||
/**
|
||||
* # tgui_list_input
|
||||
*
|
||||
* Datum used for instantiating and using a TGUI-controlled list input that prompts the user with
|
||||
* a message and shows a list of selectable options
|
||||
*/
|
||||
/datum/tgui_list_input
|
||||
/// The title of the TGUI window
|
||||
var/title
|
||||
/// The textual body of the TGUI window
|
||||
var/message
|
||||
/// The list of buttons (responses) provided on the TGUI window
|
||||
var/list/buttons
|
||||
/// Buttons (strings specifically) mapped to the actual value (e.g. a mob or a verb)
|
||||
var/list/buttons_map
|
||||
/// Value of the button that should be pre-selected on first paint.
|
||||
var/initial
|
||||
/// The button that the user has pressed, null if no selection has been made
|
||||
var/choice
|
||||
/// The time at which the tgui_list_input was created, for displaying timeout progress.
|
||||
var/start_time
|
||||
/// The lifespan of the tgui_list_input, after which the window will close and delete itself.
|
||||
var/timeout
|
||||
/// Boolean field describing if the tgui_list_input was closed by the user.
|
||||
var/closed
|
||||
|
||||
/datum/tgui_list_input/New(mob/user, message, title, list/buttons, default, timeout)
|
||||
src.title = title
|
||||
src.message = message
|
||||
src.buttons = list()
|
||||
src.buttons_map = list()
|
||||
src.initial = default
|
||||
var/list/repeat_buttons = list()
|
||||
|
||||
// Gets rid of illegal characters
|
||||
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
|
||||
|
||||
for(var/i in buttons)
|
||||
if(isnull(i))
|
||||
stack_trace("Null in a tgui_input_list() buttons")
|
||||
continue
|
||||
|
||||
var/string_key = whitelistedWords.Replace("[i]", "")
|
||||
|
||||
//avoids duplicated keys E.g: when areas have the same name
|
||||
string_key = avoid_assoc_duplicate_keys(string_key, repeat_buttons)
|
||||
|
||||
src.buttons += string_key
|
||||
src.buttons_map[string_key] = i
|
||||
|
||||
|
||||
if (timeout)
|
||||
src.timeout = timeout
|
||||
start_time = world.time
|
||||
QDEL_IN(src, timeout)
|
||||
|
||||
/datum/tgui_list_input/Destroy(force, ...)
|
||||
SStgui.close_uis(src)
|
||||
QDEL_NULL(buttons)
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Waits for a user's response to the tgui_list_input's prompt before returning. Returns early if
|
||||
* the window was closed by the user.
|
||||
*/
|
||||
/datum/tgui_list_input/proc/wait()
|
||||
while (!choice && !closed)
|
||||
stoplag(1)
|
||||
|
||||
/datum/tgui_list_input/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ListInput")
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_list_input/tgui_close(mob/user)
|
||||
. = ..()
|
||||
closed = TRUE
|
||||
|
||||
/datum/tgui_list_input/tgui_state(mob/user)
|
||||
return GLOB.tgui_always_state
|
||||
|
||||
/datum/tgui_list_input/tgui_static_data(mob/user)
|
||||
. = list(
|
||||
"title" = title,
|
||||
"message" = message,
|
||||
"buttons" = buttons,
|
||||
"initial" = initial
|
||||
)
|
||||
|
||||
/datum/tgui_list_input/tgui_data(mob/user)
|
||||
. = list()
|
||||
if(timeout)
|
||||
.["timeout"] = clamp((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS), 0, 1)
|
||||
|
||||
/datum/tgui_list_input/tgui_act(action, list/params)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
switch(action)
|
||||
if("choose")
|
||||
if (!(params["choice"] in buttons))
|
||||
return
|
||||
set_choice(buttons_map[params["choice"]])
|
||||
SStgui.close_uis(src)
|
||||
return TRUE
|
||||
if("cancel")
|
||||
SStgui.close_uis(src)
|
||||
closed = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_list_input/proc/set_choice(choice)
|
||||
src.choice = choice
|
||||
|
||||
/**
|
||||
* # async tgui_list_input
|
||||
*
|
||||
* An asynchronous version of tgui_list_input to be used with callbacks instead of waiting on user responses.
|
||||
*/
|
||||
/datum/tgui_list_input/async
|
||||
/// The callback to be invoked by the tgui_list_input upon having a choice made.
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, default, callback, timeout)
|
||||
..(user, title, message, buttons, default, timeout)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_list_input/async/Destroy(force, ...)
|
||||
QDEL_NULL(callback)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_list_input/async/tgui_close(mob/user)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/datum/tgui_list_input/async/set_choice(choice)
|
||||
. = ..()
|
||||
if(!isnull(src.choice))
|
||||
callback?.InvokeAsync(src.choice)
|
||||
|
||||
/datum/tgui_list_input/async/wait()
|
||||
return
|
||||
@@ -1,299 +0,0 @@
|
||||
/**
|
||||
* Creates a TGUI input text window and returns the user's response.
|
||||
*
|
||||
* This proc should be used to create alerts that the caller will wait for a response from.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_text(mob/user, message, title, default, timeout = 0)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_text() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/input = new(user, message, title, default, timeout)
|
||||
input.input_type = "text"
|
||||
input.tgui_interact(user)
|
||||
input.wait()
|
||||
if (input)
|
||||
. = input.choice
|
||||
qdel(input)
|
||||
|
||||
/**
|
||||
* Creates a TGUI input message window and returns the user's response.
|
||||
*
|
||||
* This proc should be used to create alerts that the caller will wait for a response from.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_message(mob/user, message, title, default, timeout = 0)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_message() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/input = new(user, message, title, default, timeout)
|
||||
input.input_type = "message"
|
||||
input.tgui_interact(user)
|
||||
input.wait()
|
||||
if (input)
|
||||
. = input.choice
|
||||
qdel(input)
|
||||
|
||||
/**
|
||||
* Creates a TGUI input num window and returns the user's response.
|
||||
*
|
||||
* This proc should be used to create alerts that the caller will wait for a response from.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_num(mob/user, message, title, default, timeout = 0)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_num() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/input = new(user, message, title, default, timeout)
|
||||
input.input_type = "num"
|
||||
input.tgui_interact(user)
|
||||
input.wait()
|
||||
if (input)
|
||||
. = input.choice
|
||||
qdel(input)
|
||||
|
||||
/**
|
||||
* Creates an asynchronous TGUI input text window with an associated callback.
|
||||
*
|
||||
* This proc should be used to create inputs that invoke a callback with the user's chosen option.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_text_async(mob/user, message, title, default, datum/callback/callback, timeout = 60 SECONDS)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_text_async() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/async/input = new(user, message, title, default, callback, timeout)
|
||||
input.input_type = "text"
|
||||
input.tgui_interact(user)
|
||||
|
||||
/**
|
||||
* Creates an asynchronous TGUI input message window with an associated callback.
|
||||
*
|
||||
* This proc should be used to create inputs that invoke a callback with the user's chosen option.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_message_async(mob/user, message, title, default, datum/callback/callback, timeout = 60 SECONDS)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_message_async() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/async/input = new(user, message, title, default, callback, timeout)
|
||||
input.input_type = "message"
|
||||
input.tgui_interact(user)
|
||||
|
||||
/**
|
||||
* Creates an asynchronous TGUI input num window with an associated callback.
|
||||
*
|
||||
* This proc should be used to create inputs that invoke a callback with the user's chosen option.
|
||||
* Arguments:
|
||||
* * user - The user to show the input box to.
|
||||
* * message - The content of the input box, shown in the body of the TGUI window.
|
||||
* * title - The title of the input box, shown on the top of the TGUI window.
|
||||
* * default - The default value pre-populated in the input box.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
|
||||
*/
|
||||
/proc/tgui_input_num_async(mob/user, message, title, default, datum/callback/callback, timeout = 60 SECONDS)
|
||||
if (istext(user))
|
||||
stack_trace("tgui_input_num_async() received text for user instead of mob")
|
||||
return
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
if (istype(user, /client))
|
||||
var/client/client = user
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_input_dialog/async/input = new(user, message, title, default, callback, timeout)
|
||||
input.input_type = "num"
|
||||
input.tgui_interact(user)
|
||||
|
||||
/**
|
||||
* # tgui_input_dialog
|
||||
*
|
||||
* Datum used for instantiating and using a TGUI-controlled input that prompts the user with
|
||||
* a message and a box for accepting text/message/num input.
|
||||
*/
|
||||
/datum/tgui_input_dialog
|
||||
/// The title of the TGUI window
|
||||
var/title
|
||||
/// The textual body of the TGUI window
|
||||
var/message
|
||||
/// The default value to initially populate the input box.
|
||||
var/initial
|
||||
/// The value that the user input into the input box, null if cancelled.
|
||||
var/choice
|
||||
/// The time at which the tgui_text_input was created, for displaying timeout progress.
|
||||
var/start_time
|
||||
/// The lifespan of the tgui_text_input, after which the window will close and delete itself.
|
||||
var/timeout
|
||||
/// Boolean field describing if the tgui_text_input was closed by the user.
|
||||
var/closed
|
||||
/// Indicates the data type we want to collect ("text", "message", "num")
|
||||
var/input_type = "text"
|
||||
|
||||
/datum/tgui_input_dialog/New(mob/user, message, title, default, timeout)
|
||||
src.title = title
|
||||
src.message = message
|
||||
// TODO - Do we need to sanitize the initial value for illegal characters?
|
||||
src.initial = default
|
||||
if (timeout)
|
||||
src.timeout = timeout
|
||||
start_time = world.time
|
||||
QDEL_IN(src, timeout)
|
||||
|
||||
/datum/tgui_input_dialog/Destroy(force, ...)
|
||||
SStgui.close_uis(src)
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Waits for a user's response to the tgui_text_input's prompt before returning. Returns early if
|
||||
* the window was closed by the user.
|
||||
*/
|
||||
/datum/tgui_input_dialog/proc/wait()
|
||||
while (!choice && !closed)
|
||||
stoplag(1)
|
||||
|
||||
/datum/tgui_input_dialog/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "InputModal")
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_input_dialog/tgui_close(mob/user)
|
||||
. = ..()
|
||||
closed = TRUE
|
||||
|
||||
/datum/tgui_input_dialog/tgui_state(mob/user)
|
||||
return GLOB.tgui_always_state
|
||||
|
||||
/datum/tgui_input_dialog/tgui_static_data(mob/user)
|
||||
. = list(
|
||||
"title" = title,
|
||||
"message" = message,
|
||||
"initial" = initial,
|
||||
"input_type" = input_type
|
||||
)
|
||||
|
||||
/datum/tgui_input_dialog/tgui_data(mob/user)
|
||||
. = list()
|
||||
if(timeout)
|
||||
.["timeout"] = clamp((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS), 0, 1)
|
||||
|
||||
/datum/tgui_input_dialog/tgui_act(action, list/params)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
switch(action)
|
||||
if("choose")
|
||||
set_choice(params["choice"])
|
||||
if(isnull(src.choice))
|
||||
return
|
||||
SStgui.close_uis(src)
|
||||
return TRUE
|
||||
if("cancel")
|
||||
SStgui.close_uis(src)
|
||||
closed = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_input_dialog/proc/set_choice(choice)
|
||||
if(input_type == "num")
|
||||
src.choice = text2num(choice)
|
||||
return
|
||||
src.choice = choice
|
||||
|
||||
/**
|
||||
* # async tgui_text_input
|
||||
*
|
||||
* An asynchronous version of tgui_text_input to be used with callbacks instead of waiting on user responses.
|
||||
*/
|
||||
/datum/tgui_input_dialog/async
|
||||
/// The callback to be invoked by the tgui_text_input upon having a choice made.
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_input_dialog/async/New(mob/user, message, title, default, callback, timeout)
|
||||
..(user, title, message, default, timeout)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_input_dialog/async/Destroy(force, ...)
|
||||
QDEL_NULL(callback)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_input_dialog/async/tgui_close(mob/user)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/datum/tgui_input_dialog/async/set_choice(choice)
|
||||
. = ..()
|
||||
if(!isnull(src.choice))
|
||||
callback?.InvokeAsync(src.choice)
|
||||
|
||||
/datum/tgui_input_dialog/async/wait()
|
||||
return
|
||||
Reference in New Issue
Block a user