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