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