From 35b3a76176839edb31c8866401c491e4bf0d8d94 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Wed, 2 Apr 2025 21:40:51 +0200 Subject: [PATCH] some fixes (#17468) --- code/datums/browser.dm | 268 ++++++++---------- .../assets/spritesheets/vending.dm | 18 +- code/modules/casino/casino_prize_vendor.dm | 2 +- code/modules/economy/vending.dm | 2 +- code/modules/telesci/gps_advanced.dm | 1 - tgui/packages/tgui-panel/chat/renderer.tsx | 17 ++ 6 files changed, 155 insertions(+), 153 deletions(-) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 7f68c185c6f..f15363958f6 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -4,19 +4,18 @@ 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/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id + 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] - var/title_image var/head_elements var/body_elements var/head_content = "" var/content = "" - var/title_buttons = "" -/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) +/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null) user = nuser + RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(user_deleted)) window_id = nwindow_id if (ntitle) title = format_text(ntitle) @@ -25,40 +24,36 @@ if (nheight) height = nheight if (nref) - ref = nref - // If a client exists, but they have disabled fancy windowing, disable it! - if(!user?.client?.prefs?.read_preference(/datum/preference/toggle/browser_style)) - return - add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs + ref = WEAKREF(nref) -//VOREStation Edit - Allow browser datums to be garbage collected -/datum/browser/Destroy() - close() - ref = null +/datum/browser/proc/user_deleted(datum/source) + SIGNAL_HANDLER user = null - . = ..() -//VOREStation Edit End - Allow browser datums to be garbage collected - -/datum/browser/proc/set_title(ntitle) - title = format_text(ntitle) /datum/browser/proc/add_head_content(nhead_content) head_content = nhead_content -/datum/browser/proc/set_title_buttons(ntitle_buttons) - title_buttons = ntitle_buttons - /datum/browser/proc/set_window_options(nwindow_options) window_options = nwindow_options -/datum/browser/proc/set_title_image(ntitle_image) - //title_image = ntitle_image - /datum/browser/proc/add_stylesheet(name, file) - stylesheets[name] = file + if (istype(name, /datum/asset/spritesheet)) + var/datum/asset/spritesheet/sheet = name + stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]" + else if (istype(name, /datum/asset/spritesheet_batched)) + var/datum/asset/spritesheet_batched/sheet = name + stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]" + else + var/asset_name = "[name].css" + + stylesheets[asset_name] = file + + if (!SSassets.cache[asset_name]) + SSassets.transport.register_asset(asset_name, file) /datum/browser/proc/add_script(name, file) - scripts[name] = file + scripts["[ckey(name)].js"] = file + SSassets.transport.register_asset("[ckey(name)].js", file) /datum/browser/proc/set_content(ncontent) content = ncontent @@ -67,25 +62,21 @@ content += ncontent /datum/browser/proc/get_header() - var/key - var/filename - for (key in stylesheets) - filename = "[ckey(key)].css" - user << browse_rsc(stylesheets[key], filename) - head_content += "" + var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common) + var/file - for (key in scripts) - filename = "[ckey(key)].js" - user << browse_rsc(scripts[key], filename) - head_content += "" + // If a client exists, but they have disabled fancy windowing, disable it! + if(user?.client?.prefs?.read_preference(/datum/preference/toggle/browser_style)) + head_content += "" + for (file in stylesheets) + head_content += "" - var/title_attributes = "class='uiTitle'" - if (title_image) - title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'" - return {" + for (file in scripts) + head_content += "" + + return {" - @@ -93,10 +84,10 @@
- [title ? "
[title]
[title_buttons]
" : ""] + [title ? "
[title]
" : ""]
"} - +//" This is here because else the rest of the file looks like a string in notepad++. /datum/browser/proc/get_footer() return {"
@@ -111,85 +102,35 @@ [get_footer()] "} -/datum/browser/proc/open(var/use_onclose = 1) - if(isnull(window_id)) //null check because this can potentially nuke goonchat +/datum/browser/proc/open(use_onclose = TRUE) + 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_userdanger("The [title] browser you tried to open failed a sanity check! Please report this on github!")) + 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) window_size = "size=[width]x[height];" + var/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common) + common_asset.send(user) + if (stylesheets.len) + SSassets.transport.send_assets(user, stylesheets) + if (scripts.len) + SSassets.transport.send_assets(user, scripts) user << browse(get_content(), "window=[window_id];[window_size][window_options]") if (use_onclose) - onclose(user, window_id, ref) + setup_onclose() -// 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) - /* - var/icon/I - if (dir >= 0) - I = new /icon(icon, icon_state, dir) - else - I = new /icon(icon, icon_state) - dir = "default" - - var/filename = "[ckey("[icon]_[icon_state]_[dir]")].png" - src << browse_rsc(I, filename) - return filename - */ - - -// 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. -// -// This is usually only needed for devices that regularly update the browse window, -// 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") -// -// 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. -// Otherwise, the user mob's machine var will be reset directly. -// -/proc/onclose(mob/user, windowid, var/atom/ref=null) - if(!user || !user.client) return - var/param = "null" - if(ref) - param = "\ref[ref]" - - winset(user, windowid, "on-close=\".windowclose [param]\"") - - //to_world("OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]") - -// the on-close client verb -// called when a browser popup window is closed after registering with proc/onclose() -// if a valid atom reference is supplied, call the atom's Topic() with "close=1" -// otherwise, just reset the client mob's machine var. -// - -/client/verb/windowclose(var/atomref as text) - set hidden = 1 // hide this verb from the user's panel - set name = ".windowclose" // no autocomplete on cmd line - - //to_world("windowclose: [atomref]") - if(atomref!="null") // if passed a real atomref - var/hsrc = locate(atomref) // find the reffed atom - if(hsrc) - //to_world("[src] Topic [href] [hsrc]") - usr = src.mob - src.Topic("close=1", list("close"="1"), 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) - //to_world("[src] was [src.mob.machine], setting to null") - src.mob.unset_machine() - return +/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?.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() if(!isnull(window_id))//null check because this can potentially nuke goonchat @@ -201,15 +142,15 @@ if (!User) return - var/output = {"
[Message]

+ var/output = {"
[Message]

- [Button1]"} + [Button1]"} if (Button2) - output += {"[Button2]"} + output += {"[Button2]"} if (Button3) - output += {"[Button3]"} + output += {"[Button3]"} output += {"
"} @@ -227,11 +168,35 @@ opentime = 0 close() -//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) -/proc/tgalert(var/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) @@ -239,27 +204,13 @@ if (3) return Button3 -//Same shit, but it returns the button number, could at some point support unlimited button amounts. -/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else - return - var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) - A.open() - A.wait() - if (A.selectedbutton) - return A.selectedbutton - /datum/browser/modal var/opentime = 0 var/timeout var/selectedbutton = 0 var/stealfocus -/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000) +/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null, StealFocus = 1, Timeout = 6000) ..() stealfocus = StealFocus if (!StealFocus) @@ -271,8 +222,8 @@ .=..() opentime = 0 -/datum/browser/modal/open() - set waitfor = 0 +/datum/browser/modal/open(use_onclose) + set waitfor = FALSE opentime = world.time if (stealfocus) @@ -304,12 +255,16 @@ if (!User) return - var/output = {"