From e3a66514d57ff4acf2f02df7d86bd2cf8be0e730 Mon Sep 17 00:00:00 2001 From: Reimar Date: Tue, 8 Dec 2015 11:31:35 +0100 Subject: initial commit --- GUI.cpp | 1316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1316 insertions(+) create mode 100644 GUI.cpp (limited to 'GUI.cpp') diff --git a/GUI.cpp b/GUI.cpp new file mode 100644 index 0000000..7dabac9 --- /dev/null +++ b/GUI.cpp @@ -0,0 +1,1316 @@ +#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("data/fonts/OpenSans-Semibold.ttf",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("data/fonts/OpenSans-Semibold.ttf",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("data/fonts/OpenSans-Bold.ttf",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("data/fonts/OpenSans-Semibold.ttf",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("data/images/fancy_button.bmp"); + if(norm == NULL) + { + cout << "Error loading bmp while creating fancy button!" << endl; + } + SDL_Surface* inac = NULL; + inac = IMG_Load("data/images/fancy_button_unavailable.bmp"); + if(inac == NULL) + { + cout << "Error loading bmp while creating fancy button!" << endl; + } + SDL_Surface* pres = NULL; + pres = IMG_Load("data/images/fancy_button_clicked.bmp"); + if(pres == NULL) + { + cout << "Error loading bmp while creating fancy button!" << endl; + } + SDL_Surface* mous = NULL; + mous = IMG_Load("data/images/fancy_button_selected.bmp"); + if(mous == NULL) + { + cout << "Error loading bmp while creating fancy button!" << endl; + } + + pressed = IMG_Load("data/images/fancy_button_clicked.bmp"); + inactive = IMG_Load("data/images/fancy_button_unavailable.bmp"); + mouseOver = IMG_Load("data/images/fancy_button_selected.bmp"); + normal = IMG_Load("data/images/fancy_button.bmp"); + 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("data/images/glowing_dot.png"); + 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("data/images/scrollbar_end_h1.png"); + barEnd2 = IMG_Load("data/images/scrollbar_end_h2.png"); + } + else + { + barEnd1 = IMG_Load("data/images/scrollbar_end_v1.png"); + barEnd2 = IMG_Load("data/images/scrollbar_end_v2.png"); + } + 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("data/images/scrollbar_h.png"); + else + barMiddle = IMG_Load("data/images/scrollbar_v.png"); + 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 = ""; +} + + -- cgit v1.2.3