#include "GUI.h" #if SDL_BYTEORDER == SDL_BIG_ENDIAN Uint32 rmask = 0xff000000; Uint32 gmask = 0x00ff0000; Uint32 bmask = 0x0000ff00; Uint32 amask = 0x000000ff; #else Uint32 rmask = 0x000000ff; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x00ff0000; Uint32 amask = 0xff000000; #endif Label::Label() { pos.x = 0; pos.y = 0; pos.w = 0; pos.h = 14; caption = ""; textColor.r = 255; textColor.g = 255; textColor.b = 255; render(); } Label::Label(string ncaption, SDL_Rect& npos) { pos = npos; textColor.r = 255; textColor.g = 255; textColor.b = 255; caption = ncaption; npos.w = render(); } int Label::setTextSize(int ntextSize) { pos.h = ntextSize; SDL_FreeSurface(image); return render(); } void Label::setTextColor(SDL_Color ntextColor) { textColor = ntextColor; SDL_FreeSurface(image); render(); } int Label::setCaption(string ncaption) { if(caption == ncaption) return pos.w; caption = ncaption; SDL_FreeSurface(image); return render(); } int Label::render() { TTF_Font *font = TTF_OpenFont((get_data_path() + "fonts/OpenSans-Semibold.ttf").c_str(),pos.h); image = NULL; image = TTF_RenderText_Solid(font, caption.c_str(),textColor); if(caption.size() == 0) cout << "empty caption!!!" << endl; if(image == NULL) { cout << "Error rendering Label with caption " << caption << endl; return 0; } TTF_CloseFont(font); pos.w = image->w; return image->w; } void Label::draw(SDL_Surface* screen) { SDL_Rect temp = pos; SDL_BlitSurface(image, NULL, screen, &temp); } Label::~Label() { SDL_FreeSurface(image); } vector textField(string s, SDL_Rect& r, int textSize) { vector result; vector > splitted = splitString(s); bool done = false; int currentLine = 0; int currentWord = 0; int currentPos = 0; while(!done) { bool done2 = false; int splitAt = splitted[currentLine].size(); while(!done2) { string temp; for(int i = currentWord; i < splitAt; ++i) { temp += splitted[currentLine][i]; if(i != (int) splitAt-1) temp += " "; } SDL_Rect npos = r; npos.y += currentPos; npos.h = textSize; if(temp != "") { Label* l = new Label(temp, npos); if(npos.w < r.w) { done2 = true; result.push_back(l); currentWord = splitAt; currentPos += textSize*1.1; } else { delete l; splitAt--; if(splitAt == currentWord) { cout << "failed rendering Textbox. Word too long?" << endl; return result; } } } else { done2 = true; currentWord = splitAt; currentPos += textSize*1.1; } } while(currentWord == (int)splitted[currentLine].size()) { currentWord = 0; currentLine++; if((int) splitted.size() == currentLine) { done = true; break; } } } r.h = currentPos + textSize; return result; } SlidingBackground::SlidingBackground(SDL_Surface *nbackground, double nxSpeed, double nySpeed) { randm = true; background = nbackground; xSpeed = nxSpeed; ySpeed = nySpeed; if(background->w > 0) { x1 = rand()%background->w; x2 = rand()%background->w; } if(background->h > 0) y = rand()%background->h; } SlidingBackground::~SlidingBackground() { SDL_FreeSurface(background); } void SlidingBackground::draw(SDL_Surface *screen) { SDL_Rect pos; pos.x = x1; pos.y = y; SDL_BlitSurface(background,NULL,screen,&pos); pos.x = x1-background->w; pos.y = y; SDL_BlitSurface(background,NULL,screen,&pos); pos.x = x2; pos.y = y - background->h; SDL_BlitSurface(background,NULL,screen,&pos); pos.x = x2 - background->w; pos.y = y - background->h; SDL_BlitSurface(background,NULL,screen,&pos); } void SlidingBackground::frame(double time) { y += ySpeed*time; if(y >= background->h) { y -= background->h; x1 = x2; x2 = 0; if(randm) x2 = rand()%background->w; } if(y < 0) { y += background->h; x2 = x1; x1 = 0; if(randm) x1 = rand()%background->w; } x1 += xSpeed*time; if(x1 < 0) x1 += background->w; if(x1 >= background->w) x1 -= background->w; x2 += xSpeed*time; if(x2 < 0) x2 += background->w; if(x2 >= background->w) x2 -= background->h; } void SlidingBackground::setRandom(bool r) { randm = r; if(r) { x1 = rand()%background->w; x2 = rand()%background->w; } else { x1 = 0; x2 = 0; } } TextBox::TextBox(vector nlabels) { labels = nlabels; } TextBox::~TextBox() { for(int i = 0; i < (int) labels.size(); ++i) delete labels[i]; } void TextBox::draw(SDL_Surface *screen) { for(int i = 0; i < (int) labels.size(); ++i) labels[i]->draw(screen); } int TextBox::handleEvents(SDL_Event event){return 0;} void TextBox::frame(double time){} void TextBox::refresh(){} Button::Button(SDL_Rect npos, SDL_Surface *nnormal, SDL_Surface *nmouseOver, SDL_Surface *npressed, SDL_Surface *ninactive) { clicked = false; over = false; deactivated = false; selected = false; isDblClckButton = false; timer = 0; pos = npos; normal = nnormal; mouseOver = nmouseOver; pressed = npressed; inactive = ninactive; cout << "This constructor is never called!" << endl; } Button::Button(SDL_Rect npos, string message, int& shouldbeTextSize) { int textSize; if(shouldbeTextSize == 0) textSize = (npos.h*2)/3; else textSize = shouldbeTextSize; clicked = false; over = false; deactivated = false; selected = false; isDblClckButton = false; timer = 0; pos = npos; SDL_Color textColor; textColor.r = 255; textColor.g = 255; textColor.b = 255; bool done = false; while(!done && textSize) { TTF_Font *font = TTF_OpenFont((get_data_path() + "fonts/OpenSans-Semibold.ttf").c_str(),textSize); normal = NULL; normal = TTF_RenderText_Solid(font, message.c_str(),textColor); if(normal == NULL) { cout << "Error rendering button with message " << message << endl; return; } done = normal->w <= pos.w; if(!done) { SDL_FreeSurface(normal); textSize--; } TTF_CloseFont(font); } if(textSize == 0) { cout << "textSize error. failbutton is fail!" << endl; return ; } done = false; while(!done && textSize) { TTF_Font *font = TTF_OpenFont((get_data_path() + "fonts/OpenSans-Bold.ttf").c_str(),textSize); mouseOver = NULL; mouseOver = TTF_RenderText_Solid(font, message.c_str(),textColor); if(mouseOver == NULL) { cout << "Error rendering button with message " << message << endl; return; } TTF_CloseFont(font); done = mouseOver->w <= pos.w; if(!done) { SDL_FreeSurface(mouseOver); textSize--; } } if(textSize == 0) { cout << "textSize error. failbutton is fail!" << endl; return ; } textColor.b = 17; textColor.g = 200; textColor.r = 250; TTF_Font *font = TTF_OpenFont((get_data_path() + "fonts/OpenSans-Semibold.ttf").c_str(),textSize); pressed = NULL; pressed = TTF_RenderText_Solid(font, message.c_str(),textColor); if(pressed == NULL) { cout << "Error rendering button with message " << message << endl; return; } textColor.b = 155; textColor.g = 155; textColor.r = 155; inactive = NULL; inactive = TTF_RenderText_Solid(font, message.c_str(),textColor); if(inactive == NULL) { cout << "Error rendering button with message " << message << endl; return; } TTF_CloseFont(font); shouldbeTextSize = textSize; } void Button::draw(SDL_Surface *screen) { SDL_Rect drawPos; if(deactivated) { drawPos.x = pos.x + (pos.w - inactive->w)/2; drawPos.y = pos.y + (pos.h - inactive->h)/2; SDL_BlitSurface(inactive,NULL,screen,&drawPos); return; } if(clicked && !isDblClckButton) { drawPos.x = pos.x + (pos.w-pressed->w)/2; drawPos.y = pos.y + (pos.h-pressed->h)/2; SDL_BlitSurface(pressed,NULL,screen,&drawPos); return; } if((over && !isDblClckButton) || selected) { drawPos.x = pos.x + (pos.w-mouseOver->w)/2; drawPos.y = pos.y + (pos.h-mouseOver->h)/2; SDL_BlitSurface(mouseOver,NULL,screen,&drawPos); return; } drawPos.x = pos.x + (pos.w-normal->w)/2; drawPos.y = pos.y + (pos.h-normal->h)/2; SDL_BlitSurface(normal,NULL,screen,&drawPos); } int Button::handleEvents(const SDL_Event& event) { int x,y; SDL_Surface *current; if(deactivated) current = inactive; else if(clicked) current = pressed; else if(over) current = mouseOver; else current = normal; int xmin = pos.x + (pos.w-current->w)/2; int xmax = pos.x + (current->w + pos.w)/2; int ymin = pos.y + (pos.h-current->h)/2; int ymax = pos.y + (current->h + pos.h)/2; if(event.type == SDL_MOUSEMOTION) { x = event.motion.x; y = event.motion.y; if(x < xmin || y < ymin || x >= xmax || y >= ymax) over = false; else over = true; } if(event.type == SDL_MOUSEBUTTONDOWN) { if(event.button.button == SDL_BUTTON_LEFT) { x = event.button.x; y = event.button.y; if(x < xmin || y < ymin || x >= xmax || y >= ymax) over = false; else { if(isDblClckButton) { if(clicked && selected) { clicked = false; selected = true; return BUTTON_CLICKED; } else { timer = 0.2; over = true; clicked = true; selected = true; return BUTTON_SELECTED; } } over = true; clicked = true; } } } if(event.type == SDL_MOUSEBUTTONUP) { if(event.button.button == SDL_BUTTON_LEFT) { x = event.button.x; y = event.button.y; if(x < xmin || y < ymin || x >= xmax || y >= ymax) over = false; else { over = true; if(clicked && !isDblClckButton) { clicked = false; if(deactivated) return BUTTON_NORMAL; if(!isDblClckButton) return BUTTON_CLICKED; } } if(!isDblClckButton) clicked = false; } } if(over) { if(pressed) return BUTTON_PRESSEDOVER; return BUTTON_PRESSEDOUT; } return BUTTON_NORMAL; } void Button::frame(double time) { timer -= time; if(timer < 0 && isDblClckButton) clicked = false; } void Button::refresh() { clicked = false; over = false; } Button::~Button() { SDL_FreeSurface(pressed); SDL_FreeSurface(mouseOver); SDL_FreeSurface(normal); //sometimes crashes the game on exit SDL_FreeSurface(inactive); } //fancy Button Button::Button(SDL_Rect npos, SDL_Surface* content, bool fancy) { if(content->h < 21) { SDL_Surface* temp = content; content = rotozoomSurface(content,0,2,0); SDL_FreeSurface(temp); } if(content->h > 42) { SDL_Surface* temp = content; content = rotozoomSurface(content,0,0.5,0); SDL_FreeSurface(temp); } deactivated = false; over = false; clicked = false; selected = false; isDblClckButton = false; timer = 0; pos = npos; int size = 48; SDL_Surface* norm = NULL; norm = IMG_Load((get_data_path() + "images/fancy_button.bmp").c_str()); if(norm == NULL) { cout << "Error loading bmp while creating fancy button!" << endl; } SDL_Surface* inac = NULL; inac = IMG_Load((get_data_path() + "images/fancy_button_unavailable.bmp").c_str()); if(inac == NULL) { cout << "Error loading bmp while creating fancy button!" << endl; } SDL_Surface* pres = NULL; pres = IMG_Load((get_data_path() + "images/fancy_button_clicked.bmp").c_str()); if(pres == NULL) { cout << "Error loading bmp while creating fancy button!" << endl; } SDL_Surface* mous = NULL; mous = IMG_Load((get_data_path() + "images/fancy_button_selected.bmp").c_str()); if(mous == NULL) { cout << "Error loading bmp while creating fancy button!" << endl; } pressed = IMG_Load((get_data_path() + "images/fancy_button_clicked.bmp").c_str()); inactive = IMG_Load((get_data_path() + "images/fancy_button_unavailable.bmp").c_str()); mouseOver = IMG_Load((get_data_path() + "images/fancy_button_selected.bmp").c_str()); normal = IMG_Load((get_data_path() + "images/fancy_button.bmp").c_str()); SDL_Rect dest; dest.x = size/2 - content->w/2; dest.y = size/2 - content->h/2; SDL_Rect temp = dest; SDL_BlitSurface(content,NULL,normal,&temp); temp = dest; if(fancy) { SDL_BlitSurface(content,NULL,pressed,&temp); temp = dest; } SDL_BlitSurface(content,NULL,inactive,&temp); temp = dest; SDL_BlitSurface(content,NULL,mouseOver,&temp); SDL_FreeSurface(content); SDL_BlitSurface(norm,NULL,normal,NULL); SDL_FreeSurface(norm); SDL_BlitSurface(pres,NULL,pressed,NULL); SDL_FreeSurface(pres); SDL_BlitSurface(mous,NULL,mouseOver,NULL); SDL_FreeSurface(mous); SDL_BlitSurface(inac,NULL,inactive,NULL); SDL_FreeSurface(inac); } //makes direction according to h/w of the Rect Scrollbar::Scrollbar(SDL_Rect npos) { state = 0; stateGoal = state; sensitivity = 0.005; clicked = false; pos = npos; if(pos.w > pos.h) horizontal = true; else horizontal = false; dot = NULL; dot = IMG_Load((get_data_path() + "images/glowing_dot.png").c_str()); if(!dot) { cout << "Error loading dot for scrollbar!" << endl; return; } bar = NULL; bar = SDL_CreateRGBSurface(0,pos.w,pos.h,32,rmask,gmask,bmask,amask); SDL_FillRect(bar,NULL,0xFF000102); SDL_SetAlpha(bar,0,255); SDL_SetColorKey(bar,SDL_SRCCOLORKEY, 0xFF000102); if(!bar) { cout << "Error loading creating scrollbarsurface" << endl; return; } SDL_Surface* barEnd1 = NULL; SDL_Surface* barEnd2 = NULL; if(horizontal) { barEnd1 = IMG_Load((get_data_path() + "images/scrollbar_end_h1.png").c_str()); barEnd2 = IMG_Load((get_data_path() + "images/scrollbar_end_h2.png").c_str()); } else { barEnd1 = IMG_Load((get_data_path() + "images/scrollbar_end_v1.png").c_str()); barEnd2 = IMG_Load((get_data_path() + "images/scrollbar_end_v2.png").c_str()); } if(!barEnd1 || !barEnd2) { cout << "Error loading end of scrollbar" << endl; return; } if(horizontal) { SDL_BlitSurface(barEnd1,NULL,bar,NULL); SDL_Rect r; r.x = pos.w - barEnd1->w; r.y = 0; SDL_BlitSurface(barEnd2,NULL,bar,&r); } else { SDL_BlitSurface(barEnd1,NULL,bar,NULL); SDL_Rect r; r.x = 0; r.y = pos.h - barEnd1->h; SDL_BlitSurface(barEnd2,NULL,bar,&r); } SDL_Surface* barMiddle = NULL; if(horizontal) barMiddle = IMG_Load((get_data_path() + "images/scrollbar_h.png").c_str()); else barMiddle = IMG_Load((get_data_path() + "images/scrollbar_v.png").c_str()); if(!barMiddle) { cout << "Error in middle of bar!" << endl; return; } int current = barEnd1->h; int maxcurrent = max(pos.w,pos.h) - barEnd1->h - barMiddle->w; while(true) { if(horizontal) { SDL_Rect r2; r2.x = current; r2.y = 0; if(current >= maxcurrent) { SDL_Rect r1; r1.x = 0; r1.y = 0; r1.h = barMiddle->h; r1.w = barMiddle->h - current + maxcurrent; SDL_BlitSurface(barMiddle,&r1,bar,&r2); break; } else SDL_BlitSurface(barMiddle, NULL, bar, &r2); current += barMiddle->w; } else { SDL_Rect r2; r2.x = 0; r2.y = current; if(current >= maxcurrent) { SDL_Rect r1; r1.x = 0; r1.y = 0; r1.h = barMiddle->h - current + maxcurrent; r1.w = barMiddle->h; SDL_BlitSurface(barMiddle,&r1,bar,&r2); break; } else SDL_BlitSurface(barMiddle, NULL, bar, &r2); current += barMiddle->h; } } SDL_FreeSurface(barMiddle); SDL_FreeSurface(barEnd1); SDL_FreeSurface(barEnd2); } Scrollbar::~Scrollbar() { SDL_FreeSurface(bar); SDL_FreeSurface(dot); } void Scrollbar::draw(SDL_Surface *screen) { SDL_Rect r = pos; SDL_BlitSurface(bar,NULL,screen,&r); if(horizontal) { r.x = pos.x + state * (pos.w-dot->w); r.y = pos.y; } else { r.x = pos.x; r.y = pos.y + state * (pos.h-dot->h); } SDL_BlitSurface(dot,NULL,screen,&r); } double Scrollbar::handleEvents(const SDL_Event& event) { double x,y; if(event.type == SDL_MOUSEMOTION && clicked) { x = event.motion.x; y = event.motion.y; if(x > 50000) x = -10; if(y > 50000) y = -10; if(horizontal) { //state = (x - dot->w/2 - pos.x)/(pos.w-dot->w/2); stateGoal = (x - dot->w/2 - pos.x)/(pos.w-dot->w); } else { //state = (y - dot->h/2 - pos.y)/(pos.h-dot->h/2); stateGoal = (y - dot->h/2 - pos.y)/(pos.h-dot->h); } if(stateGoal < 0) stateGoal = 0; if(stateGoal > 1) stateGoal = 1; // stateGoal = state; } if(event.type == SDL_MOUSEBUTTONDOWN) { if(event.button.button == SDL_BUTTON_LEFT) { x = event.button.x; y = event.button.y; if(x >= pos.x && y >= pos.y && x < pos.x + pos.w && y < pos.y + pos.h) { clicked = true; if(horizontal) { stateGoal = (x - dot->w/2 - pos.x)/(pos.w-dot->w); } else { stateGoal = (y - dot->h/2 - pos.y)/(pos.h-dot->h); } if(stateGoal < 0) stateGoal = 0; if(stateGoal > 1) stateGoal = 1; // stateGoal = state; } } if(event.button.button == SDL_BUTTON_WHEELDOWN) { stateGoal += max(sensitivity,sqrt(fabs(stateGoal-state))*sqrt(sensitivity)*3); if(stateGoal > 1) stateGoal = 1; } if(event.button.button == SDL_BUTTON_WHEELUP) { stateGoal -= max(sensitivity,sqrt(fabs(stateGoal-state))*sqrt(sensitivity)*3); if(stateGoal < 0) stateGoal = 0; } } if(event.type == SDL_MOUSEBUTTONUP) { if(event.button.button == SDL_BUTTON_LEFT) clicked = false; } return state; } double Scrollbar::frame(double time) { state = stateGoal - (stateGoal - state) * pow(M_E,-15*time); if(fabs(state - stateGoal) < 0.5 / max(pos.w,pos.h)) state = stateGoal; return state; } void Scrollbar::refresh() { } Scrollable::Scrollable(SDL_Rect npos, AbstractInteractive* nsubInteractive, SDL_Rect subRect, bool nhorizontal, bool nscrollbarSide) { wholeMenu = npos; currentSubPos = 0; pos = npos; subInteractive = nsubInteractive; horizontal = nhorizontal; fakeScreen = SDL_CreateRGBSurface(0,subRect.w,subRect.h,32,rmask,gmask,bmask,0); Uint32 colorkey = SDL_MapRGB(fakeScreen->format, 0, 1, 2); SDL_FillRect(fakeScreen,NULL,colorkey); SDL_SetColorKey(fakeScreen, SDL_SRCCOLORKEY, colorkey); SDL_Rect barRect; if(horizontal) { barRect.x = pos.x; barRect.w = pos.w; barRect.y = pos.y + nscrollbarSide*(pos.h-10); barRect.h = 10; pos.h -= 10; pos.y += !nscrollbarSide * 10; } else { barRect.x = pos.x + nscrollbarSide*(pos.w - 10); barRect.w = 10; barRect.y = pos.y; barRect.h = pos.h; pos.w -= 10; pos.x += !nscrollbarSide * 10; } bar = new Scrollbar(barRect); } Scrollable::~Scrollable() { delete subInteractive; SDL_FreeSurface(fakeScreen); } void Scrollable::draw(SDL_Surface* screen) { Uint32 colorkey = SDL_MapRGB(fakeScreen->format, 0, 1, 2); SDL_FillRect(fakeScreen,NULL,colorkey); subInteractive->draw(fakeScreen); SDL_Rect src; SDL_Rect dst; if(horizontal) { src.x = currentSubPos; src.y = 0; src.w = pos.w; src.h = fakeScreen->h; dst.x = pos.x; dst.y = pos.y + (pos.h - fakeScreen->h)/2; } else { src.x = 0; src.y = currentSubPos; src.w = fakeScreen->w; src.h = pos.h; dst.x = pos.x + (pos.w - fakeScreen->w)/2; dst.y = pos.y; } SDL_BlitSurface(fakeScreen,&src,screen,&dst); bool b = true; if(horizontal && fakeScreen->w < pos.w) b = false; if(!horizontal && fakeScreen->h < pos.h) b = false; if(b) bar->draw(screen); } int Scrollable::handleEvents(SDL_Event nevent) { bool b = true; if(horizontal && fakeScreen->w < pos.w) b = false; if(!horizontal && fakeScreen->h < pos.h) b = false; int result = 0; SDL_Rect r; if(horizontal) { r.x = pos.x - currentSubPos; r.y = pos.y + (pos.h - fakeScreen->h)/2; } else { r.y = pos.y - currentSubPos; r.x = pos.x + (pos.w - fakeScreen->w)/2; } SDL_Event event = relativate(nevent,r); if(event.type == SDL_MOUSEMOTION) { if(b) bar->handleEvents(nevent); MousePos.x = nevent.motion.x; MousePos.y = nevent.motion.y; //if(inRect(pos, nevent.motion.x, nevent.motion.y)) result = subInteractive->handleEvents(event); } if(event.type == SDL_MOUSEBUTTONDOWN) { // cout << "got an event at " << nevent.button.x << " " << nevent.button.y << endl; // cout << "send an event at " << event.button.x << " " << event.button.y << endl; if(b && inRect(wholeMenu, nevent.button.x, nevent.button.y)) bar->handleEvents(nevent); //if(inRect(pos, nevent.button.x, nevent.button.y)) result = subInteractive->handleEvents(event); } if(event.type == SDL_MOUSEBUTTONUP) { if(b && event.button.button == SDL_BUTTON_LEFT) bar->handleEvents(nevent); //if(inRect(pos, nevent.button.x, nevent.button.y)) result = subInteractive->handleEvents(event); } return result; } void Scrollable::frame(double time) { subInteractive->frame(time); setSubPosition(bar->frame(time)); } void Scrollable::setSubPosition(double d) { int last = currentSubPos; if(horizontal) currentSubPos = d * (fakeScreen->w - pos.w); else currentSubPos = d * (fakeScreen->h - pos.h); if(last != currentSubPos && inRect(pos,MousePos.x,MousePos.y)) { SDL_Event event; event.type = SDL_MOUSEMOTION; event.motion.x = MousePos.x; event.motion.y = MousePos.y; event.motion.x -= pos.x; event.motion.y -= pos.y; if(horizontal) { event.motion.x += currentSubPos; event.motion.y -= (pos.h - fakeScreen->h)/2; } else { event.motion.y += currentSubPos; event.motion.x -= (pos.w - fakeScreen->w)/2; } subInteractive->handleEvents(event); } } void Scrollable::refresh() { subInteractive->refresh(); } Menu::Menu(vector nbuttons, vector neffects, SDL_Surface *background, bool rBG) { isSelectMenu = false; onMouseDown = false; buttons = nbuttons; effects = neffects; BG = new SlidingBackground(background, 0, 100); BG->setRandom(rBG); } Menu::Menu(vector choices, vector neffects, SDL_Surface *background, bool rBG, SDL_Surface *screen) { isSelectMenu = false; onMouseDown = false; effects = neffects; BG = new SlidingBackground(background, 0, 100); BG->setRandom(rBG); int minTextSize; bool done = true; for(int i = 0; i < (int) choices.size(); ++i) { int curTextSize = 0; SDL_Rect r; r.y = screen->h*0.2 + i / ((double) choices.size()) * screen->h * 0.6; r.x = screen->w/5.0; r.w = screen->w*3.0/5.0; r.h = screen->h*0.6/((double) choices.size()); Button *b = new Button(r, choices[i], curTextSize); if(effects[i] == 0) { b->deactivated = true; } buttons.push_back(b); if(i == 0) minTextSize = curTextSize; if(minTextSize != curTextSize) { minTextSize = min(curTextSize, minTextSize); done = false; } } if(done == true) return; for(int i = 0; i < (int) choices.size(); ++i) delete buttons[i]; for(int i = 0; i < (int) choices.size(); ++i) { SDL_Rect r; r.y = screen->h*0.2 + i / ((double) choices.size()) * screen->h * 0.6; r.x = screen->w/5.0; r.w = screen->w*3.0/5.0; r.h = screen->h*0.6/((double) choices.size()); Button *b = new Button(r, choices[i], minTextSize); if(effects[i] == 0) b->deactivated = true; buttons[i] = b; } } Menu::~Menu() { delete BG; for(int i = 0; i < (int) buttons.size(); ++i) delete buttons[i]; } void Menu::draw(SDL_Surface *screen) { BG->draw(screen); for(int i = 0; i < (int) buttons.size(); ++i) buttons[i]->draw(screen); } int Menu::handleEvents(SDL_Event event) { for(int i = 0; i < (int) buttons.size(); ++i) { int temp = buttons[i]->handleEvents(event); if(((temp == BUTTON_PRESSEDOVER) || (false)) && onMouseDown) return effects[i]; if(temp == BUTTON_CLICKED && !isSelectMenu) return effects[i]; if(temp == BUTTON_CLICKED && isSelectMenu) { //cout << "Click on " << i << endl; return effects[i] | MENU_CLICK; } if(temp == BUTTON_SELECTED && isSelectMenu) { for(int j = 0; j < (int) buttons.size(); ++j) if(j != i) buttons[j]->selected = false; return effects[i] | MENU_SELECT; } } return 0; } void Menu::frame(double time) { BG->frame(time); for(int i = 0; i < (int) buttons.size(); ++i) buttons[i]->frame(time); } void Menu::refresh() { for(int i = 0; i < (int) buttons.size(); ++i) buttons[i]->refresh(); } //matrixMenu Menu::Menu(vector pics, int width, int& height, bool nisSelectMenu, bool nonMouseDown) { isSelectMenu = nisSelectMenu; onMouseDown = nonMouseDown; SDL_Rect r; r.x = 0; r.y = 0; r.w = 48; r.h = 48; for(int i = 0; i < (int) pics.size(); ++i) { if(isSelectMenu) effects.push_back(i); else effects.push_back(i | MENU_SELECT); Button *b = new Button(r, pics[i], !onMouseDown); if(isSelectMenu) b->isDblClckButton = true; buttons.push_back(b); r.x += 48; if(r.x +48 > width) { r.x = 0; r.y += 48; } } if(isSelectMenu) buttons[0]->selected = true; height = r.y; SDL_Surface* back = SDL_CreateRGBSurface(0,width,height,32,0,0,0,0); SDL_SetColorKey(back,SDL_SRCCOLORKEY,0x000102); SDL_FillRect(back,NULL,0x000102); BG = new SlidingBackground(back, 0, 0); BG->setRandom(0); } CompositMenu::CompositMenu(vector nsubmenues, SDL_Surface* nBG, SDL_Rect nsubPos, vector ntabs) { submenues = nsubmenues; subPos = nsubPos; tabs = ntabs; BG = new SlidingBackground(nBG, 0, 100); fakeScreen = SDL_CreateRGBSurface(0,subPos.w,subPos.h,32,0,0,0,0); SDL_SetColorKey(fakeScreen,SDL_SRCCOLORKEY,0x000102); state = 0; tabs[0]->selected = true; } CompositMenu::~CompositMenu() { for(int i = 0; i < (int) submenues.size(); ++i) delete submenues[i]; for(int i = 0; i < (int) tabs.size(); ++i) delete tabs[i]; delete BG; SDL_FreeSurface(fakeScreen); } void CompositMenu::draw(SDL_Surface *screen) { BG->draw(screen); SDL_FillRect(fakeScreen,NULL,0x000102); submenues[state]->draw(fakeScreen); SDL_BlitSurface(fakeScreen,NULL,screen,&subPos); for(int i = 0; i < (int) tabs.size(); ++i) tabs[i]->draw(screen); } int CompositMenu::handleEvents(SDL_Event event) { for(int i = 0; i < (int) tabs.size(); ++i) { int temp = tabs[i]->handleEvents(event); if(temp == BUTTON_SELECTED) { state = i; for(int j = 0; j < (int) tabs.size(); ++j) if(i != j) tabs[j]->selected = false; submenues[state]->refresh(); } } SDL_Event nevent = relativate(event, subPos); // if(nevent.type == SDL_MOUSEBUTTONDOWN) // { // cout << "CMenu got an event at " << event.button.x << " " << event.button.y << endl; // cout << "CMenu sent an event at " << nevent.button.x << " " << nevent.button.y << ". state is " << state << endl; // } return submenues[state]->handleEvents(nevent); } void CompositMenu::frame(double time) { BG->frame(time); submenues[state]->frame(time); for(int i = 0; i < (int) tabs.size(); ++i) tabs[i]->frame(time); } void CompositMenu::refresh() { for(int i = 0; i < (int) submenues.size(); ++i) submenues[i]->refresh(); for(int i = 0; i < (int) tabs.size(); ++i) tabs[i]->refresh(); } int CompositMenu::getState() { return state; } GetStringMenu::GetStringMenu(string headline, int niBack, int niOK, SDL_Surface* nBG, SDL_Surface* screen) { screenw = screen->w; maxLength = 22; SDL_EnableUNICODE( SDL_ENABLE ); iBack = niBack; iOK = niOK; SDL_Rect tRect; tRect.x = 0; tRect.y = screen->h/3; tRect.w = screen->w; tRect.h = 30; title = new Label(headline, tRect); tRect.x = (screen->w - title->pos.w)/2; title->pos = tRect; BG = new SlidingBackground(nBG, 0, 100); tRect.y += 40; tRect.h = 30; input = new Label("nicht leer", tRect); tRect.x = (screen->w - input->pos.w)/2; input->pos = tRect; int textSize = 0; SDL_Rect backPos = tRect; backPos.y += 40; backPos.x = screen->w/6; backPos.w = (2*screen->w)/6; backPos.h = 50; back = new Button(backPos,"back",textSize); backPos.x = screen->w/2; oK = new Button(backPos,"OK",textSize); } GetStringMenu::~GetStringMenu() { SDL_EnableUNICODE( SDL_DISABLE ); delete title; delete input; delete back; delete oK; } void GetStringMenu::draw(SDL_Surface* screen) { BG->draw(screen); title->draw(screen); if(s != "") input->draw(screen); back->draw(screen); oK->draw(screen); } int GetStringMenu::handleEvents(SDL_Event event) { if(back->handleEvents(event) == BUTTON_CLICKED) return iBack; if(oK->handleEvents(event) == BUTTON_CLICKED) return iOK; //If a key was pressed if( event.type == SDL_KEYDOWN ) { //If the string less than maximum size if((int) s.length() <= maxLength ) { if(event.key.keysym.unicode == (Uint16) ' ') { s += (char)event.key.keysym.unicode; } else if((event.key.keysym.unicode >= (Uint16) '0' ) && ( event.key.keysym.unicode <= (Uint16) '9')) { s += (char)event.key.keysym.unicode; } else if((event.key.keysym.unicode >= (Uint16) 'A') && (event.key.keysym.unicode <= (Uint16) 'Z')) { s += (char)event.key.keysym.unicode; } else if((event.key.keysym.unicode >= (Uint16) 'a') && (event.key.keysym.unicode <= (Uint16) 'z')) { s += (char)event.key.keysym.unicode; } } } //If backspace was pressed and the string isn't blank if((event.key.keysym.sym == SDLK_BACKSPACE) && (s.length() != 0)) { //Remove a character from the end s.erase(s.length() - 1); } if((event.key.keysym.sym == SDLK_RETURN) && oK->deactivated == false) { return iOK; } if(s != "") input->setCaption(s); input->pos.x = (screenw - input->pos.w)/2; return 0; } void GetStringMenu::frame(double time) { BG->frame(time); } void GetStringMenu::refresh() { s = ""; }