1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <GUI/dune/DuneStyle.h>
19 #include <misc/draw_util.h>
20 #include <GUI/Widget.h>
21 
22 #include <FileClasses/GFXManager.h>
23 #include <FileClasses/FontManager.h>
24 
25 #include <iostream>
26 #include <cmath>
27 #include <algorithm>
28 
29 extern GFXManager*  pGFXManager;
30 extern FontManager* pFontManager;
31 
32 
createSurfaceWithText(const std::string & text,Uint32 color,unsigned int fontsize)33 SDL_Surface* DuneStyle::createSurfaceWithText(const std::string& text, Uint32 color, unsigned int fontsize) {
34     if(pFontManager != nullptr) {
35         return pFontManager->createSurfaceWithText(text, color, fontsize);
36     } else {
37         // create dummy surface
38         SDL_Surface* surface;
39 
40         if((surface = SDL_CreateRGBSurface(0, text.length()*10, 12, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
41             return nullptr;
42         }
43 
44         SDL_FillRect(surface, nullptr, COLOR_TRANSPARENT);
45 
46         return surface;
47     }
48 }
49 
getTextHeight(unsigned int FontNum)50 unsigned int DuneStyle::getTextHeight(unsigned int FontNum) {
51     if(pFontManager != nullptr) {
52         return pFontManager->getTextHeight(FontNum);
53     } else {
54         return 12;
55     }
56 }
57 
getTextWidth(const std::string & text,unsigned int FontNum)58 unsigned int DuneStyle::getTextWidth(const std::string& text, unsigned int FontNum)  {
59     if(pFontManager != nullptr) {
60         return pFontManager->getTextWidth(text,FontNum);
61     } else {
62         return text.length()*10;
63     }
64 }
65 
66 
getMinimumLabelSize(const std::string & text,int fontID)67 Point DuneStyle::getMinimumLabelSize(const std::string& text, int fontID) {
68     return Point(getTextWidth(text,fontID) + 12,getTextHeight(fontID) + 4);
69 }
70 
createLabelSurface(Uint32 width,Uint32 height,const std::vector<std::string> & textLines,int fontID,Alignment_Enum alignment,Uint32 textcolor,Uint32 textshadowcolor,Uint32 backgroundcolor)71 SDL_Surface* DuneStyle::createLabelSurface(Uint32 width, Uint32 height, const std::vector<std::string>& textLines, int fontID, Alignment_Enum alignment, Uint32 textcolor, Uint32 textshadowcolor, Uint32 backgroundcolor) {
72     SDL_Surface* surface;
73 
74     // create surfaces
75     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
76         return nullptr;
77     }
78 
79     SDL_FillRect(surface, nullptr, backgroundcolor);
80 
81     if(textcolor == COLOR_DEFAULT) textcolor = defaultForegroundColor;
82     if(textshadowcolor == COLOR_DEFAULT) textshadowcolor = defaultShadowColor;
83 
84     std::vector<SDL_Surface*> textSurfaces;
85     for(const std::string& textLine : textLines) {
86         // create text background
87         textSurfaces.push_back(createSurfaceWithText(textLine, textshadowcolor, fontID));
88         // create text foreground
89         textSurfaces.push_back(createSurfaceWithText(textLine, textcolor, fontID));
90     }
91 
92     int fontheight = getTextHeight(fontID);
93     int spacing = 2;
94 
95     int textpos_y;
96 
97     if(alignment & Alignment_VCenter) {
98         int textheight = fontheight * textLines.size() + spacing * (textLines.size() - 1);
99         textpos_y = (((int) height) - textheight) / 2;
100     } else if(alignment & Alignment_Bottom) {
101         int textheight = fontheight * textLines.size() + spacing * (textLines.size() - 1);
102         textpos_y = ((int) height) - textheight - spacing;
103     } else {
104         // Alignment_Top
105         textpos_y = spacing;
106     }
107 
108     std::vector<SDL_Surface*>::const_iterator surfIter = textSurfaces.begin();
109     while(surfIter != textSurfaces.end()) {
110         SDL_Surface* textSurface1 = *surfIter;
111         ++surfIter;
112         SDL_Surface* textSurface2 = *surfIter;
113         ++surfIter;
114 
115         SDL_Rect textRect1 = calcDrawingRect(textSurface1, 0, textpos_y + 3);
116         SDL_Rect textRect2 = calcDrawingRect(textSurface2, 0, textpos_y + 2);
117         if(alignment & Alignment_Left) {
118             textRect1.x = 4;
119             textRect2.x = 3;
120         } else if(alignment & Alignment_Right) {
121             textRect1.x = width - textSurface1->w - 4;
122             textRect2.x = width - textSurface2->w - 3;
123         } else {
124             // Alignment_HCenter
125             textRect1.x = ((surface->w - textSurface1->w) / 2)+3;
126             textRect2.x = ((surface->w - textSurface2->w) / 2)+2;
127         }
128 
129         SDL_BlitSurface(textSurface1,nullptr,surface,&textRect1);
130         SDL_FreeSurface(textSurface1);
131 
132         SDL_BlitSurface(textSurface2,nullptr,surface,&textRect2);
133         SDL_FreeSurface(textSurface2);
134 
135         textpos_y += fontheight + spacing;
136     }
137 
138     return surface;
139 }
140 
141 
142 
143 
144 
getMinimumCheckboxSize(const std::string & text)145 Point DuneStyle::getMinimumCheckboxSize(const std::string& text) {
146     return Point(getTextWidth(text.c_str(),FONT_STD12) + 20 + 17,getTextHeight(FONT_STD12) + 8);
147 }
148 
createCheckboxSurface(Uint32 width,Uint32 height,const std::string & text,bool checked,bool activated,Uint32 textcolor,Uint32 textshadowcolor,Uint32 backgroundcolor)149 SDL_Surface* DuneStyle::createCheckboxSurface(Uint32 width, Uint32 height, const std::string& text, bool checked, bool activated, Uint32 textcolor, Uint32 textshadowcolor, Uint32 backgroundcolor) {
150     SDL_Surface* surface;
151 
152     // create surfaces
153     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
154         return nullptr;
155     }
156 
157     SDL_FillRect(surface, nullptr, backgroundcolor);
158 
159     if(textcolor == COLOR_DEFAULT) textcolor = defaultForegroundColor;
160     if(textshadowcolor == COLOR_DEFAULT) textshadowcolor = defaultShadowColor;
161 
162     if(activated) {
163         textcolor = brightenUp(textcolor);
164     }
165 
166     drawRect(surface, 4, 5, 4 + 17, 5 + 17, textcolor);
167     drawRect(surface, 4 + 1, 5 + 1, 4 + 17 - 1, 5 + 17 - 1, textcolor);
168 
169     if(checked) {
170         int x1 = 4 + 2;
171         int y1 = 5 + 2;
172         int x2 = 4 + 17 - 2;
173 
174         for(int i = 0; i < 15; i++) {
175             // North-West to South-East
176             putPixel(surface, x1, y1, textcolor);
177             putPixel(surface, x1+1, y1, textcolor);
178             putPixel(surface, x1-1, y1, textcolor);
179 
180             // North-East to South-West
181             putPixel(surface, x2, y1, textcolor);
182             putPixel(surface, x2+1, y1, textcolor);
183             putPixel(surface, x2-1, y1, textcolor);
184 
185             x1++;
186             y1++;
187             x2--;
188         }
189     }
190 
191 
192     SDL_Surface* textSurface1 = createSurfaceWithText(text, textshadowcolor, FONT_STD12);
193     SDL_Rect textRect1 = calcDrawingRect(textSurface1,  10+2 + 17, surface->h/2 + 3, HAlign::Left, VAlign::Center);
194     SDL_BlitSurface(textSurface1,nullptr,surface,&textRect1);
195     SDL_FreeSurface(textSurface1);
196 
197     SDL_Surface* textSurface2 = createSurfaceWithText(text, textcolor, FONT_STD12);
198     SDL_Rect textRect2 = calcDrawingRect(textSurface2,  10+1 + 17, surface->h/2 + 2, HAlign::Left, VAlign::Center);
199     SDL_BlitSurface(textSurface2,nullptr,surface,&textRect2);
200     SDL_FreeSurface(textSurface2);
201 
202     return surface;
203 }
204 
205 
206 
207 
208 
getMinimumRadioButtonSize(const std::string & text)209 Point DuneStyle::getMinimumRadioButtonSize(const std::string& text) {
210     return Point(getTextWidth(text,FONT_STD12) + 16 + 15,getTextHeight(FONT_STD12) + 8);
211 }
212 
createRadioButtonSurface(Uint32 width,Uint32 height,const std::string & text,bool checked,bool activated,Uint32 textcolor,Uint32 textshadowcolor,Uint32 backgroundcolor)213 SDL_Surface* DuneStyle::createRadioButtonSurface(Uint32 width, Uint32 height, const std::string& text, bool checked, bool activated, Uint32 textcolor, Uint32 textshadowcolor, Uint32 backgroundcolor) {
214     SDL_Surface* surface;
215 
216     // create surfaces
217     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
218         return nullptr;
219     }
220 
221     SDL_FillRect(surface, nullptr, backgroundcolor);
222 
223     if(textcolor == COLOR_DEFAULT) textcolor = defaultForegroundColor;
224     if(textshadowcolor == COLOR_DEFAULT) textshadowcolor = defaultShadowColor;
225 
226     if(activated) {
227         textcolor = brightenUp(textcolor);
228     }
229 
230     drawHLineNoLock(surface, 8, 7, 13, textcolor);
231     drawHLineNoLock(surface, 7, 8, 14, textcolor);
232     drawHLineNoLock(surface, 6, 9, 8, textcolor);
233     drawHLineNoLock(surface, 13, 9, 15, textcolor);
234     drawHLineNoLock(surface, 5, 10, 6, textcolor);
235     drawHLineNoLock(surface, 15, 10, 16, textcolor);
236     drawHLineNoLock(surface, 4, 11, 6, textcolor);
237     drawHLineNoLock(surface, 15, 11, 17, textcolor);
238 
239     drawVLineNoLock(surface, 4, 12, 15, textcolor);
240     drawVLineNoLock(surface, 5, 12, 15, textcolor);
241     drawVLineNoLock(surface, 16, 12, 15, textcolor);
242     drawVLineNoLock(surface, 17, 12, 15, textcolor);
243 
244     drawHLineNoLock(surface, 4, 16, 6, textcolor);
245     drawHLineNoLock(surface, 15, 16, 17, textcolor);
246     drawHLineNoLock(surface, 5, 17, 6, textcolor);
247     drawHLineNoLock(surface, 15, 17, 16, textcolor);
248     drawHLineNoLock(surface, 6, 18, 8, textcolor);
249     drawHLineNoLock(surface, 13, 18, 15, textcolor);
250     drawHLineNoLock(surface, 7, 19, 14, textcolor);
251     drawHLineNoLock(surface, 8, 20, 13, textcolor);
252 
253     if(checked) {
254         drawHLineNoLock(surface, 9, 11, 12, textcolor);
255         drawHLineNoLock(surface, 8, 12, 13, textcolor);
256         drawHLineNoLock(surface, 8, 13, 13, textcolor);
257         drawHLineNoLock(surface, 8, 14, 13, textcolor);
258         drawHLineNoLock(surface, 8, 15, 13, textcolor);
259         drawHLineNoLock(surface, 9, 16, 12, textcolor);
260     }
261 
262 
263     SDL_Surface* textSurface1 = createSurfaceWithText(text, textshadowcolor, FONT_STD12);
264     SDL_Rect textRect1 = calcDrawingRect(textSurface1, 8+2 + 15, surface->h/2 + 3, HAlign::Left, VAlign::Center);
265     SDL_BlitSurface(textSurface1,nullptr,surface,&textRect1);
266     SDL_FreeSurface(textSurface1);
267 
268     SDL_Surface* textSurface2 = createSurfaceWithText(text, textcolor, FONT_STD12);
269     SDL_Rect textRect2 = calcDrawingRect(textSurface2, 8+1 + 15, surface->h/2 + 2, HAlign::Left, VAlign::Center);
270     SDL_BlitSurface(textSurface2,nullptr,surface,&textRect2);
271     SDL_FreeSurface(textSurface2);
272 
273     return surface;
274 }
275 
276 
277 
createDropDownBoxButton(Uint32 size,bool pressed,bool activated,Uint32 color)278 SDL_Surface* DuneStyle::createDropDownBoxButton(Uint32 size, bool pressed, bool activated, Uint32 color) {
279     if(color == COLOR_DEFAULT) {
280         color = defaultForegroundColor;
281     }
282 
283     // create surfaces
284     SDL_Surface* surface;
285     if((surface = SDL_CreateRGBSurface(0, size, size, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
286         return nullptr;
287     }
288 
289     // create button background
290     if(pressed == false) {
291         // normal mode
292         SDL_FillRect(surface, nullptr, buttonBackgroundColor);
293         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
294         drawHLine(surface, 1, 1, surface->w-2, buttonEdgeTopLeftColor);
295         drawVLine(surface, 1, 1, surface->h-2, buttonEdgeTopLeftColor);
296         drawHLine(surface, 1, surface->h-2, surface->w-2, buttonEdgeBottomRightColor);
297         drawVLine(surface, surface->w-2, 1, surface->h-2, buttonEdgeBottomRightColor);
298     } else {
299         // pressed button mode
300         SDL_FillRect(surface, nullptr, pressedButtonBackgroundColor);
301         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
302         drawRect(surface, 1, 1, surface->w-2, surface->h-2, buttonEdgeBottomRightColor);
303     }
304 
305     int col = (pressed | activated) ? brightenUp(color) : color;
306 
307     int x1 = 3;
308     int x2 = size-3-1;
309     int y = size/3 - 1;
310 
311     // draw separated hline
312     drawHLine(surface, x1, y, x2, col);
313     y+=2;
314 
315     // down arrow
316     for(;x1 <= x2; ++x1, --x2, ++y) {
317         drawHLine(surface, x1, y, x2, col);
318     }
319 
320     return surface;
321 }
322 
323 
324 
325 
getMinimumButtonSize(const std::string & text)326 Point DuneStyle::getMinimumButtonSize(const std::string& text) {
327     return Point(getTextWidth(text.c_str(),FONT_STD10)+12,getTextHeight(FONT_STD10));
328 }
329 
createButtonSurface(Uint32 width,Uint32 height,const std::string & text,bool pressed,bool activated,Uint32 textcolor,Uint32 textshadowcolor)330 SDL_Surface* DuneStyle::createButtonSurface(Uint32 width, Uint32 height, const std::string& text, bool pressed, bool activated, Uint32 textcolor, Uint32 textshadowcolor) {
331 
332     // create surfaces
333     SDL_Surface* surface;
334     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
335         return nullptr;
336     }
337 
338     // create button background
339     if(pressed == false) {
340         // normal mode
341         SDL_FillRect(surface, nullptr, buttonBackgroundColor);
342         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
343         drawHLine(surface, 1, 1, surface->w-2, buttonEdgeTopLeftColor);
344         drawVLine(surface, 1, 1, surface->h-2, buttonEdgeTopLeftColor);
345         drawHLine(surface, 1, surface->h-2, surface->w-2, buttonEdgeBottomRightColor);
346         drawVLine(surface, surface->w-2, 1, surface->h-2, buttonEdgeBottomRightColor);
347     } else {
348         // pressed button mode
349         SDL_FillRect(surface, nullptr, pressedButtonBackgroundColor);
350         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
351         drawRect(surface, 1, 1, surface->w-2, surface->h-2, buttonEdgeBottomRightColor);
352 
353     }
354 
355     // create text on this button
356     int fontsize;
357     if( (width < getTextWidth(text,FONT_STD12) + 12) ||
358         (height < getTextHeight(FONT_STD12) + 2)) {
359         fontsize = FONT_STD10;
360     } else {
361         fontsize = FONT_STD12;
362     }
363 
364     if(textcolor == COLOR_DEFAULT) textcolor = defaultForegroundColor;
365     if(textshadowcolor == COLOR_DEFAULT) textshadowcolor = defaultShadowColor;
366 
367     SDL_Surface* textSurface1 = createSurfaceWithText(text, textshadowcolor, fontsize);
368     SDL_Rect textRect1 = calcDrawingRect(textSurface1, surface->w/2 + 2 + (pressed ? 1 : 0), surface->h/2 + 3 + (pressed ? 1 : 0), HAlign::Center, VAlign::Center);
369     SDL_BlitSurface(textSurface1,nullptr,surface,&textRect1);
370     SDL_FreeSurface(textSurface1);
371 
372     SDL_Surface* textSurface2 = createSurfaceWithText(text, (activated == true) ? brightenUp(textcolor) : textcolor, fontsize);
373     SDL_Rect textRect2 = calcDrawingRect(textSurface2, surface->w/2 + 1 + (pressed ? 1 : 0), surface->h/2 + 2 + (pressed ? 1 : 0), HAlign::Center, VAlign::Center);
374     SDL_BlitSurface(textSurface2,nullptr,surface,&textRect2);
375     SDL_FreeSurface(textSurface2);
376 
377     return surface;
378 }
379 
380 
381 
382 
getMinimumTextBoxSize(int fontID)383 Point DuneStyle::getMinimumTextBoxSize(int fontID) {
384     return Point(10,getTextHeight(fontID) + 6);
385 }
386 
createTextBoxSurface(Uint32 width,Uint32 height,const std::string & text,bool carret,int fontID,Alignment_Enum alignment,Uint32 textcolor,Uint32 textshadowcolor)387 SDL_Surface* DuneStyle::createTextBoxSurface(Uint32 width, Uint32 height, const std::string& text, bool carret, int fontID, Alignment_Enum alignment, Uint32 textcolor, Uint32 textshadowcolor) {
388 
389     // create surfaces
390     SDL_Surface* surface;
391     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
392         return nullptr;
393     }
394 
395     SDL_FillRect(surface, nullptr, buttonBackgroundColor);
396     drawRect(surface,0,0,surface->w-1,surface->h-1,buttonBorderColor);
397 
398     drawHLine(surface,1,1,surface->w-2,buttonEdgeBottomRightColor);
399     drawHLine(surface,1,2,surface->w-2,buttonEdgeBottomRightColor);
400     drawVLine(surface,1,1,surface->h-2,buttonEdgeBottomRightColor);
401     drawVLine(surface,2,1,surface->h-2,buttonEdgeBottomRightColor);
402     drawHLine(surface,1,surface->h-2,surface->w-2,buttonEdgeTopLeftColor);
403     drawVLine(surface,surface->w-2,1,surface->h-2,buttonEdgeTopLeftColor);
404 
405     if(textcolor == COLOR_DEFAULT) textcolor = defaultForegroundColor;
406     if(textshadowcolor == COLOR_DEFAULT) textshadowcolor = defaultShadowColor;
407 
408     SDL_Rect cursorPos;
409 
410     // create text in this text box
411     if(text.size() != 0) {
412         SDL_Surface* textSurface1 = createSurfaceWithText(text, textshadowcolor, fontID);
413         SDL_Surface* textSurface2 = createSurfaceWithText(text, textcolor, fontID);
414         SDL_Rect textRect1 = calcDrawingRect(textSurface1, 0, surface->h/2 + 3, HAlign::Left, VAlign::Center);
415         SDL_Rect textRect2 = calcDrawingRect(textSurface2, 0, surface->h/2 + 2, HAlign::Left, VAlign::Center);
416 
417         if(alignment & Alignment_Left) {
418             textRect1.x = 6;
419             textRect2.x = 5;
420         } else if(alignment & Alignment_Right) {
421             textRect1.x = width - textSurface1->w - 5;
422             textRect2.x = width - textSurface2->w - 4;
423         } else {
424             // Alignment_HCenter
425             textRect1.x = ((surface->w - textSurface1->w) / 2)+3;
426             textRect2.x = ((surface->w - textSurface2->w) / 2)+2;
427         }
428 
429         if(textRect1.w > surface->w - 10) {
430             textRect1.x -= (textSurface1->w - (surface->w - 10));
431             textRect2.x -= (textSurface2->w - (surface->w - 10));
432         }
433 
434         cursorPos.x = textRect2.x + textSurface2->w + 2;
435 
436         SDL_BlitSurface(textSurface1,nullptr,surface,&textRect1);
437         SDL_FreeSurface(textSurface1);
438 
439         SDL_BlitSurface(textSurface2,nullptr,surface,&textRect2);
440         SDL_FreeSurface(textSurface2);
441 
442         cursorPos.w = 1;
443     } else {
444         if(alignment & Alignment_Left) {
445             cursorPos.x = 6;
446         } else if(alignment & Alignment_Right) {
447             cursorPos.x = width - 5;
448         } else {
449             // Alignment_HCenter
450             cursorPos.x = surface->w / 2;
451         }
452         cursorPos.w = 1;
453     }
454 
455     cursorPos.y = surface->h / 2 - 8;
456     cursorPos.h = 16;
457 
458     if(carret == true) {
459         drawVLine(surface,cursorPos.x,cursorPos.y,cursorPos.y+cursorPos.h,textcolor);
460         drawVLine(surface,cursorPos.x+1,cursorPos.y,cursorPos.y+cursorPos.h,textcolor);
461     }
462 
463     return surface;
464 }
465 
466 
467 
468 
getMinimumScrollBarArrowButtonSize()469 Point DuneStyle::getMinimumScrollBarArrowButtonSize() {
470     return Point(17,17);
471 }
472 
createScrollBarArrowButton(bool down,bool pressed,bool activated,Uint32 color)473 SDL_Surface* DuneStyle::createScrollBarArrowButton(bool down, bool pressed, bool activated, Uint32 color) {
474     if(color == COLOR_DEFAULT) {
475         color = defaultForegroundColor;
476     }
477 
478     // create surfaces
479     SDL_Surface* surface;
480     if((surface = SDL_CreateRGBSurface(0, 17, 17, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
481         return nullptr;
482     }
483 
484     // create button background
485     if(pressed == false) {
486         // normal mode
487         SDL_FillRect(surface, nullptr, buttonBackgroundColor);
488         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
489         drawHLine(surface, 1, 1, surface->w-2, buttonEdgeTopLeftColor);
490         drawVLine(surface, 1, 1, surface->h-2, buttonEdgeTopLeftColor);
491         drawHLine(surface, 1, surface->h-2, surface->w-2, buttonEdgeBottomRightColor);
492         drawVLine(surface, surface->w-2, 1, surface->h-2, buttonEdgeBottomRightColor);
493     } else {
494         // pressed button mode
495         SDL_FillRect(surface, nullptr, pressedButtonBackgroundColor);
496         drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
497         drawRect(surface, 1, 1, surface->w-2, surface->h-2, buttonEdgeBottomRightColor);
498     }
499 
500     int col = (pressed | activated) ? brightenUp(color) : color;
501 
502     // draw arrow
503     if(down == true) {
504         // down arrow
505         drawHLine(surface,3,4,13,col);
506         drawHLine(surface,4,5,12,col);
507         drawHLine(surface,5,6,11,col);
508         drawHLine(surface,6,7,10,col);
509         drawHLine(surface,7,8,9,col);
510         drawHLine(surface,8,9,8,col);
511     } else {
512         // up arrow
513         drawHLine(surface,8,5,8,col);
514         drawHLine(surface,7,6,9,col);
515         drawHLine(surface,6,7,10,col);
516         drawHLine(surface,5,8,11,col);
517         drawHLine(surface,4,9,12,col);
518         drawHLine(surface,3,10,13,col);
519     }
520 
521     return surface;
522 }
523 
524 
525 
526 
getListBoxEntryHeight()527 Uint32 DuneStyle::getListBoxEntryHeight() {
528     return 16;
529 }
530 
createListBoxEntry(Uint32 width,const std::string & text,bool selected,Uint32 color)531 SDL_Surface* DuneStyle::createListBoxEntry(Uint32 width, const std::string& text, bool selected, Uint32 color) {
532     if(color == COLOR_DEFAULT) {
533         color = defaultForegroundColor;
534     }
535 
536     // create surfaces
537     SDL_Surface* surface;
538     if((surface = SDL_CreateRGBSurface(0, width, getListBoxEntryHeight(), SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
539         return nullptr;
540     }
541 
542     if(selected == true) {
543         SDL_FillRect(surface, nullptr, buttonBackgroundColor);
544     } else {
545         SDL_FillRect(surface, nullptr, COLOR_TRANSPARENT);
546     }
547 
548     SDL_Surface* textSurface;
549     textSurface = createSurfaceWithText(text, color, FONT_STD10);
550     SDL_Rect textRect = calcDrawingRect(textSurface, 3, surface->h/2 + 1, HAlign::Left, VAlign::Center);
551     SDL_BlitSurface(textSurface,nullptr,surface,&textRect);
552     SDL_FreeSurface(textSurface);
553 
554     return surface;
555 }
556 
557 
558 
559 
createProgressBarOverlay(Uint32 width,Uint32 height,double percent,Uint32 color)560 SDL_Surface* DuneStyle::createProgressBarOverlay(Uint32 width, Uint32 height, double percent, Uint32 color) {
561 
562     // create surfaces
563     SDL_Surface* pSurface;
564     if((pSurface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
565         return nullptr;
566     }
567 
568     SDL_FillRect(pSurface, nullptr, COLOR_TRANSPARENT);
569 
570     if(color == COLOR_DEFAULT) {
571         // default color
572 
573         int max_i = std::max( (int) lround(percent*(( ((int) width) - 4)/100.0)), 0);
574 
575         if (!SDL_MUSTLOCK(pSurface) || (SDL_LockSurface(pSurface) == 0)) {
576             SDL_Rect dest = { 2, 2, max_i, ((int)height)-4 };
577             SDL_FillRect(pSurface, &dest, COLOR_HALF_TRANSPARENT);
578 
579 
580             if (SDL_MUSTLOCK(pSurface))
581                 SDL_UnlockSurface(pSurface);
582         }
583     } else {
584         int max_i = lround(percent*(width/100.0));
585 
586         SDL_Rect dest = { 0, 0, max_i, (int)height };
587         SDL_FillRect(pSurface, &dest, color);
588     }
589 
590     return pSurface;
591 }
592 
593 
594 
createToolTip(const std::string & text)595 SDL_Surface* DuneStyle::createToolTip(const std::string& text) {
596     SDL_Surface* surface;
597     SDL_Surface* helpTextSurface;
598 
599     if((helpTextSurface = createSurfaceWithText(text, COLOR_YELLOW, FONT_STD10)) == nullptr) {
600         return nullptr;
601     }
602 
603     // create surfaces
604     if((surface = SDL_CreateRGBSurface(0, helpTextSurface->w + 4, helpTextSurface->h + 2, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
605         return nullptr;
606     }
607 
608     SDL_FillRect(surface, nullptr, COLOR_HALF_TRANSPARENT);
609 
610     drawRect(surface, 0, 0, helpTextSurface->w + 4 - 1, helpTextSurface->h + 2 - 1, COLOR_YELLOW);
611 
612     SDL_Rect textRect = calcDrawingRect(helpTextSurface, 3, 3);
613     SDL_BlitSurface(helpTextSurface, nullptr, surface, &textRect);
614 
615     SDL_FreeSurface(helpTextSurface);
616     return surface;
617 }
618 
619 
620 
createBackground(Uint32 width,Uint32 height)621 SDL_Surface* DuneStyle::createBackground(Uint32 width, Uint32 height) {
622     SDL_Surface* pSurface;
623     if(pGFXManager != nullptr) {
624         pSurface = getSubPicture(pGFXManager->getBackgroundSurface(), 0, 0, width, height);
625         if(pSurface == nullptr) {
626             return nullptr;
627         }
628     } else {
629         // data manager not yet loaded
630         if((pSurface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
631             return nullptr;
632         }
633         SDL_FillRect(pSurface, nullptr, buttonBackgroundColor);
634     }
635 
636 
637     drawRect(pSurface, 0, 0, pSurface->w-1, pSurface->h-1, buttonBorderColor);
638     drawHLine(pSurface, 1, 1, pSurface->w-2, buttonEdgeTopLeftColor);
639     drawHLine(pSurface, 2, 2, pSurface->w-3, buttonEdgeTopLeftColor);
640     drawVLine(pSurface, 1, 1, pSurface->h-2, buttonEdgeTopLeftColor);
641     drawVLine(pSurface, 2, 2, pSurface->h-3, buttonEdgeTopLeftColor);
642     drawHLine(pSurface, 1, pSurface->h-2, pSurface->w-2, buttonEdgeBottomRightColor);
643     drawHLine(pSurface, 2, pSurface->h-3, pSurface->w-3, buttonEdgeBottomRightColor);
644     drawVLine(pSurface, pSurface->w-2, 1, pSurface->h-2, buttonEdgeBottomRightColor);
645     drawVLine(pSurface, pSurface->w-3, 2, pSurface->h-3, buttonEdgeBottomRightColor);
646 
647     return pSurface;
648 }
649 
createWidgetBackground(Uint32 width,Uint32 height)650 SDL_Surface* DuneStyle::createWidgetBackground(Uint32 width, Uint32 height) {
651     SDL_Surface* surface;
652 
653     // create surfaces
654     if((surface = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
655         return nullptr;
656     }
657 
658     SDL_FillRect(surface, nullptr, pressedButtonBackgroundColor);
659     drawRect(surface, 0, 0, surface->w-1, surface->h-1, buttonBorderColor);
660     drawRect(surface, 1, 1, surface->w-2, surface->h-2, buttonEdgeBottomRightColor);
661 
662     return surface;
663 }
664