tgui backend
This commit is contained in:
+65
-38
@@ -4,7 +4,7 @@
|
||||
var/window_id // window_id is used as the window name for browse and onclose
|
||||
var/width = 0
|
||||
var/height = 0
|
||||
var/atom/ref = null
|
||||
var/datum/weakref/ref = null
|
||||
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
||||
var/stylesheets[0]
|
||||
var/scripts[0]
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null)
|
||||
|
||||
user = nuser
|
||||
RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/user_deleted)
|
||||
window_id = nwindow_id
|
||||
if (ntitle)
|
||||
title = format_text(ntitle)
|
||||
@@ -26,7 +26,11 @@
|
||||
if (nheight)
|
||||
height = nheight
|
||||
if (nref)
|
||||
ref = nref
|
||||
ref = WEAKREF(nref)
|
||||
|
||||
/datum/browser/proc/user_deleted(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
user = null
|
||||
|
||||
/datum/browser/proc/add_head_content(nhead_content)
|
||||
head_content = nhead_content
|
||||
@@ -35,7 +39,7 @@
|
||||
window_options = nwindow_options
|
||||
|
||||
/datum/browser/proc/add_stylesheet(name, file)
|
||||
if(istype(name, /datum/asset/spritesheet))
|
||||
if (istype(name, /datum/asset/spritesheet))
|
||||
var/datum/asset/spritesheet/sheet = name
|
||||
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
|
||||
else
|
||||
@@ -94,27 +98,32 @@
|
||||
"}
|
||||
|
||||
/datum/browser/proc/open(use_onclose = TRUE)
|
||||
if(isnull(window_id)) //null check because this can potentially nuke goonchat
|
||||
if(isnull(window_id)) //null check because this can potentially nuke goonchat
|
||||
WARNING("Browser [title] tried to open with a null ID")
|
||||
to_chat(user, "<span class='userdanger'>The [title] browser you tried to open failed a sanity check! Please report this on github!</span>")
|
||||
to_chat(user, span_userdanger("The [title] browser you tried to open failed a sanity check! Please report this on github!"))
|
||||
return
|
||||
var/window_size = ""
|
||||
if(width && height)
|
||||
if (width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
common_asset.send(user)
|
||||
if(stylesheets.len)
|
||||
if (stylesheets.len)
|
||||
SSassets.transport.send_assets(user, stylesheets)
|
||||
if(scripts.len)
|
||||
if (scripts.len)
|
||||
SSassets.transport.send_assets(user, scripts)
|
||||
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
|
||||
if(use_onclose)
|
||||
if (use_onclose)
|
||||
setup_onclose()
|
||||
|
||||
/datum/browser/proc/setup_onclose()
|
||||
set waitfor = 0 //winexists sleeps, so we don't need to.
|
||||
for (var/i in 1 to 10)
|
||||
if (user && winexists(user, window_id))
|
||||
onclose(user, window_id, ref)
|
||||
if (user?.client && winexists(user, window_id))
|
||||
var/atom/send_ref
|
||||
if(ref)
|
||||
send_ref = ref.resolve()
|
||||
if(!send_ref)
|
||||
ref = null
|
||||
onclose(user, window_id, send_ref)
|
||||
break
|
||||
|
||||
/datum/browser/proc/close()
|
||||
@@ -153,11 +162,35 @@
|
||||
opentime = 0
|
||||
close()
|
||||
|
||||
//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified)
|
||||
/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
|
||||
/**
|
||||
* **DEPRECATED: USE tgui_alert(...) INSTEAD**
|
||||
*
|
||||
* Designed as a drop in replacement for alert(); functions the same. (outside of needing User specified)
|
||||
* Arguments:
|
||||
* * User - The user to show the alert to.
|
||||
* * Message - The textual body of the alert.
|
||||
* * Title - The title of the alert's window.
|
||||
* * Button1 - The first button option.
|
||||
* * Button2 - The second button option.
|
||||
* * Button3 - The third button option.
|
||||
* * StealFocus - Boolean operator controlling if the alert will steal the user's window focus.
|
||||
* * Timeout - The timeout of the window, after which no responses will be valid.
|
||||
*/
|
||||
/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = TRUE, Timeout = 6000)
|
||||
if (!User)
|
||||
User = usr
|
||||
switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout))
|
||||
if (!istype(User))
|
||||
if (istype(User, /client))
|
||||
var/client/client = User
|
||||
User = client.mob
|
||||
else
|
||||
return
|
||||
|
||||
// Get user's response using a modal
|
||||
var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)
|
||||
A.open()
|
||||
A.wait()
|
||||
switch(A.selectedbutton)
|
||||
if (1)
|
||||
return Button1
|
||||
if (2)
|
||||
@@ -197,8 +230,8 @@
|
||||
.=..()
|
||||
opentime = 0
|
||||
|
||||
/datum/browser/modal/open(use_onclose = 1)
|
||||
set waitfor = 0
|
||||
/datum/browser/modal/open(use_onclose)
|
||||
set waitfor = FALSE
|
||||
opentime = world.time
|
||||
|
||||
if (stealfocus)
|
||||
@@ -277,7 +310,7 @@
|
||||
opentime = 0
|
||||
close()
|
||||
|
||||
/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor)
|
||||
/proc/presentpicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor)
|
||||
if (!istype(User))
|
||||
if (istype(User, /client/))
|
||||
var/client/C = User
|
||||
@@ -290,7 +323,7 @@
|
||||
if (A.selectedbutton)
|
||||
return list("button" = A.selectedbutton, "values" = A.valueslist)
|
||||
|
||||
/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null)
|
||||
/proc/input_bitfield(mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null)
|
||||
if (!User || !(bitfield in GLOB.bitfields))
|
||||
return
|
||||
var/list/pickerlist = list()
|
||||
@@ -376,13 +409,13 @@
|
||||
if ("string")
|
||||
settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"])
|
||||
if ("number")
|
||||
settings["mainsettings"][setting]["value"] = tgui_input_num(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num
|
||||
if ("color")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) as color
|
||||
if ("boolean")
|
||||
settings["mainsettings"][setting]["value"] = tgui_input_list(user, "[settings["mainsettings"][setting]["desc"]]?", "", list("Yes","No"))
|
||||
settings["mainsettings"][setting]["value"] = (settings["mainsettings"][setting]["value"] == "Yes") ? "No" : "Yes"
|
||||
if ("ckey")
|
||||
settings["mainsettings"][setting]["value"] = tgui_input_list(user, "[settings["mainsettings"][setting]["desc"]]?", "", list("none") + GLOB.directory)
|
||||
settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory
|
||||
if (settings["mainsettings"][setting]["callback"])
|
||||
var/datum/callback/callback = settings["mainsettings"][setting]["callback"]
|
||||
settings = callback.Invoke(settings)
|
||||
@@ -401,7 +434,7 @@
|
||||
opentime = 0
|
||||
close()
|
||||
|
||||
/proc/presentpreflikepicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor)
|
||||
/proc/presentpreflikepicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor)
|
||||
if (!istype(User))
|
||||
if (istype(User, /client/))
|
||||
var/client/C = User
|
||||
@@ -414,12 +447,6 @@
|
||||
if (A.selectedbutton)
|
||||
return list("button" = A.selectedbutton, "settings" = A.settings)
|
||||
|
||||
// This will allow you to show an icon in the browse window
|
||||
// This is added to mob so that it can be used without a reference to the browser object
|
||||
// There is probably a better place for this...
|
||||
/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
|
||||
|
||||
|
||||
// Registers the on-close verb for a browse window (client/verb/.windowclose)
|
||||
// this will be called when the close-button of a window is pressed.
|
||||
//
|
||||
@@ -427,8 +454,8 @@
|
||||
// e.g. canisters, timers, etc.
|
||||
//
|
||||
// windowid should be the specified window name
|
||||
// e.g. code is : user << browse(text, "window=fred")
|
||||
// then use : onclose(user, "fred")
|
||||
// e.g. code is : user << browse(text, "window=fred")
|
||||
// then use : onclose(user, "fred")
|
||||
//
|
||||
// Optionally, specify the "ref" parameter as the controlled atom (usually src)
|
||||
// to pass a "close=1" parameter to the atom's Topic() proc for special handling.
|
||||
@@ -451,18 +478,18 @@
|
||||
// otherwise, just reset the client mob's machine var.
|
||||
//
|
||||
/client/verb/windowclose(atomref as text)
|
||||
set hidden = TRUE // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
set hidden = TRUE // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
|
||||
if(atomref!="null") // if passed a real atomref
|
||||
var/hsrc = locate(atomref) // find the reffed atom
|
||||
if(atomref!="null") // if passed a real atomref
|
||||
var/hsrc = locate(atomref) // find the reffed atom
|
||||
var/href = "close=1"
|
||||
if(hsrc)
|
||||
usr = src.mob
|
||||
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
||||
return // Topic() proc via client.Topic()
|
||||
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
||||
return // Topic() proc via client.Topic()
|
||||
|
||||
// no atomref specified (or not found)
|
||||
// so just reset the user mob's machine var
|
||||
if(src && src.mob)
|
||||
if(src?.mob)
|
||||
src.mob.unset_machine()
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
. = TRUE
|
||||
var/atom/real_location = real_location()
|
||||
if(I.loc != real_location && real_location)
|
||||
if(real_location && I.loc != real_location)
|
||||
I.forceMove(real_location)
|
||||
refresh_mob_views()
|
||||
|
||||
@@ -95,16 +95,19 @@
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A)
|
||||
SIGNAL_HANDLER
|
||||
var/atom/real_location = parent
|
||||
if(A in real_location)
|
||||
usr = null
|
||||
remove_from_storage(A, null)
|
||||
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled)
|
||||
SIGNAL_HANDLER
|
||||
if(drop_all_on_deconstruct)
|
||||
do_quick_empty()
|
||||
|
||||
/datum/component/storage/concrete/proc/on_break(datum/source, damage_flag)
|
||||
SIGNAL_HANDLER
|
||||
if(drop_all_on_break)
|
||||
do_quick_empty()
|
||||
if(unlock_on_break)
|
||||
@@ -131,14 +134,16 @@
|
||||
var/list/seeing_mobs = can_see_contents()
|
||||
for(var/mob/M in seeing_mobs)
|
||||
M.client.screen -= AM
|
||||
if(ismob(parent.loc) && isitem(AM))
|
||||
var/obj/item/I = AM
|
||||
var/mob/M = parent.loc
|
||||
I.dropped(M)
|
||||
I.item_flags &= ~IN_STORAGE
|
||||
I.remove_outline()
|
||||
if(isitem(AM))
|
||||
var/obj/item/removed_item = AM
|
||||
removed_item.item_flags &= ~IN_STORAGE
|
||||
if(ismob(parent.loc))
|
||||
var/mob/carrying_mob = parent.loc
|
||||
removed_item.dropped(carrying_mob, TRUE)
|
||||
if(new_location)
|
||||
AM.forceMove(new_location) // exited comsig will handle removal reset.
|
||||
//Reset the items values
|
||||
_removal_reset(AM)
|
||||
AM.forceMove(new_location)
|
||||
//We don't want to call this if the item is being destroyed
|
||||
AM.on_exit_storage(src)
|
||||
else
|
||||
@@ -147,7 +152,7 @@
|
||||
refresh_mob_views()
|
||||
if(isobj(parent))
|
||||
var/obj/O = parent
|
||||
O.update_icon()
|
||||
O.update_appearance()
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M)
|
||||
@@ -158,7 +163,7 @@
|
||||
if(. && !prevent_warning)
|
||||
slave.mob_item_insertion_feedback(usr, M, I)
|
||||
|
||||
/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum
|
||||
/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
var/atom/parent = src.parent
|
||||
var/moved = FALSE
|
||||
@@ -168,7 +173,7 @@
|
||||
if(!M.temporarilyRemoveItemFromInventory(I))
|
||||
return FALSE
|
||||
else
|
||||
moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever.
|
||||
moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever.
|
||||
if(I.pulledby)
|
||||
I.pulledby.stop_pulling()
|
||||
if(silent)
|
||||
@@ -203,7 +208,7 @@
|
||||
/datum/component/storage/concrete/update_icon()
|
||||
if(isobj(parent))
|
||||
var/obj/O = parent
|
||||
O.update_icon()
|
||||
O.update_appearance()
|
||||
for(var/i in slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
slave.update_icon()
|
||||
|
||||
@@ -418,38 +418,38 @@
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
set waitfor = FALSE
|
||||
. = COMPONENT_NO_MOUSEDROP
|
||||
if(!ismob(M))
|
||||
return
|
||||
if(!over_object)
|
||||
return
|
||||
if(ismecha(M.loc)) // stops inventory actions in a mech
|
||||
return
|
||||
if(M.incapacitated() || !M.canUseStorage())
|
||||
return
|
||||
var/atom/A = parent
|
||||
if(ismob(M)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked
|
||||
A.add_fingerprint(M)
|
||||
if(istype(A, /obj/item))
|
||||
var/obj/item/I = A
|
||||
I.remove_outline() //Removes the outline when we drag
|
||||
if(!over_object)
|
||||
return FALSE
|
||||
if(ismecha(M.loc)) // stops inventory actions in a mech
|
||||
return FALSE
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M, trigger_on_found = TRUE)
|
||||
return
|
||||
if(isrevenant(M))
|
||||
RevenantThrow(over_object, M, source)
|
||||
return
|
||||
if(!M.incapacitated())
|
||||
if(!istype(over_object, /atom/movable/screen))
|
||||
dump_content_at(over_object, M)
|
||||
return
|
||||
if(A.loc != M)
|
||||
return
|
||||
playsound(A, "rustle", 50, 1, -5)
|
||||
A.do_jiggle()
|
||||
if(istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
var/atom/movable/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
|
||||
return
|
||||
A.add_fingerprint(M)
|
||||
A.add_fingerprint(M)
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M, trigger_on_found = TRUE)
|
||||
if(isrevenant(M))
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source)
|
||||
return
|
||||
if(!istype(over_object, /atom/movable/screen))
|
||||
INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M)
|
||||
return
|
||||
if(A.loc != M)
|
||||
return
|
||||
playsound(A, "rustle", 50, TRUE, -5)
|
||||
A.do_jiggle()
|
||||
if(istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
var/atom/movable/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
|
||||
return
|
||||
A.add_fingerprint(M)
|
||||
|
||||
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE)
|
||||
var/atom/A = parent
|
||||
|
||||
@@ -120,7 +120,7 @@ Simple datum which is instanced once per type and is used for every object of sa
|
||||
return
|
||||
I.hitsound = item_sound_override
|
||||
I.usesound = item_sound_override
|
||||
I.throwhitsound = item_sound_override
|
||||
I.mob_throw_hit_sound = item_sound_override
|
||||
// I.mob_throw_hit_sound = item_sound_override
|
||||
// I.equip_sound = item_sound_override
|
||||
// I.pickup_sound = item_sound_override
|
||||
|
||||
Reference in New Issue
Block a user