The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tooltips.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 #include "global.hpp"
15 
16 #include "tooltips.hpp"
17 
18 #include "floating_label.hpp"
19 #include "font.hpp"
20 #include "game_display.hpp"
21 #include "help/help.hpp"
22 #include "marked-up_text.hpp"
23 #include "resources.hpp"
24 #include "video.hpp"
25 
26 #include <SDL.h> // Travis doesn't like this, although it works on my machine -> '#include <SDL_sound.h>
27 
28 namespace {
29 
30 CVideo* video_ = nullptr;
31 
32 static const int font_size = font::SIZE_NORMAL;
33 static const int text_width = 400;
34 
35 struct tooltip
36 {
37  tooltip(const SDL_Rect& r, const std::string& msg, const std::string& act = "", bool use_markup = false, const surface& fg = surface())
38  : rect(r), message(msg), action(act), markup(use_markup), foreground(fg)
39  {}
40  SDL_Rect rect;
42  std::string action;
43  bool markup;
44  surface foreground;
45 };
46 
47 std::map<int, tooltip> tips;
48 std::map<int, tooltip>::const_iterator current_tooltip = tips.end();
49 
50 int tooltip_handle = 0;
51 int tooltip_id = 0;
52 
53 surface current_background = nullptr;
54 
55 }
56 
57 static void clear_tooltip()
58 {
59  if(tooltip_handle != 0) {
60  font::remove_floating_label(tooltip_handle);
61  tooltip_handle = 0;
62  }
63 }
64 
65 static void show_tooltip(const tooltip& tip)
66 {
67  if(video_ == nullptr) {
68  return;
69  }
70 
71  clear_tooltip();
72 
73  const SDL_Color bgcolor = {0,0,0,160};
74  SDL_Rect area = screen_area();
75 
76  unsigned int border = 10;
77 
78  font::floating_label flabel(tip.message, tip.foreground);
79  flabel.use_markup(tip.markup);
80  flabel.set_font_size(font_size);
82  flabel.set_clip_rect(area);
83  flabel.set_width(text_width);
85  flabel.set_bg_color(bgcolor);
86  flabel.set_border_size(border);
87 
88  tooltip_handle = font::add_floating_label(flabel);
89 
90  SDL_Rect rect = font::get_floating_label_rect(tooltip_handle);
91 
92  //see if there is enough room to fit it above the tip area
93  if(tip.rect.y > rect.h) {
94  rect.y = tip.rect.y - rect.h;
95  } else {
96  rect.y = tip.rect.y + tip.rect.h;
97  }
98 
99  rect.x = tip.rect.x;
100  if(rect.x < 0) {
101  rect.x = 0;
102  } else if(rect.x + rect.w > area.w) {
103  rect.x = area.w - rect.w;
104  }
105 
106  font::move_floating_label(tooltip_handle,rect.x,rect.y);
107 }
108 
109 namespace tooltips {
110 
112 {
113  clear_tooltips();
114  video_ = &video;
115 }
116 
118 {
119  try {
120  clear_tooltips();
121  } catch (...) {}
122  video_ = nullptr;
123 }
124 
126 {
127  clear_tooltip();
128  tips.clear();
129  current_tooltip = tips.end();
130 }
131 
132 void clear_tooltips(const SDL_Rect& rect)
133 {
134  for(std::map<int,tooltip>::iterator i = tips.begin(); i != tips.end(); ) {
135  if(sdl::rects_overlap(i->second.rect,rect)) {
136  if (i==current_tooltip) {
137  clear_tooltip();
138  }
139  tips.erase(i++);
140  current_tooltip = tips.end();
141  } else {
142  ++i;
143  }
144  }
145 }
146 
147 
148 
149 bool update_tooltip(int id, const SDL_Rect& rect, const std::string& message,
150  const std::string& action, bool use_markup)
151 {
152  std::map<int, tooltip>::iterator it = tips.find(id);
153  if (it == tips.end() ) return false;
154  it->second.action = action;
155  it->second.markup = use_markup;
156  it->second.message = message;
157  it->second.rect = rect;
158  return true;
159 }
160 
161 bool update_tooltip(int id, const SDL_Rect& rect, const std::string& message,
162  const std::string& action, bool use_markup, const surface& foreground)
163 {
164  std::map<int, tooltip>::iterator it = tips.find(id);
165  if (it == tips.end() ) return false;
166  it->second.action = action;
167  it->second.foreground = foreground;
168  it->second.markup = use_markup;
169  it->second.message = message;
170  it->second.rect = rect;
171  return true;
172 }
173 
174 void remove_tooltip(int id)
175 {
176  tips.erase(id);
177  clear_tooltip();
178 }
179 
180 int add_tooltip(const SDL_Rect& rect, const std::string& message, const std::string& action, bool use_markup, const surface& foreground)
181 {
182  for(std::map<int, tooltip>::iterator it = tips.begin(); it != tips.end();) {
183  if(sdl::rects_overlap(it->second.rect,rect)) {
184  tips.erase(it++);
185  } else {
186  ++it;
187  }
188  }
189 
190  int id = tooltip_id++;
191 
192  tips.insert(std::make_pair(id, tooltip(rect, message, action, use_markup, foreground) ));
193 
194  current_tooltip = tips.end();
195  return id;
196 }
197 
198 void process(int mousex, int mousey)
199 {
200  for(std::map<int, tooltip>::const_iterator i = tips.begin(); i != tips.end(); ++i) {
201  if(mousex > i->second.rect.x && mousey > i->second.rect.y &&
202  mousex < i->second.rect.x + i->second.rect.w && mousey < i->second.rect.y + i->second.rect.h) {
203  if(current_tooltip != i) {
204  show_tooltip(i->second);
205  current_tooltip = i;
206  }
207 
208  return;
209  }
210  }
211 
212  clear_tooltip();
213  current_tooltip = tips.end();
214 }
215 
216 bool click(int mousex, int mousey)
217 {
218  for(std::map<int, tooltip>::const_iterator i = tips.begin(); i != tips.end(); ++i) {
219  if(!i->second.action.empty() && sdl::point_in_rect(mousex, mousey, i->second.rect)) {
220  display* disp = resources::screen;
221  help::show_help(disp->video(), i->second.action);
222  return true;
223  }
224  }
225  return false;
226 }
227 
228 }
void show_help(CVideo &video, const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:117
void set_clip_rect(const SDL_Rect &r)
bool rects_overlap(const SDL_Rect &rect1, const SDL_Rect &rect2)
Tests whether two rectangles overlap.
Definition: rect.cpp:52
void set_bg_color(const SDL_Color &bg_color)
Definition: video.hpp:58
game_display * screen
Definition: resources.cpp:27
void remove_tooltip(int id)
Definition: tooltips.cpp:174
void remove_floating_label(int handle)
removes the floating label given by 'handle' from the screen
void set_font_size(int font_size)
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
-file util.hpp
const int SIZE_NORMAL
Definition: font.hpp:58
void move_floating_label(int handle, double xmove, double ymove)
moves the floating label given by 'handle' by (xmove,ymove)
void clear_tooltips()
Definition: tooltips.cpp:125
SDL_Rect screen_area()
Definition: video.cpp:135
void process(int mousex, int mousey)
Definition: tooltips.cpp:198
void set_alignment(ALIGN align)
GLuint id
Definition: glew.h:1647
void set_color(const SDL_Color &color)
static void show_tooltip(const tooltip &tip)
Definition: tooltips.cpp:65
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
Definition: rect.cpp:47
bool click(int mousex, int mousey)
Definition: tooltips.cpp:216
tooltips.
static ttip & tip()
Definition: tip.cpp:123
size_t i
Definition: function.cpp:1057
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
SDL_Rect get_floating_label_rect(int handle)
static void clear_tooltip()
Definition: tooltips.cpp:57
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
void set_border_size(int border)
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: glew.h:1222
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
manager(CVideo &video)
Definition: tooltips.cpp:111
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
bool update_tooltip(int id, const SDL_Rect &rect, const std::string &message, const std::string &action, bool use_markup)
Definition: tooltips.cpp:149
const int font_size
int add_tooltip(const SDL_Rect &rect, const std::string &message, const std::string &action, bool use_markup, const surface &foreground)
Definition: tooltips.cpp:180
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static std::vector< ttip > tips
Definition: settings.cpp:65