Adonthell 0.4
|
00001 /* 00002 $Id: win_manager.cc,v 1.12 2004/10/25 06:55:01 ksterker Exp $ 00003 00004 (C) Copyright 2000/2001 Joel Vennin 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 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 /** 00016 * @file win_theme.cc 00017 * 00018 * @author Joel Vennin 00019 * @brief Implements the win_theme class. 00020 */ 00021 00022 #include "types.h" 00023 #include "image.h" 00024 #include "win_types.h" 00025 #include "win_manager.h" 00026 00027 00028 // Pointer to the active window(s) 00029 win_manager* win_manager::active = NULL; 00030 // List of loaded themes 00031 hash_map<string, win_theme *> win_manager::theme; 00032 // List of loaded fonts 00033 hash_map<string, win_ttf *> win_manager::font; 00034 // True type font to use 00035 string win_manager::font_file; 00036 00037 00038 win_manager::win_manager () 00039 { 00040 // save a pointer to the parent window(s) 00041 prev = active; 00042 00043 // make the current window(s) active 00044 active = this; 00045 00046 // no window in focus at that point 00047 wnd_focus = NULL; 00048 00049 // we're not iterating over the window_list 00050 current = wnd_list.end (); 00051 } 00052 00053 win_manager::~win_manager () 00054 { 00055 destroy (); 00056 00057 // restore parent window(s) 00058 active = prev; 00059 } 00060 00061 // Close and delete all windows 00062 void win_manager::destroy() 00063 { 00064 list<win_base *>::iterator i; 00065 00066 for (i = wnd_list.begin(); i != wnd_list.end(); i++) 00067 { 00068 (*i)->set_manager (NULL); 00069 // delete *i; 00070 } 00071 00072 wnd_list.clear (); 00073 wnd_focus = NULL; 00074 } 00075 00076 void win_manager::init (const string & font) 00077 { 00078 font_file = font; 00079 TTF_Init (); 00080 } 00081 00082 // Delete all fonts and themes 00083 void win_manager::cleanup () 00084 { 00085 // Cleaning up themes 00086 for (hash_map <string, win_theme *>::iterator it = theme.begin (); 00087 it != theme.end (); it++) 00088 delete it->second; 00089 theme.clear (); 00090 00091 // Cleaning up fonts 00092 for (hash_map <string, win_ttf *>::iterator ifo = font.begin (); 00093 ifo != font.end (); ifo++) 00094 delete ifo->second; 00095 font.clear (); 00096 00097 TTF_Quit (); 00098 } 00099 00100 // add a window 00101 void win_manager::add (win_base *tmp) 00102 { 00103 wnd_list.push_back (tmp); 00104 tmp->set_manager (this); 00105 } 00106 00107 /* 00108 bool win_manager::exist(win_base *tmp) 00109 { 00110 for (list<win_base *>::iterator i = wnd_list.begin (); 00111 i != wnd_list.end(); i++) 00112 if (*i == tmp) return true; 00113 00114 return false; 00115 } 00116 */ 00117 00118 // remove a window 00119 void win_manager::remove (win_base *tmp) 00120 { 00121 // if the window has focus take it away 00122 if (tmp->is_focus ()) 00123 { 00124 tmp->set_focus (false); 00125 wnd_focus = NULL; 00126 } 00127 00128 // be careful if the iterator points to the element 00129 // we want to remove. This may happen if remove() is called 00130 // from a window's update() method or from win_manager::update(). 00131 if (tmp == *current) 00132 { 00133 // make sure that the iterator remains valid 00134 current++; 00135 } 00136 00137 // remove it from the window list 00138 wnd_list.remove (tmp); 00139 tmp->set_manager (NULL); 00140 00141 // if no window has the focus, give it to the topmost window 00142 if (!wnd_focus) set_focus (wnd_list.back ()); 00143 } 00144 00145 // draw all windows 00146 void win_manager::draw () 00147 { 00148 // first descent recursively down the list of parents 00149 if (prev != NULL) prev->draw (); 00150 00151 // on the way up, draw every window 00152 for (current = wnd_list.begin (); current != wnd_list.end(); current++) 00153 (*current)->draw (); 00154 } 00155 00156 // grab keyboard input 00157 void win_manager::input_update () 00158 { 00159 // only the window with the focus may recieve input 00160 if (wnd_focus) wnd_focus->input_update (); 00161 } 00162 00163 // update the state of the topmost window(s) 00164 void win_manager::update () 00165 { 00166 for (current = wnd_list.begin (); current != wnd_list.end ();) 00167 // a window signals that it wants to be closed by returning 0 here 00168 if (!(*current)->update ()) 00169 { 00170 // remove and delete it 00171 win_base *tmp = *current; 00172 00173 remove (tmp); 00174 delete tmp; 00175 } 00176 else current++; 00177 } 00178 00179 // give the focus to a window 00180 void win_manager::set_focus (win_base *tmp) 00181 { 00182 // but only if there are any windows at all 00183 if (!wnd_list.empty ()) 00184 { 00185 // remove focus from the old window 00186 if (wnd_focus) wnd_focus->set_focus (false); 00187 00188 // and give it to the new one 00189 wnd_focus = tmp; 00190 wnd_focus->set_focus (true); 00191 } 00192 } 00193 00194 // load a theme from disk 00195 void win_manager::add_theme (string name) 00196 { 00197 theme[name] = new win_theme ((char *) name.c_str ()); 00198 } 00199 00200 // remove a theme 00201 bool win_manager::remove_theme (string name) 00202 { 00203 hash_map <string, win_theme *>::iterator it = theme.find (name); 00204 if (it == theme.end ()) return false; 00205 00206 delete it->second; 00207 theme.erase (it); 00208 return true; 00209 } 00210 00211 // return a pointer to a theme 00212 win_theme * win_manager::get_theme (string name) 00213 { 00214 hash_map <string, win_theme *>::iterator it = theme.find (name); 00215 00216 // try to load it if it's not in memory yet 00217 if (it == theme.end ()) 00218 { 00219 add_theme (name); 00220 return get_theme (name); 00221 } 00222 else return it->second; 00223 } 00224 00225 // load a font from disk 00226 void win_manager::add_font (string name) 00227 { 00228 font[name] = new win_ttf ((char *) name.c_str (), font_file); 00229 } 00230 00231 // remove a font 00232 bool win_manager::remove_font (string name) 00233 { 00234 hash_map <string, win_ttf *>::iterator it = font.find (name); 00235 if (it == font.end ()) return false; 00236 00237 delete it->second; 00238 font.erase (it); 00239 return true; 00240 } 00241 00242 // return a pointer to a font 00243 win_font * win_manager::get_font (string name) 00244 { 00245 hash_map <string, win_ttf *>::iterator it = font.find (name); 00246 00247 // try to load the font if it's not in memory yet 00248 if (it == font.end ()) 00249 { 00250 add_font (name); 00251 return get_font (name); 00252 } 00253 else return it->second; 00254 }