00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022
00023 #include "menulist.h"
00024 #include "exult.h"
00025 #include "font.h"
00026 #include "gamewin.h"
00027 #include "mouse.h"
00028 #include "rect.h"
00029 #include "shapeid.h"
00030
00031
00032 MenuEntry::MenuEntry(Shape_frame *on, Shape_frame *off, int xpos, int ypos)
00033 {
00034 frame_on = on;
00035 frame_off = off;
00036 int max_width = on->get_width()>off->get_width()?on->get_width():off->get_width();
00037 int max_height = on->get_height()>off->get_height()?on->get_height():off->get_height();
00038 x = xpos;
00039 y1 = y = ypos;
00040 x1 = xpos-max_width/2;
00041 x2 = x1+max_width;
00042 y2 = y1+max_height;
00043 selected = false;
00044 dirty = true;
00045 }
00046
00047 void MenuEntry::paint(Game_window *gwin)
00048 {
00049 if (!dirty) return;
00050 dirty = false;
00051
00052 Shape_frame *shape;
00053 if(selected)
00054 shape = frame_on;
00055 else
00056 shape = frame_off;
00057 Shape_manager::get_instance()->paint_shape(
00058 x-shape->get_width()/2, y, shape);
00059 gwin->get_win()->show(x1,y1,x2-x1+1,y2-y1+1);
00060 }
00061
00062 bool MenuEntry::handle_event(SDL_Event& event)
00063 {
00064 return((event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN) ||
00065 event.type == SDL_MOUSEBUTTONUP);
00066 }
00067
00068
00069 MenuChoice::MenuChoice(Shape_frame *on, Shape_frame *off, int xpos, int ypos, Font *fnt)
00070 {
00071 frame_on = on;
00072 frame_off = off;
00073 int max_width = on->get_width()>off->get_width()?on->get_width():off->get_width();
00074 int max_height = on->get_height()>off->get_height()?on->get_height():off->get_height();
00075 x = xpos;
00076 x1 = x-max_width;
00077 y1 = y = ypos;
00078 x2 = x1 + max_width;
00079 y2 = y1 + max_height;
00080 selected = false;
00081 choice = -1;
00082 font = fnt;
00083 max_choice_width = 0;
00084 choices = new std::vector<std::string>();
00085 }
00086
00087 void MenuChoice::add_choice(const char *s)
00088 {
00089 choices->push_back(std::string(s));
00090 int len = font->get_text_width(s);
00091 max_choice_width = (len>max_choice_width)?len:max_choice_width;
00092 x2 = x+32+max_choice_width;
00093 }
00094
00095 void MenuChoice::paint(Game_window *gwin)
00096 {
00097 if (!dirty) return;
00098 dirty = false;
00099
00100 Shape_frame *shape;
00101 if(selected)
00102 shape = frame_on;
00103 else
00104 shape = frame_off;
00105
00106 Shape_manager::get_instance()->paint_shape(
00107 x-shape->get_width(), y, shape);
00108 gwin->get_win()->show(x1,y1,x2-x1+1,y2-y1+1);
00109 if(choice>=0) {
00110 gwin->get_win()->fill8(0, max_choice_width, font->get_text_height(), x+32, y);
00111 font->draw_text(gwin->get_win()->get_ib8(),
00112 x+32, y, (*choices)[choice].c_str());
00113 gwin->get_win()->show(x+32,y, x+32+max_choice_width, y+font->get_text_height());
00114 }
00115 }
00116
00117 bool MenuChoice::handle_event(SDL_Event& event)
00118 {
00119 if(event.type==SDL_MOUSEBUTTONUP) {
00120 dirty = true;
00121 choice++;
00122 if(choice>=choices->size())
00123 choice = 0;
00124 } else if(event.type==SDL_KEYDOWN) {
00125 switch(event.key.keysym.sym) {
00126 case SDLK_LEFT:
00127 dirty = true;
00128 choice--;
00129 if(choice<0)
00130 choice = choices->size()-1;
00131 break;
00132 case SDLK_RIGHT:
00133 dirty = true;
00134 choice++;
00135 if(choice>=choices->size())
00136 choice = 0;
00137 break;
00138 default:
00139 break;
00140 }
00141 }
00142 return false;
00143 }
00144
00145 MenuList::~MenuList()
00146 {
00147 MenuObject *entry;
00148 for(int i=0; i<entries->size(); i++) {
00149 entry = (*entries)[i];
00150 delete entry;
00151 }
00152 delete entries;
00153 }
00154
00155 void MenuList::set_selection(int sel)
00156 {
00157 MenuObject *entry;
00158
00159
00160 if (selected) {
00161 entry = (*entries)[selection];
00162 entry->set_selected(false);
00163 }
00164
00165
00166 selected = true;
00167 selection = sel;
00168 entry = (*entries)[selection];
00169 entry->set_selected(true);
00170 }
00171
00172 void MenuList::set_selection(int x, int y)
00173 {
00174 MenuObject *entry;
00175
00176
00177 if (selected) {
00178 entry = (*entries)[selection];
00179 if (entry->is_mouse_over(x, y))
00180 return;
00181
00182 entry->set_selected(false);
00183 }
00184
00185
00186 for(int i=0; i<entries->size(); i++) {
00187 entry = (*entries)[i];
00188 if(entry->is_mouse_over(x, y)) {
00189 entry->set_selected(true);
00190 selected = true;
00191 selection = i;
00192 return;
00193 }
00194 }
00195
00196
00197 selected = false;
00198 }
00199
00200 int MenuList::handle_events(Game_window *gwin, Mouse *mouse)
00201 {
00202 unsigned char mouse_visible;
00203 int count = entries->size();
00204 bool exit_loop = false;
00205 int scale = gwin->get_fastmouse() ? 1 : gwin->get_win()->get_scale();
00206 SDL_Event event;
00207
00208 for(int i=0; i<count; i++)
00209 (*entries)[i]->dirty = true;
00210
00211 gwin->show(1);
00212 mouse->show();
00213 do {
00214 mouse_visible = mouse->is_onscreen();
00215 if (mouse_visible) mouse->hide();
00216
00217
00218 for(int i=0; i<count; i++) {
00219 MenuObject *entry = (*entries)[i];
00220 entry->paint(gwin);
00221 }
00222
00223
00224 if (mouse_visible) {
00225 mouse->show();
00226 mouse->blit_dirty();
00227 }
00228
00229 SDL_WaitEvent(&event);
00230 if(event.type==SDL_MOUSEMOTION) {
00231 mouse->hide();
00232 mouse->move(event.motion.x / scale,
00233 event.motion.y / scale);
00234 set_selection(event.motion.x / scale,
00235 event.motion.y / scale);
00236 mouse->show();
00237 mouse->blit_dirty();
00238 } else if(event.type==SDL_MOUSEBUTTONDOWN) {
00239 if (!mouse_visible) {
00240
00241 set_selection(event.button.x / scale,
00242 event.button.y / scale);
00243 mouse->show();
00244 mouse->blit_dirty();
00245 }
00246 } else if(event.type==SDL_MOUSEBUTTONUP) {
00247 MenuObject *entry = (*entries)[selection];
00248 if (entry->is_mouse_over(
00249 event.button.x / scale,
00250 event.button.y / scale)) {
00251 exit_loop = entry->handle_event(event);
00252 }
00253 } else if(event.type==SDL_KEYDOWN) {
00254 mouse->hide();
00255 mouse->blit_dirty();
00256 switch(event.key.keysym.sym) {
00257 case SDLK_x:
00258 if(event.key.keysym.mod & KMOD_ALT) {
00259 return -1;
00260 }
00261 break;
00262 #if defined(MACOS) || defined(MACOSX)
00263 case SDLK_q:
00264 if(event.key.keysym.mod & KMOD_META) {
00265 return -1;
00266 }
00267 break;
00268 #endif
00269 case SDLK_UP:
00270 if (!selected)
00271 {
00272
00273 set_selection(selection);
00274 continue;
00275 }
00276 if(selection<=0)
00277 set_selection(count-1);
00278 else
00279 set_selection(selection-1);
00280 continue;
00281 case SDLK_DOWN:
00282 if (!selected)
00283 {
00284
00285 set_selection(selection);
00286 continue;
00287 }
00288 if(selection>=(count-1))
00289 set_selection(0);
00290 else
00291 set_selection(selection+1);
00292 continue;
00293 case SDLK_s:
00294 if ((event.key.keysym.mod & KMOD_ALT) &&
00295 (event.key.keysym.mod & KMOD_CTRL))
00296 make_screenshot(true);
00297 default:
00298 {
00299
00300 if(selected) {
00301 MenuObject *entry = (*entries)[selection];
00302 exit_loop = entry->handle_event(event);
00303 }
00304 }
00305 break;
00306 }
00307 } else if(event.type==SDL_QUIT) {
00308 return -1;
00309 }
00310 } while(!exit_loop);
00311 mouse->hide();
00312 return selection;
00313 }
00314