]> git.jsancho.org Git - lugaru.git/blob - Source/Menu.cpp
major refactor of menu system, part 1
[lugaru.git] / Source / Menu.cpp
1 #include <vector>
2 #include <string>
3 #include "gamegl.h"
4
5 #include "Menu.h"
6 using namespace Menu;
7
8 extern float multiplier;
9
10 struct MenuItem {
11     enum MenuItemType{NONE,LABEL,BUTTON,IMAGE,IMAGEBUTTON,MAPMARKER,MAPLINE,MAPLABEL} type;
12     int id;
13     string label;
14     int texture;
15     MBCallback cb;
16     int x,y,w,h;
17     float r,g,b;
18     float effectfade;
19
20     XYZ linestart;
21     XYZ lineend;
22     float linestartsize;
23     float lineendsize;
24
25     MenuItem(MenuItemType _type, int _id, const string& _label, int _texture, MBCallback _cb,
26             int _x, int _y, int _w, int _h, float _r, float _g, float _b):
27         type(_type),id(_id),label(_label),texture(_texture),cb(_cb),
28         x(_x),y(_y),w(_w),h(_h),r(_r),g(_g),b(_b),effectfade(0) {
29         if(type==MenuItem::BUTTON){
30             if(w==-1)
31                 w=label.length()*10;
32             if(h==-1)
33                 h=20;
34         }
35     }
36     MenuItem(const XYZ& start, const XYZ& end, float startsize, float endsize, float _r, float _g, float _b):
37         type(MAPLINE),id(-1),label(""),r(_r),g(_g),b(_b),
38         linestart(start),lineend(end),linestartsize(startsize),lineendsize(endsize) { }
39 };
40
41 vector<MenuItem> items;
42
43
44
45
46 void Menu::GUITick(Game* game){
47     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++){
48                 if(it->id==game->selected){
49                         it->effectfade+=multiplier*5;
50                         if(it->effectfade>1)
51                 it->effectfade=1;
52                 }else{
53                         it->effectfade-=multiplier*5;
54                         if(it->effectfade<0)
55                 it->effectfade=0;       
56                 }        
57     }
58 }
59
60 void Menu::clearMenu(){
61     items.clear();
62 }
63
64 void Menu::addLabel(int id,const string& label,int x,int y){
65     items.push_back(MenuItem(MenuItem::LABEL,id,label,0,NULL,x,y,-1,-1,1,0,0));
66 }
67 void Menu::addButton(int id,const string& label,MBCallback cb,int x,int y,int w,int h){
68     items.push_back(MenuItem(MenuItem::BUTTON,id,label,0,cb,x,y,w,h,1,0,0));
69 }
70 void Menu::addButton(int id,const string& label,MBCallback cb,int x,int y,int w,int h,float r,float g,float b){
71     items.push_back(MenuItem(MenuItem::BUTTON,id,label,0,cb,x,y,w,h,r,g,b));
72 }
73 void Menu::addImage(int id,int texture,int x,int y,int w,int h){
74     items.push_back(MenuItem(MenuItem::IMAGE,id,"",texture,NULL,x,y,w,h,1,1,1));
75 }
76 void Menu::addImageButton(int id,int texture,MBCallback cb,int x,int y,int w,int h){
77     items.push_back(MenuItem(MenuItem::IMAGEBUTTON,id,"",texture,cb,x,y,w,h,1,1,1));
78 }
79 void Menu::addImageButton(int id,int texture,MBCallback cb,int x,int y,int w,int h,float r,float g,float b){
80     items.push_back(MenuItem(MenuItem::IMAGEBUTTON,id,"",texture,cb,x,y,w,h,r,g,b));
81 }
82 void Menu::addMapLine(const XYZ& start, const XYZ& end, float startsize, float endsize, float r,float g,float b){
83     items.push_back(MenuItem(start,end,startsize,endsize,r,g,b));
84 }
85 void Menu::addMapMarker(int id,int texture,MBCallback cb,int x,int y,int w,int h,float r,float g,float b){
86     items.push_back(MenuItem(MenuItem::MAPMARKER,id,"",texture,cb,x,y,w,h,r,g,b));
87 }
88
89 void Menu::setMapItem(int id){
90     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++)
91         if(it->id==id){
92             if(it->type==MenuItem::LABEL)
93                 it->type=MenuItem::MAPLABEL;
94             break;
95         }
96 }
97
98 void Menu::setButtonText(int id,const string& label){
99     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++)
100         if(it->id==id){
101             it->label=label;
102             it->w=it->label.length()*10;
103             break;
104         }
105 }
106
107 void Menu::setButtonText(int id,const string& label,int x,int y,int w,int h){
108     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++)
109         if(it->id==id){
110             it->label=label;
111             it->x=x;
112             it->y=y;
113             if(w==-1)
114                 it->w=it->label.length()*10;
115             if(h==-1)
116                 it->h=20;
117             break;
118         }
119 }
120
121 int Menu::getSelected(int mousex, int mousey){
122     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++)
123         if(it->type==MenuItem::BUTTON || it->type==MenuItem::IMAGEBUTTON || it->type==MenuItem::MAPMARKER){
124             int mx=mousex;
125             int my=mousey;
126             if(it->type==MenuItem::MAPMARKER){
127                 mx-=1;
128                 my+=2;
129             }
130             if(mx>=it->x && mx<it->x+it->w && my>=it->y && my<it->y+it->h)
131                 return it->id;
132         }
133     return -1;
134 }
135
136 void Menu::drawItems(Game* game){
137     glEnable(GL_TEXTURE_2D);
138     glEnable(GL_ALPHA_TEST);
139     glEnable(GL_BLEND);
140     for(vector<MenuItem>::iterator it=items.begin();it!=items.end();it++){
141         switch(it->type){
142         case MenuItem::IMAGE:
143         case MenuItem::IMAGEBUTTON:
144         case MenuItem::MAPMARKER:
145             glColor4f(it->r,it->g,it->b,1);
146             glPushMatrix();
147             if(it->type==MenuItem::MAPMARKER){
148                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
149                 glTranslatef(2,-5,0); //from old code
150             }else{
151                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
152             }
153             glBindTexture(GL_TEXTURE_2D,it->texture);
154                         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
155                         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
156             glBegin(GL_QUADS);
157             glTexCoord2f(0,0);
158             glVertex3f(it->x,it->y,0);
159             glTexCoord2f(1,0);
160             glVertex3f(it->x+it->w,it->y,0);
161             glTexCoord2f(1,1);
162             glVertex3f(it->x+it->w,it->y+it->h,0);
163             glTexCoord2f(0,1);
164             glVertex3f(it->x,it->y+it->h,0);
165             glEnd();
166             if(it->type!=MenuItem::IMAGE){
167                 //mouseover highlight
168                 for(int i=0;i<10;i++){
169                     if(1-((float)i)/10-(1-it->effectfade)>0){
170                         glColor4f(it->r,it->g,it->b,(1-((float)i)/10-(1-it->effectfade))*.25);
171                         glBegin(GL_QUADS);
172                         glTexCoord2f(0,0);
173                         glVertex3f(it->x-((float)i)*1/2, it->y-((float)i)*1/2, 0);
174                         glTexCoord2f(1,0);
175                         glVertex3f(it->x+it->w+((float)i)*1/2, it->y-((float)i)*1/2, 0);
176                         glTexCoord2f(1,1);
177                         glVertex3f(it->x+it->w+((float)i)*1/2, it->y+it->h+((float)i)*1/2, 0);
178                         glTexCoord2f(0,1);
179                         glVertex3f(it->x-((float)i)*1/2, it->y+it->h+((float)i)*1/2, 0);
180                         glEnd();
181                     }
182                 }
183             }
184             glPopMatrix();
185             break;
186         case MenuItem::LABEL:
187         case MenuItem::BUTTON:
188             glColor4f(it->r,it->g,it->b,1);
189             glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
190             game->text.glPrint(it->x,it->y,it->label.c_str(),0,1,640,480);
191             if(it->type!=MenuItem::LABEL){
192                 //mouseover highlight
193                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
194                 for(int i=0;i<15;i++){
195                     if(1-((float)i)/15-(1-it->effectfade)>0){
196                         glColor4f(it->r,it->g,it->b,(1-((float)i)/10-(1-it->effectfade))*.25);
197                         game->text.glPrint(it->x-((float)i),it->y,it->label.c_str(),0,1+((float)i)/70,640,480);
198                     }
199                 }
200             }
201             break;
202         case MenuItem::MAPLABEL:
203             game->text.glPrintOutlined(0.9,0,0,it->x,it->y,it->label.c_str(),0,0.6,640,480);
204             break;
205         case MenuItem::MAPLINE: {
206             XYZ linestart=it->linestart;
207             XYZ lineend=it->lineend;
208             XYZ offset=lineend-linestart;
209             XYZ fac=offset;
210             Normalise(&fac);
211             offset=DoRotation(offset,0,0,90);
212             Normalise(&offset);
213
214             linestart+=fac*4*it->linestartsize;
215             lineend-=fac*4*it->lineendsize;
216
217             glDisable(GL_TEXTURE_2D);                                                   
218             glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
219             glColor4f(it->r,it->g,it->b,1);
220             glPushMatrix();
221             glTranslatef(2,-5,0); //from old code
222             glBegin(GL_QUADS);
223             glVertex3f(linestart.x-offset.x*it->linestartsize,  linestart.y-offset.y*it->linestartsize,          0.0f);
224             glVertex3f(linestart.x+offset.x*it->linestartsize,  linestart.y+offset.y*it->linestartsize,          0.0f);
225             glVertex3f(lineend.x+offset.x*it->lineendsize,              lineend.y+offset.y*it->lineendsize, 0.0f);
226             glVertex3f(lineend.x-offset.x*it->lineendsize,              lineend.y-offset.y*it->lineendsize, 0.0f);
227             glEnd();
228             glPopMatrix();
229             glEnable(GL_TEXTURE_2D);
230             } break;
231         }
232     }
233 }
234