summaryrefslogtreecommitdiff
path: root/GUI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'GUI.cpp')
-rw-r--r--GUI.cpp1316
1 files changed, 1316 insertions, 0 deletions
diff --git a/GUI.cpp b/GUI.cpp
new file mode 100644
index 0000000..7dabac9
--- /dev/null
+++ b/GUI.cpp
@@ -0,0 +1,1316 @@
1#include "GUI.h"
2
3#if SDL_BYTEORDER == SDL_BIG_ENDIAN
4 Uint32 rmask = 0xff000000;
5 Uint32 gmask = 0x00ff0000;
6 Uint32 bmask = 0x0000ff00;
7 Uint32 amask = 0x000000ff;
8#else
9 Uint32 rmask = 0x000000ff;
10 Uint32 gmask = 0x0000ff00;
11 Uint32 bmask = 0x00ff0000;
12 Uint32 amask = 0xff000000;
13#endif
14
15
16Label::Label()
17{
18 pos.x = 0;
19 pos.y = 0;
20 pos.w = 0;
21 pos.h = 14;
22 caption = "";
23 textColor.r = 255;
24 textColor.g = 255;
25 textColor.b = 255;
26 render();
27}
28
29Label::Label(string ncaption, SDL_Rect& npos)
30{
31 pos = npos;
32 textColor.r = 255;
33 textColor.g = 255;
34 textColor.b = 255;
35 caption = ncaption;
36 npos.w = render();
37}
38
39int Label::setTextSize(int ntextSize)
40{
41 pos.h = ntextSize;
42 SDL_FreeSurface(image);
43 return render();
44}
45
46void Label::setTextColor(SDL_Color ntextColor)
47{
48 textColor = ntextColor;
49 SDL_FreeSurface(image);
50 render();
51}
52
53int Label::setCaption(string ncaption)
54{
55 if(caption == ncaption)
56 return pos.w;
57 caption = ncaption;
58 SDL_FreeSurface(image);
59 return render();
60}
61
62int Label::render()
63{
64 TTF_Font *font = TTF_OpenFont("data/fonts/OpenSans-Semibold.ttf",pos.h);
65 image = NULL;
66 image = TTF_RenderText_Solid(font, caption.c_str(),textColor);
67 if(caption.size() == 0)
68 cout << "empty caption!!!" << endl;
69 if(image == NULL)
70 {
71 cout << "Error rendering Label with caption " << caption << endl;
72 return 0;
73 }
74 TTF_CloseFont(font);
75 pos.w = image->w;
76 return image->w;
77}
78
79
80void Label::draw(SDL_Surface* screen)
81{
82 SDL_Rect temp = pos;
83 SDL_BlitSurface(image, NULL, screen, &temp);
84}
85
86Label::~Label()
87{
88 SDL_FreeSurface(image);
89}
90
91vector<Label*> textField(string s, SDL_Rect& r, int textSize)
92{
93 vector<Label*> result;
94 vector<vector<string> > splitted = splitString(s);
95 bool done = false;
96 int currentLine = 0;
97 int currentWord = 0;
98 int currentPos = 0;
99 while(!done)
100 {
101 bool done2 = false;
102 int splitAt = splitted[currentLine].size();
103 while(!done2)
104 {
105 string temp;
106 for(int i = currentWord; i < splitAt; ++i)
107 {
108 temp += splitted[currentLine][i];
109 if(i != (int) splitAt-1)
110 temp += " ";
111 }
112 SDL_Rect npos = r;
113 npos.y += currentPos;
114 npos.h = textSize;
115 if(temp != "")
116 {
117 Label* l = new Label(temp, npos);
118 if(npos.w < r.w)
119 {
120 done2 = true;
121 result.push_back(l);
122 currentWord = splitAt;
123 currentPos += textSize*1.1;
124
125 }
126 else
127 {
128 delete l;
129 splitAt--;
130 if(splitAt == currentWord)
131 {
132 cout << "failed rendering Textbox. Word too long?" << endl;
133 return result;
134 }
135 }
136 }
137 else
138 {
139 done2 = true;
140 currentWord = splitAt;
141 currentPos += textSize*1.1;
142 }
143 }
144 while(currentWord == (int)splitted[currentLine].size())
145 {
146 currentWord = 0;
147 currentLine++;
148 if((int) splitted.size() == currentLine)
149 {
150 done = true;
151 break;
152 }
153 }
154 }
155 r.h = currentPos + textSize;
156 return result;
157}
158
159SlidingBackground::SlidingBackground(SDL_Surface *nbackground, double nxSpeed, double nySpeed)
160{
161 randm = true;
162 background = nbackground;
163 xSpeed = nxSpeed;
164 ySpeed = nySpeed;
165 if(background->w > 0)
166 {
167 x1 = rand()%background->w;
168 x2 = rand()%background->w;
169 }
170 if(background->h > 0)
171 y = rand()%background->h;
172}
173
174SlidingBackground::~SlidingBackground()
175{
176 SDL_FreeSurface(background);
177}
178
179
180void SlidingBackground::draw(SDL_Surface *screen)
181{
182 SDL_Rect pos;
183 pos.x = x1;
184 pos.y = y;
185 SDL_BlitSurface(background,NULL,screen,&pos);
186 pos.x = x1-background->w;
187 pos.y = y;
188 SDL_BlitSurface(background,NULL,screen,&pos);
189 pos.x = x2;
190 pos.y = y - background->h;
191 SDL_BlitSurface(background,NULL,screen,&pos);
192 pos.x = x2 - background->w;
193 pos.y = y - background->h;
194 SDL_BlitSurface(background,NULL,screen,&pos);
195}
196void SlidingBackground::frame(double time)
197{
198 y += ySpeed*time;
199 if(y >= background->h)
200 {
201 y -= background->h;
202 x1 = x2;
203 x2 = 0;
204 if(randm)
205 x2 = rand()%background->w;
206 }
207 if(y < 0)
208 {
209 y += background->h;
210 x2 = x1;
211 x1 = 0;
212 if(randm)
213 x1 = rand()%background->w;
214 }
215 x1 += xSpeed*time;
216 if(x1 < 0)
217 x1 += background->w;
218 if(x1 >= background->w)
219 x1 -= background->w;
220 x2 += xSpeed*time;
221 if(x2 < 0)
222 x2 += background->w;
223 if(x2 >= background->w)
224 x2 -= background->h;
225}
226
227void SlidingBackground::setRandom(bool r)
228{
229 randm = r;
230 if(r)
231 {
232 x1 = rand()%background->w;
233 x2 = rand()%background->w;
234 }
235 else
236 {
237 x1 = 0;
238 x2 = 0;
239 }
240}
241
242
243TextBox::TextBox(vector<Label*> nlabels)
244{
245 labels = nlabels;
246}
247
248TextBox::~TextBox()
249{
250 for(int i = 0; i < (int) labels.size(); ++i)
251 delete labels[i];
252}
253
254void TextBox::draw(SDL_Surface *screen)
255{
256 for(int i = 0; i < (int) labels.size(); ++i)
257 labels[i]->draw(screen);
258}
259int TextBox::handleEvents(SDL_Event event){return 0;}
260void TextBox::frame(double time){}
261void TextBox::refresh(){}
262
263Button::Button(SDL_Rect npos, SDL_Surface *nnormal, SDL_Surface *nmouseOver, SDL_Surface *npressed, SDL_Surface *ninactive)
264{
265 clicked = false;
266 over = false;
267 deactivated = false;
268 selected = false;
269 isDblClckButton = false;
270 timer = 0;
271 pos = npos;
272 normal = nnormal;
273 mouseOver = nmouseOver;
274 pressed = npressed;
275 inactive = ninactive;
276 cout << "This constructor is never called!" << endl;
277}
278
279Button::Button(SDL_Rect npos, string message, int& shouldbeTextSize)
280{
281 int textSize;
282 if(shouldbeTextSize == 0)
283 textSize = (npos.h*2)/3;
284 else
285 textSize = shouldbeTextSize;
286
287 clicked = false;
288 over = false;
289 deactivated = false;
290 selected = false;
291 isDblClckButton = false;
292 timer = 0;
293 pos = npos;
294 SDL_Color textColor;
295 textColor.r = 255;
296 textColor.g = 255;
297 textColor.b = 255;
298
299 bool done = false;
300 while(!done && textSize)
301 {
302 TTF_Font *font = TTF_OpenFont("data/fonts/OpenSans-Semibold.ttf",textSize);
303 normal = NULL;
304 normal = TTF_RenderText_Solid(font, message.c_str(),textColor);
305 if(normal == NULL)
306 {
307 cout << "Error rendering button with message " << message << endl;
308 return;
309 }
310 done = normal->w <= pos.w;
311 if(!done)
312 {
313 SDL_FreeSurface(normal);
314 textSize--;
315 }
316 TTF_CloseFont(font);
317 }
318 if(textSize == 0)
319 {
320 cout << "textSize error. failbutton is fail!" << endl;
321 return ;
322 }
323 done = false;
324 while(!done && textSize)
325 {
326 TTF_Font *font = TTF_OpenFont("data/fonts/OpenSans-Bold.ttf",textSize);
327 mouseOver = NULL;
328 mouseOver = TTF_RenderText_Solid(font, message.c_str(),textColor);
329 if(mouseOver == NULL)
330 {
331 cout << "Error rendering button with message " << message << endl;
332 return;
333 }
334 TTF_CloseFont(font);
335 done = mouseOver->w <= pos.w;
336 if(!done)
337 {
338 SDL_FreeSurface(mouseOver);
339 textSize--;
340 }
341 }
342 if(textSize == 0)
343 {
344 cout << "textSize error. failbutton is fail!" << endl;
345 return ;
346 }
347
348 textColor.b = 17;
349 textColor.g = 200;
350 textColor.r = 250;
351 TTF_Font *font = TTF_OpenFont("data/fonts/OpenSans-Semibold.ttf",textSize);
352 pressed = NULL;
353 pressed = TTF_RenderText_Solid(font, message.c_str(),textColor);
354 if(pressed == NULL)
355 {
356 cout << "Error rendering button with message " << message << endl;
357 return;
358 }
359
360 textColor.b = 155;
361 textColor.g = 155;
362 textColor.r = 155;
363 inactive = NULL;
364 inactive = TTF_RenderText_Solid(font, message.c_str(),textColor);
365 if(inactive == NULL)
366 {
367 cout << "Error rendering button with message " << message << endl;
368 return;
369 }
370 TTF_CloseFont(font);
371 shouldbeTextSize = textSize;
372}
373
374void Button::draw(SDL_Surface *screen)
375{
376 SDL_Rect drawPos;
377 if(deactivated)
378 {
379 drawPos.x = pos.x + (pos.w - inactive->w)/2;
380 drawPos.y = pos.y + (pos.h - inactive->h)/2;
381 SDL_BlitSurface(inactive,NULL,screen,&drawPos);
382 return;
383 }
384 if(clicked && !isDblClckButton)
385 {
386 drawPos.x = pos.x + (pos.w-pressed->w)/2;
387 drawPos.y = pos.y + (pos.h-pressed->h)/2;
388 SDL_BlitSurface(pressed,NULL,screen,&drawPos);
389 return;
390 }
391 if((over && !isDblClckButton) || selected)
392 {
393 drawPos.x = pos.x + (pos.w-mouseOver->w)/2;
394 drawPos.y = pos.y + (pos.h-mouseOver->h)/2;
395 SDL_BlitSurface(mouseOver,NULL,screen,&drawPos);
396 return;
397 }
398 drawPos.x = pos.x + (pos.w-normal->w)/2;
399 drawPos.y = pos.y + (pos.h-normal->h)/2;
400 SDL_BlitSurface(normal,NULL,screen,&drawPos);
401}
402
403int Button::handleEvents(const SDL_Event& event)
404{
405 int x,y;
406 SDL_Surface *current;
407 if(deactivated)
408 current = inactive;
409 else if(clicked)
410 current = pressed;
411 else if(over)
412 current = mouseOver;
413 else
414 current = normal;
415 int xmin = pos.x + (pos.w-current->w)/2;
416 int xmax = pos.x + (current->w + pos.w)/2;
417 int ymin = pos.y + (pos.h-current->h)/2;
418 int ymax = pos.y + (current->h + pos.h)/2;
419 if(event.type == SDL_MOUSEMOTION)
420 {
421 x = event.motion.x;
422 y = event.motion.y;
423 if(x < xmin || y < ymin || x >= xmax || y >= ymax)
424 over = false;
425 else
426 over = true;
427 }
428 if(event.type == SDL_MOUSEBUTTONDOWN)
429 {
430 if(event.button.button == SDL_BUTTON_LEFT)
431 {
432 x = event.button.x;
433 y = event.button.y;
434 if(x < xmin || y < ymin || x >= xmax || y >= ymax)
435 over = false;
436 else
437 {
438 if(isDblClckButton)
439 {
440 if(clicked && selected)
441 {
442 clicked = false;
443 selected = true;
444 return BUTTON_CLICKED;
445 }
446 else
447 {
448 timer = 0.2;
449 over = true;
450 clicked = true;
451 selected = true;
452 return BUTTON_SELECTED;
453 }
454 }
455 over = true;
456 clicked = true;
457 }
458 }
459 }
460 if(event.type == SDL_MOUSEBUTTONUP)
461 {
462 if(event.button.button == SDL_BUTTON_LEFT)
463 {
464 x = event.button.x;
465 y = event.button.y;
466 if(x < xmin || y < ymin || x >= xmax || y >= ymax)
467 over = false;
468 else
469 {
470 over = true;
471 if(clicked && !isDblClckButton)
472 {
473 clicked = false;
474 if(deactivated)
475 return BUTTON_NORMAL;
476 if(!isDblClckButton)
477 return BUTTON_CLICKED;
478 }
479 }
480 if(!isDblClckButton)
481 clicked = false;
482 }
483 }
484 if(over)
485 {
486 if(pressed)
487 return BUTTON_PRESSEDOVER;
488 return BUTTON_PRESSEDOUT;
489 }
490 return BUTTON_NORMAL;
491}
492
493void Button::frame(double time)
494{
495 timer -= time;
496 if(timer < 0 && isDblClckButton)
497 clicked = false;
498}
499
500void Button::refresh()
501{
502 clicked = false;
503 over = false;
504}
505
506Button::~Button()
507{
508 SDL_FreeSurface(pressed);
509 SDL_FreeSurface(mouseOver);
510 SDL_FreeSurface(normal);
511 //sometimes crashes the game on exit
512 SDL_FreeSurface(inactive);
513}
514
515//fancy Button
516Button::Button(SDL_Rect npos, SDL_Surface* content, bool fancy)
517{
518 if(content->h < 21)
519 {
520 SDL_Surface* temp = content;
521 content = rotozoomSurface(content,0,2,0);
522 SDL_FreeSurface(temp);
523 }
524 if(content->h > 42)
525 {
526 SDL_Surface* temp = content;
527 content = rotozoomSurface(content,0,0.5,0);
528 SDL_FreeSurface(temp);
529 }
530 deactivated = false;
531 over = false;
532 clicked = false;
533 selected = false;
534 isDblClckButton = false;
535 timer = 0;
536 pos = npos;
537 int size = 48;
538
539 SDL_Surface* norm = NULL;
540 norm = IMG_Load("data/images/fancy_button.bmp");
541 if(norm == NULL)
542 {
543 cout << "Error loading bmp while creating fancy button!" << endl;
544 }
545 SDL_Surface* inac = NULL;
546 inac = IMG_Load("data/images/fancy_button_unavailable.bmp");
547 if(inac == NULL)
548 {
549 cout << "Error loading bmp while creating fancy button!" << endl;
550 }
551 SDL_Surface* pres = NULL;
552 pres = IMG_Load("data/images/fancy_button_clicked.bmp");
553 if(pres == NULL)
554 {
555 cout << "Error loading bmp while creating fancy button!" << endl;
556 }
557 SDL_Surface* mous = NULL;
558 mous = IMG_Load("data/images/fancy_button_selected.bmp");
559 if(mous == NULL)
560 {
561 cout << "Error loading bmp while creating fancy button!" << endl;
562 }
563
564 pressed = IMG_Load("data/images/fancy_button_clicked.bmp");
565 inactive = IMG_Load("data/images/fancy_button_unavailable.bmp");
566 mouseOver = IMG_Load("data/images/fancy_button_selected.bmp");
567 normal = IMG_Load("data/images/fancy_button.bmp");
568 SDL_Rect dest;
569 dest.x = size/2 - content->w/2;
570 dest.y = size/2 - content->h/2;
571 SDL_Rect temp = dest;
572 SDL_BlitSurface(content,NULL,normal,&temp);
573 temp = dest;
574 if(fancy)
575 {
576 SDL_BlitSurface(content,NULL,pressed,&temp);
577 temp = dest;
578 }
579 SDL_BlitSurface(content,NULL,inactive,&temp);
580 temp = dest;
581 SDL_BlitSurface(content,NULL,mouseOver,&temp);
582 SDL_FreeSurface(content);
583 SDL_BlitSurface(norm,NULL,normal,NULL);
584 SDL_FreeSurface(norm);
585 SDL_BlitSurface(pres,NULL,pressed,NULL);
586 SDL_FreeSurface(pres);
587 SDL_BlitSurface(mous,NULL,mouseOver,NULL);
588 SDL_FreeSurface(mous);
589 SDL_BlitSurface(inac,NULL,inactive,NULL);
590 SDL_FreeSurface(inac);
591}
592
593//makes direction according to h/w of the Rect
594Scrollbar::Scrollbar(SDL_Rect npos)
595{
596 state = 0;
597 stateGoal = state;
598 sensitivity = 0.005;
599 clicked = false;
600 pos = npos;
601 if(pos.w > pos.h)
602 horizontal = true;
603 else
604 horizontal = false;
605 dot = NULL;
606 dot = IMG_Load("data/images/glowing_dot.png");
607 if(!dot)
608 {
609 cout << "Error loading dot for scrollbar!" << endl;
610 return;
611 }
612 bar = NULL;
613 bar = SDL_CreateRGBSurface(0,pos.w,pos.h,32,rmask,gmask,bmask,amask);
614 SDL_FillRect(bar,NULL,0xFF000102);
615 SDL_SetAlpha(bar,0,255);
616 SDL_SetColorKey(bar,SDL_SRCCOLORKEY, 0xFF000102);
617 if(!bar)
618 {
619 cout << "Error loading creating scrollbarsurface" << endl;
620 return;
621 }
622 SDL_Surface* barEnd1 = NULL;
623 SDL_Surface* barEnd2 = NULL;
624 if(horizontal)
625 {
626 barEnd1 = IMG_Load("data/images/scrollbar_end_h1.png");
627 barEnd2 = IMG_Load("data/images/scrollbar_end_h2.png");
628 }
629 else
630 {
631 barEnd1 = IMG_Load("data/images/scrollbar_end_v1.png");
632 barEnd2 = IMG_Load("data/images/scrollbar_end_v2.png");
633 }
634 if(!barEnd1 || !barEnd2)
635 {
636 cout << "Error loading end of scrollbar" << endl;
637 return;
638 }
639 if(horizontal)
640 {
641 SDL_BlitSurface(barEnd1,NULL,bar,NULL);
642 SDL_Rect r;
643 r.x = pos.w - barEnd1->w;
644 r.y = 0;
645 SDL_BlitSurface(barEnd2,NULL,bar,&r);
646 }
647 else
648 {
649 SDL_BlitSurface(barEnd1,NULL,bar,NULL);
650 SDL_Rect r;
651 r.x = 0;
652 r.y = pos.h - barEnd1->h;
653 SDL_BlitSurface(barEnd2,NULL,bar,&r);
654 }
655 SDL_Surface* barMiddle = NULL;
656 if(horizontal)
657 barMiddle = IMG_Load("data/images/scrollbar_h.png");
658 else
659 barMiddle = IMG_Load("data/images/scrollbar_v.png");
660 if(!barMiddle)
661 {
662 cout << "Error in middle of bar!" << endl;
663 return;
664 }
665 int current = barEnd1->h;
666 int maxcurrent = max(pos.w,pos.h) - barEnd1->h - barMiddle->w;
667 while(true)
668 {
669 if(horizontal)
670 {
671 SDL_Rect r2;
672 r2.x = current;
673 r2.y = 0;
674 if(current >= maxcurrent)
675 {
676 SDL_Rect r1;
677 r1.x = 0;
678 r1.y = 0;
679 r1.h = barMiddle->h;
680 r1.w = barMiddle->h - current + maxcurrent;
681 SDL_BlitSurface(barMiddle,&r1,bar,&r2);
682 break;
683 }
684 else
685 SDL_BlitSurface(barMiddle, NULL, bar, &r2);
686 current += barMiddle->w;
687 }
688 else
689 {
690 SDL_Rect r2;
691 r2.x = 0;
692 r2.y = current;
693 if(current >= maxcurrent)
694 {
695 SDL_Rect r1;
696 r1.x = 0;
697 r1.y = 0;
698 r1.h = barMiddle->h - current + maxcurrent;
699 r1.w = barMiddle->h;
700 SDL_BlitSurface(barMiddle,&r1,bar,&r2);
701 break;
702 }
703 else
704 SDL_BlitSurface(barMiddle, NULL, bar, &r2);
705 current += barMiddle->h;
706 }
707 }
708
709 SDL_FreeSurface(barMiddle);
710 SDL_FreeSurface(barEnd1);
711 SDL_FreeSurface(barEnd2);
712}
713
714Scrollbar::~Scrollbar()
715{
716 SDL_FreeSurface(bar);
717 SDL_FreeSurface(dot);
718}
719
720void Scrollbar::draw(SDL_Surface *screen)
721{
722 SDL_Rect r = pos;
723 SDL_BlitSurface(bar,NULL,screen,&r);
724 if(horizontal)
725 {
726 r.x = pos.x + state * (pos.w-dot->w);
727 r.y = pos.y;
728 }
729 else
730 {
731 r.x = pos.x;
732 r.y = pos.y + state * (pos.h-dot->h);
733 }
734 SDL_BlitSurface(dot,NULL,screen,&r);
735}
736
737double Scrollbar::handleEvents(const SDL_Event& event)
738{
739 double x,y;
740 if(event.type == SDL_MOUSEMOTION && clicked)
741 {
742 x = event.motion.x;
743 y = event.motion.y;
744 if(x > 50000)
745 x = -10;
746 if(y > 50000)
747 y = -10;
748 if(horizontal)
749 {
750 //state = (x - dot->w/2 - pos.x)/(pos.w-dot->w/2);
751 stateGoal = (x - dot->w/2 - pos.x)/(pos.w-dot->w);
752 }
753 else
754 {
755 //state = (y - dot->h/2 - pos.y)/(pos.h-dot->h/2);
756 stateGoal = (y - dot->h/2 - pos.y)/(pos.h-dot->h);
757 }
758 if(stateGoal < 0)
759 stateGoal = 0;
760 if(stateGoal > 1)
761 stateGoal = 1;
762// stateGoal = state;
763 }
764 if(event.type == SDL_MOUSEBUTTONDOWN)
765 {
766 if(event.button.button == SDL_BUTTON_LEFT)
767 {
768 x = event.button.x;
769 y = event.button.y;
770 if(x >= pos.x && y >= pos.y && x < pos.x + pos.w && y < pos.y + pos.h)
771 {
772 clicked = true;
773 if(horizontal)
774 {
775 stateGoal = (x - dot->w/2 - pos.x)/(pos.w-dot->w);
776 }
777 else
778 {
779 stateGoal = (y - dot->h/2 - pos.y)/(pos.h-dot->h);
780 }
781 if(stateGoal < 0)
782 stateGoal = 0;
783 if(stateGoal > 1)
784 stateGoal = 1;
785// stateGoal = state;
786 }
787 }
788 if(event.button.button == SDL_BUTTON_WHEELDOWN)
789 {
790 stateGoal += max(sensitivity,sqrt(fabs(stateGoal-state))*sqrt(sensitivity)*3);
791 if(stateGoal > 1)
792 stateGoal = 1;
793 }
794 if(event.button.button == SDL_BUTTON_WHEELUP)
795 {
796 stateGoal -= max(sensitivity,sqrt(fabs(stateGoal-state))*sqrt(sensitivity)*3);
797 if(stateGoal < 0)
798 stateGoal = 0;
799 }
800 }
801 if(event.type == SDL_MOUSEBUTTONUP)
802 {
803 if(event.button.button == SDL_BUTTON_LEFT)
804 clicked = false;
805 }
806 return state;
807}
808
809double Scrollbar::frame(double time)
810{
811 state = stateGoal - (stateGoal - state) * pow(M_E,-15*time);
812 if(fabs(state - stateGoal) < 0.5 / max(pos.w,pos.h))
813 state = stateGoal;
814 return state;
815}
816
817void Scrollbar::refresh()
818{
819}
820
821Scrollable::Scrollable(SDL_Rect npos, AbstractInteractive* nsubInteractive, SDL_Rect subRect, bool nhorizontal, bool nscrollbarSide)
822{
823 wholeMenu = npos;
824 currentSubPos = 0;
825 pos = npos;
826 subInteractive = nsubInteractive;
827 horizontal = nhorizontal;
828 fakeScreen = SDL_CreateRGBSurface(0,subRect.w,subRect.h,32,rmask,gmask,bmask,0);
829 Uint32 colorkey = SDL_MapRGB(fakeScreen->format, 0, 1, 2);
830 SDL_FillRect(fakeScreen,NULL,colorkey);
831 SDL_SetColorKey(fakeScreen, SDL_SRCCOLORKEY, colorkey);
832 SDL_Rect barRect;
833 if(horizontal)
834 {
835 barRect.x = pos.x;
836 barRect.w = pos.w;
837 barRect.y = pos.y + nscrollbarSide*(pos.h-10);
838 barRect.h = 10;
839 pos.h -= 10;
840 pos.y += !nscrollbarSide * 10;
841 }
842 else
843 {
844 barRect.x = pos.x + nscrollbarSide*(pos.w - 10);
845 barRect.w = 10;
846 barRect.y = pos.y;
847 barRect.h = pos.h;
848 pos.w -= 10;
849 pos.x += !nscrollbarSide * 10;
850 }
851 bar = new Scrollbar(barRect);
852}
853
854Scrollable::~Scrollable()
855{
856 delete subInteractive;
857 SDL_FreeSurface(fakeScreen);
858}
859
860void Scrollable::draw(SDL_Surface* screen)
861{
862 Uint32 colorkey = SDL_MapRGB(fakeScreen->format, 0, 1, 2);
863 SDL_FillRect(fakeScreen,NULL,colorkey);
864 subInteractive->draw(fakeScreen);
865 SDL_Rect src;
866 SDL_Rect dst;
867 if(horizontal)
868 {
869 src.x = currentSubPos;
870 src.y = 0;
871 src.w = pos.w;
872 src.h = fakeScreen->h;
873 dst.x = pos.x;
874 dst.y = pos.y + (pos.h - fakeScreen->h)/2;
875 }
876 else
877 {
878 src.x = 0;
879 src.y = currentSubPos;
880 src.w = fakeScreen->w;
881 src.h = pos.h;
882 dst.x = pos.x + (pos.w - fakeScreen->w)/2;
883 dst.y = pos.y;
884 }
885 SDL_BlitSurface(fakeScreen,&src,screen,&dst);
886 bool b = true;
887 if(horizontal && fakeScreen->w < pos.w)
888 b = false;
889 if(!horizontal && fakeScreen->h < pos.h)
890 b = false;
891 if(b)
892 bar->draw(screen);
893}
894
895int Scrollable::handleEvents(SDL_Event nevent)
896{
897 bool b = true;
898 if(horizontal && fakeScreen->w < pos.w)
899 b = false;
900 if(!horizontal && fakeScreen->h < pos.h)
901 b = false;
902 int result = 0;
903 SDL_Rect r;
904 if(horizontal)
905 {
906 r.x = pos.x - currentSubPos;
907 r.y = pos.y + (pos.h - fakeScreen->h)/2;
908 }
909 else
910 {
911 r.y = pos.y - currentSubPos;
912 r.x = pos.x + (pos.w - fakeScreen->w)/2;
913 }
914 SDL_Event event = relativate(nevent,r);
915 if(event.type == SDL_MOUSEMOTION)
916 {
917 if(b)
918 bar->handleEvents(nevent);
919 MousePos.x = nevent.motion.x;
920 MousePos.y = nevent.motion.y;
921 //if(inRect(pos, nevent.motion.x, nevent.motion.y))
922 result = subInteractive->handleEvents(event);
923 }
924 if(event.type == SDL_MOUSEBUTTONDOWN)
925 {
926// cout << "got an event at " << nevent.button.x << " " << nevent.button.y << endl;
927// cout << "send an event at " << event.button.x << " " << event.button.y << endl;
928 if(b && inRect(wholeMenu, nevent.button.x, nevent.button.y))
929 bar->handleEvents(nevent);
930 //if(inRect(pos, nevent.button.x, nevent.button.y))
931 result = subInteractive->handleEvents(event);
932 }
933 if(event.type == SDL_MOUSEBUTTONUP)
934 {
935 if(b && event.button.button == SDL_BUTTON_LEFT)
936 bar->handleEvents(nevent);
937 //if(inRect(pos, nevent.button.x, nevent.button.y))
938 result = subInteractive->handleEvents(event);
939 }
940 return result;
941}
942
943void Scrollable::frame(double time)
944{
945 subInteractive->frame(time);
946 setSubPosition(bar->frame(time));
947}
948
949void Scrollable::setSubPosition(double d)
950{
951 int last = currentSubPos;
952 if(horizontal)
953 currentSubPos = d * (fakeScreen->w - pos.w);
954 else
955 currentSubPos = d * (fakeScreen->h - pos.h);
956 if(last != currentSubPos && inRect(pos,MousePos.x,MousePos.y))
957 {
958 SDL_Event event;
959 event.type = SDL_MOUSEMOTION;
960 event.motion.x = MousePos.x;
961 event.motion.y = MousePos.y;
962 event.motion.x -= pos.x;
963 event.motion.y -= pos.y;
964 if(horizontal)
965 {
966 event.motion.x += currentSubPos;
967 event.motion.y -= (pos.h - fakeScreen->h)/2;
968 }
969 else
970 {
971 event.motion.y += currentSubPos;
972 event.motion.x -= (pos.w - fakeScreen->w)/2;
973 }
974 subInteractive->handleEvents(event);
975 }
976}
977
978void Scrollable::refresh()
979{
980 subInteractive->refresh();
981}
982
983Menu::Menu(vector<Button*> nbuttons, vector<int> neffects, SDL_Surface *background, bool rBG)
984{
985 isSelectMenu = false;
986 onMouseDown = false;
987 buttons = nbuttons;
988 effects = neffects;
989 BG = new SlidingBackground(background, 0, 100);
990 BG->setRandom(rBG);
991}
992
993Menu::Menu(vector<string> choices, vector<int> neffects, SDL_Surface *background, bool rBG, SDL_Surface *screen)
994{
995 isSelectMenu = false;
996 onMouseDown = false;
997 effects = neffects;
998 BG = new SlidingBackground(background, 0, 100);
999 BG->setRandom(rBG);
1000 int minTextSize;
1001 bool done = true;
1002 for(int i = 0; i < (int) choices.size(); ++i)
1003 {
1004 int curTextSize = 0;
1005 SDL_Rect r;
1006 r.y = screen->h*0.2 + i / ((double) choices.size()) * screen->h * 0.6;
1007 r.x = screen->w/5.0;
1008 r.w = screen->w*3.0/5.0;
1009 r.h = screen->h*0.6/((double) choices.size());
1010 Button *b = new Button(r, choices[i], curTextSize);
1011 if(effects[i] == 0)
1012 {
1013 b->deactivated = true;
1014 }
1015 buttons.push_back(b);
1016 if(i == 0)
1017 minTextSize = curTextSize;
1018 if(minTextSize != curTextSize)
1019 {
1020 minTextSize = min(curTextSize, minTextSize);
1021 done = false;
1022 }
1023 }
1024 if(done == true)
1025 return;
1026 for(int i = 0; i < (int) choices.size(); ++i)
1027 delete buttons[i];
1028 for(int i = 0; i < (int) choices.size(); ++i)
1029 {
1030 SDL_Rect r;
1031 r.y = screen->h*0.2 + i / ((double) choices.size()) * screen->h * 0.6;
1032 r.x = screen->w/5.0;
1033 r.w = screen->w*3.0/5.0;
1034 r.h = screen->h*0.6/((double) choices.size());
1035 Button *b = new Button(r, choices[i], minTextSize);
1036 if(effects[i] == 0)
1037 b->deactivated = true;
1038 buttons[i] = b;
1039 }
1040}
1041
1042Menu::~Menu()
1043{
1044 delete BG;
1045 for(int i = 0; i < (int) buttons.size(); ++i)
1046 delete buttons[i];
1047}
1048
1049void Menu::draw(SDL_Surface *screen)
1050{
1051 BG->draw(screen);
1052 for(int i = 0; i < (int) buttons.size(); ++i)
1053 buttons[i]->draw(screen);
1054}
1055
1056int Menu::handleEvents(SDL_Event event)
1057{
1058 for(int i = 0; i < (int) buttons.size(); ++i)
1059 {
1060 int temp = buttons[i]->handleEvents(event);
1061 if(((temp == BUTTON_PRESSEDOVER) || (false)) && onMouseDown)
1062 return effects[i];
1063 if(temp == BUTTON_CLICKED && !isSelectMenu)
1064 return effects[i];
1065 if(temp == BUTTON_CLICKED && isSelectMenu)
1066 {
1067 //cout << "Click on " << i << endl;
1068 return effects[i] | MENU_CLICK;
1069 }
1070 if(temp == BUTTON_SELECTED && isSelectMenu)
1071 {
1072 for(int j = 0; j < (int) buttons.size(); ++j)
1073 if(j != i)
1074 buttons[j]->selected = false;
1075 return effects[i] | MENU_SELECT;
1076 }
1077 }
1078 return 0;
1079}
1080
1081void Menu::frame(double time)
1082{
1083 BG->frame(time);
1084 for(int i = 0; i < (int) buttons.size(); ++i)
1085 buttons[i]->frame(time);
1086}
1087
1088void Menu::refresh()
1089{
1090 for(int i = 0; i < (int) buttons.size(); ++i)
1091 buttons[i]->refresh();
1092}
1093
1094//matrixMenu
1095Menu::Menu(vector<SDL_Surface*> pics, int width, int& height, bool nisSelectMenu, bool nonMouseDown)
1096{
1097 isSelectMenu = nisSelectMenu;
1098 onMouseDown = nonMouseDown;
1099 SDL_Rect r;
1100 r.x = 0;
1101 r.y = 0;
1102 r.w = 48;
1103 r.h = 48;
1104 for(int i = 0; i < (int) pics.size(); ++i)
1105 {
1106 if(isSelectMenu)
1107 effects.push_back(i);
1108 else
1109 effects.push_back(i | MENU_SELECT);
1110 Button *b = new Button(r, pics[i], !onMouseDown);
1111 if(isSelectMenu)
1112 b->isDblClckButton = true;
1113 buttons.push_back(b);
1114 r.x += 48;
1115 if(r.x +48 > width)
1116 {
1117 r.x = 0;
1118 r.y += 48;
1119 }
1120 }
1121 if(isSelectMenu)
1122 buttons[0]->selected = true;
1123 height = r.y;
1124 SDL_Surface* back = SDL_CreateRGBSurface(0,width,height,32,0,0,0,0);
1125 SDL_SetColorKey(back,SDL_SRCCOLORKEY,0x000102);
1126 SDL_FillRect(back,NULL,0x000102);
1127 BG = new SlidingBackground(back, 0, 0);
1128 BG->setRandom(0);
1129}
1130
1131CompositMenu::CompositMenu(vector<AbstractInteractive*> nsubmenues, SDL_Surface* nBG, SDL_Rect nsubPos, vector<Button*> ntabs)
1132{
1133 submenues = nsubmenues;
1134 subPos = nsubPos;
1135 tabs = ntabs;
1136 BG = new SlidingBackground(nBG, 0, 100);
1137 fakeScreen = SDL_CreateRGBSurface(0,subPos.w,subPos.h,32,0,0,0,0);
1138 SDL_SetColorKey(fakeScreen,SDL_SRCCOLORKEY,0x000102);
1139 state = 0;
1140 tabs[0]->selected = true;
1141}
1142
1143CompositMenu::~CompositMenu()
1144{
1145 for(int i = 0; i < (int) submenues.size(); ++i)
1146 delete submenues[i];
1147 for(int i = 0; i < (int) tabs.size(); ++i)
1148 delete tabs[i];
1149 delete BG;
1150 SDL_FreeSurface(fakeScreen);
1151}
1152
1153void CompositMenu::draw(SDL_Surface *screen)
1154{
1155 BG->draw(screen);
1156 SDL_FillRect(fakeScreen,NULL,0x000102);
1157 submenues[state]->draw(fakeScreen);
1158 SDL_BlitSurface(fakeScreen,NULL,screen,&subPos);
1159 for(int i = 0; i < (int) tabs.size(); ++i)
1160 tabs[i]->draw(screen);
1161}
1162
1163int CompositMenu::handleEvents(SDL_Event event)
1164{
1165
1166 for(int i = 0; i < (int) tabs.size(); ++i)
1167 {
1168 int temp = tabs[i]->handleEvents(event);
1169 if(temp == BUTTON_SELECTED)
1170 {
1171 state = i;
1172 for(int j = 0; j < (int) tabs.size(); ++j)
1173 if(i != j)
1174 tabs[j]->selected = false;
1175 submenues[state]->refresh();
1176 }
1177 }
1178 SDL_Event nevent = relativate(event, subPos);
1179// if(nevent.type == SDL_MOUSEBUTTONDOWN)
1180// {
1181// cout << "CMenu got an event at " << event.button.x << " " << event.button.y << endl;
1182// cout << "CMenu sent an event at " << nevent.button.x << " " << nevent.button.y << ". state is " << state << endl;
1183// }
1184 return submenues[state]->handleEvents(nevent);
1185}
1186
1187void CompositMenu::frame(double time)
1188{
1189 BG->frame(time);
1190 submenues[state]->frame(time);
1191 for(int i = 0; i < (int) tabs.size(); ++i)
1192 tabs[i]->frame(time);
1193}
1194
1195void CompositMenu::refresh()
1196{
1197 for(int i = 0; i < (int) submenues.size(); ++i)
1198 submenues[i]->refresh();
1199 for(int i = 0; i < (int) tabs.size(); ++i)
1200 tabs[i]->refresh();
1201}
1202
1203int CompositMenu::getState()
1204{
1205 return state;
1206}
1207
1208GetStringMenu::GetStringMenu(string headline, int niBack, int niOK, SDL_Surface* nBG, SDL_Surface* screen)
1209{
1210 screenw = screen->w;
1211 maxLength = 22;
1212 SDL_EnableUNICODE( SDL_ENABLE );
1213 iBack = niBack;
1214 iOK = niOK;
1215 SDL_Rect tRect;
1216 tRect.x = 0;
1217 tRect.y = screen->h/3;
1218 tRect.w = screen->w;
1219 tRect.h = 30;
1220 title = new Label(headline, tRect);
1221 tRect.x = (screen->w - title->pos.w)/2;
1222 title->pos = tRect;
1223 BG = new SlidingBackground(nBG, 0, 100);
1224 tRect.y += 40;
1225 tRect.h = 30;
1226 input = new Label("nicht leer", tRect);
1227 tRect.x = (screen->w - input->pos.w)/2;
1228 input->pos = tRect;
1229 int textSize = 0;
1230 SDL_Rect backPos = tRect;
1231 backPos.y += 40;
1232 backPos.x = screen->w/6;
1233 backPos.w = (2*screen->w)/6;
1234 backPos.h = 50;
1235 back = new Button(backPos,"back",textSize);
1236 backPos.x = screen->w/2;
1237 oK = new Button(backPos,"OK",textSize);
1238}
1239
1240GetStringMenu::~GetStringMenu()
1241{
1242 SDL_EnableUNICODE( SDL_DISABLE );
1243 delete title;
1244 delete input;
1245 delete back;
1246 delete oK;
1247}
1248
1249void GetStringMenu::draw(SDL_Surface* screen)
1250{
1251 BG->draw(screen);
1252 title->draw(screen);
1253 if(s != "")
1254 input->draw(screen);
1255 back->draw(screen);
1256 oK->draw(screen);
1257}
1258
1259int GetStringMenu::handleEvents(SDL_Event event)
1260{
1261 if(back->handleEvents(event) == BUTTON_CLICKED)
1262 return iBack;
1263 if(oK->handleEvents(event) == BUTTON_CLICKED)
1264 return iOK;
1265
1266 //If a key was pressed
1267 if( event.type == SDL_KEYDOWN )
1268 {
1269 //If the string less than maximum size
1270 if((int) s.length() <= maxLength )
1271 {
1272 if(event.key.keysym.unicode == (Uint16) ' ')
1273 {
1274 s += (char)event.key.keysym.unicode;
1275 }
1276 else if((event.key.keysym.unicode >= (Uint16) '0' ) && ( event.key.keysym.unicode <= (Uint16) '9'))
1277 {
1278 s += (char)event.key.keysym.unicode;
1279 }
1280 else if((event.key.keysym.unicode >= (Uint16) 'A') && (event.key.keysym.unicode <= (Uint16) 'Z'))
1281 {
1282 s += (char)event.key.keysym.unicode;
1283 }
1284 else if((event.key.keysym.unicode >= (Uint16) 'a') && (event.key.keysym.unicode <= (Uint16) 'z'))
1285 {
1286 s += (char)event.key.keysym.unicode;
1287 }
1288 }
1289 }
1290 //If backspace was pressed and the string isn't blank
1291 if((event.key.keysym.sym == SDLK_BACKSPACE) && (s.length() != 0))
1292 {
1293 //Remove a character from the end
1294 s.erase(s.length() - 1);
1295 }
1296 if((event.key.keysym.sym == SDLK_RETURN) && oK->deactivated == false)
1297 {
1298 return iOK;
1299 }
1300 if(s != "")
1301 input->setCaption(s);
1302 input->pos.x = (screenw - input->pos.w)/2;
1303 return 0;
1304}
1305
1306void GetStringMenu::frame(double time)
1307{
1308 BG->frame(time);
1309}
1310
1311void GetStringMenu::refresh()
1312{
1313 s = "";
1314}
1315
1316