00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #include "font.hpp"
00018 #include "marked-up_text.hpp"
00019 #include "sdl_utils.hpp"
00020 #include "tooltips.hpp"
00021 #include "video.hpp"
00022
00023 #include <vector>
00024
00025 static bool rectangles_overlap(const SDL_Rect& a, const SDL_Rect& b)
00026 {
00027 const bool xoverlap = (a.x >= b.x && a.x < b.x + b.w) ||
00028 (b.x >= a.x && b.x < a.x + a.w);
00029
00030 const bool yoverlap = (a.y >= b.y && a.y < b.y + b.h) ||
00031 (b.y >= a.y && b.y < a.y + a.h);
00032
00033 return xoverlap && yoverlap;
00034 }
00035
00036 namespace {
00037
00038 CVideo* video_ = NULL;
00039
00040 static const int font_size = font::SIZE_SMALL;
00041 #ifdef USE_TINY_GUI
00042 static const int text_width = 260;
00043 #else
00044 static const int text_width = 400;
00045 #endif
00046
00047 struct tooltip
00048 {
00049 tooltip(const SDL_Rect& r, const std::string& msg) : rect(r), message(msg)
00050 {}
00051 SDL_Rect rect;
00052 std::string message;
00053 };
00054
00055 std::vector<tooltip> tips;
00056 std::vector<tooltip>::const_iterator current_tooltip = tips.end();
00057
00058 int tooltip_handle = 0;
00059
00060 surface current_background = NULL;
00061
00062 }
00063
00064 static void clear_tooltip()
00065 {
00066 if(tooltip_handle != 0) {
00067 font::remove_floating_label(tooltip_handle);
00068 tooltip_handle = 0;
00069 }
00070 }
00071
00072 static void show_tooltip(const tooltip& tip)
00073 {
00074 if(video_ == NULL) {
00075 return;
00076 }
00077
00078 clear_tooltip();
00079
00080 const SDL_Color bgcolour = {0,0,0,128};
00081 SDL_Rect area = screen_area();
00082
00083 #ifdef USE_TINY_GUI
00084 unsigned int border = 2;
00085 #else
00086 unsigned int border = 10;
00087 #endif
00088
00089 const std::string wrapped_message = font::word_wrap_text(tip.message, font_size, text_width);
00090 tooltip_handle = font::add_floating_label(wrapped_message,font_size,font::NORMAL_COLOUR,
00091 0,0,0,0,-1,area,font::LEFT_ALIGN,&bgcolour,border);
00092
00093 SDL_Rect rect = font::get_floating_label_rect(tooltip_handle);
00094
00095
00096 if(tip.rect.y > rect.h) {
00097 rect.y = tip.rect.y - rect.h;
00098 } else {
00099 rect.y = tip.rect.y + tip.rect.h;
00100 }
00101
00102 rect.x = tip.rect.x;
00103 if(rect.x < 0) {
00104 rect.x = 0;
00105 } else if(rect.x + rect.w > area.w) {
00106 rect.x = area.w - rect.w;
00107 }
00108
00109 font::move_floating_label(tooltip_handle,rect.x,rect.y);
00110 }
00111
00112 namespace tooltips {
00113
00114 manager::manager(CVideo& video)
00115 {
00116 clear_tooltips();
00117 video_ = &video;
00118 }
00119
00120 manager::~manager()
00121 {
00122 clear_tooltips();
00123 video_ = NULL;
00124 }
00125
00126 void clear_tooltips()
00127 {
00128 clear_tooltip();
00129 tips.clear();
00130 current_tooltip = tips.end();
00131 }
00132
00133 void clear_tooltips(const SDL_Rect& rect)
00134 {
00135 for(std::vector<tooltip>::iterator i = tips.begin(); i != tips.end(); ) {
00136 if(rectangles_overlap(i->rect,rect)) {
00137 if (i==current_tooltip) {
00138 clear_tooltip();
00139 }
00140 i = tips.erase(i);
00141 current_tooltip = tips.end();
00142 } else {
00143 ++i;
00144 }
00145 }
00146 }
00147
00148 void add_tooltip(const SDL_Rect& rect, const std::string& message)
00149 {
00150 for(std::vector<tooltip>::iterator i = tips.begin(); i != tips.end(); ++i) {
00151 if(rectangles_overlap(i->rect,rect)) {
00152 *i = tooltip(rect,message);
00153 return;
00154 }
00155 }
00156
00157 tips.push_back(tooltip(rect,message));
00158 current_tooltip = tips.end();
00159 }
00160
00161 void process(int mousex, int mousey)
00162 {
00163 for(std::vector<tooltip>::const_iterator i = tips.begin(); i != tips.end(); ++i) {
00164 if(mousex > i->rect.x && mousey > i->rect.y &&
00165 mousex < i->rect.x + i->rect.w && mousey < i->rect.y + i->rect.h) {
00166 if(current_tooltip != i) {
00167 show_tooltip(*i);
00168 current_tooltip = i;
00169 }
00170
00171 return;
00172 }
00173 }
00174
00175 clear_tooltip();
00176 current_tooltip = tips.end();
00177 }
00178
00179 }