2021-03-28 23:55:13 +02:00
|
|
|
/* Copyright (C) 2021 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2006-04-24 01:14:18 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
|
|
|
#include "GUITooltip.h"
|
2015-08-21 19:08:41 +02:00
|
|
|
|
2019-09-20 15:11:18 +02:00
|
|
|
#include "gui/CGUI.h"
|
2021-05-06 10:22:37 +02:00
|
|
|
#include "gui/ObjectTypes/CTooltip.h"
|
2015-08-21 19:08:41 +02:00
|
|
|
#include "lib/timer.h"
|
2006-04-24 01:14:18 +02:00
|
|
|
#include "ps/CLogger.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
Tooltips:
|
|
|
|
When holding the mouse stationary over an object for some amount of time,
|
|
|
|
the tooltip is displayed. If the mouse moves off that object, the tooltip
|
|
|
|
disappears. If the mouse re-enters an object within a short time, the new
|
|
|
|
tooltip is displayed immediately. (This lets you run the mouse across a
|
|
|
|
series of buttons, without waiting ages for the text to pop up every time.)
|
|
|
|
|
|
|
|
See Visual Studio's toolbar buttons for an example.
|
|
|
|
|
|
|
|
|
|
|
|
Implemented as a state machine:
|
|
|
|
|
|
|
|
(where "*" lines are checked constantly, and "<" lines are handled
|
|
|
|
on entry to that state)
|
|
|
|
|
|
|
|
IN MOTION
|
|
|
|
* If the mouse stops, check whether it should have a tooltip and move to
|
|
|
|
'STATIONARY, NO TOOLTIP' or 'STATIONARY, TOOLIP'
|
|
|
|
* If the mouse enters an object with a tooltip delay of 0, switch to 'SHOWING'
|
|
|
|
|
|
|
|
STATIONARY, NO TOOLTIP
|
|
|
|
* If the mouse moves, switch to 'IN MOTION'
|
|
|
|
|
|
|
|
STATIONARY, TOOLTIP
|
|
|
|
< Set target time = now + tooltip time
|
|
|
|
* If the mouse moves, switch to 'IN MOTION'
|
|
|
|
* If now > target time, switch to 'SHOWING'
|
|
|
|
|
|
|
|
SHOWING
|
|
|
|
< Start displaying the tooltip
|
|
|
|
* If the mouse leaves the object, check whether the new object has a tooltip
|
|
|
|
and switch to 'SHOWING' or 'COOLING'
|
|
|
|
|
|
|
|
COOLING (since I can't think of a better name)
|
|
|
|
< Stop displaying the tooltip
|
|
|
|
< Set target time = now + cooldown time
|
|
|
|
* If the mouse has moved and is over a tooltipped object, switch to 'SHOWING'
|
|
|
|
* If now > target time, switch to 'STATIONARY, NO TOOLTIP'
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
ST_IN_MOTION,
|
|
|
|
ST_STATIONARY_NO_TOOLTIP,
|
|
|
|
ST_STATIONARY_TOOLTIP,
|
|
|
|
ST_SHOWING,
|
|
|
|
ST_COOLING
|
|
|
|
};
|
|
|
|
|
|
|
|
GUITooltip::GUITooltip()
|
2019-09-23 01:28:25 +02:00
|
|
|
: m_State(ST_IN_MOTION), m_PreviousObject(nullptr), m_PreviousTooltipName()
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const double CooldownTime = 0.25; // TODO: Don't hard-code this value
|
|
|
|
|
2010-10-30 06:02:42 +02:00
|
|
|
bool GUITooltip::GetTooltip(IGUIObject* obj, CStr& style)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2021-05-01 14:38:05 +02:00
|
|
|
if (!obj)
|
|
|
|
return false;
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2021-05-01 14:38:05 +02:00
|
|
|
if (obj->GetTooltipText().empty())
|
|
|
|
return false;
|
2010-10-31 23:00:28 +01:00
|
|
|
|
2021-05-01 14:38:05 +02:00
|
|
|
style = obj->GetTooltipStyle();
|
|
|
|
if (style.empty())
|
|
|
|
style = "default";
|
|
|
|
return true;
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
2021-03-28 23:55:13 +02:00
|
|
|
void GUITooltip::ShowTooltip(IGUIObject* obj, const CVector2D& pos, const CStr& style, CGUI& pGUI)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2011-04-30 15:01:45 +02:00
|
|
|
ENSURE(obj);
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2007-02-01 15:46:14 +01:00
|
|
|
if (style.empty())
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
|
|
|
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
if (!tooltipobj || !tooltipobj->SettingExists("use_object"))
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2015-01-22 21:36:24 +01:00
|
|
|
LOGERROR("Cannot find tooltip named '%s'", style.c_str());
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
IGUIObject* usedobj; // object actually used to display the tooltip in.
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
const CStr& usedObjectName = tooltipobj->GetUsedObject();
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
if (usedObjectName.empty())
|
|
|
|
{
|
|
|
|
usedobj = tooltipobj;
|
2021-05-06 10:22:37 +02:00
|
|
|
tooltipobj->SetMousePos(pos);
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
}
|
|
|
|
else
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2019-08-21 12:12:33 +02:00
|
|
|
usedobj = pGUI.FindObjectByName(usedObjectName);
|
2015-08-21 19:08:41 +02:00
|
|
|
if (!usedobj)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2015-01-22 21:36:24 +01:00
|
|
|
LOGERROR("Cannot find object named '%s' used by tooltip '%s'", usedObjectName.c_str(), style.c_str());
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
if (usedobj->SettingExists("caption"))
|
|
|
|
{
|
2021-05-01 14:38:05 +02:00
|
|
|
const CStrW& text = obj->GetTooltipText();
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
usedobj->SetSettingFromString("caption", text, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOGERROR("Object '%s' used by tooltip '%s' must have a caption setting!", usedobj->GetPresentableName().c_str(), style.c_str());
|
|
|
|
return;
|
|
|
|
}
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
usedobj->SetHidden(false);
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
2019-08-21 12:12:33 +02:00
|
|
|
void GUITooltip::HideTooltip(const CStr& style, CGUI& pGUI)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2007-02-01 15:46:14 +01:00
|
|
|
if (style.empty())
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
|
|
|
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
if (!tooltipobj || !tooltipobj->SettingExists("use_object") || !tooltipobj->SettingExists("hide_object"))
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
LOGERROR("Cannot find tooltip named '%s' or it is not a tooltip", style.c_str());
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-06 10:22:37 +02:00
|
|
|
const CStr& usedObjectName = tooltipobj->GetUsedObject();
|
2019-08-23 16:43:10 +02:00
|
|
|
if (!usedObjectName.empty())
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2019-08-21 12:12:33 +02:00
|
|
|
IGUIObject* usedobj = pGUI.FindObjectByName(usedObjectName);
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
if (usedobj && usedobj->SettingExists("caption"))
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
Move static GUI<>::SetSetting operating on IGUIObject to a member IGUIObject::SetSetting.
Remove PSERROR codes from SetSetting (let std::map throw an out_of_range
if a caller wants to Set a setting that doesn't exist without having
checked with SettingExists, equal to GetSetting from 92b6cdfeab).
That also simplifies std::function SetSettingWrap construct from
0a7d0ecdde to void IGUIObject::SettingChanged.
Don't trigger debug_warn or exceptions in GUITooltip::ShowTooltip if the
XML author specified wrong tooltip input, and dodge another
dynamic_cast.
Rename existing IGUIObject::SetSetting to
IGUIObject::SetSettingFromString and comment that it is purposed for
parsing XML files.
Remove SetSetting default value, so that authors are made aware
explicitly of the need to decide the function broadcasting a message,
refs d87057b1c0, 719f2d7967, ...
Change const bool& SkipMessage to const bool SendMessage, so that a
positive value relates to a positive action.
Clean AddSettings whitespace and integer types.
Differential Revision: https://code.wildfiregames.com/D2231
Tested on: gcc 9.1.0, clang 8.0.1, Jenkins
Comments By: Philip on IRC on 2010-07-24 on GUIUtil being ugly, in case
that one counts
This was SVN commit r22796.
2019-08-28 13:21:11 +02:00
|
|
|
usedobj->SetSettingFromString("caption", L"", true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOGERROR("Object named '%s' used by tooltip '%s' does not exist or does not have a caption setting!", usedObjectName.c_str(), style.c_str());
|
2006-04-24 01:14:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
if (tooltipobj->ShouldHideObject())
|
|
|
|
usedobj->SetHidden(true);
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
else
|
2021-05-06 10:22:37 +02:00
|
|
|
tooltipobj->SetHidden(true);
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 14:25:07 +02:00
|
|
|
static i32 GetTooltipDelay(const CStr& style, CGUI& pGUI)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2021-05-06 10:22:37 +02:00
|
|
|
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
|
|
|
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
2019-08-23 16:43:10 +02:00
|
|
|
|
2015-08-21 19:08:41 +02:00
|
|
|
if (!tooltipobj)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2015-01-22 21:36:24 +01:00
|
|
|
LOGERROR("Cannot find tooltip object named '%s'", style.c_str());
|
2019-08-23 16:43:10 +02:00
|
|
|
return 500;
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
2019-08-23 16:43:10 +02:00
|
|
|
|
2021-05-06 10:22:37 +02:00
|
|
|
return tooltipobj->GetTooltipDelay();
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
2021-03-28 23:55:13 +02:00
|
|
|
void GUITooltip::Update(IGUIObject* Nearest, const CVector2D& MousePos, CGUI& GUI)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
// Called once per frame, so efficiency isn't vital
|
2008-01-07 21:03:19 +01:00
|
|
|
double now = timer_Time();
|
2006-04-24 01:14:18 +02:00
|
|
|
|
|
|
|
CStr style;
|
|
|
|
int nextstate = -1;
|
|
|
|
|
|
|
|
switch (m_State)
|
|
|
|
{
|
|
|
|
case ST_IN_MOTION:
|
|
|
|
if (MousePos == m_PreviousMousePos)
|
|
|
|
{
|
|
|
|
if (GetTooltip(Nearest, style))
|
|
|
|
nextstate = ST_STATIONARY_TOOLTIP;
|
|
|
|
else
|
|
|
|
nextstate = ST_STATIONARY_NO_TOOLTIP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Check for movement onto a zero-delayed tooltip
|
|
|
|
if (GetTooltip(Nearest, style) && GetTooltipDelay(style, GUI)==0)
|
|
|
|
{
|
|
|
|
// Reset any previous tooltips completely
|
|
|
|
//m_Time = now + (double)GetTooltipDelay(style, GUI) / 1000.;
|
|
|
|
HideTooltip(m_PreviousTooltipName, GUI);
|
|
|
|
|
|
|
|
nextstate = ST_SHOWING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_STATIONARY_NO_TOOLTIP:
|
|
|
|
if (MousePos != m_PreviousMousePos)
|
|
|
|
nextstate = ST_IN_MOTION;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_STATIONARY_TOOLTIP:
|
|
|
|
if (MousePos != m_PreviousMousePos)
|
|
|
|
nextstate = ST_IN_MOTION;
|
|
|
|
else if (now >= m_Time)
|
|
|
|
{
|
|
|
|
// Make sure the tooltip still exists
|
|
|
|
if (GetTooltip(Nearest, style))
|
|
|
|
nextstate = ST_SHOWING;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Failed to retrieve style - the object has probably been
|
|
|
|
// altered, so just restart the process
|
|
|
|
nextstate = ST_IN_MOTION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_SHOWING:
|
2021-05-01 14:38:05 +02:00
|
|
|
// Handle sub-object tooltips.
|
|
|
|
if (Nearest == m_PreviousObject)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2010-02-28 22:26:06 +01:00
|
|
|
// Still showing the same object's tooltip, but the text might have changed
|
|
|
|
if (GetTooltip(Nearest, style))
|
|
|
|
ShowTooltip(Nearest, MousePos, style, GUI);
|
2021-05-01 14:38:05 +02:00
|
|
|
else
|
|
|
|
nextstate = ST_COOLING;
|
2010-02-28 22:26:06 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Mouse moved onto a new object
|
2006-04-24 01:14:18 +02:00
|
|
|
if (GetTooltip(Nearest, style))
|
2015-08-21 19:08:41 +02:00
|
|
|
{
|
2006-04-24 01:14:18 +02:00
|
|
|
CStr style_old;
|
|
|
|
|
2015-08-21 19:08:41 +02:00
|
|
|
// If we're displaying a tooltip with no delay, then we want to
|
2006-04-24 01:14:18 +02:00
|
|
|
// reset so that other object that should have delay can't
|
|
|
|
// "ride this tail", it have to wait.
|
|
|
|
// Notice that this doesn't apply to when you go from one delay=0
|
|
|
|
// to another delay=0
|
2015-08-21 19:08:41 +02:00
|
|
|
if (GetTooltip(m_PreviousObject, style_old) && GetTooltipDelay(style_old, GUI) == 0 &&
|
|
|
|
GetTooltipDelay(style, GUI) != 0)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
HideTooltip(m_PreviousTooltipName, GUI);
|
|
|
|
nextstate = ST_IN_MOTION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Hide old scrollbar
|
|
|
|
HideTooltip(m_PreviousTooltipName, GUI);
|
|
|
|
nextstate = ST_SHOWING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nextstate = ST_COOLING;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_COOLING:
|
|
|
|
if (GetTooltip(Nearest, style))
|
|
|
|
nextstate = ST_SHOWING;
|
|
|
|
else if (now >= m_Time)
|
|
|
|
nextstate = ST_IN_MOTION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle state-entry code:
|
|
|
|
if (nextstate != -1)
|
|
|
|
{
|
|
|
|
switch (nextstate)
|
|
|
|
{
|
|
|
|
case ST_STATIONARY_TOOLTIP:
|
|
|
|
m_Time = now + (double)GetTooltipDelay(style, GUI) / 1000.;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_SHOWING:
|
|
|
|
ShowTooltip(Nearest, MousePos, style, GUI);
|
|
|
|
m_PreviousTooltipName = style;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ST_COOLING:
|
|
|
|
HideTooltip(m_PreviousTooltipName, GUI);
|
|
|
|
m_Time = now + CooldownTime;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_State = nextstate;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_PreviousMousePos = MousePos;
|
|
|
|
m_PreviousObject = Nearest;
|
|
|
|
}
|