/* Byond Vue UI framework main ui datum. */ /datum/vueui var/name = "Vueui" // title of ui window var/title = "HTML5 UI" // user that opened this ui var/mob/user // object that contains this ui var/datum/object // browser window width var/width = 100 // browser window height var/height = 100 // current state of ui data var/list/data // currently used server generated assets var/list/assets // current status of ui var/status = STATUS_INTERACTIVE var/datum/topic_state/state = null // currently active ui component var/activeui = "test" // header used for this ui, should be set before open() var/header = "default" // window id var/windowid // determines if ui state should be constantly be cheacked for updates var/auto_update_content = FALSE /** * Creates a new ui * * @param nuser - user that has opened this ui * @param nobject - object that hosts this ui and handles all data / Topic processing * @param nactiveui - Vue component that is opened to render this ui's data * @param nwidth - initial width of this ui * @param nheight - initial height of this ui * @param ntitle - title of this ui * @param ndata - initial data. Optional. * @param nstate - Topic state used for this ui's checks. Optional. * * @return nothing */ /datum/vueui/New(var/nuser, var/nobject, var/nactiveui = 0, var/nwidth = 0, var/nheight = 0, var/ntitle, var/list/ndata, var/datum/topic_state/nstate = default_state) user = nuser object = nobject data = ndata state = nstate if (nactiveui) activeui = nactiveui if (nwidth) width = nwidth if (nheight) height = nheight if (ntitle) title = ntitle SSvueui.ui_opened(src) windowid = "vueui\ref[src]" name = "Vueui [object]/[user]" /** * Opens this ui, gathers initial data * * @return nothing */ /datum/vueui/proc/open() if(QDELETED(object)) return if(!user.client) return if(!data) data = object.vueui_data_change(null, user, src) update_status() if(!status || status == STATUS_CLOSE) return var/params = "window=[windowid];" if(width && height) params += "size=[width]x[height];" send_resources_and_assets(user.client) user << browse(generate_html(), params) winset(user, "mapwindow.map", "focus=true") addtimer(CALLBACK(src, /datum/vueui/proc/setclose), 1) /datum/vueui/proc/setclose() winset(user, windowid, "on-close=\"vueuiclose \ref[src]\"") /** * Closes this ui * * @return nothing */ /datum/vueui/proc/close() SSvueui.ui_closed(src) user << browse(null, "window=[windowid]") status = null /** * Generates base html for this ui to be rendered. * * @return html code - text */ /datum/vueui/proc/generate_html() #ifdef UIDEBUG var/debugtxt = "
" #else var/debugtxt = "" #endif return {"
Javascript file has failed to load. Click here to force load resources
[debugtxt] "} /** * Generates json state object to be sent to ui. * * @return json object - text */ /datum/vueui/proc/generate_data_json() var/list/sdata = list() sdata["state"] = src.data sdata["assets"] = list() sdata["active"] = activeui sdata["uiref"] = "\ref[src]" sdata["status"] = status sdata["title"] = title sdata["wtime"] = world.time for(var/asset_name in assets) var/asset = assets[asset_name] sdata["assets"][asset_name] = list("ref" = ckey("\ref[asset["img"]]")) return json_encode(sdata) /** * Sends all resources required for proper renderig of ui * * @param cl - client that should get assets * * @return nothing */ /datum/vueui/proc/send_resources_and_assets(var/client/cl) #ifdef UIDEBUG cl << browse_rsc(file("vueui/dist/app.js"), "vueui.js") cl << browse_rsc(file("vueui/dist/app.css"), "vueui.css") #else var/datum/asset/assets = get_asset_datum(/datum/asset/simple/vueui) assets.send(cl) #endif for(var/asset_name in assets) var/asset = assets[asset_name] if (!QDELETED(asset["img"])) cl << browse_rsc(asset["img"], "vueuiimg_" + ckey("\ref[asset["img"]]") + ".png") /** * Sends requested asset to ui's client * * @param name - asset's name that should be sent to client * * @return nothing */ /datum/vueui/proc/send_asset(var/name) if (!QDELETED(user) || !user.client) return name = ckey(name) if (name in assets) user.client << browse_rsc(assets[name]["img"], "vueuiimg_" + ckey("\ref[assets[name]["img"]]") + ".png") /** * Adds / sets dynamic asset for this ui's use * * @param name - name of asset that should be added * @param img - image, an asset that will be used * * @return nothing */ /datum/vueui/proc/add_asset(var/name, var/image/img) if(QDELETED(img)) return name = ckey(name) LAZYINITLIST(assets) assets[name] = list("name" = name, "img" = img) /** * Removes dynamic asset for this ui's use * * @param name - name of asset that will be removed * * @return nothing */ /datum/vueui/proc/remove_asset(var/name) name = ckey(name) assets -= assets[name] /** * Handles interactivity and state updates * * @return nothing */ /datum/vueui/Topic(href, href_list) update_status() if(status < STATUS_INTERACTIVE || user != usr) return if(href_list["vueuiforceresource"]) if(user.client) user.client << browse_rsc(file("vueui/dist/app.js"), "vueui.js") user.client << browse_rsc(file("vueui/dist/app.css"), "vueui.css") open() if(href_list["vueuistateupdate"]) var/rdata = json_decode(href_list["vueuistateupdate"]) var/ndata = rdata["state"] var/ret = object.vueui_data_change(ndata, user, src) if(ret) ndata = ret push_change(ret) src.data = ndata if(href_list["vueuipushonly"]) return href_list["vueui"] = src // Let's pass our UI object to object for it to do things. object.Topic(href, href_list) /** * Pushes latest data to client (Including metadata such as: assets index, status, activeui) * * @param ndate - new data that should be pushed to client, if null then exisitng data is pushed * * @return nothing */ /datum/vueui/proc/push_change(var/list/ndata) if(ndata && status > STATUS_DISABLED) src.data = ndata user << output(list2params(list(generate_data_json())),"[windowid].browser:receiveUIState") /** * Check for change and push that change of data * * @param force - determines should data be pushed even if no change is present * * @return nothing */ /datum/vueui/proc/check_for_change(var/force = 0) if(status > STATUS_DISABLED) var/ret = object.vueui_data_change(data, user, src) if(ret) push_change(ret) else if (force) push_change(null) else if (force && status == STATUS_DISABLED) push_change(null) /** * Set the current status (also known as visibility) of this ui. * * @param state int The status to set, see the defines at the top of this file * * @return nothing */ /datum/vueui/proc/set_status(nstatus) if (nstatus != status) // Only update if it is different status = nstatus if(nstatus > STATUS_DISABLED) check_for_change(1) // Gather data and update it else if (nstatus == STATUS_DISABLED) push_change(null) // Only update ui data else close() /** * Update the status (visibility) of this ui based on the user's status * * @return nothing */ /datum/vueui/proc/update_status() set_status(object.CanUseTopic(user, state)) /** * Process this ui * * @return nothing */ /datum/vueui/process() if (!object || !user || status < 0) close() return update_status() if(auto_update_content) check_for_change() /** * Returns actuve theme on varous conditions * * @return themes class - text */ /datum/vueui/proc/get_theme_class() return SSvueui.get_html_theme_class(user) #undef UIDEBUG