Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
30 KB
Referenced Files
None
Subscribers
None
diff --git a/src/GUIListBox.cpp b/src/GUIListBox.cpp
index 20785b0..6ca43ab 100644
--- a/src/GUIListBox.cpp
+++ b/src/GUIListBox.cpp
@@ -1,439 +1,445 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GUIListBox.h"
using namespace std;
GUIListBox::GUIListBox(int left,int top,int width,int height,bool enabled,bool visible,int gravity):
GUIObject(left,top,width,height,0,NULL,-1,enabled,visible,gravity),itemHeight(24),selectable(true){
//Set the state -1.
state=-1;
//Create the scrollbar and add it to the children.
- scrollBar=new GUIScrollBar(0,0,16,0,1,0,0,0,0,0,true,false);
+ scrollBar=new GUIScrollBar(width-16,0,16,height,1,0,0,0,1,1,true,true);
childControls.push_back(scrollBar);
}
GUIListBox::~GUIListBox(){
//Remove all items and cache.
clearItems();
//We need to delete every child we have.
for(unsigned int i=0;i<childControls.size();i++){
delete childControls[i];
}
//Deleted the childs now empty the childControls vector.
childControls.clear();
}
bool GUIListBox::handleEvents(int x,int y,bool enabled,bool visible,bool processed){
//Boolean if the event is processed.
bool b=processed;
//The GUIObject is only enabled when he and his parent are enabled.
enabled=enabled && this->enabled;
//The GUIObject is only enabled when he and his parent are enabled.
visible=visible && this->visible;
//Get the absolute position.
x+=left;
y+=top;
- //Calculate the scrollbar position.
- scrollBar->left=width-16;
- scrollBar->height=height;
- int m=item.size(),n=height/itemHeight;
- if(m>n){
- scrollBar->maxValue=m-n;
- scrollBar->smallChange=1;
- scrollBar->largeChange=n;
- scrollBar->visible=true;
+ //Update the scrollbar.
+ if(scrollBar->visible)
b=b||scrollBar->handleEvents(x,y,enabled,visible,b);
- }else{
- scrollBar->value=0;
- scrollBar->maxValue=0;
- scrollBar->visible=false;
- }
//Set state negative.
state=-1;
//Check if the GUIListBox is visible, enabled and no event has been processed before.
if(enabled&&visible&&!b){
//The mouse location (x=i, y=j) and the mouse button (k).
int i,j;
SDL_GetMouseState(&i,&j);
//Convert the mouse location to a relative location.
i-=x+2;
j-=y+2;
//Check if the mouse is inside the GUIListBox.
if(i>=0&&i<width-4&&j>=0&&j<height-4){
//Calculate the y location with the scrollbar position.
int idx=j/itemHeight+scrollBar->value;
//If the entry isn't above the max we have an event.
if(idx>=0&&idx<(int)item.size()){
state=idx;
//Check if the left mouse button is pressed.
if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT && value!=idx){
value=idx;
//If event callback is configured then add an event to the queue.
if(eventCallback){
GUIEvent e={eventCallback,name,this,GUIEventClick};
GUIEventQueue.push_back(e);
}
}
}
//Check for mouse wheel scrolling.
if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_WHEELDOWN && scrollBar->enabled){
scrollBar->value++;
if(scrollBar->value>scrollBar->maxValue)
scrollBar->value=scrollBar->maxValue;
}else if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_WHEELUP && scrollBar->enabled){
scrollBar->value--;
if(scrollBar->value<0)
scrollBar->value=0;
}
}
}
//Process child controls event except for the scrollbar.
//That's why i starts at one.
for(unsigned int i=1;i<childControls.size();i++){
bool b1=childControls[i]->handleEvents(x,y,enabled,visible,b);
//The event is processed when either our or the childs is true (or both).
b=b||b1;
}
return b;
}
void GUIListBox::render(int x,int y,bool draw){
+ if(updateScrollbar){
+ //Calculate the height of the content.
+ int maxY;
+ for(int i=0;i<images.size();i++){
+ maxY+=images.at(i)->h;
+ }
+
+ //Check if we need to show the scrollbar for many entries.
+ if(maxY<height){
+ scrollBar->maxValue=0;
+ scrollBar->value=0;
+ scrollBar->visible=false;
+ }else{
+ scrollBar->visible=true;
+ scrollBar->maxValue=item.size();
+ int yy=0;
+ for(int i=images.size()-1;i>0;i--){
+ yy+=images.at(i)->h;
+ if(yy>height)
+ break;
+ else
+ scrollBar->maxValue--;
+ }
+ scrollBar->largeChange=item.size()/4;
+ }
+ updateScrollbar=false;
+ }
+
//Rectangle the size of the GUIObject, used to draw borders.
//SDL_Rect r; //Unused local variable :/
//There's no need drawing the GUIObject when it's invisible.
if(!visible||!draw)
return;
//Get the absolute x and y location.
x+=left;
y+=top;
//Draw the background box.
SDL_Rect r={x,y,width,height};
SDL_FillRect(screen,&r,0xFFFFFFFF);
- //We need to draw the items.
- //The number of items.
- int m=item.size();
- //The number of items that are visible.
- int n=(int)floor((float)height/(float)itemHeight)+1;
- //Integer containing the current entry that is being drawn.
- int i;
- //The y coordinate the current entries reaches.
- int j;
-
- //If the number of items is higher than fits on the screen set the begin value (m) to scrollBar->value+n.
- if(m>scrollBar->value+n)
- m=scrollBar->value+n;
-
- //Loop through the (visible) entries and draw them.
- for(i=scrollBar->value,j=y+1;j>height,i<m;i++,j+=itemHeight){
+ //Loop through the entries and draw them.
+ for(int i=scrollBar->value,j=y+1;j>height,i<item.size();i++){
//Check if the current item is out side of the widget.
- int yOver=itemHeight;
+ int yOver=images[i]->h;
if(j+images[i]->h>y+height)
yOver=y+height-j;
if(yOver>0){
if(selectable){
//Check if the mouse is hovering on current entry. If so draw borders around it.
if(state==i)
drawGUIBox(x,j-1,width,yOver+1,screen,0x00000000);
//Check if the current entry is selected. If so draw a gray background.
if(value==i)
drawGUIBox(x,j-1,width,yOver+1,screen,0xDDDDDDFF);
}
//Draw the image.
SDL_Rect clip;
clip.x=0;
clip.y=0;
clip.w=images[i]->w;
- clip.h=yOver-2;
+ clip.h=yOver;
applySurface(x,j,images[i],screen,&clip);
+ }else{
+ break;
}
+ j+=images[i]->h;
}
//Draw borders around the whole thing.
drawGUIBox(x,y,width,height,screen,0x00000000);
//We now need to draw all the children of the GUIObject.
for(unsigned int i=0;i<childControls.size();i++){
childControls[i]->render(x,y,draw);
}
}
void GUIListBox::clearItems(){
item.clear();
for(unsigned int i=0;i<images.size();i++){
SDL_FreeSurface(images[i]);
}
images.clear();
}
void GUIListBox::addItem(std::string name, SDL_Surface* image){
item.push_back(name);
if(image){
itemHeight=image->h;
images.push_back(image);
}else if(!image&&!name.empty()){
SDL_Color black={0,0,0,0};
SDL_Surface* tmp=TTF_RenderUTF8_Blended(fontText,name.c_str(),black);
images.push_back(tmp);
}
- //Update scrollbar state.
- handleEvents();
+ updateScrollbar=true;
}
void GUIListBox::updateItem(int index, std::string newText, SDL_Surface* newImage){
item.at(index)=newText;
if(newImage){
itemHeight=newImage->h;
SDL_FreeSurface(images.at(index));
images.at(index)=newImage;
}else if(!newImage&&!newText.empty()){
SDL_FreeSurface(images.at(index));
SDL_Color black={0,0,0,0};
SDL_Surface* tmp=TTF_RenderUTF8_Blended(fontText,newText.c_str(),black);
images.at(index)=tmp;
}
+
+ updateScrollbar=true;
}
std::string GUIListBox::getItem(int index){
return item.at(index);
}
GUISingleLineListBox::GUISingleLineListBox(int left,int top,int width,int height,bool enabled,bool visible,int gravity):
GUIObject(left,top,width,height,0,NULL,-1,enabled,visible,gravity),animation(0){}
bool GUISingleLineListBox::handleEvents(int x,int y,bool enabled,bool visible,bool processed){
//Boolean if the event is processed.
bool b=processed;
//The GUIObject is only enabled when he and his parent are enabled.
enabled=enabled && this->enabled;
//The GUIObject is only enabled when he and his parent are enabled.
visible=visible && this->visible;
//Get the absolute position.
x+=left-gravityX;
y+=top;
state&=~0xF;
if(enabled&&visible){
//The mouse location (x=i, y=j) and the mouse button (k).
int i,j,k;
k=SDL_GetMouseState(&i,&j);
//Convert the mouse location to a relative location.
i-=x;
j-=y;
//The selected button.
//0=nothing 1=left 2=right.
int idx=0;
//Check which button the mouse is above.
if(i>=0&&i<width&&j>=0&&j<height){
if(i<26 && i<width/2){
//The left arrow.
idx=1;
}else if(i>=width-26){
//The right arrow.
idx=2;
}
}
//If idx is 0 it means the mous doesn't hover any arrow so reset animation.
if(idx==0)
animation=0;
//Check if there's a mouse button press or not.
if(k&SDL_BUTTON(1)){
if(((state>>4)&0xF)==idx)
state|=idx;
}else{
state|=idx;
}
//Check if there's a mouse press.
if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT && idx){
state=idx|(idx<<4);
}else if(event.type==SDL_MOUSEBUTTONUP && event.button.button==SDL_BUTTON_LEFT && idx && ((state>>4)&0xF)==idx){
int m=(int)item.size();
if(m>0){
if(idx==2){
idx=value+1;
if(idx<0||idx>=m) idx=0;
if(idx!=value){
value=idx;
//If there is an event callback then call it.
if(eventCallback){
GUIEvent e={eventCallback,name,this,GUIEventClick};
GUIEventQueue.push_back(e);
}
}
}else if(idx==1){
idx=value-1;
if(idx<0||idx>=m) idx=m-1;
if(idx!=value){
value=idx;
//If there is an event callback then call it.
if(eventCallback){
GUIEvent e={eventCallback,name,this,GUIEventClick};
GUIEventQueue.push_back(e);
}
}
}
}
}
if(event.type==SDL_MOUSEBUTTONUP) state&=0xF;
}else{
//Set state zero.
state=0;
}
//Also let the children handle their events.
for(unsigned int i=0;i<childControls.size();i++){
bool b1=childControls[i]->handleEvents(x,y,enabled,visible,b);
//The event is processed when either our or the childs is true (or both).
b=b||b1;
}
return b;
}
void GUISingleLineListBox::render(int x,int y,bool draw){
//Rectangle the size of the GUIObject, used to draw borders.
SDL_Rect r;
//There's no need drawing the GUIObject when it's invisible.
if(!visible)
return;
//NOTE: logic in the render method since it's the only part that gets called every frame.
if((state&0xF)==0x1 || (state&0xF)==0x2){
animation++;
if(animation>20)
animation=-20;
}
//Get the absolute x and y location.
x+=left;
y+=top;
if(gravity==GUIGravityCenter)
gravityX=int(width/2);
else if(gravity==GUIGravityRight)
gravityX=width;
x-=gravityX;
//Check if the enabled state changed or the caption, if so we need to clear the (old) cache.
if(enabled!=cachedEnabled || item[value].compare(cachedCaption)!=0){
//Free the cache.
SDL_FreeSurface(cache);
cache=NULL;
//And cache the new values.
cachedEnabled=enabled;
cachedCaption=item[value];
}
//Draw the text.
if(value>=0 && value<(int)item.size()){
//Get the text.
const char* lp=item[value].c_str();
//Check if the text is empty or not.
if(lp!=NULL && lp[0]){
if(!cache){
SDL_Color color;
if(inDialog)
color=themeTextColorDialog;
else
color=themeTextColor;
cache=TTF_RenderUTF8_Blended(fontGUI,lp,color);
//If the text is too wide then we change to smaller font (?)
//NOTE: The width is 32px smaller (2x16px for the arrows).
if(cache->w>width-32){
SDL_FreeSurface(cache);
cache=TTF_RenderUTF8_Blended(fontGUISmall,lp,color);
}
}
if(draw){
//Center the text both vertically as horizontally.
r.x=x+(width-cache->w)/2;
r.y=y+(height-cache->h)/2-GUI_FONT_RAISE;
//Draw the text and free the surface afterwards.
SDL_BlitSurface(cache,NULL,screen,&r);
}
}
}
if(draw){
//Draw the arrows.
SDL_Rect r2={48,0,16,16};
r.x=x;
if((state&0xF)==0x1)
r.x+=abs(animation/2);
r.y=y+4;
if(inDialog)
applySurface(r.x,r.y,arrowLeft2,screen,NULL);
else
applySurface(r.x,r.y,arrowLeft1,screen,NULL);
r.x=x+width-16;
if((state&0xF)==0x2)
r.x-=abs(animation/2);
if(inDialog)
applySurface(r.x,r.y,arrowRight2,screen,NULL);
else
applySurface(r.x,r.y,arrowRight1,screen,NULL);
}
//We now need to draw all the children of the GUIObject.
for(unsigned int i=0;i<childControls.size();i++){
childControls[i]->render(x,y,draw);
}
}
diff --git a/src/GUIListBox.h b/src/GUIListBox.h
index 869c3ce..ad1530d 100644
--- a/src/GUIListBox.h
+++ b/src/GUIListBox.h
@@ -1,118 +1,124 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GUILISTBOX_H
#define GUILISTBOX_H
#include "GUIObject.h"
#include "GUIScrollBar.h"
//GUIObject that displays a list.
//It extends GUIObject because it's a special GUIObject.
class GUIListBox:public GUIObject{
public:
//Vector containing the entries of the list.
std::vector<std::string> item;
std::vector<SDL_Surface*> images;
bool selectable;
private:
//Scrollbar used when there are more entries than fit on the screen.
GUIScrollBar* scrollBar;
+
+ //Boolean if update for scrollbar is needed.
+ bool updateScrollbar;
+
+ //Integer for height of a single item.
+ //TODO: Remove this variable and because different items can be different size.
int itemHeight;
public:
//Constructor.
//left: The relative x location of the GUIListBox.
//top: The relative y location of the GUIListBox.
//witdh: The width of the GUIListBox.
//height: The height of the GUIListBox.
//enabled: Boolean if the GUIListBox is enabled or not.
//visible: Boolean if the GUIListBox is visisble or not.
GUIListBox(int left=0,int top=0,int width=0,int height=0,bool enabled=true,bool visible=true,int gravity=GUIGravityLeft);
//Destructor
~GUIListBox();
//Method to remove all items and clear cache.
void clearItems();
//Method to add an item to the widget.
//name: Text of the item.
//image: Custom image for the widget, if NULL the image will be generated from name string.
void addItem(std::string name, SDL_Surface* image=NULL);
//Method to update an item in the widget.
//index: index of the item.
//newName: New text for the item.
//newImage: New custom image for the widget, if NULL the image will be generated from newName string.
void updateItem(int index, std::string newText, SDL_Surface* newImage=NULL);
//Method used the get item names from the widget.
//index: index of the item.
std::string getItem(int index);
//Method used to handle mouse and/or key events.
//x: The x mouse location.
//y: The y mouse location.
//enabled: Boolean if the parent is enabled or not.
//visible: Boolean if the parent is visible or not.
//processed: Boolean if the event has been processed (by the parent) or not.
//Returns: Boolean if the event is processed by the child.
virtual bool handleEvents(int x=0,int y=0,bool enabled=true,bool visible=true,bool processed=false);
//Method that will render the GUIListBox.
//x: The x location to draw the GUIListBox. (x+left)
//y: The y location to draw the GUIListBox. (y+top)
virtual void render(int x=0,int y=0,bool draw=true);
};
//GUIObject that displays a list on only one line.
//Instead of clicking the entries of the list you iterate through them.
//It extends GUIObject because it's a special GUIObject.
class GUISingleLineListBox:public GUIObject{
public:
//Vector containing the entries of the list.
std::vector<std::string> item;
//Integer used for the animation of the arrow.
int animation;
public:
//Constructor.
//left: The relative x location of the GUIListBox.
//top: The relative y location of the GUIListBox.
//witdh: The width of the GUIListBox.
//height: The height of the GUIListBox.
//enabled: Boolean if the GUIListBox is enabled or not.
//visible: Boolean if the GUIListBox is visisble or not.
GUISingleLineListBox(int left=0,int top=0,int width=0,int height=0,bool enabled=true,bool visible=true,int gravity=GUIGravityLeft);
//Method used to handle mouse and/or key events.
//x: The x mouse location.
//y: The y mouse location.
//enabled: Boolean if the parent is enabled or not.
//visible: Boolean if the parent is visible or not.
//processed: Boolean if the event has been processed (by the parent) or not.
//Returns: Boolean if the event is processed by the child.
virtual bool handleEvents(int x=0,int y=0,bool enabled=true,bool visible=true,bool processed=false);
//Method that will render the GUIListBox.
//x: The x location to draw the GUIListBox. (x+left)
//y: The y location to draw the GUIListBox. (y+top)
virtual void render(int x=0,int y=0,bool draw=true);
};
#endif
diff --git a/src/StatisticsScreen.cpp b/src/StatisticsScreen.cpp
index 8b1d46b..2bc848e 100644
--- a/src/StatisticsScreen.cpp
+++ b/src/StatisticsScreen.cpp
@@ -1,350 +1,354 @@
/*
* Copyright (C) 2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include "StatisticsManager.h"
#include "StatisticsScreen.h"
#include "Globals.h"
#include "Functions.h"
#include "ThemeManager.h"
#include "InputManager.h"
#include "GUIListBox.h"
#include "GUIScrollBar.h"
#ifdef __APPLE__
#include <SDL_image/SDL_image.h>
#include <SDL_gfx/SDL_gfxPrimitives.h>
#else
#include <SDL/SDL_image.h>
#include <SDL/SDL_gfxPrimitives.h>
#endif
using namespace std;
//GUI events are handled here.
//name: The name of the element that invoked the event.
//obj: Pointer to the object that invoked the event.
//eventType: Integer containing the type of event.
void StatisticsScreen::GUIEventCallback_OnEvent(std::string name,GUIObject* obj,int eventType){
//Check what type of event it was.
if(eventType==GUIEventClick){
if(name=="cmdBack"){
//Goto the main menu.
setNextState(STATE_MENU);
}
}
}
#define DRAW_PLAYER_STATISTICS(name,var,format) { \
surface=TTF_RenderUTF8_Blended(fontGUISmall,name,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(0,y,surface,stats,NULL); \
y+=(h1=surface->h); \
SDL_FreeSurface(surface); \
sprintf(s,format,statsMgr.player##var+statsMgr.shadow##var); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(400-surface->w,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
sprintf(s,format,statsMgr.player##var); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(520-surface->w,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
sprintf(s,format,statsMgr.shadow##var); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(640-surface->w,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
}
#define DRAW_MISC_STATISTICS_1(name1,var1,format1) { \
surface=TTF_RenderUTF8_Blended(fontGUISmall,name1,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(0,y,surface,stats,NULL); \
x=surface->w+8; \
y+=(h1=surface->h); \
SDL_FreeSurface(surface); \
sprintf(s,format1,statsMgr.var1); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
}
//we are so lazy that we just use height of the first one, ignore second one
#define DRAW_MISC_STATISTICS_2(name1,var1,format1,name2,var2,format2) { \
surface=TTF_RenderUTF8_Blended(fontGUISmall,name1,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(0,y,surface,stats,NULL); \
x=surface->w+8; \
y+=(h1=surface->h); \
SDL_FreeSurface(surface); \
sprintf(s,format1,statsMgr.var1); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
surface=TTF_RenderUTF8_Blended(fontGUISmall,name2,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(320,y-surface->h,surface,stats,NULL); \
x=surface->w+328; \
SDL_FreeSurface(surface); \
sprintf(s,format2,statsMgr.var2); \
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor); \
SDL_SetAlpha(surface,0,0xFF); \
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL); \
SDL_FreeSurface(surface); \
}
//Constructor.
StatisticsScreen::StatisticsScreen(){
//Update in-game time.
statsMgr.updatePlayTime();
//Load needed pictures.
//Note: we don't use ImageManager because we need to process these pictures.
SDL_Surface* bmPlayer=IMG_Load((getDataPath()+"themes/Cloudscape/characters/player.png").c_str());
SDL_Surface* bmShadow=IMG_Load((getDataPath()+"themes/Cloudscape/characters/shadow.png").c_str());
SDL_Surface* bmMedal=IMG_Load((getDataPath()+"gfx/medals.png").c_str());
//Disable the alpha channel.
SDL_SetAlpha(bmPlayer,0,0xFF);
SDL_SetAlpha(bmShadow,0,0xFF);
SDL_SetAlpha(bmMedal,0,0xFF);
//Render the title.
title=TTF_RenderUTF8_Blended(fontTitle,_("Achievements and Statistics"),themeTextColor);
//Render stats.
stats=SDL_CreateRGBSurface(SDL_SWSURFACE,640,400,32,RMASK,GMASK,BMASK,AMASK);
char s[64];
SDL_Surface *surface;
SDL_Rect r;
int x,y=0,h1;
Uint32 clr=SDL_MapRGB(stats->format,themeTextColor.r,themeTextColor.g,themeTextColor.b);
//Player and shadow specific statistics
surface=TTF_RenderUTF8_Blended(fontGUISmall,_("Total"),themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(400-surface->w,40-surface->h,surface,stats,NULL);
SDL_FreeSurface(surface);
r.x=0;r.y=0;r.w=23;r.h=40;
applySurface(520-r.w,0,bmPlayer,stats,&r);
applySurface(640-r.w,0,bmShadow,stats,&r);
y+=40;
DRAW_PLAYER_STATISTICS(_("Traveling distance (m)"),TravelingDistance,"%0.2f");
DRAW_PLAYER_STATISTICS(_("Jump times"),Jumps,"%d");
DRAW_PLAYER_STATISTICS(_("Die times"),Dies,"%d");
DRAW_PLAYER_STATISTICS(_("Squashed times"),Squashed,"%d");
//Game specific statistics.
r.x=0;r.y=y;r.w=stats->w;r.h=2;
SDL_FillRect(stats,&r,clr);
y+=2;
DRAW_MISC_STATISTICS_2(_("Recordings:"),recordTimes,"%d",_("Switch pulled times:"),switchTimes,"%d");
DRAW_MISC_STATISTICS_1(_("Swap times:"),swapTimes,"%d");
DRAW_MISC_STATISTICS_2(_("Save times:"),saveTimes,"%d",_("Load times:"),loadTimes,"%d");
//Level specific statistics
r.x=0;r.y=y;r.w=stats->w;r.h=2;
SDL_FillRect(stats,&r,clr);
y+=2;
surface=TTF_RenderUTF8_Blended(fontGUISmall,_("Completed levels:"),themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(0,y,surface,stats,NULL);
x=surface->w+8;
y+=(h1=surface->h);
SDL_FreeSurface(surface);
sprintf(s,"%d",statsMgr.completedLevels);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL);
SDL_FreeSurface(surface);
sprintf(s,"%d",statsMgr.completedLevels-statsMgr.goldLevels-statsMgr.silverLevels);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(400-surface->w,y-(surface->h+h1)/2,surface,stats,NULL);
r.x=0;r.y=0;r.w=30;r.h=30;
applySurface(400-surface->w-30,y-(30+h1)/2,bmMedal,stats,&r);
SDL_FreeSurface(surface);
sprintf(s,"%d",statsMgr.silverLevels);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(520-surface->w,y-(surface->h+h1)/2,surface,stats,NULL);
r.x+=30;
applySurface(520-surface->w-30,y-(30+h1)/2,bmMedal,stats,&r);
SDL_FreeSurface(surface);
sprintf(s,"%d",statsMgr.goldLevels);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(640-surface->w,y-(surface->h+h1)/2,surface,stats,NULL);
r.x+=30;
applySurface(640-surface->w-30,y-(30+h1)/2,bmMedal,stats,&r);
SDL_FreeSurface(surface);
//Other statistics.
r.x=0;r.y=y;r.w=stats->w;r.h=2;
SDL_FillRect(stats,&r,clr);
y+=2;
surface=TTF_RenderUTF8_Blended(fontGUISmall,_("In-game time:"),themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(0,y,surface,stats,NULL);
x=surface->w+8;
y+=(h1=surface->h);
SDL_FreeSurface(surface);
sprintf(s,"%02d:%02d:%02d",statsMgr.playTime/3600,(statsMgr.playTime/60)%60,statsMgr.playTime%60);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL);
SDL_FreeSurface(surface);
surface=TTF_RenderUTF8_Blended(fontGUISmall,_("Level editing time:"),themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(320,y-surface->h,surface,stats,NULL);
x=surface->w+328;
SDL_FreeSurface(surface);
sprintf(s,"%02d:%02d:%02d",statsMgr.levelEditTime/3600,(statsMgr.levelEditTime/60)%60,statsMgr.levelEditTime%60);
surface=TTF_RenderUTF8_Blended(fontText,s,themeTextColor);
SDL_SetAlpha(surface,0,0xFF);
applySurface(x,y-(surface->h+h1)/2,surface,stats,NULL);
SDL_FreeSurface(surface);
DRAW_MISC_STATISTICS_1(_("Created levels:"),createdLevels,"%d");
//Free loaded surface.
SDL_FreeSurface(bmPlayer);
SDL_FreeSurface(bmShadow);
SDL_FreeSurface(bmMedal);
//Create GUI.
createGUI();
}
//Destructor.
StatisticsScreen::~StatisticsScreen(){
//Delete the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//Free images.
SDL_FreeSurface(title);
SDL_FreeSurface(stats);
}
//Method that will create the GUI for the options menu.
void StatisticsScreen::createGUI(){
//Create the root element of the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
GUIObjectRoot=new GUIObject(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,GUIObjectNone);
//Create back button.
GUIObject* obj=new GUIObject(SCREEN_WIDTH*0.5,SCREEN_HEIGHT-60,-1,36,GUIObjectButton,_("Back"),0,true,true,GUIGravityCenter);
obj->name="cmdBack";
obj->eventCallback=this;
GUIObjectRoot->addChild(obj);
//Create list box.
listBox=new GUISingleLineListBox((SCREEN_WIDTH-500)/2,104,500,32);
listBox->item.push_back(_("Achievements"));
listBox->item.push_back(_("Statistics"));
listBox->value=0;
GUIObjectRoot->addChild(listBox);
list=new GUIListBox(64,150,SCREEN_WIDTH-128,SCREEN_HEIGHT-150-72);
list->selectable=false;
GUIObjectRoot->addChild(list);
for(int idx=0;achievementList[idx].id!=NULL;++idx){
time_t *lpt=NULL;
map<string,OwnedAchievement>::iterator it=statsMgr.achievements.find(achievementList[idx].id);
if(it!=statsMgr.achievements.end()){
lpt=&it->second.achievedTime;
}
SDL_Rect r;
r.x=r.y=0;
r.w=list->width-16;
SDL_Surface *surface=statsMgr.createAchievementSurface(&achievementList[idx],NULL,&r,false,lpt);
- if(surface!=NULL)
+ if(surface!=NULL){
+ hlineRGBA(surface,0,surface->w,0,0,0,0,32);
+ hlineRGBA(surface,0,surface->w,surface->h-1,0,0,0,128);
+ hlineRGBA(surface,0,surface->w,surface->h-2,0,0,0,32);
list->addItem("",surface);
+ }
}
}
//In this method all the key and mouse events should be handled.
//Note: The GUIEvents won't be handled here.
void StatisticsScreen::handleEvents(){
//Check if we need to quit, if so enter the exit state.
if(event.type==SDL_QUIT){
setNextState(STATE_EXIT);
}
//Check if the escape button is pressed, if so go back to the main menu.
if(inputMgr.isKeyUpEvent(INPUTMGR_ESCAPE)){
setNextState(STATE_MENU);
}
}
//All the logic that needs to be done should go in this method.
void StatisticsScreen::logic(){
}
//This method handles all the rendering.
void StatisticsScreen::render(){
//Draw background.
objThemes.getBackground(true)->draw(screen);
objThemes.getBackground(true)->updateAnimation();
//Draw title.
applySurface((SCREEN_WIDTH-title->w)/2,40-TITLE_FONT_RAISE,title,screen,NULL);
//Draw statistics.
if(listBox->value==1){
list->visible=false;
applySurface((SCREEN_WIDTH-stats->w)/2,144,stats,screen,NULL);
}else{
list->visible=true;
}
}
//Method that will be called when the screen size has been changed in runtime.
void StatisticsScreen::resize(){
//Recreate the gui to fit the new resolution.
createGUI();
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 16, 7:22 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
64186
Default Alt Text
(30 KB)

Event Timeline