- Joined
- Jul 18, 2010
- Messages
- 2,377
new
old
ToolTips
In the warcraft 3's UI-framework, Tooltips are also frames. With that they can be more complex have child-Frames and be from various frametypes. Therefore they can display alot of different things.
Most Frames can have a Tooltip, but it has to be from the same Group: frame<->frame (BUTTON - FRAME); simpleframe <-> simpleframe (SIMPLEBUTTON - SIMPLEFRAME). From the SimpleFrame group only SIMPLEBUTTON can have a Tooltip.
This capitel covers Tooltips for the Frame group. While most is the same for both groups, there are small differences.
A Tooltip-Frames is visible, if the mouse does point at the primary Frame. The enable State of a Frame does not alter the Tooltip behaviour but hiding the Frame does.
The frame needs to be able to take control of the mouse on the screen.
It can happen that the Tooltip-Frame itself gets malformed if it leaves the 4:3 Screen, the children of the Tooltip-Frame are unaffected, hence it is suggested to add an empty FRAME parent for the acutal wanted Tooltip-Frame.
One tooltip-frame can serve many as tooltip.
Text is displayed bold/wrongly when it is the tooltip of multiple Frames. Happens also as child of the tooltip.
Tooltips can either be given in map script or fdf.
In fdf
ToolTip "FrameName",
Inside mapscript one uses
BlzFrameSetTooltip takes framehandle frame, framehandle tooltip returns nothing
Using this native activades the tooltip visible rule. Sadly calling this native does not hide a simpleframe tooltip.
Tooltip Examples
Let's create a TextButton with a TEXT Tooltip. This works out of the Box without any custom Toc or custom fdf.
Lua:
do
local real = MarkGameStarted
function MarkGameStarted()
real()
-- create a new Button which inherits from "ScriptDialogButton"
local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
-- place the Button to the center of the Screen
BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
-- set the Button's text
BlzFrameSetText(button, "My Button Text")
-- Create a TEXT-Frame
local tooltipFrame = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
-- tooltipFrame becomes button's tooltip
BlzFrameSetTooltip(button, tooltipFrame)
-- Place the Tooltip above the Button
BlzFrameSetPoint(tooltipFrame, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.01)
-- Prevent the TEXT from taking mouse control
BlzFrameSetEnable(tooltipFrame, false)
BlzFrameSetText(tooltipFrame, "Nothing will Happen when you click this Button.")
end
end
BoxText tooltip
The last example works but a text in a Box would be better. This is done by creating an BACKDROP the Box and a TEXT Frame as the child of the Box. The Box becomes the tooltip, as Child the Text will share the visibility of it's Parent the box.
For the BACKDROP we use "QuestButtonBaseTemplate".
Lua:
do
local real = MarkGameStarted
function MarkGameStarted()
real()
-- create a new Button which inherits from "ScriptDialogButton"
local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
-- place the Button to the center of the Screen
BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
-- set the Button's text
BlzFrameSetText(button, "My Button Text")
-- Create the Background a Backdrop
local tooltipFrameBackGround = BlzCreateFrame("QuestButtonBaseTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
BlzFrameSetSize(tooltipFrameBackGround, 0.25, 0.025)
-- Create the Text as child of the Background
local tooltipFrameText = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", tooltipFrameBackGround, "", 0)
-- Copy Size and Position with a small offset.
BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, 0.01, 0.01)
BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_TOPRIGHT, tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, -0.01, -0.01)
-- The background becomes the button's tooltip, the Text as child of the background will share the visibility
BlzFrameSetTooltip(button, tooltipFrameBackGround)
-- Place the Tooltip above the Button
BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.01)
-- Prevent the TEXT from taking mouse control
BlzFrameSetEnable(tooltipFrameText, false)
BlzFrameSetText(tooltipFrameText, "Nothing will Happen when you click this Button.")
end
end
BoxedText ToolTips Dynamic amount of Lines
The previous example is okay, but there is something quite a hassle about it, one has to set the size of the box. it would be much better when the box fits itself to the text.
This can be done, Instead of making the text fit into the box one makes the Box extend to the text's postion. The game even supports one in handling multilines with using 0 as Height for the TEXT-Frame. But one has to now care that the box is relative to the text means one has to place the text with the box's additional size.
Lua:
do
local real = MarkGameStarted
function MarkGameStarted()
real()
-- create a new Button which inherits from "ScriptDialogButton"
local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
-- place the Button to the center of the Screen
BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
-- set the Button's text
BlzFrameSetText(button, "My Button Text")
-- Create the Background a Backdrop
local tooltipFrameBackGround = BlzCreateFrame("QuestButtonBaseTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
-- Create the Text as child of the Background
local tooltipFrameText = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", tooltipFrameBackGround, "", 0)
-- the text has a Width of 0.25, and starts a new line when the given text is longer
BlzFrameSetSize(tooltipFrameText, 0.25, 0)
-- Copy Size and Position with a small offset.
BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, -0.01, -0.01)
BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, tooltipFrameText, FRAMEPOINT_TOPRIGHT, 0.01, 0.01)
-- The background becomes the button's tooltip, the Text as child of the background will share the visibility
BlzFrameSetTooltip(button, tooltipFrameBackGround)
-- Place the Tooltip above the Button
BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.01)
-- Prevent the TEXT from taking mouse control
BlzFrameSetEnable(tooltipFrameText, false)
BlzFrameSetText(tooltipFrameText, "Nothing will Happen when you click this Button. But here a longer text. The only son of King Terenas, Arthas is an idealistic, yet somewhat rash, young man who dreams of one day succeeding his father as King of Lordaeron. Arthas became an apprentice paladin at nineteen and has served as a favorite pupil of Uther the Lightbringer ever since. Though Arthas loves the kindly Uther as an uncle, he longs to take command of his own destiny and become a hero like those brave veterans who fought the orcs during the Second War. ")
end
end
SimpleFrame ToolTip
a working example of an SimpleFrameTooltip. It creates a "SIMPLEBUTTON" based on a Blueprint from fdf and a code driven "SIMPLESTATUSBAR". The "SIMPLESTATUSBAR" is used as icon and tooltip.
Lua:
do
local real = MarkGameStarted
function MarkGameStarted()
real()
local simpleFrame = BlzCreateSimpleFrame("UpperButtonBarButtonTemplate", BlzGetFrameByName("ConsoleUI", 0), 0)
BlzFrameSetAbsPoint(simpleFrame, FRAMEPOINT_CENTER, 0.4, 0.3)
local icon = BlzCreateFrameByType("SIMPLESTATUSBAR", "", BlzGetFrameByName("ConsoleUI", 0), "", 0)
BlzFrameClearAllPoints(icon)
BlzFrameSetPoint(icon, FRAMEPOINT_BOTTOM, simpleFrame, FRAMEPOINT_TOP, 0, 0.006)
BlzFrameSetSize(icon, 0.04, 0.04)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNPriest", 0, false)
BlzFrameSetValue(icon, 100)
BlzFrameSetTooltip(simpleFrame, icon)
-- SimpleFrameTooltip is not hidden by calling BlzFrameSetTooltip, hide it
BlzFrameSetVisible(icon, false)
end
end
Many blizzard's made BACKDROPs can be used. One could look here UI: List - Default MainFrames.
BlzFrameIsVisible(frame) also returns the correct value for frames working as tooltips, This is async hence quite fast but also dangerous. It could be used to perform an IsFrame hovered without enter/Leaver events (which are sending network packages). When doing that one creates an empty "FRAME" and defines it as Tooltip sets up a way to know which tooltip and Frame belong together and periodicly check for the visiblity of the Tooltip "FRAME", if it is visible and not the last hovered one you have the async enter event.
Undoing the tooltip state is problematic.
Introduction
In the UI-frame natives, tooltips are frames that are on default hidden. When one hovers the frame the tooltip is assigned to, the tooltip becomes visible. Tooltips itself are also frames that can have childs and be customized.That is the native one uses to make a tooltip-Frame become some frames tooltip.
BlzFrameSetTooltip takes framehandle frame, framehandle tooltip returns nothing
SimpleFrames and Tooltips
SimpleFrames can normally not have tooltips and they can also not be a tooltip for Frames. A SIMPLEBUTTON can have other SimpleFrames as tooltip.One can give a SimpleFrame a tooltip by creating a substitute FRAME which copies all points of the simpleframe. That substitute only handles the tooltip and is empty. When one hovers the SimpleFrame the substitute FRAME kicks in and shows its tooltip giving the feeling that it is the SimpleFrames tooltip. That way also SimpleFrames or BACKDROPs can have tooltips.
Example 1
In example 1, we create 3 Frames: a BACKDROP, a TEXT and a FRAME. The BACKDROP shows a Paladin icon. The FRAME copies the points of the BACKDROP and handles the Tooltip showing. As last the TEXT-Frame is the tooltip itself which is shown when one hovers the Paladin icon with the mouse.The FRAME is needed in this example because BACKDROPs can not have events nor tooltips. FRAME can't have events either but can have a tooltip.
In this example all frames are created with BlzCreateFrameByType, that is done so one does not have to bother fdf for this example.
BlzCreateFrameByType takes string typeName, string name, framehandle owner, string inherits, integer createContext
Lua:
function Face()
local face = BlzCreateFrameByType("BACKDROP", "Face", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)--Create a new frame of Type BACKDROP
local faceHover = BlzCreateFrameByType("FRAME", "FaceFrame", face,"", 0) --face is a BACKDROP it can not have events nor a tooltip, thats why one creates an empty frame managing that.
local tooltip = BlzCreateFrameByType("TEXT", "FaceFrameTooltip", face,"", 0)--Create a new frame of Type TEXT
--faceHover would be unneeded if face would support events/tooltip
BlzFrameSetAllPoints(faceHover, face) --faceHover copies the size and position of face.
BlzFrameSetTooltip(faceHover, tooltip) --when faceHover is hovered with the mouse frame tooltip becomes visible.
BlzFrameSetSize(face, 0.04, 0.04)
BlzFrameSetAbsPoint(face, FRAMEPOINT_CENTER, 0.4, 0.3)
BlzFrameSetAbsPoint(tooltip, FRAMEPOINT_CENTER, 0.2, 0.3)
BlzFrameSetText(tooltip, "Human Paladin Face")
BlzFrameSetTexture(face, "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin",0, true)--face uses paladin blp as texture.
end
That code has to be executed. It does not run by itself.
-
Start
-
Events
-
Map initialization
-
-
Conditions
-
Actions
-
Custom script: Face()
-
-
Example 2
The tooltip in the previous example is not really good looking, it's just some Text on the screen. I want it to be in a box and look similar to the default tooltip. Well because such a frame does not exist in the default fdf and one can not manipulate the shown text of the default tooltip frame (as far as I know), one has to create it.That will be our Boxed Text fdf. "BoxedText" is the frame we create. What can that "BoxedText" do? It mimics the default Tooltip-Box and has 2 children: "BoxedTextTitle" and "BoxedTextValue". The title is shown in the first line and below that title BoxedTextValue will be placed. BoxedTextValue has a smaller Text size than BoxedTextTitle.
Code:
// -- LOCAL TEMPLATES -------------------------------------------------------
Frame "BACKDROP" "BoxedTextBackgroundTemplate" {
DecorateFileNames, //Look-Up Names in some String table (for example gameinterface)
BackdropTileBackground, //Tile mode enabled
BackdropBackground "ToolTipBackground", //BackgroundFile
BackdropCornerFlags "UL|UR|BL|BR|T|L|B|R",
BackdropCornerSize 0.008, //higher numbers make the corners bigger.
BackdropBackgroundInsets 0.0022 0.0022 0.0022 0.0022, //makes the background smaller, from the outside.
BackdropEdgeFile "ToolTipBorder", //the border File
BackdropBlendAll,
}
// -- Frames -------------------------------------------------------
Frame "BACKDROP" "BoxedText" INHERITS "BoxedTextBackgroundTemplate" {
UseActiveContext,
Frame "TEXT" "BoxedTextTitle" {
UseActiveContext,
DecorateFileNames,
SetPoint TOPLEFT, "BoxedText", TOPLEFT, 0.005, -0.005, //Positionate "BoxedTextSimpleTitle"'s TOPLEFT to "BoxedText"'s TOPLEFT with an offset
SetPoint TOPRIGHT, "BoxedText", TOPRIGHT, -0.005, -0.005,
FontFlags "FIXEDSIZE",
FrameFont "MasterFont", 0.014, "",
FontColor 1.0 1.0 1.0 1.0, //Red Green Blue Alpha 0.0 to 1.0
FontShadowColor 0.0 0.0 0.0 0.9,
FontShadowOffset 0.001 -0.001,
}
Frame "TEXT" "BoxedTextValue" {
UseActiveContext,
DecorateFileNames,
SetPoint TOPLEFT, "BoxedText", TOPLEFT, 0.005, -0.02,
SetPoint BOTTOMRIGHT, "BoxedText", BOTTOMRIGHT, -0.005, 0.005,
FontFlags "FIXEDSIZE",
FrameFont "MasterFont", 0.012, "",
FontColor 1.0 1.0 1.0 1.0,
FontShadowColor 0.0 0.0 0.0 0.9,
FontShadowOffset 0.001 -0.001,
}
}
Now we need to change the code a bit. Instead of TEXT, we now create a Frame of name "BoxedText". Also the tooltip is not a TEXT anymore, it's now a box, means we have to access the children of the box showing the text. They are BoxedTextValue and BoxedTextTitle.
Lua:
function Face2()
BlzLoadTOCFile("war3mapimported\\BoxedText.toc")
local face = BlzCreateFrameByType("BACKDROP", "Face", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)--Create a new frame of Type BACKDROP
local faceHover = BlzCreateFrameByType("FRAME", "FaceFrame", face,"", 0) --face is a BACKDROP it can not have events nor a tooltip, thats why one creates an empty frame managing that.
local tooltip = BlzCreateFrame("BoxedText", face, 0, 0)--Create the BoxedText Frame
--faceHover would be unneeded if face would support events/tooltip
BlzFrameSetAllPoints(faceHover, face) --faceHover copies the size and position of face.
BlzFrameSetTooltip(faceHover, tooltip) --when faceHover is hovered with the mouse frame tooltip becomes visible.
BlzFrameSetSize(face, 0.04, 0.04)
BlzFrameSetAbsPoint(face, FRAMEPOINT_CENTER, 0.4, 0.3)
BlzFrameSetAbsPoint(tooltip, FRAMEPOINT_CENTER, 0.2, 0.3)
BlzFrameSetSize(tooltip, 0.15, 0.08)
BlzFrameSetText(BlzGetFrameByName("BoxedTextValue",0), "Human Paladin Face, but it is not uther.")--BoxedText has a child showing the text, set that childs Text.
BlzFrameSetText(BlzGetFrameByName("BoxedTextTitle",0), "Paladin")--BoxedText has a child showing the Title-text, set that childs Text.
BlzFrameSetTexture(face, "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin",0, true)--face uses paladin blp as texture.
end
-
Start
-
Events
-
Map initialization
-
-
Conditions
-
Actions
-
Custom script: Face2()
-
-
That is nice, Text in a box, also similar to the default one.
Instead of creating such a BoxedText one could use a TEXTAREA. TEXTAREA does most of BoxedText, but it has a scrollbar blocking a part of the right side and it requires the box to have a min size (else it crashes the game / the thread). Also it becomes a bit tricky with the title.
ChangeLog: Added <UseActiveContext,> to the children in fdf. Without it, the tooltip text inside the box would work wrong for createcontext not be 0.
Added the version from the big UI tutorial the old is still there in a tab
Other UI-Frame Tutorials
The following links might provide more insight into this subject.UI: Change Lumber Text
[JASS/AI] - UI: Create a TextButton
[JASS/AI] - UI: Positionate Frames (important)
UI: toc-Files
UI: Reading a FDF
UI - The concept of Parent-Frames
[JASS/AI] - UI: FrameEvents and FrameTypes
UI: Frames and Tooltips
[JASS/AI] - UI: Creating a Bar
UI - Simpleframes
UI: What are BACKDROPs?
UI: GLUEBUTTON
UI: TEXTAREA the scrolling Text Frame
UI: EditBox - Text Input
[JASS/AI] - UI: Creating a Cam control
UI: Showing 3 Multiboards
UI: OriginFrames
Default Names for BlzGetFrameByName (Access to Existing game-Frames)
[JASS/AI] - UI: List - Default MainFrames (built in CreateAble)
Attachments
Last edited: