Add a new GUI2 tooltip.
The placement of tooltip is controlled by the WML of the GUI engine. The code is not used yet, only available with a proof-of-concept define named DEBUG_TOOLTIP.
This commit is contained in:
parent
8ff55378cc
commit
5da495122a
7 changed files with 354 additions and 0 deletions
|
@ -3,6 +3,7 @@ Version 1.11.9+dev:
|
|||
* Updated translations:
|
||||
* GUI2
|
||||
* Added: FAI-function handling in GUI2 widgets.
|
||||
* Added: A new tooltip window.
|
||||
* Miscellaneous and bug fixes:
|
||||
* Fixed: A compilation warning with DEBUG_WINDOW_LAYOUT_GRAPHS.
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#textdomain wesnoth-lib
|
||||
###
|
||||
### Definition of the window used to show large tooltips.
|
||||
### The placement algorithms used are described in the
|
||||
### »Tooltip placement« section in the GUI2 design document.
|
||||
###
|
||||
### gui/dialogs/title_screen.cpp has test code, which is
|
||||
### activated by defining the DEBUG_TOOLTIP macro.
|
||||
###
|
||||
|
||||
[window]
|
||||
|
@ -46,3 +51,188 @@
|
|||
[/resolution]
|
||||
|
||||
[/window]
|
||||
|
||||
|
||||
#define __GUI_WINDOW_HEIGHT
|
||||
(
|
||||
if(window_height = 0
|
||||
# Determine the wanted maximum height. #
|
||||
# The value should be high enough to avoid an #
|
||||
# unable to place exception. #
|
||||
, 100000
|
||||
# Determine the height to use. #
|
||||
, window_height)
|
||||
)#enddef
|
||||
|
||||
|
||||
#define __GUI_WINDOW_FUNCTIONS
|
||||
def placement_method(m, w, s)
|
||||
(
|
||||
if((w.y > s.y) or ((w.x * 2) > s.x)
|
||||
, 'V'
|
||||
, if(m.y >= w.y
|
||||
, if(m.x >= w.x, 'I', 'III')
|
||||
, if(m.x >= w.x, 'II', 'IV')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
def set_x(m, w, s)
|
||||
(
|
||||
[
|
||||
switch(
|
||||
placement_method(m, w, s)
|
||||
, 'I' , m.x - w.x
|
||||
, 'II' , m.x - w.x
|
||||
, 'III' , 5
|
||||
# extra offset to avoid being obscured by the mouse. #
|
||||
, 'IV' , m.x + 15
|
||||
, 'V' , 5
|
||||
, #default# m.x
|
||||
),
|
||||
#
|
||||
debug_print('placement_method, mouse ', m),
|
||||
debug_print('window ', w),
|
||||
debug_print('screen ', s),
|
||||
debug_print('y margin', s.y - (m.y + w.y)),
|
||||
debug_print('result ', placement_method(m, w, s)),
|
||||
#
|
||||
|
||||
][0]
|
||||
);
|
||||
|
||||
def set_y(m, w, s)
|
||||
(
|
||||
switch(
|
||||
placement_method(m, w, s)
|
||||
, 'I' , m.y - w.y
|
||||
, 'II' , 5
|
||||
, 'III' , m.y - w.y
|
||||
, 'IV' , 5
|
||||
, 'V' , 5
|
||||
, #default# m.y - w.y
|
||||
)
|
||||
);
|
||||
|
||||
def get_maximum_width(w, s)
|
||||
(
|
||||
if(w.x = 0
|
||||
# The default width upon the initial run. #
|
||||
, 160
|
||||
, if(w.y <= s.y
|
||||
# If the window's height fits use that. #
|
||||
, w.x
|
||||
# Else use an increased width, which should reduce #
|
||||
# the required height. #
|
||||
, 2 * w.x))
|
||||
);
|
||||
|
||||
def set_w(r, w, s)
|
||||
(
|
||||
switch(
|
||||
r
|
||||
, 'maximum', get_maximum_width(w, s)
|
||||
, 'size', w.x
|
||||
)
|
||||
);
|
||||
|
||||
def reevaluate_best_size(w, s)
|
||||
(
|
||||
[
|
||||
w.y > s.y,
|
||||
#
|
||||
debug_print('window ', w),
|
||||
debug_print('screen ', s)
|
||||
#
|
||||
][0]
|
||||
);
|
||||
#enddef
|
||||
|
||||
#define __GUI_WINDOW_X
|
||||
(
|
||||
set_x(
|
||||
loc(mouse_x, mouse_y)
|
||||
, loc(window_width, window_height)
|
||||
, loc(screen_width, screen_height))
|
||||
)
|
||||
#enddef
|
||||
|
||||
#define __GUI_WINDOW_Y
|
||||
(
|
||||
set_y(
|
||||
loc(mouse_x, mouse_y)
|
||||
, loc(window_width, window_height)
|
||||
, loc(screen_width, screen_height))
|
||||
)#enddef
|
||||
|
||||
#define __GUI_WINDOW_WIDTH
|
||||
(
|
||||
set_w(
|
||||
size_request_mode
|
||||
, loc(window_width, window_height)
|
||||
, loc(screen_width, screen_height))
|
||||
)#enddef
|
||||
|
||||
#define __GUI_WINDOW_REEVALUATE_BEST_SIZE
|
||||
(
|
||||
reevaluate_best_size(
|
||||
loc(window_width, window_height)
|
||||
, loc(screen_width, screen_height))
|
||||
)#enddef
|
||||
|
||||
[window]
|
||||
id = "tooltip"
|
||||
description = "The tooltip popup window with large tooltips, eg in the main menu."
|
||||
|
||||
[resolution]
|
||||
definition = "tooltip_large"
|
||||
|
||||
automatic_placement = "false"
|
||||
|
||||
functions = "{__GUI_WINDOW_FUNCTIONS}"
|
||||
|
||||
x = "{__GUI_WINDOW_X}"
|
||||
y = "{__GUI_WINDOW_Y}"
|
||||
width = "{__GUI_WINDOW_WIDTH}"
|
||||
height = "{__GUI_WINDOW_HEIGHT}"
|
||||
reevaluate_best_size = "{__GUI_WINDOW_REEVALUATE_BEST_SIZE}"
|
||||
|
||||
# TODO tooltips in this window make little sense.
|
||||
# Have to think of a nice solution.
|
||||
[tooltip]
|
||||
id = "tooltip"
|
||||
[/tooltip]
|
||||
|
||||
[helptip]
|
||||
id = "tooltip"
|
||||
[/helptip]
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
|
||||
[label]
|
||||
id = "label"
|
||||
definition = "default"
|
||||
|
||||
wrap = "true"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/resolution]
|
||||
|
||||
[/window]
|
||||
|
||||
#undef __GUI_WINDOW_REEVALUATE_BEST_SIZE
|
||||
#undef __GUI_WINDOW_HEIGHT
|
||||
#undef __GUI_WINDOW_WIDTH
|
||||
#undef __GUI_WINDOW_Y
|
||||
#undef __GUI_WINDOW_X
|
||||
#undef __GUI_WINDOW_FUNCTIONS
|
||||
|
|
|
@ -21,6 +21,7 @@ if(ENABLE_DESIGN_DOCUMENTS)
|
|||
gui2/introduction.tex
|
||||
gui2/overall_design.tex
|
||||
gui2/design_details.tex
|
||||
gui2/design_details/tooltip_placement.tex
|
||||
gui2/creating_widgets_and_dialogs.tex
|
||||
gui2/files_for_the_widget.tex
|
||||
gui2/files_for_the_window.tex
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
\usepackage{lmodern}
|
||||
\usepackage[colorlinks]{hyperref}
|
||||
|
||||
\usepackage{enumerate}
|
||||
\usepackage[section]{placeins}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{positioning,shapes.geometric}
|
||||
\usepackage{verbatim}
|
||||
|
||||
\usepackage{gui2}
|
||||
|
|
|
@ -180,3 +180,4 @@ Subclasses of the tnotifier should add an notification function, so the notifier
|
|||
can call all callbacks in the list. The notifier should take care of this
|
||||
calling.
|
||||
|
||||
\input{gui2/design_details/tooltip_placement}
|
||||
|
|
116
doc/design/gui2/design_details/tooltip_placement.tex
Normal file
116
doc/design/gui2/design_details/tooltip_placement.tex
Normal file
|
@ -0,0 +1,116 @@
|
|||
\section{Tooltip placement}
|
||||
\label{sec:tooltip_placement}
|
||||
|
||||
|
||||
The placement of the GUI2 tooltips are handled by the tooltip window. This
|
||||
window needs to determine where it wants the tooltip to be placed, and
|
||||
determine its optimal size.
|
||||
|
||||
\begin{description}
|
||||
\item[\cref{sec:tooltip_placement:normal}]
|
||||
Shows the how normal tooltips look in the game window.
|
||||
|
||||
\item[\cref{sec:tooltip_placement:large}]
|
||||
Shows the how large tooltips look in the game window.
|
||||
|
||||
\item[\cref{sec:tooltip_placement:huge}]
|
||||
Shows the how huge tooltips look in the game window.
|
||||
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsection{Normal}
|
||||
\label{sec:tooltip_placement:normal}
|
||||
|
||||
This tooltip has a single line of text and the width of the tooltip is below or
|
||||
equal to the wanted width of the tooltip. The wanted width of the tooltip is
|
||||
determined by a size where the line-length of the text is pleasant to read.
|
||||
|
||||
Or the tooltip has either a end of line character, causing it to be spread
|
||||
over several lines, or its text is too long for the wanted width, causing it to
|
||||
be wrapped. The text's height will still fit on the screen.
|
||||
|
||||
\Cref{fig:tooltip_placement} gives a visual representation of the placement
|
||||
algorithms used. The algorithms used are:
|
||||
\begin{enumerate}[I.]
|
||||
\item\label{sec:tooltip_placement:algorithm:I}
|
||||
This is the preferred placement of the tooltip. The lower right corner of
|
||||
the tooltip is attached to the top left of the mouse pointer.
|
||||
|
||||
\item\label{sec:tooltip_placement:algorithm:II}
|
||||
This is used when the mouse \mbox{x-position} is greater than the width of
|
||||
the tooltip window, but the mouse \mbox{y-position} is smaller than the
|
||||
height of the tooltip window. The top of the tooltip is attached to the top
|
||||
of the screen at the left side of the mouse pointer.
|
||||
|
||||
\item\label{sec:tooltip_placement:algorithm:III}
|
||||
This is used when the mouse \mbox{x-position} is smaller than the width of
|
||||
the tooltip window, but the mouse \mbox{x-position} is greater than the
|
||||
height of the tooltip window. The left side of the tooltip is attached to
|
||||
the left side of the screen at the top of the mouse pointer.
|
||||
|
||||
\item\label{sec:tooltip_placement:algorithm:IV}
|
||||
This is used when the mouse \mbox{x-position} is smaller than the width of
|
||||
the tooltip window, and the mouse \mbox{y-position} is smaller than the
|
||||
height of the tooltip window. The top of the tooltip is attached to the top
|
||||
of the screen at the right side of the mouse pointer.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
\begin{figure}[tbh]
|
||||
\centering\begin{tikzpicture}[
|
||||
x=0.0008\textwidth
|
||||
, y=0.0008\textwidth
|
||||
, pointer/.style={dart, draw=black, rotate=120, anchor=tip, fill=gray!60}
|
||||
, shadow/.style={dart, draw=black!40, rotate=120, anchor=tip, fill=gray!15}
|
||||
, tooltip/.style={draw=black, minimum width=100, minimum height=50}
|
||||
]
|
||||
|
||||
\draw (0,0) rectangle (1200, 800);
|
||||
|
||||
% pointer size 55 x 75
|
||||
\node[pointer] at (1135, 80) {};
|
||||
\node[tooltip, anchor=south east] at (1135, 80) {Algorithm I};
|
||||
|
||||
\node[shadow] at (1135, 795) {};
|
||||
\node[pointer] at (1135, 725) {};
|
||||
\node[shadow] at (1135, 615) {};
|
||||
\node[tooltip, anchor=north east] at (1135, 795) {Algorithm II};
|
||||
|
||||
|
||||
\node[shadow] at (5, 80) {};
|
||||
\node[pointer] at (155, 80) {};
|
||||
\node[shadow] at (370, 80) {};
|
||||
\node[tooltip, anchor=south west] at (5, 80) {Algorithm III};
|
||||
|
||||
\node[shadow] at (5, 795) {};
|
||||
\node[pointer] at (5, 725) {};
|
||||
\node[shadow] at (5, 615) {};
|
||||
\node[tooltip, anchor=north west] at (70, 795) {Algorithm III};
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\caption{Overview of the tooltip placement.}
|
||||
\label{fig:tooltip_placement}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\subsection{Large}
|
||||
\label{sec:tooltip_placement:large}
|
||||
|
||||
This tooltip needs so much space that its height no longer fits on the
|
||||
screen. In this case the width will be increased. There is no guarantee the
|
||||
tooltip will fit properly; the creator of the tooltip should consider
|
||||
whether or not it contains too much information. Once the width is adjusted the
|
||||
placement algorithm used it the same as for the normal tooltip, see
|
||||
\cref{sec:tooltip_placement:normal}.
|
||||
|
||||
|
||||
\subsection{Huge}
|
||||
\label{sec:tooltip_placement:huge}
|
||||
|
||||
The tooltip will certainly not fit nicely on the screen and no attempt is
|
||||
made to even try to do something sane. Instead it is placed in the top left
|
||||
corner. Unless a very small screen resolution is used the creator of the
|
||||
tooltip really needs to consider reducing the amount of text on the tooltip.
|
||||
There is no guarantee the entire tooltip is visible.
|
|
@ -26,6 +26,10 @@
|
|||
#include "gui/auxiliary/tips.hpp"
|
||||
#include "gui/dialogs/debug_clock.hpp"
|
||||
#include "gui/dialogs/language_selection.hpp"
|
||||
//#define DEBUG_TOOLTIP
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
#include "gui/dialogs/tip.hpp"
|
||||
#endif
|
||||
#include "gui/widgets/button.hpp"
|
||||
#include "gui/widgets/label.hpp"
|
||||
#include "gui/widgets/multi_page.hpp"
|
||||
|
@ -277,6 +281,37 @@ void ttitle_screen::post_build(CVideo& video, twindow& window)
|
|||
, QUIT_GAME));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
static void debug_tooltip(
|
||||
twindow& window
|
||||
, bool& handled
|
||||
, const tpoint& coordinate)
|
||||
{
|
||||
std::string message = "Hello world.";
|
||||
/*
|
||||
* This function is used to test the tooltip placement algorithms as
|
||||
* described in the »Tooltip placement« section in the GUI2 design
|
||||
* document.
|
||||
*
|
||||
* Use a 1024 x 768 screen size, set the maximum loop iteration to:
|
||||
* - 0 to test with a normal tooltip placement.
|
||||
* - 30 to test with a larger normal tooltip placement.
|
||||
* - 60 to test with a huge tooltip placement.
|
||||
* - 150 to test with a borderline to insanely huge tooltip placement.
|
||||
* - 180 to test with an insanely huge tooltip placement.
|
||||
*/
|
||||
for(int i = 0; i < 0; ++i) {
|
||||
message += " More greetings.";
|
||||
}
|
||||
gui2::tip::remove();
|
||||
gui2::tip::show(window.video()
|
||||
, "tooltip"
|
||||
, message
|
||||
, coordinate);
|
||||
handled = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ttitle_screen::pre_show(CVideo& video, twindow& window)
|
||||
{
|
||||
set_restore(false);
|
||||
|
@ -284,6 +319,12 @@ void ttitle_screen::pre_show(CVideo& video, twindow& window)
|
|||
window.set_enter_disabled(true);
|
||||
window.set_escape_disabled(true);
|
||||
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
window.connect_signal<event::SDL_MOUSE_MOTION>(
|
||||
boost::bind(debug_tooltip, boost::ref(window), _3, _5)
|
||||
, event::tdispatcher::front_child);
|
||||
#endif
|
||||
|
||||
/**** Set the version number ****/
|
||||
if(tcontrol* control
|
||||
= find_widget<tcontrol>(&window, "revision_number", false, false)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue