NanoUI Goes To Brazil
@@ -1,22 +0,0 @@
|
||||
SUBSYSTEM_DEF(nanoui)
|
||||
name = "NanoUI"
|
||||
wait = 5
|
||||
flags = SS_NO_INIT
|
||||
// a list of current open /nanoui UIs, grouped by src_object and ui_key
|
||||
var/list/open_uis = list()
|
||||
// a list of current open /nanoui UIs, not grouped, for use in processing
|
||||
var/list/processing_uis = list()
|
||||
|
||||
/datum/controller/subsystem/nanoui/Recover()
|
||||
if(SSnanoui.open_uis)
|
||||
open_uis |= SSnanoui.open_uis
|
||||
if(SSnanoui.processing_uis)
|
||||
processing_uis |= SSnanoui.processing_uis
|
||||
|
||||
/datum/controller/subsystem/nanoui/stat_entry()
|
||||
return ..("[processing_uis.len] UIs")
|
||||
|
||||
/datum/controller/subsystem/nanoui/fire(resumed)
|
||||
for(var/thing in processing_uis)
|
||||
var/datum/nanoui/UI = thing
|
||||
UI.process()
|
||||
@@ -31,5 +31,5 @@
|
||||
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
|
||||
|
||||
tag = null
|
||||
SSnanoui.close_uis(src)
|
||||
SStgui.close_uis(src)
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
current.verbs -= /datum/changeling/proc/EvolutionMenu
|
||||
current.mind = null
|
||||
|
||||
SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user
|
||||
if(new_character.mind) //remove any mind currently in our new body's mind variable
|
||||
new_character.mind.current = null
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ var/datum/uplink/uplink = new()
|
||||
if(!can_buy(U))
|
||||
return
|
||||
|
||||
if(U.CanUseTopic(user, inventory_state) != STATUS_INTERACTIVE)
|
||||
if(U.CanUseTopic(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
var/cost = cost(U.uses, U)
|
||||
|
||||
@@ -286,5 +286,5 @@ var/global/list/changeling_fabricated_clothing = list(
|
||||
if(!registered_user)
|
||||
registered_user = usr
|
||||
usr.set_id_info(src)
|
||||
ui_interact(registered_user)
|
||||
tgui_interact(registered_user)
|
||||
..()
|
||||
@@ -260,7 +260,7 @@ update_flag
|
||||
|
||||
..()
|
||||
|
||||
SSnanoui.update_uis(src) // Update all NanoUIs attached to src
|
||||
SStgui.update_uis(src) // Update all NanoUIs attached to src
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(!card && user.unEquip(I))
|
||||
I.forceMove(src)
|
||||
card = I
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
update_icon()
|
||||
else if(card)
|
||||
to_chat(user, "<span class='warning'>There is already ID card inside.</span>")
|
||||
|
||||
@@ -851,11 +851,13 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/attack_ghost(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui)
|
||||
/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AiAirlock", name)
|
||||
ui.open()
|
||||
if(custom_state)
|
||||
ui.set_state(custom_state)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/door/airlock/tgui_data(mob/user)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
var/id_tag
|
||||
|
||||
var/datum/topic_state/remote/remote_state
|
||||
var/obj/machinery/embedded_controller/radio/airlock/master_controller
|
||||
|
||||
/obj/machinery/dummy_airlock_controller/process()
|
||||
@@ -25,15 +24,10 @@
|
||||
break
|
||||
if(!master_controller)
|
||||
qdel(src)
|
||||
else
|
||||
remote_state = new /datum/topic_state/remote(src, master_controller)
|
||||
|
||||
/obj/machinery/dummy_airlock_controller/Destroy()
|
||||
if(master_controller)
|
||||
master_controller.dummy_terminals -= src
|
||||
if(remote_state)
|
||||
qdel(remote_state)
|
||||
remote_state = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/dummy_airlock_controller/interface_interact(var/mob/user)
|
||||
|
||||
@@ -192,7 +192,6 @@
|
||||
if(inoperable())
|
||||
to_chat(usr, "\The [src] doesn't appear to function.")
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/media/jukebox/tgui_status(mob/user)
|
||||
|
||||
@@ -233,7 +233,6 @@
|
||||
/obj/machinery/partslathe/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/partslathe/ui_assets(mob/user)
|
||||
|
||||
@@ -95,7 +95,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
|
||||
/obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user)
|
||||
if(W?.is_multitool())
|
||||
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
|
||||
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state))
|
||||
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
// Check for duplicate controllers with this ID
|
||||
for(var/thing in pointdefense_controllers)
|
||||
var/obj/machinery/pointdefense_control/PC = thing
|
||||
@@ -211,7 +211,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
|
||||
/obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user)
|
||||
if(W?.is_multitool())
|
||||
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
|
||||
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state))
|
||||
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>")
|
||||
id_tag = new_ident
|
||||
return
|
||||
|
||||
@@ -104,7 +104,6 @@ var/list/obj/machinery/requests_console/allConsoles = list()
|
||||
/obj/machinery/requests_console/attack_hand(user as mob)
|
||||
if(..(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui)
|
||||
|
||||
@@ -144,6 +144,6 @@
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
if(CanInteract(user, physical_state))
|
||||
if(CanInteract(user, GLOB.tgui_physical_state))
|
||||
beep = !beep
|
||||
to_chat(user, "<span class='notice'>You turn the sound on \the [src] [beep ? "on" : "off"].</span>")
|
||||
|
||||
@@ -559,12 +559,12 @@
|
||||
target.attack_hand(src.occupant)
|
||||
return 1
|
||||
if(istype(target, /obj/machinery/embedded_controller))
|
||||
target.ui_interact(src.occupant)
|
||||
target.tgui_interact(src.occupant)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/mecha/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
. = user.shared_living_nano_distance(src_object) //allow them to interact with anything they can interact with normally.
|
||||
/obj/mecha/contents_tgui_distance(var/src_object, var/mob/living/user)
|
||||
. = user.shared_living_tgui_distance(src_object) //allow them to interact with anything they can interact with normally.
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
//Allow interaction with the mecha or anything that is part of the mecha
|
||||
if(src_object == src || (src_object in src))
|
||||
|
||||
@@ -233,7 +233,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
initialize_exonet(user)
|
||||
alert_called = 0
|
||||
update_icon()
|
||||
ui_interact(user) // TGUITODO: Remove
|
||||
tgui_interact(user)
|
||||
if(video_source)
|
||||
watch_video(user)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/in_hack_mode = 0
|
||||
var/list/known_targets
|
||||
var/list/supported_types
|
||||
var/datum/topic_state/default/must_hack/hack_state
|
||||
var/datum/tgui_state/default/must_hack/hack_state
|
||||
|
||||
/obj/item/device/multitool/hacktool/New()
|
||||
..()
|
||||
@@ -39,7 +39,8 @@
|
||||
if(!attempt_hack(user, A))
|
||||
return 0
|
||||
|
||||
A.ui_interact(user, state = hack_state)
|
||||
// Note, if you ever want to expand supported_types, you must manually add the custom state argument to their tgui_interact
|
||||
A.tgui_interact(user, custom_state = hack_state)
|
||||
return 1
|
||||
|
||||
/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target)
|
||||
@@ -83,18 +84,18 @@
|
||||
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
|
||||
known_targets -= target
|
||||
|
||||
/datum/topic_state/default/must_hack
|
||||
/datum/tgui_state/default/must_hack
|
||||
var/obj/item/device/multitool/hacktool/hacktool
|
||||
|
||||
/datum/topic_state/default/must_hack/New(var/hacktool)
|
||||
/datum/tgui_state/default/must_hack/New(var/hacktool)
|
||||
src.hacktool = hacktool
|
||||
..()
|
||||
|
||||
/datum/topic_state/default/must_hack/Destroy()
|
||||
/datum/tgui_state/default/must_hack/Destroy()
|
||||
hacktool = null
|
||||
return ..()
|
||||
|
||||
/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user)
|
||||
/datum/tgui_state/default/must_hack/can_use_topic(src_object, mob/user)
|
||||
if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
@@ -151,14 +151,6 @@ var/global/list/default_medbay_channels = list(
|
||||
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/item/device/radio/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nano_ui/master_ui, datum/topic_state/state)
|
||||
log_runtime(EXCEPTION("Warning: [user] attempted to call ui_interact on radio [src] [type]. This is deprecated. Please update the caller to tgui_interact."))
|
||||
|
||||
/obj/item/device/radio/Topic(href, href_list)
|
||||
if(href_list["track"])
|
||||
log_runtime(EXCEPTION("Warning: Topic() was improperly called on radio [src] [type], with the track href and \[[href] [json_encode(href_list)]]. Please update the caller to use tgui_act."))
|
||||
. = ..()
|
||||
|
||||
/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
popup.set_content(jointext(dat,null))
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/tvcamera/Topic(bred, href_list, state = physical_state)
|
||||
/obj/item/device/tvcamera/Topic(bred, href_list, state = GLOB.tgui_physical_state)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["channel"])
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
old_turf.unregister_dangerous_object(src)
|
||||
new_turf.register_dangerous_object(src)
|
||||
|
||||
/obj/Topic(href, href_list, var/datum/topic_state/state = default_state)
|
||||
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(usr && ..())
|
||||
return 1
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
CouldNotUseTopic(usr)
|
||||
return 1
|
||||
|
||||
/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state)
|
||||
/obj/CanUseTopic(var/mob/user, var/datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(user.CanUseObjTopic(src))
|
||||
return ..()
|
||||
to_chat(user, "<span class='danger'>[bicon(src)]Access Denied!</span>")
|
||||
@@ -69,7 +69,7 @@
|
||||
return 1
|
||||
|
||||
/obj/proc/CouldUseTopic(var/mob/user)
|
||||
var/atom/host = nano_host()
|
||||
var/atom/host = tgui_host()
|
||||
host.add_hiddenprint(user)
|
||||
|
||||
/obj/proc/CouldNotUseTopic(var/mob/user)
|
||||
@@ -135,7 +135,6 @@
|
||||
in_use = 0
|
||||
|
||||
/obj/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
..()
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
if(!UWC)
|
||||
return
|
||||
var/datum/category_item/underwear/selected_underwear = input(H, "Choose underwear:", "Choose underwear", H.all_underwear[UWC.name]) as null|anything in UWC.items
|
||||
if(selected_underwear && CanUseTopic(H, default_state))
|
||||
if(selected_underwear && CanUseTopic(H, GLOB.tgui_default_state))
|
||||
H.all_underwear[UWC.name] = selected_underwear
|
||||
H.hide_underwear[UWC.name] = FALSE
|
||||
. = TRUE
|
||||
|
||||
@@ -433,45 +433,6 @@
|
||||
// Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal")
|
||||
// ..()
|
||||
|
||||
/datum/asset/nanoui
|
||||
var/list/common = list()
|
||||
|
||||
var/list/common_dirs = list(
|
||||
"nano/css/",
|
||||
"nano/images/",
|
||||
"nano/images/modular_computers/",
|
||||
"nano/js/"
|
||||
)
|
||||
var/list/template_dirs = list(
|
||||
"nano/templates/"
|
||||
)
|
||||
|
||||
/datum/asset/nanoui/register()
|
||||
// Crawl the directories to find files.
|
||||
for(var/path in common_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
||||
if(fexists(path + filename))
|
||||
common[filename] = fcopy_rsc(path + filename)
|
||||
register_asset(filename, common[filename])
|
||||
// Combine all templates into a single bundle.
|
||||
var/list/template_data = list()
|
||||
for(var/path in template_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
|
||||
template_data[filename] = file2text(path + filename)
|
||||
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
|
||||
var/fname = "data/nano_templates_bundle.js"
|
||||
fdel(fname)
|
||||
text2file(template_bundle, fname)
|
||||
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
|
||||
fdel(fname)
|
||||
|
||||
/datum/asset/nanoui/send(client)
|
||||
send_asset_list(client, common)
|
||||
|
||||
//Pill sprites for UIs
|
||||
/datum/asset/chem_master
|
||||
var/assets = list()
|
||||
@@ -522,4 +483,29 @@
|
||||
|
||||
/datum/asset/spritesheet/sheetmaterials/register()
|
||||
InsertAll("", 'icons/obj/stacks.dmi')
|
||||
..()
|
||||
..()
|
||||
|
||||
// Nanomaps
|
||||
/datum/asset/simple/nanomaps
|
||||
// It REALLY doesnt matter too much if these arent up to date
|
||||
// They are relatively big
|
||||
assets = list(
|
||||
"southern_cross_nanomap_z1.png" = 'icons/_nanomaps/southern_cross_nanomap_z1.png',
|
||||
"southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png',
|
||||
"southern_cross_nanomap_z2.png" = 'icons/_nanomaps/southern_cross_nanomap_z2.png',
|
||||
"southern_cross_nanomap_z3.png" = 'icons/_nanomaps/southern_cross_nanomap_z3.png',
|
||||
"southern_cross_nanomap_z5.png" = 'icons/_nanomaps/southern_cross_nanomap_z5.png',
|
||||
"southern_cross_nanomap_z6.png" = 'icons/_nanomaps/southern_cross_nanomap_z6.png',
|
||||
"tether_nanomap_z1.png" = 'icons/_nanomaps/tether_nanomap_z1.png',
|
||||
"tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png',
|
||||
"tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png',
|
||||
"tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png',
|
||||
"tether_nanomap_z2.png" = 'icons/_nanomaps/tether_nanomap_z2.png',
|
||||
"tether_nanomap_z3.png" = 'icons/_nanomaps/tether_nanomap_z3.png',
|
||||
"tether_nanomap_z4.png" = 'icons/_nanomaps/tether_nanomap_z4.png',
|
||||
"tether_nanomap_z5.png" = 'icons/_nanomaps/tether_nanomap_z5.png',
|
||||
"tether_nanomap_z6.png" = 'icons/_nanomaps/tether_nanomap_z6.png',
|
||||
"tether_nanomap_z7.png" = 'icons/_nanomaps/tether_nanomap_z7.png',
|
||||
"tether_nanomap_z8.png" = 'icons/_nanomaps/tether_nanomap_z8.png',
|
||||
"tether_nanomap_z9.png" = 'icons/_nanomaps/tether_nanomap_z9.png',
|
||||
)
|
||||
@@ -8,8 +8,6 @@
|
||||
var/obj/item/clothing/glasses/hud/omni/hud = null
|
||||
var/mode = "civ"
|
||||
icon_state = "glasses"
|
||||
var/datum/nano_module/arscreen
|
||||
var/arscreen_path
|
||||
var/datum/tgui_module/tgarscreen
|
||||
var/tgarscreen_path
|
||||
var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection
|
||||
@@ -18,34 +16,24 @@
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/New()
|
||||
..()
|
||||
if(arscreen_path)
|
||||
arscreen = new arscreen_path(src)
|
||||
if(tgarscreen_path)
|
||||
tgarscreen = new tgarscreen_path(src)
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/Destroy()
|
||||
QDEL_NULL(arscreen)
|
||||
QDEL_NULL(tgarscreen)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/dropped()
|
||||
if(arscreen)
|
||||
SSnanoui.close_uis(src)
|
||||
if(tgarscreen)
|
||||
SStgui.close_uis(src)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/emp_act(var/severity)
|
||||
if(arscreen)
|
||||
SSnanoui.close_uis(src)
|
||||
if(tgarscreen)
|
||||
SStgui.close_uis(src)
|
||||
var/disconnect_ar = arscreen
|
||||
var/disconnect_tgar = tgarscreen
|
||||
arscreen = null
|
||||
tgarscreen = null
|
||||
spawn(20 SECONDS)
|
||||
arscreen = disconnect_ar
|
||||
tgarscreen = disconnect_tgar
|
||||
|
||||
//extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
to_chat(usr, "Your module is not installed in a hardsuit.")
|
||||
return
|
||||
|
||||
module.holder.ui_interact(usr, nano_state = contained_state)
|
||||
module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state)
|
||||
|
||||
/obj/item/rig_module/ai_container
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
if(!target)
|
||||
if(ai_card)
|
||||
if(istype(ai_card,/obj/item/device/aicard))
|
||||
ai_card.tgui_interact(H, custom_state = deep_inventory_state)
|
||||
ai_card.tgui_interact(H, custom_state = GLOB.tgui_deep_inventory_state)
|
||||
else
|
||||
eject_ai(H)
|
||||
update_verb_holder()
|
||||
|
||||
@@ -53,13 +53,12 @@
|
||||
O.loc = src
|
||||
held_card = O
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/account_database/attack_hand(mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/account_database/tgui_interact(mob/user, datum/tgui/ui)
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
output.assembly = src
|
||||
|
||||
/obj/item/device/electronic_assembly/device/check_interactivity(mob/user)
|
||||
if(!CanInteract(user, state = deep_inventory_state))
|
||||
if(!CanInteract(user, state = GLOB.tgui_deep_inventory_state))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ D [1]/ ||
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
/datum/integrated_io/nano_host()
|
||||
return holder.nano_host()
|
||||
/datum/integrated_io/tgui_host()
|
||||
return holder.tgui_host()
|
||||
|
||||
|
||||
/datum/integrated_io/proc/data_as_type(var/as_type)
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
/datum/integrated_io/list/display_pin_type()
|
||||
return IC_FORMAT_LIST
|
||||
|
||||
/datum/integrated_io/list/Topic(href, href_list, state = interactive_state)
|
||||
/datum/integrated_io/list/Topic(href, href_list, state = GLOB.tgui_always_state)
|
||||
if(!holder.check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/attack_self(mob/user)
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
if(!CanInteract(user, physical_state))
|
||||
if(!CanInteract(user, GLOB.tgui_physical_state))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
@@ -124,13 +124,13 @@
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0)
|
||||
if(istext(new_data) && CanInteract(user, physical_state))
|
||||
if(istext(new_data) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to \"[new_data]\".</span>")
|
||||
if("number")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && CanInteract(user, physical_state))
|
||||
if(isnum(new_data) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [new_data].</span>")
|
||||
if("ref")
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter a number, please.","Number pad", get_pin_data(IC_OUTPUT, 1)) as null|num
|
||||
if(isnum(new_input) && CanInteract(user, physical_state))
|
||||
if(isnum(new_input) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter some words, please.","Number pad", get_pin_data(IC_OUTPUT, 1)) as null|text
|
||||
if(istext(new_input) && CanInteract(user, physical_state))
|
||||
if(istext(new_input) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/input/colorpad/ask_for_input(mob/user)
|
||||
var/new_color = input(user, "Enter a color, please.", "Color pad", get_pin_data(IC_OUTPUT, 1)) as color|null
|
||||
if(new_color && CanInteract(user, physical_state))
|
||||
if(new_color && CanInteract(user, GLOB.tgui_physical_state))
|
||||
set_pin_data(IC_OUTPUT, 1, new_color)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
/obj/item/integrated_circuit/memory/constant/attack_self(mob/user)
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
if(!CanInteract(user, physical_state))
|
||||
if(!CanInteract(user, GLOB.tgui_physical_state))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
@@ -97,13 +97,13 @@
|
||||
if("string")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data) && CanInteract(user, physical_state))
|
||||
if(istext(new_data) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("number")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && CanInteract(user, physical_state))
|
||||
if(isnum(new_data) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("ref")
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
medicalActive1 = null
|
||||
medicalActive2 = null
|
||||
medical_cannotfind = 0
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
to_chat(usr, "<span class='notice'>You reset your record-viewing software.</span>")
|
||||
|
||||
/mob/living/silicon/pai/cancel_camera()
|
||||
|
||||
@@ -41,7 +41,6 @@ var/global/list/default_pai_software = list()
|
||||
set category = "pAI Commands"
|
||||
set name = "Software Interface"
|
||||
|
||||
ui_interact(src)
|
||||
tgui_interact(src)
|
||||
|
||||
/mob/living/silicon/pai/tgui_state(mob/user)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/mob/Logout()
|
||||
SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
||||
SStgui.on_logout(src) // Cleanup any TGUIs the user has open
|
||||
player_list -= src
|
||||
disconnect_time = world.realtime //VOREStation Addition: logging when we disappear.
|
||||
|
||||
@@ -220,12 +220,6 @@
|
||||
else
|
||||
return -1
|
||||
|
||||
/obj/item/modular_computer/initial_data()
|
||||
return get_header_data()
|
||||
|
||||
/obj/item/modular_computer/update_layout()
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/apply_visual(mob/M)
|
||||
if(TM)
|
||||
return TM.apply_visual(M)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/*
|
||||
This state checks that the user is an admin, end of story
|
||||
*/
|
||||
/var/global/datum/topic_state/admin_state/admin_state = new()
|
||||
|
||||
/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user)
|
||||
return check_rights(R_ADMIN|R_EVENT, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
@@ -1,37 +0,0 @@
|
||||
/datum/proc/nano_host()
|
||||
return src
|
||||
|
||||
/datum/proc/nano_container()
|
||||
return src
|
||||
|
||||
/datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state)
|
||||
var/src_object = nano_host()
|
||||
return state.can_use_topic(src_object, user)
|
||||
|
||||
/datum/topic_state/proc/href_list(var/mob/user)
|
||||
return list()
|
||||
|
||||
/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/proc/shared_nano_interaction()
|
||||
if (src.stat || !client)
|
||||
return STATUS_CLOSE // no updates, close the interface
|
||||
else if (incapacitated())
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/mob/living/silicon/ai/shared_nano_interaction()
|
||||
if(lacks_power())
|
||||
return STATUS_CLOSE
|
||||
if (check_unable(1, 0))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/shared_nano_interaction()
|
||||
. = STATUS_INTERACTIVE
|
||||
if(!has_power)
|
||||
return STATUS_CLOSE
|
||||
if(lockdown)
|
||||
. = STATUS_DISABLED
|
||||
return min(., ..())
|
||||
@@ -1,7 +0,0 @@
|
||||
/*
|
||||
This state only checks if user is conscious.
|
||||
*/
|
||||
/var/global/datum/topic_state/conscious_state/conscious_state = new()
|
||||
|
||||
/datum/topic_state/conscious_state/can_use_topic(var/src_object, var/mob/user)
|
||||
return user.stat == CONSCIOUS ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
This state checks if user is somewhere within src_object, as well as the default NanoUI interaction.
|
||||
*/
|
||||
/var/global/datum/topic_state/contained_state/contained_state = new()
|
||||
|
||||
/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user)
|
||||
if(!src_object.contains(user))
|
||||
return STATUS_CLOSE
|
||||
|
||||
return user.shared_nano_interaction()
|
||||
|
||||
/atom/proc/contains(var/atom/location)
|
||||
if(!location)
|
||||
return 0
|
||||
if(location == src)
|
||||
return 1
|
||||
|
||||
return contains(location.loc)
|
||||
@@ -1,91 +0,0 @@
|
||||
/var/global/datum/topic_state/default/default_state = new()
|
||||
|
||||
/datum/topic_state/default/href_list(var/mob/user)
|
||||
return list()
|
||||
|
||||
/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user)
|
||||
return user.default_can_use_topic(src_object)
|
||||
|
||||
/mob/proc/default_can_use_topic(var/src_object)
|
||||
return STATUS_CLOSE // By default no mob can do anything with NanoUI
|
||||
|
||||
/mob/observer/dead/default_can_use_topic(var/src_object)
|
||||
if(can_admin_interact())
|
||||
return STATUS_INTERACTIVE // Admins are more equal
|
||||
if(!client || get_dist(src_object, src) > client.view) // Preventing ghosts from having a million windows open by limiting to objects in range
|
||||
return STATUS_CLOSE
|
||||
return STATUS_UPDATE // Ghosts can view updates
|
||||
|
||||
/mob/living/silicon/pai/default_can_use_topic(var/src_object)
|
||||
if((src_object == src || src_object == radio || src_object == communicator) && !stat)
|
||||
return STATUS_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction()
|
||||
if(. <= STATUS_DISABLED)
|
||||
return
|
||||
|
||||
// robots can interact with things they can see within their view range
|
||||
if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view)
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
|
||||
/mob/living/silicon/ai/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction()
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
// Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras)
|
||||
// unless it's on the same level as the object it's interacting with.
|
||||
var/turf/T = get_turf(src_object)
|
||||
if(!T || !(z == T.z || (T.z in using_map.player_levels)))
|
||||
return STATUS_CLOSE
|
||||
|
||||
// If an object is in view then we can interact with it
|
||||
if(src_object in view(client.view, src))
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
// If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view
|
||||
if(is_in_chassis())
|
||||
//stop AIs from leaving windows open and using then after they lose vision
|
||||
if(cameranet && !cameranet.checkTurfVis(get_turf(src_object)))
|
||||
return STATUS_CLOSE
|
||||
return STATUS_INTERACTIVE
|
||||
else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
|
||||
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
return user.shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
|
||||
return STATUS_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
if (dist <= 1)
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
else if (dist <= 2)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
else if (dist <= 4)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. != STATUS_CLOSE)
|
||||
if(loc)
|
||||
. = min(., loc.contents_nano_distance(src_object, src))
|
||||
if(STATUS_INTERACTIVE)
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/carbon/human/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. != STATUS_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object))
|
||||
if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction.
|
||||
return STATUS_INTERACTIVE
|
||||
@@ -1,6 +0,0 @@
|
||||
/mob/living/simple_mob/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. != STATUS_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object))
|
||||
|
||||
//Allows simple mobs to interact with nanoui as long as they have "has_hands = TRUE"
|
||||
@@ -1,7 +0,0 @@
|
||||
/*
|
||||
This state always returns STATUS_INTERACTIVE
|
||||
*/
|
||||
/var/global/datum/topic_state/interactive/interactive_state = new()
|
||||
|
||||
/datum/topic_state/interactive/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_INTERACTIVE
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags).
|
||||
*/
|
||||
/var/global/datum/topic_state/inventory_state/inventory_state = new()
|
||||
|
||||
/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!(src_object in user))
|
||||
return STATUS_CLOSE
|
||||
|
||||
|
||||
return user.shared_nano_interaction()
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
This state checks if src_object is contained anywhere in the user's inventory, including bags, etc.
|
||||
*/
|
||||
/var/global/datum/topic_state/deep_inventory_state/deep_inventory_state = new()
|
||||
|
||||
/datum/topic_state/deep_inventory_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!user.contains(src_object))
|
||||
return STATUS_CLOSE
|
||||
|
||||
return user.shared_nano_interaction()
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
This state checks that the src_object is on the user's glasses slot.
|
||||
*/
|
||||
/var/global/datum/topic_state/glasses_state/glasses_state = new()
|
||||
|
||||
/datum/topic_state/glasses_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.glasses == src_object)
|
||||
return user.shared_nano_interaction()
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
/var/global/datum/topic_state/nif_state/nif_state = new()
|
||||
|
||||
/datum/topic_state/nif_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.nif && H.nif.stat == NIF_WORKING && src_object == H.nif)
|
||||
return user.shared_nano_interaction()
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
/var/global/datum/topic_state/commlink_state/commlink_state = new()
|
||||
|
||||
/datum/topic_state/commlink_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.nif && H.nif.stat == NIF_WORKING && H.nif.comm == src_object)
|
||||
return user.shared_nano_interaction()
|
||||
|
||||
return STATUS_CLOSE
|
||||
@@ -1,6 +0,0 @@
|
||||
/var/global/datum/topic_state/default/outside/outside_state = new()
|
||||
|
||||
/datum/topic_state/default/outside/can_use_topic(var/src_object, var/mob/user)
|
||||
if(user in src_object)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
@@ -1,18 +0,0 @@
|
||||
/var/global/datum/topic_state/physical/physical_state = new()
|
||||
|
||||
/datum/topic_state/physical/can_use_topic(var/src_object, var/mob/user)
|
||||
. = user.shared_nano_interaction(src_object)
|
||||
if(. > STATUS_CLOSE)
|
||||
return min(., user.check_physical_distance(src_object))
|
||||
|
||||
/mob/proc/check_physical_distance(var/src_object)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/observer/dead/check_physical_distance(var/src_object)
|
||||
return default_can_use_topic(src_object)
|
||||
|
||||
/mob/living/check_physical_distance(var/src_object)
|
||||
return shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/silicon/check_physical_distance(var/src_object)
|
||||
return max(STATUS_UPDATE, shared_living_nano_distance(src_object))
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
This state checks that user is capable, within range of the remoter, etc. and that src_object meets the basic requirements for interaction (being powered, non-broken, etc.
|
||||
Whoever initializes this state is also responsible for deleting it properly.
|
||||
*/
|
||||
/datum/topic_state/remote
|
||||
var/datum/remoter
|
||||
var/datum/remote_target
|
||||
var/datum/topic_state/remoter_state
|
||||
|
||||
/datum/topic_state/remote/New(var/remoter, var/remote_target, var/datum/topic_state/remoter_state = default_state)
|
||||
src.remoter = remoter
|
||||
src.remote_target = remote_target
|
||||
src.remoter_state = remoter_state
|
||||
..()
|
||||
|
||||
/datum/topic_state/remote/Destroy()
|
||||
src.remoter = null
|
||||
src.remoter_state = null
|
||||
|
||||
// Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes.
|
||||
SSnanoui.update_uis(remote_target.nano_container())
|
||||
remote_target = null
|
||||
return ..()
|
||||
|
||||
/datum/topic_state/remote/can_use_topic(var/datum/src_object, var/mob/user)
|
||||
if(!(remoter && remoter_state)) // The remoter is gone, let us leave
|
||||
return STATUS_CLOSE
|
||||
|
||||
if(src_object != remote_target)
|
||||
error("remote - Unexpected src_object: Expected '[remote_target]'/[remote_target.type], was '[src_object]'/[src_object.type]")
|
||||
|
||||
// This checks if src_object is powered, etc.
|
||||
// The interactive state is otherwise simplistic and only returns STATUS_INTERACTIVE and never checks distances, etc.
|
||||
. = src_object.CanUseTopic(user, interactive_state)
|
||||
if(. == STATUS_CLOSE)
|
||||
return
|
||||
|
||||
// This is the (generally) heavy checking, making sure the user is capable, within range of the remoter source, etc.
|
||||
return min(., remoter.CanUseTopic(user, remoter_state))
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
This state checks that the src_object is the same the as user
|
||||
*/
|
||||
/var/global/datum/topic_state/self_state/self_state = new()
|
||||
|
||||
/datum/topic_state/self_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(src_object != user)
|
||||
return STATUS_CLOSE
|
||||
return user.shared_nano_interaction()
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
This state checks that the user is on the same Z-level as src_object
|
||||
*/
|
||||
|
||||
/var/global/datum/topic_state/z_state/z_state = new()
|
||||
|
||||
/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user)
|
||||
var/turf/turf_obj = get_turf(src_object)
|
||||
var/turf/turf_usr = get_turf(user)
|
||||
if(!turf_obj || !turf_usr)
|
||||
return STATUS_CLOSE
|
||||
|
||||
return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
@@ -1,60 +0,0 @@
|
||||
/datum/nano_module
|
||||
var/name
|
||||
var/datum/host
|
||||
var/list/using_access
|
||||
|
||||
/datum/nano_module/New(var/datum/host)
|
||||
..()
|
||||
src.host = host.nano_host()
|
||||
|
||||
/datum/nano_module/nano_host()
|
||||
return host ? host : src
|
||||
|
||||
/datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state)
|
||||
return CanUseTopic(usr, state) == STATUS_INTERACTIVE
|
||||
|
||||
/datum/nano_module/proc/check_eye(var/mob/user)
|
||||
return -1
|
||||
|
||||
/datum/nano_module/proc/check_access(var/mob/user, var/access)
|
||||
if(!access)
|
||||
return 1
|
||||
|
||||
if(using_access)
|
||||
if(access in using_access)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
if(!istype(user))
|
||||
return 0
|
||||
|
||||
var/obj/item/weapon/card/id/I = user.GetIdCard()
|
||||
if(!I)
|
||||
return 0
|
||||
|
||||
if(access in I.access)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/datum/nano_module/proc/print_text(var/text, var/mob/user)
|
||||
var/obj/item/modular_computer/MC = nano_host()
|
||||
if(istype(MC))
|
||||
if(!MC.nano_printer)
|
||||
to_chat(user, "Error: No printer detected. Unable to print document.")
|
||||
return
|
||||
|
||||
if(!MC.nano_printer.print_text(text))
|
||||
to_chat(user, "Error: Printer was unable to print the document. It may be out of paper.")
|
||||
else
|
||||
to_chat(user, "Error: Unable to detect compatible printer interface. Are you running NTOSv2 compatible system?")
|
||||
|
||||
/datum/proc/initial_data()
|
||||
return list()
|
||||
|
||||
/datum/proc/update_layout()
|
||||
return FALSE
|
||||
|
||||
/datum/nano_module/proc/relaymove(var/mob/user, direction)
|
||||
return FALSE
|
||||
@@ -1,44 +0,0 @@
|
||||
// This file contains all Nano procs/definitions for external classes/objects
|
||||
|
||||
/**
|
||||
* Called when a Nano UI window is closed
|
||||
* This is how Nano handles closed windows
|
||||
* It must be a verb so that it can be called using winset
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/client/verb/nanoclose(var/uiref as text)
|
||||
set hidden = 1 // hide this verb from the user's panel
|
||||
set name = "nanoclose"
|
||||
|
||||
var/datum/nanoui/ui = locate(uiref)
|
||||
|
||||
if (istype(ui))
|
||||
ui.close()
|
||||
|
||||
if(ui.ref)
|
||||
var/href = "close=1"
|
||||
src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic()
|
||||
else if (ui.on_close_logic)
|
||||
// no atomref specified (or not found)
|
||||
// so just reset the user mob's machine var
|
||||
if(src && src.mob)
|
||||
src.mob.unset_machine()
|
||||
|
||||
/**
|
||||
* The ui_interact proc is used to open and update Nano UIs
|
||||
* If ui_interact is not used then the UI will not update correctly
|
||||
* ui_interact is currently defined for /atom/movable
|
||||
*
|
||||
* @param user /mob The mob who is interacting with this ui
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||
* @param force_open boolean Force the UI to (re)open, even if it's already open
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
return
|
||||
|
||||
// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob
|
||||
/mob/var/list/open_uis = list()
|
||||
@@ -1,224 +0,0 @@
|
||||
|
||||
/**
|
||||
* Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data
|
||||
*
|
||||
* @param user /mob The mob who opened/owns the ui
|
||||
* @param src_object /obj|/mob The obj or mob which the ui belongs to
|
||||
* @param ui_key string A string key used for the ui
|
||||
* @param ui /datum/nanoui An existing instance of the ui (can be null)
|
||||
* @param data list The data to be passed to the ui, if it exists
|
||||
* @param force_open boolean The ui is being forced to (re)open, so close ui if it exists (instead of updating)
|
||||
*
|
||||
* @return /nanoui Returns the found ui, for null if none exists
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data, var/force_open = 0)
|
||||
if (isnull(ui)) // no ui has been passed, so we'll search for one
|
||||
{
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
}
|
||||
if (!isnull(ui))
|
||||
// The UI is already open
|
||||
if (!force_open)
|
||||
ui.push_data(data)
|
||||
return ui
|
||||
else
|
||||
ui.reinitialise(new_initial_data=data)
|
||||
return ui
|
||||
|
||||
return null
|
||||
|
||||
/**
|
||||
* Get an open /nanoui ui for the current user, src_object and ui_key
|
||||
*
|
||||
* @param user /mob The mob who opened/owns the ui
|
||||
* @param src_object /obj|/mob The obj or mob which the ui belongs to
|
||||
* @param ui_key string A string key used for the ui
|
||||
*
|
||||
* @return /nanoui Returns the found ui, or null if none exists
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/get_open_ui(var/mob/user, src_object, ui_key)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open")
|
||||
return null
|
||||
else if (isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list))
|
||||
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open for this object")
|
||||
return null
|
||||
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if (ui.user == user)
|
||||
return ui
|
||||
|
||||
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - ui not found")
|
||||
return null
|
||||
|
||||
/**
|
||||
* Update all /nanoui uis attached to src_object
|
||||
*
|
||||
* @param src_object /obj|/mob The obj or mob which the uis are attached to
|
||||
*
|
||||
* @return int The number of uis updated
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/update_uis(src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0
|
||||
|
||||
var/update_count = 0
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
|
||||
ui.process(1)
|
||||
update_count++
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* Close all /nanoui uis attached to src_object
|
||||
*
|
||||
* @param src_object /obj|/mob The obj or mob which the uis are attached to
|
||||
*
|
||||
* @return int The number of uis close
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/close_uis(src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0
|
||||
|
||||
var/close_count = 0
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
|
||||
ui.close()
|
||||
close_count++
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* Update /nanoui uis belonging to user
|
||||
*
|
||||
* @param user /mob The mob who owns the uis
|
||||
* @param src_object /obj|/mob If src_object is provided, only update uis which are attached to src_object (optional)
|
||||
* @param ui_key string If ui_key is provided, only update uis with a matching ui_key (optional)
|
||||
*
|
||||
* @return int The number of uis updated
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // has no open uis
|
||||
|
||||
var/update_count = 0
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(1)
|
||||
update_count++
|
||||
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* Close /nanoui uis belonging to user
|
||||
*
|
||||
* @param user /mob The mob who owns the uis
|
||||
* @param src_object /obj|/mob If src_object is provided, only close uis which are attached to src_object (optional)
|
||||
* @param ui_key string If ui_key is provided, only close uis with a matching ui_key (optional)
|
||||
*
|
||||
* @return int The number of uis closed
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
//testing("nanomanager/close_user_uis mob [user.name] has no open uis")
|
||||
return 0 // has no open uis
|
||||
|
||||
var/close_count = 0
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.close()
|
||||
close_count++
|
||||
|
||||
//testing("nanomanager/close_user_uis mob [user.name] closed [open_uis.len] of [close_count] uis")
|
||||
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* Add a /nanoui ui to the list of open uis
|
||||
* This is called by the /nanoui open() proc
|
||||
*
|
||||
* @param ui /nanoui The ui to add
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/ui_opened(var/datum/nanoui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
open_uis[src_object_key] = list(ui.ui_key = list())
|
||||
else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
open_uis[src_object_key][ui.ui_key] = list();
|
||||
|
||||
ui.user.open_uis |= ui
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
uis |= ui
|
||||
processing_uis |= ui
|
||||
//testing("nanomanager/ui_opened mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]")
|
||||
|
||||
/**
|
||||
* Remove a /nanoui ui from the list of open uis
|
||||
* This is called by the /nanoui close() proc
|
||||
*
|
||||
* @param ui /nanoui The ui to remove
|
||||
*
|
||||
* @return int 0 if no ui was removed, 1 if removed successfully
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/ui_closed(var/datum/nanoui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // wasn't open
|
||||
else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
return 0 // wasn't open
|
||||
|
||||
processing_uis.Remove(ui)
|
||||
if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface)
|
||||
ui.user.open_uis.Remove(ui)
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
uis.Remove(ui)
|
||||
|
||||
//testing("nanomanager/ui_closed mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]")
|
||||
|
||||
return 1
|
||||
|
||||
/**
|
||||
* This is called on user logout
|
||||
* Closes/clears all uis attached to the user's /mob
|
||||
*
|
||||
* @param user /mob The user's mob
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
//
|
||||
/datum/controller/subsystem/nanoui/proc/user_logout(var/mob/user)
|
||||
//testing("nanomanager/user_logout user [user.name]")
|
||||
return close_user_uis(user)
|
||||
|
||||
/**
|
||||
* This is called when a player transfers from one mob to another
|
||||
* Transfers all open UIs to the new mob
|
||||
*
|
||||
* @param oldMob /mob The user's old mob
|
||||
* @param newMob /mob The user's new mob
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/controller/subsystem/nanoui/proc/user_transferred(var/mob/oldMob, var/mob/newMob)
|
||||
//testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]")
|
||||
if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0)
|
||||
//testing("nanomanager/user_transferred mob [oldMob.name] has no open uis")
|
||||
return 0 // has no open uis
|
||||
|
||||
if (isnull(newMob.open_uis) || !istype(newMob.open_uis, /list))
|
||||
newMob.open_uis = list()
|
||||
|
||||
for (var/datum/nanoui/ui in oldMob.open_uis)
|
||||
ui.user = newMob
|
||||
newMob.open_uis.Add(ui)
|
||||
|
||||
oldMob.open_uis.Cut()
|
||||
|
||||
return 1 // success
|
||||
@@ -1,529 +0,0 @@
|
||||
/**********************************************************
|
||||
NANO UI FRAMEWORK
|
||||
|
||||
nanoui class (or whatever Byond calls classes)
|
||||
|
||||
nanoui is used to open and update nano browser uis
|
||||
**********************************************************/
|
||||
|
||||
/datum/nanoui
|
||||
// the user who opened this ui
|
||||
var/mob/user
|
||||
// the object this ui "belongs" to
|
||||
var/datum/src_object
|
||||
// the title of this ui
|
||||
var/title
|
||||
// the key of this ui, this is to allow multiple (different) uis for each src_object
|
||||
var/ui_key
|
||||
// window_id is used as the window name/identifier for browse and onclose
|
||||
var/window_id
|
||||
// the browser window width
|
||||
var/width = 0
|
||||
// the browser window height
|
||||
var/height = 0
|
||||
// whether to use extra logic when window closes
|
||||
var/on_close_logic = 1
|
||||
// an extra ref to use when the window is closed, usually null
|
||||
var/atom/ref = null
|
||||
// options for modifying window behaviour
|
||||
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
|
||||
// the list of stylesheets to apply to this ui
|
||||
var/list/stylesheets = list()
|
||||
// the list of javascript scripts to use for this ui
|
||||
var/list/scripts = list()
|
||||
// a list of templates which can be used with this ui
|
||||
var/templates[0]
|
||||
// the layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
|
||||
var/layout_key = "default"
|
||||
// this sets whether to re-render the ui layout with each update (default 0, turning on will break the map ui if it's in use)
|
||||
var/auto_update_layout = 0
|
||||
// this sets whether to re-render the ui content with each update (default 1)
|
||||
var/auto_update_content = 1
|
||||
// the default state to use for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
|
||||
var/state_key = "default"
|
||||
// show the map ui, this is used by the default layout
|
||||
var/show_map = 0
|
||||
// the map z level to display
|
||||
var/map_z_level = 1
|
||||
// initial data, containing the full data structure, must be sent to the ui (the data structure cannot be extended later on)
|
||||
var/list/initial_data[0]
|
||||
// set to 1 to update the ui automatically every master_controller tick
|
||||
var/is_auto_updating = 0
|
||||
// the current status/visibility of the ui
|
||||
var/status = STATUS_INTERACTIVE
|
||||
|
||||
// Relationship between a master interface and its children. Used in update_status
|
||||
var/datum/nanoui/master_ui
|
||||
var/list/datum/nanoui/children = list()
|
||||
var/datum/topic_state/state = null
|
||||
|
||||
/**
|
||||
* Create a new nanoui instance.
|
||||
*
|
||||
* @param nuser /mob The mob who has opened/owns this ui
|
||||
* @param nsrc_object /obj|/mob The obj or mob which this ui belongs to
|
||||
* @param nui_key string A string key to use for this ui. Allows for multiple unique uis on one src_oject
|
||||
* @param ntemplate string The filename of the template file from /nano/templates (e.g. "my_template.tmpl")
|
||||
* @param ntitle string The title of this ui
|
||||
* @param nwidth int the width of the ui window
|
||||
* @param nheight int the height of the ui window
|
||||
* @param nref /atom A custom ref to use if "on_close_logic" is set to 1
|
||||
*
|
||||
* @return /nanoui new nanoui object
|
||||
*/
|
||||
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
user = nuser
|
||||
src_object = nsrc_object
|
||||
ui_key = nui_key
|
||||
window_id = "[ui_key]\ref[src_object]"
|
||||
|
||||
src.master_ui = master_ui
|
||||
if(master_ui)
|
||||
master_ui.children += src
|
||||
src.state = state
|
||||
|
||||
// add the passed template filename as the "main" template, this is required
|
||||
add_template("main", ntemplate_filename)
|
||||
|
||||
if (ntitle)
|
||||
title = sanitize(ntitle)
|
||||
if (nwidth)
|
||||
width = nwidth
|
||||
if (nheight)
|
||||
height = nheight
|
||||
if (nref)
|
||||
ref = nref
|
||||
|
||||
add_common_assets()
|
||||
|
||||
/**
|
||||
* Use this proc to add assets which are common to (and required by) all nano uis
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/add_common_assets()
|
||||
add_script("libraries.min.js") // A JS file comprising of jQuery, doT.js and jQuery Timer libraries (compressed together)
|
||||
add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions.
|
||||
add_script("nano_templates_bundle.js") // Contains all templates, generated by asset cache system at server start.
|
||||
add_script("nano_template.js") // The NanoTemplate JS, this is used to render templates.
|
||||
add_script("nano_state_manager.js") // The NanoStateManager JS, it handles updates from the server and passes data to the current state
|
||||
add_script("nano_state.js") // The NanoState JS, this is the base state which all states must inherit from
|
||||
add_script("nano_state_default.js") // The NanoStateDefault JS, this is the "default" state (used by all UIs by default), which inherits from NanoState
|
||||
add_script("nano_state_pda.js") // The NanoStatePDA JS, this is the state used for PDAs.
|
||||
add_script("nano_base_callbacks.js") // The NanoBaseCallbacks JS, this is used to set up (before and after update) callbacks which are common to all UIs
|
||||
add_script("nano_base_helpers.js") // The NanoBaseHelpers JS, this is used to set up template helpers which are common to all UIs
|
||||
add_stylesheet("shared.css") // this CSS sheet is common to all UIs
|
||||
add_stylesheet("shared_vr.css") // VOREStation Add
|
||||
add_stylesheet("icons.css") // this CSS sheet is common to all UIs
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param push_update int (bool) Push an update to the ui to update it's status (an update is always sent if the status has changed to red (0))
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_status(state, push_update)
|
||||
if (state != status) // Only update if it is different
|
||||
if (status == STATUS_DISABLED)
|
||||
status = state
|
||||
if (push_update)
|
||||
update()
|
||||
else
|
||||
status = state
|
||||
if (push_update || status == 0)
|
||||
push_data(null, 1) // Update the UI, force the update in case the status is 0, data is null so that previous data is used
|
||||
|
||||
/**
|
||||
* Update the status (visibility) of this ui based on the user's status
|
||||
*
|
||||
* @param push_update int (bool) Push an update to the ui to update it's status. This is set to 0/false if an update is going to be pushed anyway (to avoid unnessary updates)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/update_status(var/push_update = 0)
|
||||
var/obj/host = src_object.nano_host()
|
||||
var/new_status = host.CanUseTopic(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
set_status(new_status, push_update)
|
||||
if(new_status == STATUS_CLOSE)
|
||||
close()
|
||||
|
||||
/**
|
||||
* Set the ui to auto update (every master_controller tick)
|
||||
*
|
||||
* @param state int (bool) Set auto update to 1 or 0 (true/false)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_auto_update(nstate = 1)
|
||||
is_auto_updating = nstate
|
||||
|
||||
/**
|
||||
* Set the initial data for the ui. This is vital as the data structure set here cannot be changed when pushing new updates.
|
||||
*
|
||||
* @param data /list The list of data for this ui
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_initial_data(list/data)
|
||||
initial_data = data
|
||||
|
||||
/**
|
||||
* Get config data to sent to the ui.
|
||||
*
|
||||
* @return /list config data
|
||||
*/
|
||||
/datum/nanoui/proc/get_config_data()
|
||||
var/name = "[src_object]"
|
||||
name = sanitize(name)
|
||||
var/list/config_data = list(
|
||||
"title" = title,
|
||||
"srcObject" = list("name" = name),
|
||||
"stateKey" = state_key,
|
||||
"status" = status,
|
||||
"autoUpdateLayout" = auto_update_layout,
|
||||
"autoUpdateContent" = auto_update_content,
|
||||
"showMap" = show_map,
|
||||
"mapZLevel" = map_z_level,
|
||||
"user" = list("name" = user.name)
|
||||
)
|
||||
return config_data
|
||||
|
||||
/**
|
||||
* Get data to sent to the ui.
|
||||
*
|
||||
* @param data /list The list of general data for this ui (can be null to use previous data sent)
|
||||
*
|
||||
* @return /list data to send to the ui
|
||||
*/
|
||||
/datum/nanoui/proc/get_send_data(var/list/data)
|
||||
var/list/config_data = get_config_data()
|
||||
|
||||
var/list/send_data = list("config" = config_data)
|
||||
|
||||
if (!isnull(data))
|
||||
send_data["data"] = data
|
||||
|
||||
return send_data
|
||||
|
||||
/**
|
||||
* Set the browser window options for this ui
|
||||
*
|
||||
* @param nwindow_options string The new window options
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_window_options(nwindow_options)
|
||||
window_options = nwindow_options
|
||||
|
||||
/**
|
||||
* Add a CSS stylesheet to this UI
|
||||
* These must be added before the UI has been opened, adding after that will have no effect
|
||||
*
|
||||
* @param file string The name of the CSS file from /nano/css (e.g. "my_style.css")
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/add_stylesheet(file)
|
||||
stylesheets.Add(file)
|
||||
|
||||
/**
|
||||
* Add a JavsScript script to this UI
|
||||
* These must be added before the UI has been opened, adding after that will have no effect
|
||||
*
|
||||
* @param file string The name of the JavaScript file from /nano/js (e.g. "my_script.js")
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/add_script(file)
|
||||
scripts.Add(file)
|
||||
|
||||
/**
|
||||
* Add a template for this UI
|
||||
* Templates are combined with the data sent to the UI to create the rendered view
|
||||
* These must be added before the UI has been opened, adding after that will have no effect
|
||||
*
|
||||
* @param key string The key which is used to reference this template in the frontend
|
||||
* @param filename string The name of the template file from /nano/templates (e.g. "my_template.tmpl")
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/add_template(key, filename)
|
||||
templates[key] = filename
|
||||
|
||||
/**
|
||||
* Set the layout key for use in the frontend Javascript
|
||||
* The layout key is the basic layout key for the page
|
||||
* Two files are loaded on the client based on the layout key varable:
|
||||
* -> a template in /nano/templates with the filename "layout_<layout_key>.tmpl
|
||||
* -> a CSS stylesheet in /nano/css with the filename "layout_<layout_key>.css
|
||||
*
|
||||
* @param nlayout string The layout key to use
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_layout_key(nlayout_key)
|
||||
layout_key = lowertext(nlayout_key)
|
||||
|
||||
/**
|
||||
* Set the ui to update the layout (re-render it) on each update, turning this on will break the map ui (if it's being used)
|
||||
*
|
||||
* @param state int (bool) Set update to 1 or 0 (true/false) (default 0)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_auto_update_layout(nstate)
|
||||
auto_update_layout = nstate
|
||||
|
||||
/**
|
||||
* Set the ui to update the main content (re-render it) on each update
|
||||
*
|
||||
* @param state int (bool) Set update to 1 or 0 (true/false) (default 1)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_auto_update_content(nstate)
|
||||
auto_update_content = nstate
|
||||
|
||||
/**
|
||||
* Set the state key for use in the frontend Javascript
|
||||
*
|
||||
* @param nstate_key string The key of the state to use
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_state_key(nstate_key)
|
||||
state_key = nstate_key
|
||||
|
||||
/**
|
||||
* Toggle showing the map ui
|
||||
*
|
||||
* @param nstate_key boolean 1 to show map, 0 to hide (default is 0)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_show_map(nstate)
|
||||
show_map = nstate
|
||||
|
||||
/**
|
||||
* Toggle showing the map ui
|
||||
*
|
||||
* @param nstate_key boolean 1 to show map, 0 to hide (default is 0)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/set_map_z_level(nz)
|
||||
map_z_level = nz
|
||||
|
||||
/**
|
||||
* Set whether or not to use the "old" on close logic (mainly unset_machine())
|
||||
*
|
||||
* @param state int (bool) Set on_close_logic to 1 or 0 (true/false)
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/use_on_close_logic(state)
|
||||
on_close_logic = state
|
||||
|
||||
/**
|
||||
* Return the HTML for this UI
|
||||
*
|
||||
* @return string HTML for the UI
|
||||
*/
|
||||
/datum/nanoui/proc/get_html()
|
||||
|
||||
// before the UI opens, add the layout files based on the layout key
|
||||
add_stylesheet("layout_[layout_key].css")
|
||||
add_template("layout", "layout_[layout_key].tmpl")
|
||||
|
||||
var/head_content = ""
|
||||
|
||||
for (var/filename in scripts)
|
||||
head_content += "<script type='text/javascript' src='[filename]'></script> "
|
||||
|
||||
for (var/filename in stylesheets)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'> "
|
||||
|
||||
var/template_data_json = "{}" // An empty JSON object
|
||||
if (templates.len > 0)
|
||||
template_data_json = strip_improper(json_encode(templates))
|
||||
|
||||
var/list/send_data = get_send_data(initial_data)
|
||||
var/initial_data_json = replacetext(replacetext(json_encode(send_data), """, "&#34;"), "'", "'")
|
||||
initial_data_json = strip_improper(initial_data_json);
|
||||
|
||||
var/url_parameters_json = json_encode(list("src" = "\ref[src]"))
|
||||
|
||||
return {"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<script type='text/javascript'>
|
||||
function receiveUpdateData(jsonString)
|
||||
{
|
||||
// We need both jQuery and NanoStateManager to be able to recieve data
|
||||
// At the moment any data received before those libraries are loaded will be lost
|
||||
if (typeof NanoStateManager != 'undefined' && typeof jQuery != 'undefined')
|
||||
{
|
||||
NanoStateManager.receiveUpdateData(jsonString);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// alert('browser.recieveUpdateData failed due to jQuery or NanoStateManager being unavailiable.');
|
||||
//}
|
||||
}
|
||||
</script>
|
||||
[head_content]
|
||||
</head>
|
||||
<body scroll=auto data-template-data='[template_data_json]' data-url-parameters='[url_parameters_json]' data-initial-data='[initial_data_json]'>
|
||||
<div id='uiLayout'>
|
||||
</div>
|
||||
<noscript>
|
||||
<div id='uiNoScript'>
|
||||
<h2>JAVASCRIPT REQUIRED</h2>
|
||||
<p>Your Internet Explorer's Javascript is disabled (or broken).<br/>
|
||||
Enable Javascript and then open this UI again.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/**
|
||||
* Open this UI
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/open()
|
||||
if(!user.client)
|
||||
return
|
||||
|
||||
// An attempted fix to UIs sometimes locking up spamming runtime errors due to src_object being null for whatever reason.
|
||||
// This hard-deletes the UI, preventing the device that uses the UI from being locked up permanently.
|
||||
if(!src_object)
|
||||
del(src)
|
||||
|
||||
var/window_size = ""
|
||||
if (width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
update_status(0)
|
||||
if(status == STATUS_CLOSE)
|
||||
return
|
||||
|
||||
user << browse(get_html(), "window=[window_id];[window_size][window_options]")
|
||||
winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map
|
||||
on_close_winset()
|
||||
//onclose(user, window_id)
|
||||
SSnanoui.ui_opened(src)
|
||||
|
||||
/**
|
||||
* Reinitialise this UI, potentially with a different template and/or initial data
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/reinitialise(template, new_initial_data)
|
||||
if(template)
|
||||
add_template("main", template)
|
||||
if(new_initial_data)
|
||||
set_initial_data(new_initial_data)
|
||||
open()
|
||||
|
||||
/**
|
||||
* Close this UI
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/close()
|
||||
is_auto_updating = 0
|
||||
SSnanoui.ui_closed(src)
|
||||
user << browse(null, "window=[window_id]")
|
||||
for(var/datum/nanoui/child in children)
|
||||
child.close()
|
||||
children.Cut()
|
||||
state = null
|
||||
master_ui = null
|
||||
|
||||
/**
|
||||
* Set the UI window to call the nanoclose verb when the window is closed
|
||||
* This allows Nano to handle closed windows
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/on_close_winset()
|
||||
if(!user.client)
|
||||
return
|
||||
var/params = "\ref[src]"
|
||||
|
||||
winset(user, window_id, "on-close=\"nanoclose [params]\"")
|
||||
|
||||
/**
|
||||
* Push data to an already open UI window
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/push_data(data, force_push = 0)
|
||||
update_status(0)
|
||||
if (status == STATUS_DISABLED && !force_push)
|
||||
return // Cannot update UI, no visibility
|
||||
|
||||
var/list/send_data = get_send_data(data)
|
||||
|
||||
//to_chat(user,list2json_usecache(send_data)) // used for debugging //NANO DEBUG HOOK
|
||||
user << output(list2params(list(strip_improper(json_encode(send_data)))),"[window_id].browser:receiveUpdateData")
|
||||
|
||||
/**
|
||||
* This Topic() proc is called whenever a user clicks on a link within a Nano UI
|
||||
* If the UI status is currently STATUS_INTERACTIVE then call the src_object Topic()
|
||||
* If the src_object Topic() returns 1 (true) then update all UIs attached to src_object
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/Topic(href, href_list)
|
||||
update_status(0) // update the status
|
||||
if (status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user
|
||||
return
|
||||
|
||||
// This is used to toggle the nano map ui
|
||||
var/map_update = 0
|
||||
if(href_list["showMap"])
|
||||
set_show_map(text2num(href_list["showMap"]))
|
||||
map_update = 1
|
||||
|
||||
if(href_list["mapZLevel"])
|
||||
set_map_z_level(text2num(href_list["mapZLevel"]))
|
||||
map_update = 1
|
||||
|
||||
if ((src_object && src_object.Topic(href, href_list, state)) || map_update)
|
||||
SSnanoui.update_uis(src_object) // update all UIs attached to src_object
|
||||
|
||||
/**
|
||||
* Process this UI, updating the entire UI or just the status (aka visibility)
|
||||
* This process proc is called by the master_controller
|
||||
*
|
||||
* @param update string For this UI to update
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/process(update = 0)
|
||||
if (!src_object || !user)
|
||||
close()
|
||||
return
|
||||
|
||||
if (status && (update || is_auto_updating))
|
||||
update() // Update the UI (update_status() is called whenever a UI is updated)
|
||||
else
|
||||
update_status(1) // Not updating UI, so lets check here if status has changed
|
||||
|
||||
/**
|
||||
* Update the UI
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/update(var/force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||
@@ -47,6 +47,6 @@
|
||||
else
|
||||
to_chat(usr,"<span class='warning'>No valid landing sites in range.</span>")
|
||||
possible_d = shuttle.get_possible_destinations()
|
||||
if(CanInteract(usr, global.default_state) && (D in possible_d))
|
||||
if(CanInteract(usr, GLOB.tgui_default_state) && (D in possible_d))
|
||||
shuttle.set_destination(possible_d[D])
|
||||
return TRUE
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
if(opened)
|
||||
wires.Interact(user)
|
||||
|
||||
return ui_interact(user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/grid_checker/proc/power_failure(var/announce = TRUE)
|
||||
if(announce)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
C.reagents.add_reagent(id, to_restore)
|
||||
. = 1
|
||||
if(.)
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/chemical_dispenser
|
||||
dispense_reagents = list(
|
||||
|
||||
@@ -147,9 +147,9 @@ var/list/infomorph_emotions = list(
|
||||
return 0
|
||||
..()
|
||||
|
||||
/mob/living/silicon/infomorph/default_can_use_topic(var/src_object)
|
||||
/mob/living/silicon/infomorph/default_can_use_tgui_topic(var/src_object)
|
||||
if(src_object in src)
|
||||
return shared_nano_interaction()
|
||||
return shared_tgui_interaction()
|
||||
|
||||
/////////// DAMAGES
|
||||
/mob/living/silicon/infomorph/emp_act(severity)
|
||||
@@ -190,7 +190,7 @@ var/list/infomorph_emotions = list(
|
||||
medicalActive1 = null
|
||||
medicalActive2 = null
|
||||
medical_cannotfind = 0
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
to_chat(usr, "<span class='notice'>You reset your record-viewing software.</span>")
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
switch(action)
|
||||
if("pick")
|
||||
var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations()
|
||||
if(dest_key && CanInteract(usr, global.default_state))
|
||||
if(dest_key && CanInteract(usr, GLOB.tgui_default_state))
|
||||
shuttle.set_destination(dest_key, usr)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
ui.set_map_z_level(params["mapZLevel"])
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_module/atmos_control/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/nanomaps),
|
||||
)
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
name = "Crew monitor"
|
||||
tgui_id = "CrewMonitor"
|
||||
|
||||
/datum/tgui_module/crew_monitor/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/nanomaps),
|
||||
)
|
||||
|
||||
/datum/tgui_module/crew_monitor/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
sleep(3)
|
||||
return NANOMAP_TERMINALERR
|
||||
|
||||
var/icon/Tile = icon(file("nano/mapbase1200.png"))
|
||||
var/icon/Tile = icon('icons/_nanomaps/mapbase1200.png')
|
||||
if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION)
|
||||
to_world_log("NanoMapGen: <B>ERROR: BASE IMAGE DIMENSIONS ARE NOT [NANOMAP_MAX_ICON_DIMENSION]x[NANOMAP_MAX_ICON_DIMENSION]</B>")
|
||||
sleep(3)
|
||||
@@ -123,3 +123,7 @@
|
||||
if((TK in mutations) && (get_dist(src, src_object) <= 2))
|
||||
return STATUS_INTERACTIVE
|
||||
return ..()
|
||||
|
||||
// Topic Extensions for old UIs
|
||||
/datum/proc/CanUseTopic(var/mob/user, var/datum/tgui_state/state)
|
||||
return tgui_status(user, state)
|
||||
@@ -10,3 +10,11 @@ GLOBAL_DATUM_INIT(tgui_deep_inventory_state, /datum/tgui_state/deep_inventory_st
|
||||
if(!user.contains(src_object))
|
||||
return STATUS_CLOSE
|
||||
return user.shared_tgui_interaction(src_object)
|
||||
|
||||
/atom/proc/contains(var/atom/location)
|
||||
if(!location)
|
||||
return 0
|
||||
if(location == src)
|
||||
return 1
|
||||
|
||||
return contains(location.loc)
|
||||
|
||||
@@ -68,12 +68,12 @@ GLOBAL_DATUM_INIT(tgui_default_state, /datum/tgui_state/default, new)
|
||||
|
||||
/mob/living/silicon/pai/default_can_use_tgui_topic(src_object)
|
||||
// pAIs can only use themselves and the owner's radio.
|
||||
if((src_object == src || src_object == radio) && !stat)
|
||||
if((src_object == src || src_object == radio || src_object == communicator) && !stat)
|
||||
return STATUS_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/observer/dead/default_can_use_tgui_topic()
|
||||
if(check_rights(R_ADMIN, 0, src))
|
||||
if(can_admin_interact())
|
||||
return STATUS_INTERACTIVE // Admins are more equal
|
||||
return STATUS_UPDATE // Ghosts can view updates
|
||||
|
||||
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 246 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 383 KiB After Width: | Height: | Size: 383 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@@ -1,297 +0,0 @@
|
||||
<!-- TOC depth:6 withLinks:1 updateOnSave:0 orderedList:0 -->
|
||||
|
||||
- [NanoUI](#nanoui)
|
||||
- [Introduction](#introduction)
|
||||
- [Components](#components)
|
||||
- [`ui_interact()`](#ui_interact)
|
||||
- [`Topic()`](#topic)
|
||||
- [Template (doT)](#template-dot)
|
||||
- [Helpers](#helpers)
|
||||
- [Link](#link)
|
||||
- [displayBar](#displayBar)
|
||||
- [doT](#dot)
|
||||
- [Styling](#styling)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
<!-- /TOC -->
|
||||
# NanoUI
|
||||
|
||||
## Introduction
|
||||
|
||||
### Credit goes to Neersighted of /tg/station for the styling and large chunks of content of this README.
|
||||
|
||||
NanoUI is one of the three primary user interface libraries currently in use
|
||||
on Polaris (browse(), /datum/browser, NanoUI). It is the most complex of the three,
|
||||
but offers quite a few advantages, most notably in default features.
|
||||
|
||||
NanoUI adds a `ui_interact()` proc to all atoms, which, ideally, should be called
|
||||
via `interact()`; However, the current standardized layout is `ui_interact()` being
|
||||
directly called from anywhere in the atom, generally `attack_hand()` or `attack_self()`.
|
||||
The `ui_interact()` proc should not contain anything but NanoUI data and code.
|
||||
|
||||
Here is a simple example from
|
||||
[poolcontroller.dm @ ParadiseSS13/Paradise](https://github.com/ParadiseSS13/Paradise/blob/master/code/game/machinery/poolcontroller.dm).
|
||||
|
||||
```
|
||||
/obj/machinery/poolcontroller/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/poolcontroller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
data["currentTemp"] = temperature
|
||||
data["emagged"] = emagged
|
||||
data["TempColor"] = temperaturecolor
|
||||
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "poolcontroller.tmpl", "Pool Controller Interface", 520, 410)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Components
|
||||
|
||||
### `ui_interact()`
|
||||
|
||||
The `ui_interact()` proc is used to open a NanoUI (or update it if already open).
|
||||
As NanoUI will call this proc to update your UI, you should include the data list
|
||||
within it. On /tg/station, this is handled via `get_ui_data()`, however, as it would
|
||||
take quite a long time to convert every single one of the 100~ UI's to using such a method,
|
||||
it is instead just directly created within `ui_interact()`.
|
||||
|
||||
The parameters for `try_update_ui` and `/datum/nanoui/New()` are documented in
|
||||
the code [here](https://github.com/PolarisSS13/Polaris/tree/master/code/modules/nano).
|
||||
|
||||
For:
|
||||
`/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state)`
|
||||
Most of the parameters are fairly self explanatory.
|
||||
- `nuser` is the person who gets to see the UI window
|
||||
- `nsrc_obj` is the thing you want to call Topic() on
|
||||
- `nui_key` should almost always be `main`
|
||||
- `ntemplate_filename` is the filename with `.tmpl` extension in /nano/templates/
|
||||
- `ntitle` is what you want to show at the top of the UI window
|
||||
- `nwidth` is the width of the new window
|
||||
- `nheight` is the height of the new window
|
||||
- `nref` is used for onclose()
|
||||
- `master_ui` is used for UIs that have multiple children, see code for examples
|
||||
- And finally, `state`.
|
||||
|
||||
The most interesting parameter here is `state`, which allows the object to choose the
|
||||
checks that allow the UI to be interacted with.
|
||||
|
||||
The default state (`default_state`) checks that the user is alive, conscious,
|
||||
and within a few tiles. It allows universal access to silicons. Other states
|
||||
exist, and may be more appropriate for different interfaces. For example,
|
||||
`physical_state` requires the user to be nearby, even if they are a silicon.
|
||||
`inventory_state` checks that the user has the object in their first-level
|
||||
(not container) inventory, this is suitable for devices such as radios;
|
||||
`admin_state` checks that the user is an admin (good for admin tools).
|
||||
|
||||
```
|
||||
/obj/item/the/thing/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
var/data[0]
|
||||
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open = force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "template_name_here.tmpl", title, width, height)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
```
|
||||
|
||||
### `Topic()`
|
||||
|
||||
`Topic()` handles input from the UI. Typically you will recieve some data from
|
||||
a button press, or pop up a input dialog to take a numerical value from the
|
||||
user. Sanity checking is useful here, as `Topic()` is trivial to spoof with
|
||||
arbitrary data.
|
||||
|
||||
The `Topic()` interface is just the same as with more conventional,
|
||||
stringbuilder-based UIs, and this needs little explanation.
|
||||
|
||||
```
|
||||
/obj/item/weapon/tank/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["dist_p"])
|
||||
if(href_list["dist_p"] == "custom")
|
||||
var/custom = input(usr, "What rate do you set the regulator to? The dial reads from 0 to [TANK_MAX_RELEASE_PRESSURE].") as null|num
|
||||
if(isnum(custom))
|
||||
href_list["dist_p"] = custom
|
||||
.()
|
||||
else if(href_list["dist_p"] == "reset")
|
||||
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
else if(href_list["dist_p"] == "min")
|
||||
distribute_pressure = TANK_MIN_RELEASE_PRESSURE
|
||||
else if(href_list["dist_p"] == "max")
|
||||
distribute_pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
else
|
||||
distribute_pressure = text2num(href_list["dist_p"])
|
||||
distribute_pressure = min(max(round(distribute_pressure), TANK_MIN_RELEASE_PRESSURE), TANK_MAX_RELEASE_PRESSURE)
|
||||
if(href_list["stat"])
|
||||
if(istype(loc,/mob/living/carbon))
|
||||
var/mob/living/carbon/location = loc
|
||||
if(location.internal == src)
|
||||
location.internal = null
|
||||
location.internals.icon_state = "internal0"
|
||||
to_chat(usr, "<span class='notice'>You close the tank release valve.</span>")
|
||||
if(location.internals)
|
||||
location.internals.icon_state = "internal0"
|
||||
else
|
||||
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
|
||||
location.internal = src
|
||||
to_chat(usr, "<span class='notice'>You open \the [src] valve.</span>")
|
||||
if(location.internals)
|
||||
location.internals.icon_state = "internal1"
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need something to connect to \the [src]!</span>")
|
||||
```
|
||||
|
||||
### Template (doT)
|
||||
|
||||
NanoUI templates are written in a customized version of
|
||||
[doT](https://olado.github.io/doT/index.html),
|
||||
a Javascript template engine. Data is accessed from the `data` object,
|
||||
configuration (not used in pratice) from the `config` object, and template
|
||||
helpers are accessed from the `helper` object.
|
||||
|
||||
It is worth explaining that Polaris's version of doT uses custom syntax
|
||||
for the templates. The `?` operator is split into `if`, `else if parameter`, and `else`,
|
||||
instead of `?`, `?? paramater`, `??`, and the `=` operator is replaced with `:`. Refer
|
||||
to the chart below for a full comparison.
|
||||
|
||||
#### Helpers
|
||||
|
||||
##### Link
|
||||
|
||||
`{{:helpers.link(text, icon, {'parameter': true}, status, class, id)}}`
|
||||
|
||||
Used to create a link (button), which will pass its parameters to `Topic()`.
|
||||
|
||||
* Text: The text content of the link/button
|
||||
* Icon: The icon shown to the left of the link (http://fontawesome.io/)
|
||||
* Parameters: The values to be passed to `Topic()`'s `href_list`.
|
||||
* Status: `null` for clickable, a class for selected/unclickable.
|
||||
* Class: Styling to apply to the link.
|
||||
* ID: Sets the element ID.
|
||||
|
||||
Status and Class have almost the same effect. However, changing a link's status
|
||||
from `null` to something else makes it unclickable, while setting a custom Class
|
||||
does not.
|
||||
|
||||
Ternary operators are often used to avoid writing many `if` statements.
|
||||
For example, depending on if a value in `data` is true or false we can set a
|
||||
button to clickable or selected:
|
||||
|
||||
`{{:helper.link('Close', 'lock', {'stat': 1}, data.valveOpen ? null : 'selected')}}`
|
||||
|
||||
Available classes/statuses are:
|
||||
|
||||
* null (normal)
|
||||
* selected
|
||||
* disabled
|
||||
* yellowButton
|
||||
* redButton
|
||||
* linkDanger
|
||||
|
||||
##### displayBar
|
||||
|
||||
`{{:helpers.displayBar(value, min, max, class, text)}}`
|
||||
|
||||
Used to create a bar, to display a numerical value visually. Min and Max default
|
||||
to 0 and 100, but you can change them to avoid doing your own percent calculations.
|
||||
|
||||
* Value: Defaults to a percentage but can be a straight number if Min/Max are set
|
||||
* Min: The minimum value (left hand side) of the bar
|
||||
* Max: The maximum value (right hand side) of the bar
|
||||
* Class: The color of the bar (null/normal, good, average, bad)
|
||||
* Text: The text label for the data contained in the bar (often just number form)
|
||||
|
||||
As with buttons, ternary operators are quite useful:
|
||||
|
||||
`{{:helper.bar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : ((data.tankPressure > 100) ? 'average' : 'bad'))}}`
|
||||
|
||||
|
||||
#### doT
|
||||
|
||||
doT is a simple template language, with control statements mixed in with
|
||||
regular HTML and interpolation expressions.
|
||||
|
||||
However, Polaris uses a custom version with a different syntax. Refer
|
||||
to the chart below for the differences.
|
||||
|
||||
Operator | doT | equiv |
|
||||
|-----------|------------|-------------------|
|
||||
|Conditional| ? | if |
|
||||
| | ?? | else |
|
||||
| | ?? (param) | else if(param) |
|
||||
|Interpolate| = | : |
|
||||
|^ + Encode | ! | > |
|
||||
|Evaluation | # | # |
|
||||
|Defines | ## # | ## # |
|
||||
|Iteration | ~ (param) | for (param) |
|
||||
|
||||
Here is a simple example from tanks, checking if a variable is true:
|
||||
|
||||
```
|
||||
{{if data.maskConnected}}
|
||||
<span>The regulator is connected to a mask.</span>
|
||||
{{else if}}
|
||||
<span>The regulator is not connected to a mask.</span>
|
||||
{{/if}}
|
||||
```
|
||||
|
||||
The doT tutorial is [here](https://olado.github.io/doT/tutorial.html).
|
||||
|
||||
__Print Tag__
|
||||
- The print tag outputs the given expression as text to the UI.
|
||||
|
||||
`{{:data.variable}}`
|
||||
`{{:functioncall()}}`
|
||||
|
||||
(with escape):
|
||||
|
||||
`{{>expression }}`
|
||||
|
||||
|
||||
__If Tag__
|
||||
- The if tag displays content conditionally based on the provided expression being true.
|
||||
- When combined with the else tag the if tag can also show content if the provided expression is false.
|
||||
- The else tag can optionally have an expression provided (e.g. "`{{else expression2}}`"), giving it "elseif" functionality.
|
||||
|
||||
`{{if expression}} <expression true content> {{/if}}`
|
||||
`{{if expression}} <expression true content> {{else}} <expression false content> {{/if}}`
|
||||
`{{if expression1}} <expression1 true content> {{else expression2}} <expression2 true content> {{/if}}`
|
||||
|
||||
__For Tag__
|
||||
- Loop through entries in an array; it can be associative (with keys) or numerical indexed, but you have to use some special syntax for assocative lists.
|
||||
- Each time the `for` tag iterates though the array it sets a variable (default "value") to the data of the current entry (another variable, default "index", contains the index). An example of this is using the print tag to print the contents (e.g. `{{:value.key1}}` and `{{:value.key2}}`).
|
||||
- If combined with an `empty` tag the for tag can display content when the array is empty.
|
||||
|
||||
Indexed:
|
||||
`{{for array}} <list entry content> {{/for}}`
|
||||
`{{for array}} <list entry content> {{empty}} <empty list content> {{/for}}`
|
||||
|
||||
Associative:
|
||||
`{{for object:key:index}} <key, value> {{/for}}`
|
||||
|
||||
|
||||
__Inclusion Tag__
|
||||
- Include the contents of another template which has been added to the ui.
|
||||
`{{#def.atmosphericScan}}`
|
||||
|
||||
- You first must have added a template to the ui server side in your DM code:
|
||||
`ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")`
|
||||
|
||||
- Then you can reference it in the main template. The tag will be replaced by the contents of the named template. All tags in the named template are evaluated as normal.
|
||||
|
||||
#### Styling
|
||||
/tg/station has standardized styling, with specific article tags, and headers, and sections.
|
||||
However, as the templates are already horrifying unstandardized, Polaris does not have any
|
||||
particular styling standards.
|
||||
|
||||
The only real requirement is that it, A. Looks alrightish, and B. Functions properly. Try
|
||||
to avoid snowflaking anything into the main CSS file, please.
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# Setup
|
||||
import os, json, shutil, glob, platform
|
||||
|
||||
if(platform.system() != "Windows"):
|
||||
print("Error: This script doesn't work on anything but Windows. How are you even planning to develop BYOND off windows?")
|
||||
exit()
|
||||
|
||||
cdir = (os.getcwd())
|
||||
if(cdir[-4:] != "nano"):
|
||||
print("This script must be run from the nano directory.")
|
||||
exit()
|
||||
|
||||
def find_cache():
|
||||
target = os.path.join(os.path.expanduser("~"), "Documents", "BYOND", "cache")
|
||||
for root, dirs, files in os.walk(target):
|
||||
if "nano_templates_bundle.js" in files:
|
||||
return root
|
||||
|
||||
cache = find_cache()
|
||||
if cache == None:
|
||||
print("Failed to find BYOND Cache.")
|
||||
exit()
|
||||
|
||||
# Send all of the random files to the cache
|
||||
def send_to_cache(arrayOfFiles):
|
||||
for file in arrayOfFiles:
|
||||
target = os.path.join(cache, os.path.split(file)[1])
|
||||
shutil.copyfile(file, target)
|
||||
|
||||
send_to_cache([os.path.join(cdir, "css", f) for f in os.listdir(os.path.join(cdir, "css")) if os.path.isfile(os.path.join(cdir, "css", f))])
|
||||
send_to_cache([os.path.join(cdir, "images", f) for f in os.listdir(os.path.join(cdir, "images")) if os.path.isfile(os.path.join(cdir, "images", f))])
|
||||
send_to_cache([os.path.join(cdir, "js", f) for f in os.listdir(os.path.join(cdir, "js")) if os.path.isfile(os.path.join(cdir, "js", f))])
|
||||
|
||||
# Handle creating the tmpl bundle
|
||||
arrOfFiles = glob.glob(os.path.join(cdir, "templates", "*.tmpl"))
|
||||
|
||||
tmpl_bundle_header = "function nanouiTemplateBundle(){return "
|
||||
tmpl_bundle_footer = ";}"
|
||||
|
||||
big_json_array = {}
|
||||
|
||||
for file in arrOfFiles:
|
||||
tmpl_name = os.path.split(file)[1]
|
||||
with open(file, 'r') as tmpl:
|
||||
big_json_array[tmpl_name] = tmpl.read()
|
||||
|
||||
tmpl_bundle = tmpl_bundle_header + json.dumps(big_json_array) + tmpl_bundle_footer
|
||||
|
||||
# Send the tmpl bundle to the cache
|
||||
with open(os.path.join(cache, "nano_templates_bundle.js"), "w") as templateBundleFile:
|
||||
templateBundleFile.write(tmpl_bundle)
|
||||
templateBundleFile.close()
|
||||
@@ -1,378 +0,0 @@
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
.icon24
|
||||
{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.icon24.uiStatusGood
|
||||
{
|
||||
background: url(uiIcons24.png) 0 0 no-repeat;
|
||||
}
|
||||
|
||||
.icon24.uiStatusAverage
|
||||
{
|
||||
background: url(uiIcons24.png) 0 -24px no-repeat;
|
||||
}
|
||||
|
||||
.icon24.uiStatusBad
|
||||
{
|
||||
background: url(uiIcons24.png) 0 -48px no-repeat;
|
||||
}
|
||||
|
||||
/* states and images */
|
||||
.uiIcon16 {
|
||||
float: left;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 2px 2px 0 2px;
|
||||
background-image: url(uiIcons16.png);
|
||||
}
|
||||
|
||||
.uiLinkPendingIcon {
|
||||
display: none;
|
||||
float: left;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 2px 2px 0 2px;
|
||||
background-image: url(uiLinkPendingIcon.gif);
|
||||
}
|
||||
|
||||
.linkPending .uiIcon16 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.linkPending .uiLinkPendingIcon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
.uiIcon16.icon-blank { background-position: 16px 16px; }
|
||||
|
||||
.uiIcon16.icon-carat-1-n { background-position: 0 0; }
|
||||
.uiIcon16.icon-carat-1-ne { background-position: -16px 0; }
|
||||
.uiIcon16.icon-carat-1-e { background-position: -32px 0; }
|
||||
.uiIcon16.icon-carat-1-se { background-position: -48px 0; }
|
||||
.uiIcon16.icon-carat-1-s { background-position: -64px 0; }
|
||||
.uiIcon16.icon-carat-1-sw { background-position: -80px 0; }
|
||||
.uiIcon16.icon-carat-1-w { background-position: -96px 0; }
|
||||
.uiIcon16.icon-carat-1-nw { background-position: -112px 0; }
|
||||
.uiIcon16.icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.uiIcon16.icon-carat-2-e-w { background-position: -144px 0; }
|
||||
|
||||
.uiIcon16.icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.uiIcon16.icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.uiIcon16.icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.uiIcon16.icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.uiIcon16.icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.uiIcon16.icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.uiIcon16.icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.uiIcon16.icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.uiIcon16.icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.uiIcon16.icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
|
||||
.uiIcon16.icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.uiIcon16.icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.uiIcon16.icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.uiIcon16.icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.uiIcon16.icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.uiIcon16.icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.uiIcon16.icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.uiIcon16.icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.uiIcon16.icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.uiIcon16.icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.uiIcon16.icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.uiIcon16.icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
|
||||
.uiIcon16.icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.uiIcon16.icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.uiIcon16.icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.uiIcon16.icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
|
||||
.uiIcon16.icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.uiIcon16.icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.uiIcon16.icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.uiIcon16.icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.uiIcon16.icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.uiIcon16.icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
|
||||
.uiIcon16.icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.uiIcon16.icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.uiIcon16.icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.uiIcon16.icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
|
||||
.uiIcon16.icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.uiIcon16.icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.uiIcon16.icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.uiIcon16.icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
|
||||
.uiIcon16.icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.uiIcon16.icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.uiIcon16.icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.uiIcon16.icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.uiIcon16.icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.uiIcon16.icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.uiIcon16.icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.uiIcon16.icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
|
||||
.uiIcon16.icon-arrow-4 { background-position: 0 -80px; }
|
||||
.uiIcon16.icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.uiIcon16.icon-extlink { background-position: -32px -80px; }
|
||||
.uiIcon16.icon-newwin { background-position: -48px -80px; }
|
||||
.uiIcon16.icon-refresh { background-position: -64px -80px; }
|
||||
.uiIcon16.icon-shuffle { background-position: -80px -80px; }
|
||||
.uiIcon16.icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.uiIcon16.icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.uiIcon16.icon-radiation { background-position: -128px -80px; }
|
||||
.uiIcon16.icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.uiIcon16.icon-folder-open { background-position: -16px -96px; }
|
||||
.uiIcon16.icon-document { background-position: -32px -96px; }
|
||||
.uiIcon16.icon-document-b { background-position: -48px -96px; }
|
||||
.uiIcon16.icon-note { background-position: -64px -96px; }
|
||||
.uiIcon16.icon-mail-closed { background-position: -80px -96px; }
|
||||
.uiIcon16.icon-mail-open { background-position: -96px -96px; }
|
||||
.uiIcon16.icon-suitcase { background-position: -112px -96px; }
|
||||
.uiIcon16.icon-comment { background-position: -128px -96px; }
|
||||
.uiIcon16.icon-person { background-position: -144px -96px; }
|
||||
.uiIcon16.icon-print { background-position: -160px -96px; }
|
||||
.uiIcon16.icon-trash { background-position: -176px -96px; }
|
||||
.uiIcon16.icon-locked { background-position: -192px -96px; }
|
||||
.uiIcon16.icon-unlocked { background-position: -208px -96px; }
|
||||
.uiIcon16.icon-bookmark { background-position: -224px -96px; }
|
||||
.uiIcon16.icon-tag { background-position: -240px -96px; }
|
||||
.uiIcon16.icon-home { background-position: 0 -112px; }
|
||||
.uiIcon16.icon-flag { background-position: -16px -112px; }
|
||||
.uiIcon16.icon-calendar { background-position: -32px -112px; }
|
||||
.uiIcon16.icon-cart { background-position: -48px -112px; }
|
||||
.uiIcon16.icon-pencil { background-position: -64px -112px; }
|
||||
.uiIcon16.icon-clock { background-position: -80px -112px; }
|
||||
.uiIcon16.icon-disk { background-position: -96px -112px; }
|
||||
.uiIcon16.icon-calculator { background-position: -112px -112px; }
|
||||
.uiIcon16.icon-zoomin { background-position: -128px -112px; }
|
||||
.uiIcon16.icon-zoomout { background-position: -144px -112px; }
|
||||
.uiIcon16.icon-search { background-position: -160px -112px; }
|
||||
.uiIcon16.icon-wrench { background-position: -176px -112px; }
|
||||
.uiIcon16.icon-gear { background-position: -192px -112px; }
|
||||
.uiIcon16.icon-heart { background-position: -208px -112px; }
|
||||
.uiIcon16.icon-star { background-position: -224px -112px; }
|
||||
.uiIcon16.icon-link { background-position: -240px -112px; }
|
||||
.uiIcon16.icon-cancel { background-position: 0 -128px; }
|
||||
.uiIcon16.icon-plus { background-position: -16px -128px; }
|
||||
.uiIcon16.icon-plusthick { background-position: -32px -128px; }
|
||||
.uiIcon16.icon-minus { background-position: -48px -128px; }
|
||||
.uiIcon16.icon-minusthick { background-position: -64px -128px; }
|
||||
.uiIcon16.icon-close { background-position: -80px -128px; }
|
||||
.uiIcon16.icon-closethick { background-position: -96px -128px; }
|
||||
.uiIcon16.icon-key { background-position: -112px -128px; }
|
||||
.uiIcon16.icon-lightbulb { background-position: -128px -128px; }
|
||||
.uiIcon16.icon-scissors { background-position: -144px -128px; }
|
||||
.uiIcon16.icon-clipboard { background-position: -160px -128px; }
|
||||
.uiIcon16.icon-copy { background-position: -176px -128px; }
|
||||
.uiIcon16.icon-contact { background-position: -192px -128px; }
|
||||
.uiIcon16.icon-image { background-position: -208px -128px; }
|
||||
.uiIcon16.icon-video { background-position: -224px -128px; }
|
||||
.uiIcon16.icon-script { background-position: -240px -128px; }
|
||||
.uiIcon16.icon-alert { background-position: 0 -144px; }
|
||||
.uiIcon16.icon-alert-red { background-image: url(uiIcons16Red.png); background-position: 0 -144px; }
|
||||
.uiIcon16.icon-info { background-position: -16px -144px; }
|
||||
.uiIcon16.icon-notice { background-position: -32px -144px; }
|
||||
.uiIcon16.icon-help { background-position: -48px -144px; }
|
||||
.uiIcon16.icon-check { background-position: -64px -144px; }
|
||||
.uiIcon16.icon-bullet { background-position: -80px -144px; }
|
||||
.uiIcon16.icon-radio-on { background-position: -96px -144px; }
|
||||
.uiIcon16.icon-radio-off { background-position: -112px -144px; }
|
||||
.uiIcon16.icon-pin-w { background-position: -128px -144px; }
|
||||
.uiIcon16.icon-pin-s { background-position: -144px -144px; }
|
||||
.uiIcon16.icon-phone { background-position: -160px -144px; }
|
||||
.uiIcon16.icon-list { background-position: -176px -144px; }
|
||||
.uiIcon16.icon-syringe { background-position: -192px -144px; }
|
||||
.uiIcon16.icon-play { background-position: 0 -160px; }
|
||||
.uiIcon16.icon-pause { background-position: -16px -160px; }
|
||||
.uiIcon16.icon-seek-next { background-position: -32px -160px; }
|
||||
.uiIcon16.icon-seek-prev { background-position: -48px -160px; }
|
||||
.uiIcon16.icon-seek-end { background-position: -64px -160px; }
|
||||
.uiIcon16.icon-seek-start { background-position: -80px -160px; }
|
||||
|
||||
/* uiIcon-seek-first is deprecated, use uiIcon-seek-start instead */
|
||||
.uiIcon16.icon-seek-first { background-position: -80px -160px; }
|
||||
.uiIcon16.icon-stop { background-position: -96px -160px; }
|
||||
.uiIcon16.icon-eject { background-position: -112px -160px; }
|
||||
.uiIcon16.icon-volume-off { background-position: -128px -160px; }
|
||||
.uiIcon16.icon-volume-on { background-position: -144px -160px; }
|
||||
.uiIcon16.icon-power { background-position: 0 -176px; }
|
||||
.uiIcon16.icon-signal-diag { background-position: -16px -176px; }
|
||||
.uiIcon16.icon-signal { background-position: -32px -176px; }
|
||||
.uiIcon16.icon-signal-green { background-image: url(uiIcons16Green.png); background-position: -32px -176px; }
|
||||
|
||||
.uiIcon16.icon-battery-0 { background-position: -48px -176px; }
|
||||
.uiIcon16.icon-battery-1 { background-position: -64px -176px; }
|
||||
.uiIcon16.icon-battery-2 { background-position: -80px -176px; }
|
||||
.uiIcon16.icon-battery-3 { background-position: -96px -176px; }
|
||||
|
||||
.uiIcon16.icon-circle-plus { background-position: 0 -192px; }
|
||||
.uiIcon16.icon-circle-minus { background-position: -16px -192px; }
|
||||
.uiIcon16.icon-circle-close { background-position: -32px -192px; }
|
||||
.uiIcon16.icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.uiIcon16.icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.uiIcon16.icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.uiIcon16.icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.uiIcon16.icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.uiIcon16.icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.uiIcon16.icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.uiIcon16.icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.uiIcon16.icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.uiIcon16.icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.uiIcon16.icon-circle-check { background-position: -208px -192px; }
|
||||
|
||||
.uiIcon16.icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.uiIcon16.icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.uiIcon16.icon-circlesmall-close { background-position: -32px -208px; }
|
||||
|
||||
.uiIcon16.icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.uiIcon16.icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.uiIcon16.icon-squaresmall-close { background-position: -80px -208px; }
|
||||
|
||||
.uiIcon16.icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.uiIcon16.icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.uiIcon16.icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.uiIcon16.icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.uiIcon16.icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.uiIcon16.icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
.uiIcon16.icon-batt_full { background-image: url(c_max.gif); background-position: 0px 0px }
|
||||
.uiIcon16.icon-batt_disc { background-image: url(c_discharging.gif); background-position: 0px 0px }
|
||||
.uiIcon16.icon-batt_chrg { background-image: url(c_charging.gif); background-position: 0px 0px }
|
||||
|
||||
/*yes, defining these all like this is awful, but unless the javascript for icon handling is sorted out this will have to do*/
|
||||
.uiIcon16.icon-empty64 { background-image: url(uiIcons64.png); background-position: 0 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-phone64 { background-image: url(uiIcons64.png); background-position: -64px 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-comment64 { background-image: url(uiIcons64.png); background-position: -128px 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-list64 { background-image: url(uiIcons64.png); background-position: -192px 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-gear64 { background-image: url(uiIcons64.png); background-position: -256px 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-person64 { background-image: url(uiIcons64.png); background-position: -320px 0; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-newspaper64 { background-image: url(uiIcons64.png); background-position: 0 -64px; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-note64 { background-image: url(uiIcons64.png); background-position: -64px -64px; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-close64 { background-image: url(uiIcons64.png); background-position: -128px -64px; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-sun64 { background-image: url(uiIcons64.png); background-position: -192px -64px; width: 64px; height: 64px; }
|
||||
.uiIcon16.icon-external64 { background-image: url(uiIcons64.png); background-position: -256px -64px; width: 64px; height: 64px; }
|
||||
|
||||
.uiIcon16.icon-pill { background-image: url(pills32.png); width: 32px; height: 32px;}
|
||||
.uiIcon16.icon-pill.pill1 { background-position: -64px -96px; }
|
||||
.uiIcon16.icon-pill.pill2 { background-position: -64px -96px; }
|
||||
.uiIcon16.icon-pill.pill3 { background-position: -96px -32px; }
|
||||
.uiIcon16.icon-pill.pill4 { background-position: -96px -32px; }
|
||||
.uiIcon16.icon-pill.pill5 { background-position: 0 0; }
|
||||
.uiIcon16.icon-pill.pill6 { background-position: -32px 0; }
|
||||
.uiIcon16.icon-pill.pill7 { background-position: -64px 0; }
|
||||
.uiIcon16.icon-pill.pill8 { background-position: -96px 0; }
|
||||
.uiIcon16.icon-pill.pill9 { background-position: -128px 0; }
|
||||
.uiIcon16.icon-pill.pill10 { background-position: 0 -32px; }
|
||||
.uiIcon16.icon-pill.pill11 { background-position: -32px -32px; }
|
||||
.uiIcon16.icon-pill.pill12 { background-position: -64px -32px; }
|
||||
.uiIcon16.icon-pill.pill13 { background-position: -96px -32px; }
|
||||
.uiIcon16.icon-pill.pill14 { background-position: -128px -32px; }
|
||||
.uiIcon16.icon-pill.pill15 { background-position: 0 -64px; }
|
||||
.uiIcon16.icon-pill.pill16 { background-position: -32px -64px; }
|
||||
.uiIcon16.icon-pill.pill17 { background-position: -64px -64px; }
|
||||
.uiIcon16.icon-pill.pill18 { background-position: -96px -64px; }
|
||||
.uiIcon16.icon-pill.pill19 { background-position: -128px -64px; }
|
||||
.uiIcon16.icon-pill.pill20 { background-position: 0 -96px; }
|
||||
.uiIcon16.icon-pill.pill21 { background-position: -32px -96px; }
|
||||
.uiIcon16.icon-pill.pill22 { background-position: -64px -96px; }
|
||||
.uiIcon16.icon-pill.pill23 { background-position: -96px -96px; }
|
||||
.uiIcon16.icon-pill.pill24 { background-position: -128px -96px; }
|
||||
.uiIcon16.icon-pill.bottle1 { background-position: 0 -128px; }
|
||||
.uiIcon16.icon-pill.bottle2 { background-position: -32px -128px; }
|
||||
.uiIcon16.icon-pill.bottle3 { background-position: -64px -128px; }
|
||||
.uiIcon16.icon-pill.bottle4 { background-position: -96px -128px; }
|
||||
|
||||
.mapIcon16 {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url(uiIcons16Green.png);
|
||||
background-position: -144px -96px;
|
||||
background-repeat: no-repeat;
|
||||
zoom: 0.125;
|
||||
margin-left: -1px;
|
||||
/*margin-bottom: -1px;*/
|
||||
}
|
||||
.mapIcon16.dead {
|
||||
background-image: url(uiIcons16Red.png);
|
||||
}
|
||||
|
||||
/* Command Positions */
|
||||
.mapIcon16.rank-captain {
|
||||
background-position: -224px -112px;
|
||||
}
|
||||
.mapIcon16.rank-headofpersonnel {
|
||||
background-position: -112px -96px;
|
||||
}
|
||||
.mapIcon16.rank-headofsecurity {
|
||||
background-position: -112px -128px;
|
||||
}
|
||||
.mapIcon16.rank-chiefengineer {
|
||||
background-position: -176px -112px;
|
||||
}
|
||||
.mapIcon16.rank-researchdirector {
|
||||
background-position: -128px -128px;
|
||||
}
|
||||
.mapIcon16.rank-chiefmedicalofficer {
|
||||
background-position: -32px -128px;
|
||||
}
|
||||
|
||||
/* Engineering Positions */
|
||||
.mapIcon16.rank-stationengineer {
|
||||
background-position: -176px -112px;
|
||||
}
|
||||
.mapIcon16.rank-atmospherictechnician {
|
||||
background-position: -176px -112px;
|
||||
}
|
||||
|
||||
/* Medical Positions */
|
||||
.mapIcon16.rank-medicaldoctor {
|
||||
background-position: -32px -128px;
|
||||
}
|
||||
.mapIcon16.rank-geneticist {
|
||||
background-position: -32px -128px;
|
||||
}
|
||||
.mapIcon16.rank-psychiatrist {
|
||||
background-position: -32px -128px;
|
||||
}
|
||||
.mapIcon16.rank-chemist {
|
||||
background-position: -32px -128px;
|
||||
}
|
||||
|
||||
/* Science Positions */
|
||||
.mapIcon16.rank-scientist {
|
||||
background-position: -128px -128px;
|
||||
}
|
||||
.mapIcon16.rank-geneticist {
|
||||
background-position: -128px -128px;
|
||||
}
|
||||
.mapIcon16.rank-roboticist {
|
||||
background-position: -128px -128px;
|
||||
}
|
||||
.mapIcon16.rank-xenobiologist {
|
||||
background-position: -128px -128px;
|
||||
}
|
||||
|
||||
/* Security Positions */
|
||||
.mapIcon16.rank-warden {
|
||||
background-position: -112px -128px;
|
||||
}
|
||||
.mapIcon16.rank-detective {
|
||||
background-position: -112px -128px;
|
||||
}
|
||||
.mapIcon16.rank-securityofficer {
|
||||
background-position: -112px -128px;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
body {
|
||||
background: #272727 url(uiBasicBackground.png) 50% 0 repeat-x;
|
||||
}
|
||||
|
||||
#uiContent {
|
||||
clear: both;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#uiLoadingNotice {
|
||||
position: relative;
|
||||
background: url(uiNoticeBackground.jpg) 50% 50%;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
padding: 3px 4px 3px 4px;
|
||||
margin: 4px 0 4px 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
body {
|
||||
background: #272727 url(uiBackground.png) 50% 0 repeat-x;
|
||||
}
|
||||
|
||||
#uiWrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#uiTitleWrapper {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#uiTitleText {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 44px;
|
||||
width: 66%;
|
||||
overflow: hidden;
|
||||
color: #E9C183;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#uiTitle.icon {
|
||||
padding: 6px 8px 6px 42px;
|
||||
background-position: 2px 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#uiTitleFluff {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 12px;
|
||||
width: 42px;
|
||||
height: 24px;
|
||||
background: url(uiTitleFluff.png) 50% 50% no-repeat;
|
||||
}
|
||||
|
||||
#uiStatusIcon {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 12px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
#uiMapWrapper {
|
||||
clear: both;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#uiMapHeader {
|
||||
position: relative;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#uiMapContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 550px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #40628a;
|
||||
background: url(nanomapBackground.png);
|
||||
}
|
||||
|
||||
#uiMap {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -280px 0 0 -280px; /* VOREStation Edit - Tether map is small */
|
||||
width: 140px; /* VOREStation Edit - Tether map is small */
|
||||
height: 140px; /* VOREStation Edit - Tether map is small */
|
||||
overflow: hidden;
|
||||
zoom: 4;
|
||||
}
|
||||
|
||||
#uiMapImage {
|
||||
position: absolute;
|
||||
bottom: 1px;
|
||||
left: 1px;
|
||||
width: 140px; /* VOREStation Edit - Tether map is small */
|
||||
height: 140px; /* VOREStation Edit - Tether map is small */
|
||||
}
|
||||
|
||||
#uiMapContent {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: 140px; /* VOREStation Edit - Tether map is small */
|
||||
height: 140px; /* VOREStation Edit - Tether map is small */
|
||||
}
|
||||
|
||||
#uiMapFooter {
|
||||
position: relative;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#uiContent {
|
||||
clear: both;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#uiMapTooltip {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
border: 1px solid #40628a;
|
||||
background-color: #272727;
|
||||
padding: 8px;
|
||||
display: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#uiLoadingNotice {
|
||||
position: relative;
|
||||
background: url(uiNoticeBackground.jpg) 50% 50%;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
padding: 3px 4px 3px 4px;
|
||||
margin: 4px 0 4px 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,803 +0,0 @@
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #ffffff;
|
||||
line-height: 170%;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
background: #272727;
|
||||
}
|
||||
|
||||
#uiNoScript {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -60px 0 0 -150px;
|
||||
width: 280px;
|
||||
height: 120px;
|
||||
background: #ffffff;
|
||||
border: 2px solid #ff0000;
|
||||
color: #000000;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
z-index: 9999;
|
||||
padding: 0px 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: #40628a;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.link, .linkOn, .linkOff, .selected, .disabled, .yellowButton, .redButton {
|
||||
float: left;
|
||||
min-width: 15px;
|
||||
height: 16px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
background: #40628a;
|
||||
border: 1px solid #161616;
|
||||
padding: 0px 4px 4px 4px;
|
||||
margin: 0 2px 2px 0;
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.link32 {
|
||||
float: left;
|
||||
min-width: 15px;
|
||||
max-width: 31px;
|
||||
height: 31px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
background: #40628a;
|
||||
border: 1px solid #161616;
|
||||
margin: 0 2px 2px 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.hasIcon {
|
||||
padding: 0px 4px 4px 0px;
|
||||
}
|
||||
|
||||
a:hover, .zoomLink:hover, .linkActive:hover {
|
||||
background: #507aac;
|
||||
}
|
||||
|
||||
.linkPending, .linkPending:hover {
|
||||
color: #ffffff;
|
||||
background: #507aac;
|
||||
}
|
||||
|
||||
a.white, a.white:link, a.white:visited, a.white:active {
|
||||
color: #40628a;
|
||||
text-decoration: none;
|
||||
background: #ffffff;
|
||||
border: 1px solid #161616;
|
||||
padding: 1px 4px 1px 4px;
|
||||
margin: 0 2px 0 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
a.white:hover {
|
||||
color: #ffffff;
|
||||
background: #40628a;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover, .selected, a.selected:link, a.selected:visited, a.selected:active, a.selected:hover {
|
||||
color: #ffffff;
|
||||
background: #2f943c;
|
||||
}
|
||||
|
||||
.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover, .disabled, a.disabled:link, a.disabled:visited, a.disabled:active, a.disabled:hover {
|
||||
color: #ffffff;
|
||||
background: #999999;
|
||||
border-color: #666666;
|
||||
}
|
||||
|
||||
a.icon, .linkOn.icon, .linkOff.icon, .selected.icon, .disabled.icon {
|
||||
position: relative;
|
||||
padding: 1px 4px 2px 20px;
|
||||
}
|
||||
|
||||
a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.icon img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.linkDanger, a.linkDanger:link, a.linkDanger:visited, a.linkDanger:active {
|
||||
color: #ffffff;
|
||||
background-color: #ff0000;
|
||||
border-color: #aa0000;
|
||||
}
|
||||
|
||||
.linkDanger:hover {
|
||||
background-color: #ff6666;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 4px 0 0 10px;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 0 0 2px 0;
|
||||
}
|
||||
|
||||
img, a img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
padding: 12px 0 6px 0;
|
||||
color: #FFFFFF;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.good {
|
||||
color: #4f7529;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.average {
|
||||
color: #cd6500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bad {
|
||||
color: #ee0000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.idle {
|
||||
color: #272727;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.redButton {
|
||||
background: #ea0000;
|
||||
}
|
||||
|
||||
.greenButton {
|
||||
background: #00aa00;
|
||||
}
|
||||
|
||||
.yellowButton {
|
||||
background: #cacc00;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #8BA5C4;
|
||||
}
|
||||
|
||||
.dark {
|
||||
color: #272727;
|
||||
}
|
||||
|
||||
.caption {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.multiLine {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.noticePlaceholder {
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
padding: 3px 4px 3px 4px;
|
||||
margin: 4px 0 4px 0;
|
||||
}
|
||||
|
||||
.notice {
|
||||
position: relative;
|
||||
background: url(uiNoticeBackground.jpg) 50% 50%;
|
||||
color: #000000;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
padding: 3px 4px 3px 4px;
|
||||
margin: 4px 0 4px 0;
|
||||
}
|
||||
|
||||
.notice.icon {
|
||||
padding: 2px 4px 0 20px;
|
||||
}
|
||||
|
||||
.notice img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
div.notice {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.itemGroup {
|
||||
border: 1px solid #e9c183;
|
||||
background: #2c2c2c;
|
||||
padding: 4px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
margin: 4px 0 0 0;
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.itemContentNarrow, .itemContent, .itemContentWide, .itemContentSmall, .itemContentMedium {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.itemContentNarrow {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.itemContent {
|
||||
width: 69%;
|
||||
}
|
||||
|
||||
.itemLabelNarrow, .itemLabel, .itemLabelWide, .itemLabelWider, .itemLabelWidest {
|
||||
float: left;
|
||||
color: #e9c183;
|
||||
}
|
||||
|
||||
.itemLabelNarrow {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.itemLabel {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.itemLabelWide {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.itemLabelWider {
|
||||
width: 69%;
|
||||
}
|
||||
|
||||
.itemLabelWidest {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.itemContentWide {
|
||||
width: 79%;
|
||||
}
|
||||
|
||||
.itemContentSmall {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.itemContentMedium {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
.statusDisplay {
|
||||
background: #000000;
|
||||
color: #ffffff;
|
||||
border: 1px solid #40628a;
|
||||
padding: 4px;
|
||||
margin: 3px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.statusDisplayRecords {
|
||||
background: #000000;
|
||||
color: #ffffff;
|
||||
border: 1px solid #40628a;
|
||||
padding: 4px;
|
||||
margin: 3px 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.statusDisplayComm {
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: #ffffff;
|
||||
padding-bottom: 4px;
|
||||
border-top: 0 none;
|
||||
border-left: 0 none;
|
||||
border-right: 0 none;
|
||||
border-bottom: 2px inset #40628a;
|
||||
margin: 3px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.statusLabel {
|
||||
width: 138px;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
color: #98B0C3;
|
||||
}
|
||||
|
||||
.statusValue {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.block {
|
||||
padding: 8px;
|
||||
margin: 10px 4px 4px 4px;
|
||||
border: 1px solid #40628a;
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
.block h3 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.displayBar {
|
||||
position: relative;
|
||||
width: 236px;
|
||||
height: 16px;
|
||||
border: 1px solid #666666;
|
||||
float: left;
|
||||
margin: 0 5px 0 0;
|
||||
overflow: hidden;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.displayBarText, .displayBarVerticalText, .displayBarBeakerText{
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: 5px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.displayBarFill {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background: #40628a;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.displayBarVertical {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 200px;
|
||||
border: 1px solid #666666;
|
||||
float: left;
|
||||
margin: 0 5px 0 0;
|
||||
overflow: hidden;
|
||||
background: #40628a;
|
||||
}
|
||||
|
||||
.displayBarVerticalFill {
|
||||
width: 100%;
|
||||
height: 0%;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
/*used in xenobio2 computer*/
|
||||
|
||||
.displayBarBeaker {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
height: 110px;
|
||||
border-right: 2px solid rgb(102, 179, 255);
|
||||
border-left: 2px solid rgb(102, 179, 255);
|
||||
border-bottom: 2px solid rgb(102, 179, 255);
|
||||
float: left;
|
||||
margin: 0 5px 0 0;
|
||||
overflow: hidden;
|
||||
background: #40628a;
|
||||
}
|
||||
|
||||
.displayBarBeakerFill {
|
||||
width: 100%;
|
||||
height: 0%;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
background: rgba(153, 204, 255, 0.3);
|
||||
}
|
||||
|
||||
.displayBarFill.alignRight {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.displayBarFill.good {
|
||||
color: #ffffff;
|
||||
background: #4f7529;
|
||||
}
|
||||
|
||||
.displayBarFill.average {
|
||||
color: #ffffff;
|
||||
background: #cd6500;
|
||||
}
|
||||
|
||||
.displayBarFill.bad {
|
||||
color: #ffffff;
|
||||
background: #ee0000;
|
||||
}
|
||||
|
||||
.displayBarFill.highlight {
|
||||
color: #ffffff;
|
||||
background: #8BA5C4;
|
||||
}
|
||||
|
||||
.clearBoth {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.clearLeft {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.clearRight {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.inactive, a.inactive:link, a.inactive:visited, a.inactive:active, a.inactive:hover {
|
||||
color: #ffffff;
|
||||
background: #999999;
|
||||
border-color: #666666;
|
||||
}
|
||||
|
||||
.fixedLeft {
|
||||
width: 110px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fixedLeftWide {
|
||||
width: 165px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fixedLeftWider {
|
||||
width: 220px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fixedLeftWidest {
|
||||
width: 250px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fixedLeftWiderRed {
|
||||
width: 220px;
|
||||
float: left;
|
||||
background: #ee0000;
|
||||
}
|
||||
|
||||
.floatRight {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.floatLeft {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* Used in PDA */
|
||||
|
||||
.wholeScreen {
|
||||
position: absolute;
|
||||
color: #517087;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pdalink {
|
||||
float: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* DNA Modifier UI (dna_modifier.tmpl) */
|
||||
|
||||
.dnaBlock {
|
||||
float: left;
|
||||
width: 90px;
|
||||
padding: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.dnaBlockNumber {
|
||||
font-family: Fixed, monospace;
|
||||
float: left;
|
||||
color: #ffffff;
|
||||
background: #363636;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dnaSubBlock {
|
||||
font-family: Fixed, monospace;
|
||||
float: left;
|
||||
padding: 0;
|
||||
min-width: 16px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url(uiMaskBackground.png);
|
||||
}
|
||||
|
||||
.maskContent {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin: 200px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.fixed {
|
||||
table-layout:fixed;
|
||||
}
|
||||
|
||||
table.fixed td {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Table stuffs for power monitor */
|
||||
table.pmon {
|
||||
border: 2px solid RoyalBlue;
|
||||
}
|
||||
|
||||
table.pmon td, table.pmon th {
|
||||
border-bottom: 1px dotted black;
|
||||
padding: 0px 5px 0px 5px;
|
||||
}
|
||||
|
||||
/* Table Stuffs for manifest*/
|
||||
|
||||
th.Command {
|
||||
background: #3333FF;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Security {
|
||||
background: #8e0000;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Medical {
|
||||
background: #006600;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Engineering {
|
||||
background: #b27300;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Science {
|
||||
background: #a65ba6;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Cargo {
|
||||
background: #bb9040;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Planetside{
|
||||
background: #555555;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Civilian {
|
||||
background: #a32800;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Miscellaneous {
|
||||
background: #666666;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
th.Silicon {
|
||||
background: #222222;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* Damage/health colors for crew monitoring computer */
|
||||
|
||||
.dead {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.alive {
|
||||
color: #7cfc00;
|
||||
}
|
||||
|
||||
.burn {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.brute {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.toxin {
|
||||
color: lime;
|
||||
}
|
||||
|
||||
.oxyloss {
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
/* 75px width used in power monitoring console buttons */
|
||||
.width75btn {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
/*Communicator Homescreen*/
|
||||
div.homeContainer {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
div.homeScreen {
|
||||
padding: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.link64 {
|
||||
float: left;
|
||||
min-width: 15px;
|
||||
max-width: 68px;
|
||||
height: 64px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
background: rgba(64, 98, 138, 0.6);
|
||||
border: 1px solid #161616;
|
||||
padding: 0 0 4px 0;
|
||||
margin: 0 0 30px 5.5%;
|
||||
cursor: default;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.link64:hover {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/*Communicator Dialing*/
|
||||
.dialPad {
|
||||
clear: both;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.dialPadKeys {
|
||||
float: left;
|
||||
width: 47px;
|
||||
height: 47px;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
background: rgba(64, 98, 138, 0.15);
|
||||
border: 1px inset rgba(100, 100, 100, 0.25);
|
||||
cursor: default;
|
||||
line-height: 47px;
|
||||
}
|
||||
|
||||
.dialPadKeys:hover {
|
||||
background: rgba(80, 122, 172, 0.5);
|
||||
}
|
||||
|
||||
.dialPadButtons {
|
||||
float: left;
|
||||
width: 63.2px;
|
||||
height: 63.2px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
background: rgba(64, 98, 138, 0.15);
|
||||
border: 1px inset rgba(100, 100, 100, 0.25);
|
||||
padding: 0 0 4px 0;
|
||||
cursor: default;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.dialPadButtons:hover {
|
||||
background: rgba(80, 122, 172, 0.5);
|
||||
font-size: 13px;
|
||||
|
||||
}
|
||||
|
||||
.dialPadAddress {
|
||||
float: left;
|
||||
width: 192px;
|
||||
height: 18px;
|
||||
background: rgba(64, 98, 138, 0.15);
|
||||
color: #ffffff;
|
||||
border-left: 1px inset #40628a;
|
||||
border-top: 1px inset #40628a;
|
||||
border-bottom: 1px inset #40628a;
|
||||
|
||||
}
|
||||
|
||||
.dialPadAddress:hover{
|
||||
background: rgba(80, 122, 172, 0.5);
|
||||
}
|
||||
|
||||
.dialPadClear {
|
||||
float: left;
|
||||
width: 19%;
|
||||
height: 18px;
|
||||
background: rgba(64, 98, 138, 0.15);
|
||||
color: #ffffff;
|
||||
border-right: 1px inset #40628a;
|
||||
border-top: 1px inset #40628a;
|
||||
border-bottom: 1px inset #40628a;
|
||||
}
|
||||
|
||||
.dialPadClear:hover{
|
||||
background: rgba(80, 122, 172, 0.5);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
th.Exploration{
|
||||
background: #bab421;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 70 KiB |