POLARIS: Tooltip framework, and mob tooltips

This commit is contained in:
Arokha Sieyes
2018-03-12 18:25:53 -04:00
committed by Leshana
parent 70ac478aea
commit de6da4a86c
31 changed files with 531 additions and 0 deletions

View File

@@ -276,3 +276,16 @@ Proc for attack log creation, because really why not
humans += H
return humans
/proc/getviewsize(view)
var/viewX
var/viewY
if(isnum(view))
var/totalviewrange = 1 + 2 * view
viewX = totalviewrange
viewY = totalviewrange
else
var/list/viewrangelist = splittext(view,"x")
viewX = text2num(viewrangelist[1])
viewY = text2num(viewrangelist[2])
return list(viewX, viewY)

View File

@@ -511,3 +511,9 @@
/atom/proc/AllowDrop()
return FALSE
/atom/proc/make_nametag_name(mob/user)
return name
/atom/proc/make_nametag_desc(mob/user)
return "" //Desc itself is often too long to use

View File

@@ -22,6 +22,7 @@
var/adminobs = null
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
var/datum/tooltip/tooltips = null
var/adminhelped = 0

View File

@@ -7,24 +7,28 @@
S["UI_style_color"] >> pref.UI_style_color
S["UI_style_alpha"] >> pref.UI_style_alpha
S["ooccolor"] >> pref.ooccolor
S["tooltipstyle"] >> pref.tooltipstyle
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
S["UI_style"] << pref.UI_style
S["UI_style_color"] << pref.UI_style_color
S["UI_style_alpha"] << pref.UI_style_alpha
S["ooccolor"] << pref.ooccolor
S["tooltipstyle"] >> pref.tooltipstyle
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color))
pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha))
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, all_tooltip_styles[1])
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
. = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
. += "<b>Custom UI</b> (recommended for White UI):<br>"
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a><3E><table style='display:inline;' bgcolor='[pref.UI_style_color]'><tr><td>__</td></tr></table><3E><a href='?src=\ref[src];reset=ui'>reset</a><br>"
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a><3E><a href='?src=\ref[src];reset=alpha'>reset</a><br>"
. += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>"
if(can_select_ooc_color(user))
. += "<b>OOC Color:</b><3E>"
if(pref.ooccolor == initial(pref.ooccolor))
@@ -57,6 +61,12 @@
pref.ooccolor = new_ooccolor
return TOPIC_REFRESH
else if(href_list["select_tooltip_style"])
var/tooltip_style_new = input(user, "Choose tooltip style.", "Character Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles
if(!tooltip_style_new || !CanUseTopic(user)) return TOPIC_NOACTION
pref.tooltipstyle = tooltip_style_new
return TOPIC_REFRESH
else if(href_list["reset"])
switch(href_list["reset"])
if("ui")

View File

@@ -98,6 +98,12 @@ var/list/_client_preferences_by_type
enabled_description = "Show"
disabled_description = "Hide"
/datum/client_preference/mob_tooltips
description ="Mob tooltips"
key = "MOB_TOOLTIPS"
enabled_description = "Show"
disabled_description = "Hide"
/datum/client_preference/attack_icons
description ="Attack icons"
key = "ATTACK_ICONS"

View File

@@ -21,6 +21,7 @@ datum/preferences
var/UI_style = "Midnight"
var/UI_style_color = "#ffffff"
var/UI_style_alpha = 255
var/tooltipstyle = "Midnight" //Style for popup tooltips
//character preferences
var/real_name //our character's name

View File

@@ -192,6 +192,19 @@
feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_mob_tooltips()
set name = "Toggle Mob Tooltips"
set category = "Preferences"
set desc = "Toggles displaying name/species over mobs when moused over."
var/pref_path = /datum/client_preference/mob_tooltips
toggle_preference(pref_path)
prefs.save_preferences()
src << "You will now [(is_preference_enabled(/datum/client_preference/mob_tooltips)) ? "see" : "not see"] mob tooltips."
feedback_add_details("admin_verb","TMobTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//Toggles for Staff
//Developers

View File

@@ -20,6 +20,15 @@
"Hologram" = 'icons/mob/screen1_robot_minimalist.dmi'
)
var/global/list/all_tooltip_styles = list(
"Midnight", //Default for everyone is the first one,
"Plasmafire",
"Retro",
"Slimecore",
"Operative",
"Clockwork"
)
/proc/ui_style2icon(ui_style)
if(ui_style in all_ui_styles)
return all_ui_styles[ui_style]

View File

@@ -1562,3 +1562,53 @@
status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't.
else
layer = HIDING_LAYER
/mob/living/carbon/human/proc/get_display_species()
//Shows species in tooltip
//Beepboops get special text if obviously beepboop
if(looksSynthetic())
if(gender == MALE)
return "Android"
else if(gender == FEMALE)
return "Gynoid"
else
return "Synthetic"
//Else species name
if(species)
return species.get_examine_name()
//Else CRITICAL FAILURE!
return ""
/mob/living/carbon/human/make_nametag_name(mob/user)
return name //Could do fancy stuff here?
/mob/living/carbon/human/make_nametag_desc(mob/user)
var/msg = ""
if(hasHUD(user,"security"))
//Try to find their name
var/perpname
if(wear_id)
var/obj/item/weapon/card/id/I = wear_id.GetID()
if(I)
perpname = I.registered_name
else
perpname = name
else
perpname = name
//Try to find their record
var/criminal = "None"
if(perpname)
var/datum/data/record/G = find_general_record("name", perpname)
if(G)
var/datum/data/record/S = find_security_record("id", G.fields["id"])
if(S)
criminal = S.fields["criminal"]
//If it's interesting, append
if(criminal != "None")
msg += "([criminal]) "
if(hasHUD(user,"medical"))
msg += "(Health: [round((health/getMaxHealth())*100)]%) "
msg += get_display_species()
return msg

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/scarybat
name = "space bats"
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
tt_desc = "Desmodus rotundus" //Common vampire bat
icon = 'icons/mob/bats.dmi'
icon_state = "bat"
icon_living = "bat"

View File

@@ -2,6 +2,7 @@
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "RawrRawr!!"
tt_desc = "Ursinae aetherius" //...bearspace? Maybe.
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
tt_desc = "Cyprinus aetherius" //carpspace? maybe
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"

View File

@@ -2,6 +2,7 @@
/mob/living/simple_animal/cat
name = "cat"
desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
tt_desc = "Felis catus"
intelligence_level = SA_ANIMAL
icon_state = "cat2"
item_state = "cat2"

View File

@@ -3,6 +3,7 @@
name = "corgi"
real_name = "corgi"
desc = "It's a corgi."
tt_desc = "Canis familiaris"
intelligence_level = SA_ANIMAL
icon_state = "corgi"
icon_living = "corgi"
@@ -37,6 +38,7 @@
real_name = "Ian" //Intended to hold the name without altering it.
gender = MALE
desc = "It's a corgi."
tt_desc = "Canis commandus"
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"

View File

@@ -2,6 +2,7 @@
/mob/living/simple_animal/crab
name = "crab"
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
tt_desc = "Ranina ranina"
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"

View File

@@ -2,6 +2,7 @@
/mob/living/simple_animal/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
tt_desc = "Oreamnos americanus"
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
@@ -85,6 +86,7 @@
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
tt_desc = "Bos taurus"
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
@@ -153,6 +155,7 @@
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
tt_desc = "Gallus domesticus"
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
@@ -203,6 +206,7 @@ var/global/chicken_count = 0
/mob/living/simple_animal/chicken
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
tt_desc = "Gallus domesticus"
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"

View File

@@ -8,6 +8,7 @@
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes."
tt_desc = "Atrax robustus gigantus"
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/goose
name = "space goose"
desc = "That's no duck. That's a space goose. You have a bad feeling about this."
tt_desc = "Anser aetherius" //Goose space?!
icon_state = "goose"
icon_living = "goose"
icon_dead = "goose_dead"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/lizard
name = "Lizard"
desc = "A cute tiny lizard."
tt_desc = "Gekko gecko"
icon = 'icons/mob/critter.dmi'
icon_state = "lizard"
icon_living = "lizard"

View File

@@ -2,6 +2,7 @@
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
tt_desc = "Mus musculus"
icon_state = "mouse_gray"
item_state = "mouse_gray"
icon_living = "mouse_gray"

View File

@@ -31,6 +31,7 @@
/mob/living/simple_animal/parrot
name = "parrot"
desc = "The parrot squawks, \"It's a parrot! BAWWK!\""
tt_desc = "Poicephalus robustus"
icon = 'icons/mob/animal.dmi'
icon_state = "parrot_fly"
icon_living = "parrot_fly"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/penguin
name = "space penguin"
desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
tt_desc = "Aptenodytes forsteri"
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/slime
name = "pet slime"
desc = "A lovable, domesticated slime."
tt_desc = "Amorphidae proteus"
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
icon_living = "grey baby slime"

View File

@@ -1,6 +1,7 @@
/mob/living/simple_animal/spiderbot
name = "spider-bot"
desc = "A skittering robotic friend!"
tt_desc = "Maintenance Robot"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"

View File

@@ -5,6 +5,7 @@
/mob/living/simple_animal
name = "animal"
desc = ""
icon = 'icons/mob/animal.dmi'
health = 20
maxHealth = 20
@@ -13,6 +14,8 @@
mob_swap_flags = MONKEY|SLIME|HUMAN
mob_push_flags = MONKEY|SLIME|HUMAN
var/tt_desc = "Uncataloged Life Form" //Tooltip description
//Settings for played mobs
var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob
var/ai_inactive = 0 // Set to 1 to turn off most AI actions
@@ -1697,3 +1700,6 @@
/mob/living/simple_animal/retaliate
retaliate = 1
destroy_surroundings = 1
/mob/living/simple_animal/make_nametag_desc(mob/user)
return "<i>tt_desc</i>"

View File

@@ -57,3 +57,7 @@
//set macro to normal incase it was overriden (like cyborg currently does)
client.set_hotkeys_macro("macro", "hotkeymode")
if(!client.tooltips)
client.tooltips = new(client)

View File

@@ -1143,3 +1143,14 @@ mob/proc/yank_out_object()
//Throwing stuff
/mob/proc/throw_item(atom/target)
return
/mob/MouseEntered(location, control, params)
if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips))
openToolTip(user = usr, tip_src = src, params = params, title = make_nametag_name(usr), content = make_nametag_desc(usr))
..()
/mob/MouseExited()
closeToolTip(usr) //No reason not to, really
..()

View File

@@ -0,0 +1,124 @@
/*
Tooltips v1.1 - 22/10/15
Developed by Wire (#goonstation on irc.synirc.net)
- Added support for screen_loc pixel offsets. Should work. Maybe.
- Added init function to more efficiently send base vars
Configuration:
- Set control to the correct skin element (remember to actually place the skin element)
- Set file to the correct path for the .html file (remember to actually place the html file)
- Attach the datum to the user client on login, e.g.
/client/New()
src.tooltips = new /datum/tooltip(src)
Usage:
- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively:
/obj/screen/hud
MouseEntered(location, control, params)
usr.client.tooltip.show(params, title = src.name, content = src.desc)
MouseExited()
usr.client.tooltip.hide()
Customization:
- Theming can be done by passing the theme var to show() and using css in the html file to change the look
- For your convenience some pre-made themes are included
Notes:
- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man.
- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck!
- After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13
*/
/datum/tooltip
var/client/owner
var/control = "mainwindow.tooltip"
var/showing = 0
var/queueHide = 0
var/init = 0
/datum/tooltip/New(client/C)
if (C)
owner = C
owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]")
..()
/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none")
if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size))
return 0
if (!init)
//Initialize some vars
init = 1
owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init")
showing = 1
if (title && content)
title = "<h1>[title]</h1>"
content = "<p>[content]</p>"
else if (title && !content)
title = "<p>[title]</p>"
else if (!title && content)
content = "<p>[content]</p>"
// Strip macros from item names
title = replacetext(title, "\proper", "")
title = replacetext(title, "\improper", "")
//Make our dumb param object
if(params[1] != "i") //Byond Bug: http://www.byond.com/forum/?post=2352648
params = "icon-x=16;icon-y=16;[params]" //Put in some placeholders
params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"}
//Send stuff to the tooltip
var/view_size = getviewsize(owner.view)
owner << output(list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update")
//If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips
showing = 0
if (queueHide)
hide()
return 1
/datum/tooltip/proc/hide()
if (queueHide)
schedule_task_with_source_in(1, src, .proc/do_hide)
else
do_hide()
queueHide = showing ? TRUE : FALSE
return TRUE
/datum/tooltip/proc/do_hide()
winshow(owner, control, FALSE)
/* TG SPECIFIC CODE */
//Open a tooltip for user, at a location based on params
//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc)
//Includes sanity.checks
/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "")
if(istype(user))
if(user.client && user.client.tooltips)
if(!theme && user.client.prefs && user.client.prefs.tooltipstyle)
theme = lowertext(user.client.prefs.tooltipstyle)
if(!theme)
theme = "midnight"
user.client.tooltips.show(tip_src, params, title, content, theme)
//Arbitrarily close a user's tooltip
//Includes sanity checks.
/proc/closeToolTip(mob/user)
if(istype(user))
if(user.client && user.client.tooltips)
user.client.tooltips.hide()

View File

@@ -0,0 +1,249 @@
<!DOCTYPE html>
<html>
<head>
<title>Tooltip</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrap {
position: absolute;
top: 0;
left: 0;
max-width: 298px;
border: 2px solid #1B2967;
}
.content {
font: bold 12px Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: #ffffff;
padding: 8px;
border: 2px solid #0033CC;
background: #005CB8;
}
h1 {
margin: -5px 0 2px 0;
font-size: 1.2em;
line-height: 1.4;
}
p {
margin: 0;
line-height: 1.2;
}
/* Custom Themes */
.blob .wrap {border-color: #2E2E2E;}
.blob .content {color: #82ED00; border-color: #4E4C4A; background-color: #191918;}
.parasite .wrap {border-color: #88868D;}
.parasite .content {color: #EFEEEF; border-color: #35333A; background-color: #636169;}
.alien .wrap {border-color: #33165B;}
.alien .content {color: #25004A; border-color: #5A3076; background-color: #6D3A8E;}
.wraith .wrap {border-color: #492136;}
.wraith .content {border-color: #331726; background-color: #471962;}
.cult .wrap {border-color: #292222;}
.cult .content {color: #FF0000; border-color: #4C4343; background-color: #3C3434;}
.clockcult .wrap {border-color: #170800;}
.clockcult .content {color: #B18B25; border-color: #000000; background-color: #5F380E;}
.pod .wrap {border-color: #052401;}
.pod .content {border-color: #326D29; background-color: #569F4B;}
.colo-pod .wrap {border-color: #256fb9;}
.colo-pod .content {border-color: #000000; background-color: #000000;}
.hisgrace .wrap {border-color: #7C1414;}
.hisgrace .content {color: #15D512; border-color: #9D1414; background-color: #861414;}
/* TG: Themes */
/* ScreenUI */
.midnight .wrap {border-color: #2B2B33;}
.midnight .content {color: #6087A0; border-color: #2B2B33; background-color: #36363C;}
.plasmafire .wrap {border-color: #21213D;}
.plasmafire .content {color: #FFA800 ; border-color: #21213D; background-color:#1D1D36;}
.retro .wrap {border-color: #005E00;}
.retro .content {color: #003366; border-color: #005E00; background-color: #00BD00;}
.slimecore .wrap {border-color: #18640E;}
.slimecore .content {color: #6EA161; border-color: #11450B; background-color: #354E35;}
.operative .wrap {border-color: #1E0101;}
.operative .content {color: #FFFFFF; border-color: #750000; background-color: #350000;}
.clockwork .wrap {border-color: #170800;}
.clockwork .content {color: #B18B25; border-color: #000000; background-color: #5F380E;}
</style>
</head>
<body>
<div id="wrap" class="wrap">
<div id="content" class="content"></div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
var tooltip = {
'tileSize': 32,
'control': '',
'params': {},
'client_view_w': 0,
'client_view_h': 0,
'text': '',
'theme': '',
'padding': 2,
init: function(tileSize, control) {
tooltip.tileSize = parseInt(tileSize);
tooltip.control = control;
},
hide: function() {
window.location = 'byond://winset?id='+tooltip.control+';is-visible=false';
},
updateCallback: function(map) {
if (typeof map === 'undefined' || !map) {return false;}
//alert(tooltip.params+' | '+tooltip.clientView+' | '+tooltip.text+' | '+tooltip.theme); //DEBUG
//Some reset stuff to avoid fringe issues with sizing
window.location = 'byond://winset?id='+tooltip.control+';anchor1=0,0;size=999x999';
//Get the real icon size according to the client view
var mapWidth = map['view-size'].x,
mapHeight = map['view-size'].y,
tilesShown = tooltip.client_view_w
realIconSize = mapWidth / tilesShown,
resizeRatio = realIconSize / tooltip.tileSize,
//Calculate letterboxing offsets
leftOffset = (map.size.x - mapWidth) / 2,
topOffset = (map.size.y - mapHeight) / 2;
//alert(realIconSize + ' | ' +tooltip.tileSize + ' | ' + resizeRatio); //DEBUG
//Parse out the tile and cursor locations from params (e.g. "icon-x=32;icon-y=29;screen-loc=3:10,15:29")
var paramsA = tooltip.params.cursor.split(';');
if (paramsA.length < 3) {return false;} //Sometimes screen-loc is never sent ahaha fuck you byond
//icon-x
var iconX = paramsA[0];
iconX = iconX.split('=');
iconX = parseInt(iconX[1]);
//icon-y
var iconY = paramsA[1];
iconY = iconY.split('=');
iconY = parseInt(iconY[1]);
//screen-loc
var screenLoc = paramsA[2];
screenLoc = screenLoc.split('=');
screenLoc = screenLoc[1].split(',');
if (screenLoc.length < 2) {return false;}
var left = screenLoc[0];
var top = screenLoc[1];
if (!left || !top) {return false;}
screenLoc = left.split(':');
left = parseInt(screenLoc[0]);
var enteredX = parseInt(screenLoc[1]);
screenLoc = top.split(':');
top = parseInt(screenLoc[0]);
var enteredY = parseInt(screenLoc[1]);
//Screen loc offsets on objects (e.g. "WEST+0:6,NORTH-1:26") can royally mess with positioning depending on where the cursor enters
//This is a giant bitch to parse. Note that it only expects screen_loc in the format <west>,<north>.
var oScreenLoc = tooltip.params.screenLoc.split(','); //o for original ok
var west = oScreenLoc[0].split(':');
if (west.length > 1) { //Only if west has a pixel offset
var westOffset = parseInt(west[1]);
if (westOffset !== 0) {
if ((iconX + westOffset) !== enteredX) { //Cursor entered on the offset tile
left = left + (westOffset < 0 ? 1 : -1);
}
leftOffset = leftOffset + (westOffset * resizeRatio);
}
}
if (oScreenLoc.length > 1) { //If north is given
var north = oScreenLoc[1].split(':');
if (north.length > 1) { //Only if north has a pixel offset
var northOffset = parseInt(north[1]);
if (northOffset !== 0) {
if ((iconY + northOffset) === enteredY) { //Cursor entered on the original tile
top--;
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Cursor entered on the offset tile
if (northOffset < 0) { //Offset southwards
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Offset northwards
top--;
topOffset = topOffset - (northOffset * resizeRatio);
}
}
}
}
}
//Handle special cases (for fuck sake)
if (tooltip.special !== 'none') {
//Put yo special cases here
}
//Clamp values
left = (left < 0 ? 0 : (left > tilesShown ? tilesShown : left));
top = (top < 0 ? 0 : (top > tilesShown ? tilesShown : top));
//Calculate where on the screen the popup should appear (below the hovered tile)
var posX = Math.round(((left - 1) * realIconSize) + leftOffset + tooltip.padding); //-1 to position at the left of the target tile
var posY = Math.round(((tilesShown - top + 1) * realIconSize) + topOffset + tooltip.padding); //+1 to position at the bottom of the target tile
//alert(mapWidth+' | '+mapHeight+' | '+tilesShown+' | '+realIconSize+' | '+leftOffset+' | '+topOffset+' | '+left+' | '+top+' | '+posX+' | '+posY); //DEBUG
$('body').attr('class', tooltip.theme);
var $content = $('#content'),
$wrap = $('#wrap');
$wrap.attr('style', '');
$content.off('mouseover');
$content.html(tooltip.text);
$wrap.width($wrap.width() + 2); //Dumb hack to fix a bizarre sizing bug
var docWidth = $wrap.outerWidth(),
docHeight = $wrap.outerHeight();
if (posY + docHeight > map.size.y) { //Is the bottom edge below the window? Snap it up if so
posY = (posY - docHeight) - realIconSize - tooltip.padding;
}
//Actually size, move and show the tooltip box
window.location = 'byond://winset?id='+tooltip.control+';size='+docWidth+'x'+docHeight+';pos='+posX+','+posY+';is-visible=true';
$content.on('mouseover', function() {
tooltip.hide();
});
},
update: function(params, client_vw , clien_vh , text, theme, special) {
//Assign our global object
tooltip.params = $.parseJSON(params);
tooltip.client_view_w = parseInt(client_vw);
tooltip.client_view_h = parseInt(clien_vh);
tooltip.text = text;
tooltip.theme = theme;
tooltip.special = special;
//Go get the map details
window.location = 'byond://winget?callback=tooltip.updateCallback;id=mapwindow.map;property=size,view-size';
},
};
</script>
</body>
</html>

View File

@@ -1936,6 +1936,14 @@ window "mainwindow"
is-checked = false
group = ""
button-type = pushbox
elem "tooltip"
type = BROWSER
pos = 0,0
size = 999x999
anchor1 = none
anchor2 = none
is-visible = false
saved-params = ""
window "mapwindow"
elem "mapwindow"

View File

@@ -2313,6 +2313,7 @@
#include "code\modules\tables\tables.dm"
#include "code\modules\tables\update_triggers.dm"
#include "code\modules\tension\tension.dm"
#include "code\modules\tooltip\tooltip.dm"
#include "code\modules\turbolift\_turbolift.dm"
#include "code\modules\turbolift\turbolift.dm"
#include "code\modules\turbolift\turbolift_areas.dm"