1 /*
2 * Copyright (C) 2011-2013 Me and My Shadow
3 *
4 * This file is part of Me and My Shadow.
5 *
6 * Me and My Shadow is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Me and My Shadow is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Functions.h"
21 #include "GameState.h"
22 #include "OptionsMenu.h"
23 #include "ThemeManager.h"
24 #include "GUIListBox.h"
25 #include "GUISlider.h"
26 #include "InputManager.h"
27 #include "LevelPackManager.h"
28 #include "StatisticsManager.h"
29 #include "MusicManager.h"
30 #include "SoundManager.h"
31 #include <iostream>
32 #include <sstream>
33
34 #include "libs/tinyformat/tinyformat.h"
35 #include "libs/tinygettext/tinygettext.hpp"
36 #include "libs/findlocale/findlocale.h"
37
38 using namespace std;
39
40 /////////////////////////OPTIONS_MENU//////////////////////////////////
41
42 //Some variables for the options.
43 static bool fullscreen,internet,fade,quickrec;
44 static string themeName,languageName;
45 static int lastLang,lastRes;
46
47 static bool useProxy;
48 static string internetProxy;
49
50 static bool restartFlag;
51
52 static SDL_Point currentRes;
53 static vector<SDL_Point> resolutionList;
54
Options(ImageManager & imageManager,SDL_Renderer & renderer)55 Options::Options(ImageManager& imageManager,SDL_Renderer& renderer){
56 //Render the title.
57 title = titleTextureFromText(renderer, _("Settings"), objThemes.getTextColor(false), SCREEN_WIDTH);
58
59 //Initialize variables.
60 lastJumpSound=0;
61 clearIconHower=false;
62 section = 2;
63 section2 = 1;
64
65 //Load icon image and tooltip text.
66 clearIcon=imageManager.loadTexture(getDataPath()+"gfx/menu/clear-progress.png",renderer);
67 /// TRANSLATORS: Used for button which clear any level progress like unlocked levels and highscores.
68 clearTooltip=textureFromText(renderer, *fontText, _("Clear Progress"), objThemes.getTextColor(true));
69
70 //Set some default settings.
71 fullscreen=getSettings()->getBoolValue("fullscreen");
72 languageName=getSettings()->getValue("lang");
73 themeName=processFileName(getSettings()->getValue("theme"));
74 internet=getSettings()->getBoolValue("internet");
75 internetProxy=getSettings()->getValue("internet-proxy");
76 useProxy=!internetProxy.empty();
77 fade=getSettings()->getBoolValue("fading");
78 quickrec=getSettings()->getBoolValue("quickrecord");
79
80 //Set the restartFlag false.
81 restartFlag=false;
82
83 //Now create the gui.
84 createGUI(imageManager,renderer);
85 }
86
~Options()87 Options::~Options(){
88 //Delete the GUI.
89 if(GUIObjectRoot){
90 delete GUIObjectRoot;
91 GUIObjectRoot=NULL;
92 }
93 }
94
createGUI(ImageManager & imageManager,SDL_Renderer & renderer)95 void Options::createGUI(ImageManager& imageManager,SDL_Renderer& renderer){
96 //Variables for positioning
97 const int columnW=SCREEN_WIDTH*0.3;
98 const int column1X=SCREEN_WIDTH*0.15;
99 const int column2X=SCREEN_WIDTH*0.55;
100 const int lineHeight=40;
101
102 //Create the root element of the GUI.
103 if(GUIObjectRoot){
104 delete GUIObjectRoot;
105 GUIObjectRoot=NULL;
106 }
107 GUIObjectRoot=new GUIObject(imageManager,renderer,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
108
109 //Single line list for different tabs.
110 GUISingleLineListBox* listBox=new GUISingleLineListBox(imageManager,renderer,(SCREEN_WIDTH-500)/2,104,500,32);
111 listBox->addItem(_("General"));
112 listBox->addItem(_("Controls"));
113 listBox->value=0;
114 listBox->name="lstTabs";
115 listBox->eventCallback=this;
116 GUIObjectRoot->addChild(listBox);
117
118 //Create general tab.
119 tabGeneral=new GUIObject(imageManager,renderer,0,150,SCREEN_WIDTH,SCREEN_HEIGHT);
120 GUIObjectRoot->addChild(tabGeneral);
121
122 //Now we create GUIObjects for every option.
123 GUIObject* obj=new GUILabel(imageManager,renderer,column1X,0,columnW,36,_("Music"));
124 tabGeneral->addChild(obj);
125
126 musicSlider=new GUISlider(imageManager,renderer,column2X,0,columnW,36,atoi(getSettings()->getValue("music").c_str()),0,128,15);
127 musicSlider->name="sldMusic";
128 musicSlider->eventCallback=this;
129 tabGeneral->addChild(musicSlider);
130
131 obj=new GUILabel(imageManager,renderer,column1X,lineHeight,columnW,36,_("Sound"));
132 tabGeneral->addChild(obj);
133
134 soundSlider=new GUISlider(imageManager,renderer,column2X,lineHeight,columnW,36,atoi(getSettings()->getValue("sound").c_str()),0,128,15);
135 soundSlider->name="sldSound";
136 soundSlider->eventCallback=this;
137 tabGeneral->addChild(soundSlider);
138
139 obj=new GUILabel(imageManager,renderer,column1X,2*lineHeight,columnW,36,_("Resolution"));
140 obj->name="lstResolution";
141 tabGeneral->addChild(obj);
142
143 //Create list with many different resolutions.
144 resolutions = new GUISingleLineListBox(imageManager,renderer,column2X,2*lineHeight,columnW,36);
145 resolutions->value=-1;
146
147 //Only get the resolution list if it hasn't been done before.
148 if(resolutionList.empty()){
149 resolutionList=getResolutionList();
150 }
151
152 //Get current resolution from config file. Thus it can be user defined.
153 currentRes.x=atoi(getSettings()->getValue("width").c_str());
154 currentRes.y=atoi(getSettings()->getValue("height").c_str());
155
156 for(int i=0; i<(int)resolutionList.size();i++){
157 //Create a string from width and height and then add it to list.
158 ostringstream out;
159 out << resolutionList[i].x << "x" << resolutionList[i].y;
160 resolutions->addItem(out.str());
161
162 //Check if current resolution matches, select it.
163 if(resolutionList[i].x==currentRes.x && resolutionList[i].y==currentRes.y){
164 resolutions->value=i;
165 }
166 }
167
168 //Add current resolution if it isn't already in the list.
169 if(resolutions->value==-1){
170 ostringstream out;
171 out << currentRes.x << "x" << currentRes.y;
172 resolutions->addItem(out.str());
173 resolutions->value=resolutions->item.size()-1;
174 }
175 lastRes=resolutions->value;
176
177 tabGeneral->addChild(resolutions);
178
179 obj=new GUILabel(imageManager,renderer,column1X,3*lineHeight,columnW,36,_("Language"));
180 tabGeneral->addChild(obj);
181
182 //Create GUI list with available languages.
183 langs = new GUISingleLineListBox(imageManager,renderer,column2X,3*lineHeight,columnW,36);
184 langs->name="lstLanguages";
185
186 /// TRANSLATORS: as detect user's language automatically
187 langs->addItem("",_("Auto-Detect"));
188 langs->addItem("en","English");
189
190 //Get a list of every available language.
191 set<tinygettext::Language> languages = dictionaryManager->get_languages();
192 for (set<tinygettext::Language>::iterator s0 = languages.begin(); s0 != languages.end(); ++s0){
193 //If language in loop is the same in config file, then select it
194 if(getSettings()->getValue("lang")==s0->str()){
195 lastLang=distance(languages.begin(),s0)+2;
196 }
197 //Add language in loop to list and listbox.
198 langs->addItem(s0->str(),s0->get_name());
199 }
200
201 //If Auto or English are selected.
202 if(getSettings()->getValue("lang")==""){
203 lastLang=0;
204 }else if(getSettings()->getValue("lang")=="en"){
205 lastLang=1;
206 }
207
208 langs->value=lastLang;
209 tabGeneral->addChild(langs);
210
211 obj=new GUILabel(imageManager,renderer,column1X,4*lineHeight,columnW,36,_("Theme"));
212 obj->name="theme";
213 tabGeneral->addChild(obj);
214
215 //Create the theme option gui element.
216 theme=new GUISingleLineListBox(imageManager,renderer,column2X,4*lineHeight,columnW,36);
217 theme->name="lstTheme";
218
219 //Vector containing the theme locations and names.
220 vector<pair<string,string> > themes;
221 vector<string> v=enumAllDirs(getUserPath(USER_DATA)+"themes/");
222 for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
223 string location=getUserPath(USER_DATA)+"themes/"+*i;
224 themes.push_back(pair<string,string>(location,*i));
225 }
226 vector<string> v2=enumAllDirs(getDataPath()+"themes/");
227 for(vector<string>::iterator i=v2.begin(); i!=v2.end(); ++i){
228 string location=getDataPath()+"themes/"+*i;
229 themes.push_back(pair<string,string>(location,*i));
230 }
231
232 //Try to find the configured theme so we can display it.
233 int value=-1;
234 for(vector<pair<string,string> >::iterator i=themes.begin(); i!=themes.end(); ++i){
235 if(i->first==themeName) {
236 value=i-themes.begin();
237 }
238 }
239 theme->addItems(themes);
240 if(value==-1)
241 value=theme->item.size()-1;
242 theme->value=value;
243 //NOTE: We call the event handling method to correctly set the themename.
244 GUIEventCallback_OnEvent(imageManager,renderer,"lstTheme",theme,GUIEventChange);
245 theme->eventCallback=this;
246 tabGeneral->addChild(theme);
247
248 //Proxy settings.
249 obj=new GUILabel(imageManager,renderer,column1X,5*lineHeight,columnW,36,_("Internet proxy"));
250 obj->name="chkProxy";
251 obj->eventCallback=this;
252 tabGeneral->addChild(obj);
253 obj=new GUITextBox(imageManager,renderer,column2X,5*lineHeight,columnW,36,internetProxy.c_str());
254 obj->name="txtProxy";
255 obj->eventCallback=this;
256 tabGeneral->addChild(obj);
257
258 obj=new GUICheckBox(imageManager,renderer,column1X,6*lineHeight,columnW,36,_("Fullscreen"),fullscreen?1:0);
259 obj->name="chkFullscreen";
260 obj->eventCallback=this;
261 tabGeneral->addChild(obj);
262
263 obj = new GUICheckBox(imageManager, renderer, column1X, 7 * lineHeight, columnW, 36, _("Quick record"), quickrec ? 1 : 0);
264 obj->name = "chkQuickRec";
265 obj->eventCallback = this;
266 tabGeneral->addChild(obj);
267
268 obj=new GUICheckBox(imageManager,renderer,column2X,6*lineHeight,columnW,36,_("Internet"),internet?1:0);
269 obj->name="chkInternet";
270 obj->eventCallback=this;
271 tabGeneral->addChild(obj);
272
273 obj=new GUICheckBox(imageManager,renderer,column2X,7*lineHeight,columnW,36,_("Fade transition"),fade?1:0);
274 obj->name="chkFade";
275 obj->eventCallback=this;
276 tabGeneral->addChild(obj);
277
278 //Create the controls tab.
279 tabControls=inputMgr.showConfig(imageManager,renderer,SCREEN_HEIGHT-210);
280 tabControls->top=140;
281 tabControls->visible=false;
282 GUIObjectRoot->addChild(tabControls);
283
284 //Save original keys.
285 for(int i=0;i<INPUTMGR_MAX;i++){
286 tmpKeys[i]=inputMgr.getKeyCode((InputManagerKeys)i,false);
287 tmpAlternativeKeys[i]=inputMgr.getKeyCode((InputManagerKeys)i,true);
288 }
289
290 //Create buttons.
291 cmdBack = new GUIButton(imageManager, renderer, SCREEN_WIDTH*0.3, SCREEN_HEIGHT - 60, -1, 36, _("Cancel"), 0, true, true, GUIGravityCenter);
292 cmdBack->name = "cmdBack";
293 cmdBack->eventCallback = this;
294 GUIObjectRoot->addChild(cmdBack);
295
296 cmdSave = new GUIButton(imageManager, renderer, SCREEN_WIDTH*0.7, SCREEN_HEIGHT - 60, -1, 36, _("Save Changes"), 0, true, true, GUIGravityCenter);
297 cmdSave->name = "cmdSave";
298 cmdSave->eventCallback = this;
299 GUIObjectRoot->addChild(cmdSave);
300 }
301
convertInt(int i)302 static string convertInt(int i){
303 stringstream ss;
304 ss << i;
305 return ss.str();
306 }
307
GUIEventCallback_OnEvent(ImageManager & imageManager,SDL_Renderer & renderer,std::string name,GUIObject * obj,int eventType)308 void Options::GUIEventCallback_OnEvent(ImageManager& imageManager, SDL_Renderer& renderer, std::string name,GUIObject* obj,int eventType){
309 //Check what type of event it was.
310 if(eventType==GUIEventClick){
311 if(name=="cmdBack"){
312 //Reset the key changes.
313 for(int i=0;i<INPUTMGR_MAX;i++){
314 inputMgr.setKeyCode((InputManagerKeys)i,tmpKeys[i],false);
315 inputMgr.setKeyCode((InputManagerKeys)i,tmpAlternativeKeys[i],true);
316 }
317
318 //Reset the music volume.
319 getMusicManager()->setVolume(atoi(getSettings()->getValue("music").c_str()));
320 Mix_Volume(-1,atoi(getSettings()->getValue("sound").c_str()));
321
322 //And goto the main menu.
323 setNextState(STATE_MENU);
324 }else if(name=="cmdSave"){
325 //Save is pressed thus save
326 char s[64];
327 sprintf(s,"%d",soundSlider->value);
328 getSettings()->setValue("sound",s);
329 sprintf(s,"%d",musicSlider->value);
330 getSettings()->setValue("music",s);
331 getMusicManager()->setEnabled(musicSlider->value>0);
332 Mix_Volume(-1,soundSlider->value);
333 getSettings()->setValue("fullscreen",fullscreen?"1":"0");
334 getSettings()->setValue("internet",internet?"1":"0");
335 getSettings()->setValue("theme",themeName);
336 getSettings()->setValue("fading",fade?"1":"0");
337 getSettings()->setValue("quickrecord",quickrec?"1":"0");
338 //Before loading the theme remove the previous one from the stack.
339 objThemes.removeTheme();
340 loadTheme(imageManager,renderer,themeName);
341 if(!useProxy)
342 internetProxy.clear();
343 getSettings()->setValue("internet-proxy",internetProxy);
344 getSettings()->setValue("lang",langs->getName());
345
346 //Is resolution from the list or is it user defined in config file
347 if(resolutions->value<(int)resolutionList.size()){
348 getSettings()->setValue("width",convertInt(resolutionList[resolutions->value].x));
349 getSettings()->setValue("height",convertInt(resolutionList[resolutions->value].y));
350 }else{
351 getSettings()->setValue("width",convertInt(currentRes.x));
352 getSettings()->setValue("height",convertInt(currentRes.y));
353 }
354
355 //Save the key configuration.
356 inputMgr.saveConfig();
357
358 //Save the settings.
359 saveSettings();
360
361 //Before we return check if some .
362 if(restartFlag || resolutions->value!=lastRes){
363 //The resolution changed so we need to recreate the screen.
364 if(!createScreen()){
365 //Screen creation failed so set to safe settings.
366 getSettings()->setValue("fullscreen","0");
367 getSettings()->setValue("width",convertInt(resolutionList[lastRes].x));
368 getSettings()->setValue("height",convertInt(resolutionList[lastRes].y));
369
370 if(!createScreen()){
371 //Everything fails so quit.
372 setNextState(STATE_EXIT);
373 return;
374 }
375 }
376
377 //The screen is created, now load the (menu) theme.
378 if(!loadTheme(imageManager,renderer,"")){
379 //Loading the theme failed so quit.
380 setNextState(STATE_EXIT);
381 return;
382 }
383 }
384
385 if(langs->value!=lastLang){
386 //We set the language.
387 language=langs->getName();
388
389 if (language.empty()) {
390 // The language is set to auto-detect.
391 FL_Locale *locale;
392 FL_FindLocale(&locale, FL_MESSAGES);
393
394 language = locale->lang;
395 if (locale->country != NULL){
396 language += string("_") + string(locale->country);
397 }
398 if (locale->variant != NULL){
399 language += string("@") + string(locale->variant);
400 }
401
402 FL_FreeLocale(&locale);
403 }
404
405 dictionaryManager->set_language(tinygettext::Language::from_name(language));
406
407 #ifdef WIN32
408 //Some ad-hoc fix for Windows since it accepts "zh-CN" but not "zh_CN"
409 std::string language2;
410 for (auto c : language) {
411 if (isalnum(c)) language2.push_back(c);
412 else if (c == '_') language2.push_back('-');
413 else break;
414 }
415 const char* languagePtr = language2.c_str();
416 #else
417 const char* languagePtr = language.c_str();
418 #endif
419
420 tfm::setLocale(languagePtr);
421 setlocale(LC_TIME, languagePtr);
422
423 getLevelPackManager()->updateLanguage();
424
425 //And reload the font.
426 if(!loadFonts()){
427 //Loading failed so quit.
428 setNextState(STATE_EXIT);
429 return;
430 }
431 }
432
433 //Now return to the main menu.
434 setNextState(STATE_MENU);
435 }else if(name=="chkFullscreen"){
436 fullscreen=obj->value?true:false;
437
438 //Check if fullscreen changed.
439 if(fullscreen==getSettings()->getBoolValue("fullscreen")){
440 //We disable the restart message flag.
441 restartFlag=false;
442 }else{
443 //We set the restart message flag.
444 restartFlag=true;
445 }
446
447 }else if(name=="chkInternet"){
448 internet=obj->value?true:false;
449 }else if(name=="chkProxy"){
450 useProxy=obj->value?true:false;
451 }else if(name=="chkFade"){
452 fade=obj->value?true:false;
453 }else if(name=="chkQuickRec"){
454 quickrec=obj->value?true:false;
455 }
456 }
457 if(name=="lstTheme"){
458 if(theme!=NULL && theme->value>=0 && theme->value<(int)theme->item.size()){
459 //Convert the themeName to contain %DATA%, etc...
460 themeName=compressFileName(theme->item[theme->value].first);
461 }
462 }else if(name=="txtProxy"){
463 internetProxy=obj->caption;
464
465 //Check if the internetProxy field is empty.
466 useProxy=!internetProxy.empty();
467 }else if(name=="sldMusic"){
468 getMusicManager()->setEnabled(musicSlider->value>0);
469 getMusicManager()->setVolume(musicSlider->value);
470 }else if(name=="sldSound"){
471 Mix_Volume(-1,soundSlider->value);
472 if(lastJumpSound==0){
473 getSoundManager()->playSound("jump");
474 lastJumpSound=15;
475 }
476 }
477 if(name=="lstTabs"){
478 if(obj->value==0){
479 tabGeneral->visible=true;
480 tabControls->visible=false;
481 }else{
482 tabGeneral->visible=false;
483 tabControls->visible=true;
484 }
485 }
486 }
487
handleEvents(ImageManager & imageManager,SDL_Renderer & renderer)488 void Options::handleEvents(ImageManager& imageManager, SDL_Renderer& renderer){
489 //Check keyboard navigation.
490 if (tabGeneral && tabGeneral->visible) {
491 if (inputMgr.isKeyDownEvent(INPUTMGR_TAB)) {
492 isKeyboardOnly = true;
493 section = (section == 2) ? 3 : 2;
494
495 //Update selection.
496 if (section == 2) {
497 tabGeneral->selectNextControl(1, -1);
498 } else {
499 tabGeneral->setSelectedControl(-1);
500 }
501 }
502 if (section == 2) {
503 tabGeneral->handleKeyboardNavigationEvents(imageManager, renderer, UpDownFocus | ReturnControls | LeftRightControls);
504 } else if (section == 3) {
505 if (inputMgr.isKeyDownEvent(INPUTMGR_DOWN) || inputMgr.isKeyDownEvent(INPUTMGR_RIGHT)) {
506 isKeyboardOnly = true;
507 section2++;
508 if (section2 > 3) section2 = 1;
509 } else if (inputMgr.isKeyDownEvent(INPUTMGR_UP) || inputMgr.isKeyDownEvent(INPUTMGR_LEFT)) {
510 isKeyboardOnly = true;
511 section2--;
512 if (section2 < 1) section2 = 3;
513 }
514 if (isKeyboardOnly && inputMgr.isKeyDownEvent(INPUTMGR_SELECT) && section == 3) {
515 if (section2 == 1) {
516 GUIEventCallback_OnEvent(imageManager, renderer, cmdBack->name, cmdBack, GUIEventClick);
517 } else if (section2 == 2) {
518 GUIEventCallback_OnEvent(imageManager, renderer, cmdSave->name, cmdSave, GUIEventClick);
519 }
520 }
521 }
522 }
523
524 //Process mouse event only when it's not keyboard only mode.
525 if (!isKeyboardOnly) {
526 //Get the x and y location of the mouse.
527 int x, y;
528 SDL_GetMouseState(&x, &y);
529
530 //Check icon.
531 if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN){
532 if (y >= SCREEN_HEIGHT - 56 && y < SCREEN_HEIGHT - 8 && x >= SCREEN_WIDTH - 56)
533 clearIconHower = true;
534 else
535 clearIconHower = false;
536 }
537 }
538
539 //Update highlight on keyboard only mode.
540 if (isKeyboardOnly) {
541 cmdBack->state = (section == 3 && section2 == 1) ? 1 : 0;
542 cmdSave->state = (section == 3 && section2 == 2) ? 1 : 0;
543 clearIconHower = (section == 3 && section2 == 3);
544 }
545
546 if ((isKeyboardOnly ? inputMgr.isKeyDownEvent(INPUTMGR_SELECT) :
547 (event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT)) && clearIconHower)
548 {
549 if(msgBox(imageManager,renderer,_("Do you really want to reset level progress?"),MsgBoxYesNo,_("Warning"))==MsgBoxYes){
550 //We delete the progress folder.
551 #ifdef WIN32
552 removeDirectory((getUserPath()+"progress").c_str());
553 createDirectory((getUserPath()+"progress").c_str());
554 #else
555 removeDirectory((getUserPath(USER_DATA)+"/progress").c_str());
556 createDirectory((getUserPath(USER_DATA)+"/progress").c_str());
557 #endif
558 //Reset statistics.
559 statsMgr.reloadCompletedLevelsAndAchievements();
560 }
561 }
562
563 //Check if we need to quit, if so enter the exit state.
564 if(event.type==SDL_QUIT){
565 setNextState(STATE_EXIT);
566 }
567
568 //Check if the escape button is pressed, if so go back to the main menu.
569 if (inputMgr.isKeyDownEvent(INPUTMGR_ESCAPE) && (tabControls == NULL || !tabControls->visible)) {
570 setNextState(STATE_MENU);
571 }
572 }
573
logic(ImageManager &,SDL_Renderer &)574 void Options::logic(ImageManager&, SDL_Renderer&){
575 //Increase the lastJumpSound variable if needed.
576 if(lastJumpSound!=0){
577 lastJumpSound--;
578 }
579 }
580
render(ImageManager &,SDL_Renderer & renderer)581 void Options::render(ImageManager&, SDL_Renderer& renderer){
582 //Draw background.
583 objThemes.getBackground(true)->draw(renderer);
584 objThemes.getBackground(true)->updateAnimation();
585
586 //Now render the title.
587 drawTitleTexture(SCREEN_WIDTH, *title, renderer);
588
589 //Check if an icon is selected/highlighted and draw tooltip
590 if(clearIconHower){
591 const SDL_Rect texSize = rectFromTexture(*clearTooltip);
592 drawGUIBox(-2,SCREEN_HEIGHT-texSize.h-2,texSize.w+4,texSize.h+4,renderer,0xFFFFFFFF);
593 applyTexture(0,SCREEN_HEIGHT-texSize.h,clearTooltip,renderer);
594 }
595
596 //Draw border of icon if it's keyboard only mode.
597 if (isKeyboardOnly && clearIconHower) {
598 drawGUIBox(SCREEN_WIDTH - 52, SCREEN_HEIGHT - 52, 40, 40, renderer, 0xFFFFFF40);
599 }
600
601 //Draw icon.
602 applyTexture(SCREEN_WIDTH-48,SCREEN_HEIGHT-48,*clearIcon,renderer);
603
604 //NOTE: The rendering of the GUI is done in Main.
605 }
606
resize(ImageManager & imageManager,SDL_Renderer & renderer)607 void Options::resize(ImageManager& imageManager, SDL_Renderer& renderer){
608 //Recreate the gui to fit the new resolution.
609 createGUI(imageManager,renderer);
610 }
611