tooltips.cpp

Go to the documentation of this file.
00001 /* $Id: tooltips.cpp 24869 2008-03-19 17:48:22Z brunowolff $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
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     //see if there is enough room to fit it above the tip area
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 }

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs