Page MenuHomePhabricator (Chris)

GUIListBox.cpp
No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None

GUIListBox.cpp

/****************************************************************************
** Copyright (C) 2011 Luka Horvat <redreaper132 at gmail.com>
** Copyright (C) 2011 Edward Lii <edward_iii at myway.com>
** Copyright (C) 2011 O. Bahri Gordebak <gordebak at gmail.com>
**
**
** This file may be used under the terms of the GNU General Public
** License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the GNU General Public License
** along with this program. 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):
GUIObject(left,top,width,height,0,NULL,-1,enabled,visible){
//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);
childControls.push_back(scrollBar);
}
bool GUIListBox::handleEvents(int x,int y,bool enabled,bool visible,bool processed){
//If there is a quit event cleanup and stop.
if(event.type==SDL_QUIT){
nextState=STATE_EXIT;
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
GUIEventQueue.clear();
return true;
}
//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-4)/24;
if(m>n){
scrollBar->max=m-n;
scrollBar->smallChange=1;
scrollBar->largeChange=n;
scrollBar->visible=true;
b=b||scrollBar->handleEvents(x,y,enabled,visible,b);
}else{
scrollBar->value=0;
scrollBar->max=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,k;
k=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/24+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+=4;
if(scrollBar->value > scrollBar->max)
scrollBar->value = scrollBar->max;
}else if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_WHEELUP && scrollBar->enabled){
scrollBar->value-=4;
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){
//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;
//Get the absolute x and y location.
x+=left;
y+=top;
//Set the rectangle to the size of the GUIListBox.
r.x=x;
r.y=y;
r.w=width;
r.h=height;
SDL_FillRect(screen,&r,0);
//Now shrink the rectangle by one pixel and fillRect with white.
//This will leave an one pixel border.
r.x=x+1;
r.y=y+1;
r.w=width-2;
r.h=height-2;
SDL_FillRect(screen,&r,-1);
//We need to draw the items.
//The number of items.
int m=item.size();
//The number of items that are visible.
int n=(height-4)/24;
//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 higer 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+2;i<m;i++,j+=24){
//The background color for the entry.
int clr=-1;
//If i is the selected entry then give it a light grey background.
if(value==i)
clr=SDL_MapRGB(screen->format,192,192,192);
//Set the rectangle of the entry.
r.x=x+2;
r.y=j;
r.w=width-4;
r.h=24;
//Check if the current entry is selected.
if(state==i){
//Selected means we draw a black border around
SDL_FillRect(screen,&r,0);
r.x+=1;
r.y+=1;
r.w-=2;
r.h-=2;
}
//Now fill the entry with the background clr.
SDL_FillRect(screen,&r,clr);
//Now draw the text.
const char* s=item[i].c_str();
//Make sure the text isn't empty.
if(s && s[0]){
//Render black text.
SDL_Color black={0,0,0,0};
SDL_Surface *bm=TTF_RenderText_Blended(fontSmall,s,black);
//Calculate the text location, center it vertically.
r.x=x+4;
r.y=j+12-bm->h/2;
//Draw the text and free the rendered surface.
SDL_BlitSurface(bm,NULL,screen,&r);
SDL_FreeSurface(bm);
}
}
//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);
}
}
GUISingleLineListBox::GUISingleLineListBox(int left,int top,int width,int height,bool enabled,bool visible):
GUIObject(left,top,width,height,0,NULL,-1,enabled,visible){}
bool GUISingleLineListBox::handleEvents(int x,int y,bool enabled,bool visible,bool processed){
//If there is a quit event cleanup and stop.
if(event.type==SDL_QUIT){
nextState=STATE_EXIT;
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
GUIEventQueue.clear();
return true;
}
//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;
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<16 && i<width/2){
//The left arrow.
idx=1;
}else if(i>=width-16){
//The right arrow.
idx=2;
}
}
//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){
//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;
//Get the absolute x and y location.
x+=left;
y+=top;
//Two colors, gray and lightgray.
int clr_lightgray=SDL_MapRGB(screen->format,192,192,192);
int clr_gray=SDL_MapRGB(screen->format,128,128,128);
//Draw the rectangle the size of the GUIObject black.
r.x=x;
r.y=y;
r.w=width;
r.h=height;
SDL_FillRect(screen,&r,0);
//Shrink the rectangle by one pixel and draw white leaving a one pixel border.
r.x=x+1;
r.y=y+1;
r.w=width-2;
r.h=height-2;
SDL_FillRect(screen,&r,-1);
//Draw the highlight.
if((state&0xF)==0x1){
r.w=15;
SDL_FillRect(screen,&r,(state&0xF0)?clr_gray:clr_lightgray);
}
if((state&0xF)==0x2){
r.x=x+width-16;
r.w=15;
SDL_FillRect(screen,&r,(state&0xF0)?clr_gray:clr_lightgray);
}
//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]){
//Render black text.
SDL_Color black={0,0,0,0};
SDL_Surface* bm=TTF_RenderText_Blended(fontSmall,lp,black);
//Center the text both vertically as horizontally.
r.x=x+(width-bm->w)/2;
r.y=y+(height-bm->h)/2;
//Draw the text and free the surface afterwards.
SDL_BlitSurface(bm,NULL,screen,&r);
SDL_FreeSurface(bm);
}
}
//Draw the arrows.
SDL_Rect r2={48,0,16,16};
r.x=x;
r.y=y+(height-16)/2;
SDL_BlitSurface(bmGUI,&r2,screen,&r);
r2.x=64;
r.x=x+width-16;
SDL_BlitSurface(bmGUI,&r2,screen,&r);
//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);
}
}

File Metadata

Mime Type
text/x-c++
Expires
Sat, Nov 14, 5:17 PM (12 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
139790
Default Alt Text
GUIListBox.cpp (10 KB)

Event Timeline