mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
The One Where I Port Modals
This commit is contained in:
@@ -162,13 +162,13 @@
|
||||
set name = "Fix TGUI"
|
||||
set category = "OOC"
|
||||
|
||||
if(alert(src, "Only use this verb if you have a white TGUI window stuck on your screen.", "Fix TGUI", "Continue", "Nevermind") != "Continue")
|
||||
if(alert(src, "Only use this verb if you have a white TGUI window stuck on your screen.", "Fix TGUI", "Continue", "Nevermind") != "Continue") // Not tgui_alert since we're fixing tgui
|
||||
return
|
||||
|
||||
SStgui.close_user_uis(mob)
|
||||
if(alert(src, "Did that fix the problem?", "Fix TGUI", "Yes", "No") == "No")
|
||||
if(alert(src, "Did that fix the problem?", "Fix TGUI", "Yes", "No") == "No") // Not tgui_alert since we're fixing tgui
|
||||
SStgui.force_close_all_windows(mob)
|
||||
alert(src, "UIs should be fixed now. If not, please cry to your nearest coder.", "Fix TGUI")
|
||||
alert(src, "UIs should be fixed now. If not, please cry to your nearest coder.", "Fix TGUI") // Not tgui_alert since we're fixing tgui
|
||||
|
||||
/**
|
||||
* verb
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
var/datum/shuttle/S = locate(params["ref"])
|
||||
if(istype(S, /datum/shuttle/autodock/multi))
|
||||
var/datum/shuttle/autodock/multi/shuttle = S
|
||||
var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations()
|
||||
var/dest_key = tgui_input_list(usr, "Choose shuttle destination", "Shuttle Destination", shuttle.get_destinations())
|
||||
if(dest_key)
|
||||
shuttle.set_destination(dest_key, usr)
|
||||
shuttle.launch(src)
|
||||
@@ -80,13 +80,13 @@
|
||||
if(!LAZYLEN(possible_d))
|
||||
to_chat(usr, "<span class='warning'>There are no possible destinations for [shuttle] ([shuttle.type])</span>")
|
||||
return FALSE
|
||||
D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d
|
||||
D = tgui_input_list(usr, "Choose shuttle destination", "Shuttle Destination", possible_d)
|
||||
if(D)
|
||||
shuttle.set_destination(possible_d[D])
|
||||
shuttle.launch()
|
||||
else if(istype(S, /datum/shuttle/autodock))
|
||||
var/datum/shuttle/autodock/shuttle = S
|
||||
if(alert(usr, "Are you sure you want to launch [shuttle]?", "Launching Shuttle", "Yes", "No") == "Yes")
|
||||
if(tgui_alert(usr, "Are you sure you want to launch [shuttle]?", "Launching Shuttle", list("Yes", "No")) == "Yes")
|
||||
shuttle.launch(src)
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The shuttle control panel isn't quite sure how to move [S] ([S?.type]).</span>")
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
to_chat(usr, "<span class='notice'>Age has been set to '[S.age]'.</span>")
|
||||
. = TRUE
|
||||
if("appearance")
|
||||
var/datum/card_state/choice = input(usr, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states()
|
||||
var/datum/card_state/choice = tgui_input_list(usr, "Select the appearance for this card.", "Agent Card Appearance", id_card_states())
|
||||
if(choice && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.icon_state = choice.icon_state
|
||||
S.item_state = choice.item_state
|
||||
@@ -118,7 +118,7 @@
|
||||
to_chat(usr, "<span class='notice'>Sex changed to '[new_sex]'.</span>")
|
||||
. = TRUE
|
||||
if("factoryreset")
|
||||
if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
if(tgui_alert(usr, "This will factory reset the card, including access and owner. Continue?", "Factory Reset", list("No", "Yes")) == "Yes" && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
S.age = initial(S.age)
|
||||
S.access = syndicate_access.Copy()
|
||||
S.assignment = initial(S.assignment)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
return 1
|
||||
if("hair_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select hair color.", "Hair Color", rgb(target.r_hair, target.g_hair, target.b_hair)) as color|null
|
||||
var/new_hair = input(usr, "Please select hair color.", "Hair Color", rgb(target.r_hair, target.g_hair, target.b_hair)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
var/r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
var/g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -151,7 +151,7 @@
|
||||
return 1
|
||||
if("facial_hair_color")
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
|
||||
var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(target.r_facial, target.g_facial, target.b_facial)) as color|null
|
||||
var/new_facial = input(usr, "Please select facial hair color.", "Facial Hair Color", rgb(target.r_facial, target.g_facial, target.b_facial)) as color|null
|
||||
if(new_facial && can_still_topic(usr, state))
|
||||
var/r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
var/g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
@@ -162,7 +162,7 @@
|
||||
return 1
|
||||
if("eye_color")
|
||||
if(can_change(APPEARANCE_EYE_COLOR))
|
||||
var/new_eyes = input("Please select eye color.", "Eye Color", rgb(target.r_eyes, target.g_eyes, target.b_eyes)) as color|null
|
||||
var/new_eyes = input(usr, "Please select eye color.", "Eye Color", rgb(target.r_eyes, target.g_eyes, target.b_eyes)) as color|null
|
||||
if(new_eyes && can_still_topic(usr, state))
|
||||
var/r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
var/g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
@@ -186,7 +186,7 @@
|
||||
return TRUE
|
||||
if("ears_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select ear color.", "Ear Color", rgb(target.r_ears, target.g_ears, target.b_ears)) as color|null
|
||||
var/new_hair = input(usr, "Please select ear color.", "Ear Color", rgb(target.r_ears, target.g_ears, target.b_ears)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_ears = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_ears = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -197,7 +197,7 @@
|
||||
return 1
|
||||
if("ears2_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select secondary ear color.", "2nd Ear Color", rgb(target.r_ears2, target.g_ears2, target.b_ears2)) as color|null
|
||||
var/new_hair = input(usr, "Please select secondary ear color.", "2nd Ear Color", rgb(target.r_ears2, target.g_ears2, target.b_ears2)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_ears2 = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_ears2 = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -220,7 +220,7 @@
|
||||
return TRUE
|
||||
if("tail_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select tail color.", "Tail Color", rgb(target.r_tail, target.g_tail, target.b_tail)) as color|null
|
||||
var/new_hair = input(usr, "Please select tail color.", "Tail Color", rgb(target.r_tail, target.g_tail, target.b_tail)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_tail = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_tail = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -231,7 +231,7 @@
|
||||
return 1
|
||||
if("tail2_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select secondary tail color.", "2nd Tail Color", rgb(target.r_tail2, target.g_tail2, target.b_tail2)) as color|null
|
||||
var/new_hair = input(usr, "Please select secondary tail color.", "2nd Tail Color", rgb(target.r_tail2, target.g_tail2, target.b_tail2)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_tail2 = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_tail2 = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -254,7 +254,7 @@
|
||||
return TRUE
|
||||
if("wing_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select wing color.", "Wing Color", rgb(target.r_wing, target.g_wing, target.b_wing)) as color|null
|
||||
var/new_hair = input(usr, "Please select wing color.", "Wing Color", rgb(target.r_wing, target.g_wing, target.b_wing)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_wing = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_wing = hex2num(copytext(new_hair, 4, 6))
|
||||
@@ -265,7 +265,7 @@
|
||||
return 1
|
||||
if("wing2_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select secondary wing color.", "2nd Wing Color", rgb(target.r_wing2, target.g_wing2, target.b_wing2)) as color|null
|
||||
var/new_hair = input(usr, "Please select secondary wing color.", "2nd Wing Color", rgb(target.r_wing2, target.g_wing2, target.b_wing2)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
target.r_wing2 = hex2num(copytext(new_hair, 2, 4))
|
||||
target.g_wing2 = hex2num(copytext(new_hair, 4, 6))
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
if(isAI(usr) || isrobot(usr))
|
||||
to_chat(usr, "<span class='warning'>Firewalls prevent you from recalling the shuttle.</span>")
|
||||
return
|
||||
var/response = alert("Are you sure you wish to recall the shuttle?", "Confirm", "Yes", "No")
|
||||
var/response = tgui_alert(usr, "Are you sure you wish to recall the shuttle?", "Confirm", list("Yes", "No"))
|
||||
if(response == "Yes")
|
||||
cancel_call_proc(usr)
|
||||
setMenuState(usr, COMM_SCREEN_MAIN)
|
||||
@@ -301,7 +301,7 @@
|
||||
var/datum/comm_message_listener/l = obtain_message_listener()
|
||||
if(params["msgid"])
|
||||
setCurrentMessage(usr, text2num(params["msgid"]))
|
||||
var/response = alert("Are you sure you wish to delete this message?", "Confirm", "Yes", "No")
|
||||
var/response = tgui_alert(usr, "Are you sure you wish to delete this message?", "Confirm", list("Yes", "No"))
|
||||
if(response == "Yes")
|
||||
if(current_viewing_message)
|
||||
if(l != global_message_listener)
|
||||
@@ -324,11 +324,11 @@
|
||||
post_status(src, params["statdisp"], user = usr)
|
||||
|
||||
if("setmsg1")
|
||||
stat_msg1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40)
|
||||
stat_msg1 = reject_bad_text(sanitize(input(usr, "Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40)
|
||||
setMenuState(usr, COMM_SCREEN_STAT)
|
||||
|
||||
if("setmsg2")
|
||||
stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40)
|
||||
stat_msg2 = reject_bad_text(sanitize(input(usr, "Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40)
|
||||
setMenuState(usr, COMM_SCREEN_STAT)
|
||||
|
||||
// OMG CENTCOMM LETTERHEAD
|
||||
@@ -337,7 +337,7 @@
|
||||
if(centcomm_message_cooldown > world.time)
|
||||
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
||||
return
|
||||
var/input = sanitize(input("Please choose a message to transmit to [using_map.boss_short] via quantum entanglement. \
|
||||
var/input = sanitize(input(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)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
data["isAI"] = isAI(user)
|
||||
|
||||
var/z = get_z(user)
|
||||
var/list/map_levels = uniquelist(using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
||||
var/list/map_levels = uniqueList(using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
||||
data["map_levels"] = map_levels
|
||||
|
||||
var/list/crewmembers = list()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
switch(action)
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input("Enter a new ident tag.", "Gyrotron Control", gyro_tag) as null|text)
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Gyrotron Control", gyro_tag) as null|text)
|
||||
if(new_ident)
|
||||
gyro_tag = new_ident
|
||||
return TRUE
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
if(computer && program.can_run(usr, 1) && id_card)
|
||||
var/t1 = params["assign_target"]
|
||||
if(t1 == "Custom")
|
||||
var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment", id_card.assignment), 45)
|
||||
var/temp_t = sanitize(input(usr, "Enter a custom job assignment.","Assignment", id_card.assignment), 45)
|
||||
//let custom jobs function as an impromptu alt title, mainly for sechuds
|
||||
if(temp_t)
|
||||
id_card.assignment = temp_t
|
||||
|
||||
@@ -427,7 +427,7 @@
|
||||
if(CF.unsendable)
|
||||
continue
|
||||
filenames.Add(CF.filename)
|
||||
var/picked_file = input(user, "Please pick a file to send as attachment (max 32GQ)") as null|anything in filenames
|
||||
var/picked_file = tgui_input_list(user, "Please pick a file to send as attachment (max 32GQ)", "Select Attachment", filenames)
|
||||
|
||||
if(!picked_file)
|
||||
return 1
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
/* HELM */
|
||||
if("add")
|
||||
var/datum/computer_file/data/waypoint/R = new()
|
||||
var/sec_name = input("Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
|
||||
var/sec_name = input(usr, "Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
|
||||
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("Input new entry x coordinate", "Coordinate input", linked.x) as num
|
||||
var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
|
||||
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
|
||||
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("Input new destiniation x coordinate", "Coordinate input", dx) as num|null
|
||||
var/newx = input(usr, "Input new destiniation x coordinate", "Coordinate input", dx) as num|null
|
||||
if(newx)
|
||||
dx = CLAMP(newx, 1, world.maxx)
|
||||
|
||||
if(params["sety"])
|
||||
var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null
|
||||
var/newy = input(usr, "Input new destiniation y coordinate", "Coordinate input", dy) as num|null
|
||||
if(newy)
|
||||
dy = CLAMP(newy, 1, world.maxy)
|
||||
. = TRUE
|
||||
@@ -356,13 +356,13 @@
|
||||
. = TRUE
|
||||
|
||||
if("speedlimit")
|
||||
var/newlimit = input("Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null
|
||||
var/newlimit = input(usr, "Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null
|
||||
if(newlimit)
|
||||
speedlimit = CLAMP(newlimit/1000, 0, 100)
|
||||
. = TRUE
|
||||
|
||||
if("accellimit")
|
||||
var/newlimit = input("Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null
|
||||
var/newlimit = input(usr, "Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null
|
||||
if(newlimit)
|
||||
accellimit = max(newlimit/1000, 0)
|
||||
. = TRUE
|
||||
@@ -402,7 +402,7 @@
|
||||
. = TRUE
|
||||
|
||||
if("set_global_limit")
|
||||
var/newlim = input("Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num
|
||||
var/newlim = input(usr, "Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num
|
||||
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("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
|
||||
var/newlim = input(usr, "Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
|
||||
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("Set new sensors range", "Sensor range", sensors.range) as num|null
|
||||
var/nrange = input(usr, "Set new sensors range", "Sensor range", sensors.range) as num|null
|
||||
if(nrange)
|
||||
sensors.set_range(CLAMP(nrange, 1, world.view))
|
||||
. = TRUE
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
return TRUE
|
||||
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input("Enter a new ident tag.", "Core Control", core_tag) as null|text)
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Core Control", core_tag) as null|text)
|
||||
if(new_ident)
|
||||
core_tag = new_ident
|
||||
return TRUE
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
return TRUE
|
||||
|
||||
if("set_tag")
|
||||
var/new_ident = sanitize_text(input("Enter a new ident tag.", "Gyrotron Control", fuel_tag) as null|text)
|
||||
var/new_ident = sanitize_text(input(usr, "Enter a new ident tag.", "Gyrotron Control", fuel_tag) as null|text)
|
||||
if(new_ident)
|
||||
fuel_tag = new_ident
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = I
|
||||
|
||||
var/desc = input("Please select a location to lock in.", "Locking Menu") in L|null
|
||||
var/desc = tgui_input_list(usr, "Please select a location to lock in.", "Locking Menu", L)
|
||||
if(!desc)
|
||||
return FALSE
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
|
||||
169
code/modules/tgui/tgui_alert.dm
Normal file
169
code/modules/tgui/tgui_alert.dm
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* 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
|
||||
195
code/modules/tgui/tgui_input_list.dm
Normal file
195
code/modules/tgui/tgui_input_list.dm
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* 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.
|
||||
* * 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 list")
|
||||
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.
|
||||
* * 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 list")
|
||||
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
|
||||
/// 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()
|
||||
var/list/repeat_buttons = list()
|
||||
|
||||
// Gets rid of illegal characters
|
||||
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
|
||||
|
||||
for(var/i in buttons)
|
||||
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
|
||||
)
|
||||
|
||||
/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
|
||||
Reference in New Issue
Block a user