1 /***************************************************************************
2  * Brutal Chess
3  * http://brutalchess.sf.net
4  *
5  * File : menuitem.cpp
6  * Authors : Mike Cook, Joe Flint, Neil Pankey
7  **************************************************************************/
8 
9 #include "fontloader.h"
10 #include "menu.h"
11 #include "menuitem.h"
12 #include "SDL.h"
13 
14 #include <iostream>
15 #include <string>
16 
17 using namespace std;
18 
drawText(const string & text)19 void drawText(const string & text)
20 {
21 	glScaled(1/1000.0, 1/1000.0, 1/1000.0);
22 	FontLoader::print(0, 0, text.c_str());
23 	glScaled(1000, 1000, 1000);
24 }
25 
draw(float a)26 void MenuItem::draw(float a)
27 {
28     // If the MenuItem isn't hovered, only draw the text.
29     if (!m_is_hovered) {
30         drawText(m_label);
31         return;
32     }
33 
34     // Otherwise, see if its fading in our out and adjust appropriately.
35     double dist;
36     double scale;
37     if (m_state == HOVERIN || m_state == HOVEROUT || m_state == SELECTANIM) {
38         dist = m_slidetimer.value();
39         scale = m_scaletimer.value();
40         // If we're running the select animation, we need to scale.
41 		if (m_state == SELECTANIM) {
42 			drawHovered(a);
43             glScaled(scale, scale, 0.0);
44 		}
45         // If we're hovering out, we need to slide left.
46         //if (m_state == HOVEROUT)
47         //    glTranslated(dist, 0.0, 0.0);
48         drawHovered(a*m_alphatimer.value());
49         m_alphatimer++;
50         m_slidetimer++;
51         m_scaletimer++;
52         // If the timer is done, we reset the state to STILL, also
53         // if we are hovering out, we need to translate back to where
54         // we slid to (since we change the state here), and un-set
55         // m_is_hovered.
56         if (m_alphatimer.done()) {
57             if (m_state == HOVEROUT) {
58                 m_is_hovered = false;
59                 //glTranslated(-dist, 0.0, 0.0);
60             }
61             else if (m_state == SELECTANIM) {
62                 glScaled(1/scale, 1/scale, 0.0);
63                 hoverIn();
64             }
65             m_state = STILL;
66         }
67     }
68     else {
69         // If we aren't hovering in or out, just draw at the current
70         // alpha of the options set.
71         drawHovered(a);
72     }
73     // If we're hovering out then we've slid to the left some distance,
74     // we need to slide that distance back to the right.
75     //if (m_state == HOVEROUT)
76     //    glTranslated(-dist, 0.0, 0.0);
77     if (m_state == SELECTANIM)
78         glScaled(1/scale, 1/scale, 0.0);
79     glColor4f(0.0, 0.0, 0.0, 0.5*a);
80     drawText(m_label);
81 }
82 
onSelect()83 void MenuItem::onSelect()
84 {
85     m_state = SELECTANIM;
86     m_scaletimer = Timer(Timer::LOGARITHMIC);
87     m_scaletimer.setRange(1.0, 1.5);
88     m_scaletimer.setDuration(0.4);
89     m_scaletimer.start();
90 
91     m_alphatimer = Timer(Timer::LOGARITHMIC);
92     m_alphatimer.setRange(1.0, 0.0);
93     m_alphatimer.setDuration(0.4);
94     m_alphatimer.start();
95 }
96 
hoverIn()97 void MenuItem::hoverIn()
98 {
99     m_state = HOVERIN;
100     m_alphatimer = Timer(Timer::LOGARITHMIC);
101     m_alphatimer.setRange(0.0, 1.0);
102     m_alphatimer.setDuration(0.2);
103     m_alphatimer.start();
104     m_is_hovered = true;
105 }
106 
hoverOut()107 void MenuItem::hoverOut()
108 {
109     m_state = HOVEROUT;
110     m_alphatimer = Timer(Timer::LOGARITHMIC);
111     m_alphatimer.setRange(1.0, 0.0);
112     m_alphatimer.setDuration(0.3);
113     m_alphatimer.start();
114 
115     m_slidetimer = Timer(Timer::LOGARITHMIC);
116     m_slidetimer.setRange(0.0, -0.015);
117     m_slidetimer.setDuration(0.3);
118     m_slidetimer.start();
119 }
120 
121 // Draw the splash behind a hovered MenuItem.
drawHovered(const float a)122 void MenuItem::drawHovered(const float a)
123 {
124     const float width       =  0.645;
125     const float height      =  0.046;
126     const float xoffset     = -0.005;
127     const float yoffset     = -0.01;
128     const float fletchwidth =  0.005;
129 
130 	glEnable(GL_BLEND);
131 
132     // Draw the shaded splash background.
133     glTranslated(width/2.0 + xoffset, height/2.0 + yoffset, 0.0);
134     glBegin(GL_QUADS);
135 		glColor4f(0.0, 0.0, 0.0, 0.0*a);
136         glVertex2f( width/2.0, -height/2.0);
137         glVertex2f( width/2.0,  height/2.0);
138 		glColor4f(0.0, 0.0, 0.0, 0.2*a);
139         glVertex2f(-width/2.0,  height/2.0);
140         glVertex2f(-width/2.0, -height/2.0);
141     glEnd();
142 
143     // Draw the fletch at the left of the MenuItem.
144     glTranslated(-width/2.0, -height/2.0, 0.0);
145     glBegin(GL_QUADS);
146 		glColor4f(0.0, 0.0, 0.0, 0.5*a);
147         glVertex2f(-fletchwidth,   0.0);
148         glVertex2f(         0.0,   0.0);
149         glVertex2f(         0.0, height);
150         glVertex2f(-fletchwidth, height);
151     glEnd();
152     glTranslated(-xoffset, -yoffset, 0.0);
153 }
154 
155 // Send the event wit the specified code to the event handler.
sendUserEvent(int eventCode)156 void MenuItem::sendUserEvent(int eventCode)
157 {
158 	SDL_Event event;
159 	event.type = SDL_USEREVENT;
160 	event.user.code = eventCode;
161 	SDL_PushEvent(&event);
162 }
163 
164 // ******** ActionItem ********
onSelect()165 void ActionItem::onSelect()
166 {
167     MenuItem::onSelect();
168 	sendUserEvent(m_eventCode);
169 }
170 
171 // ******** ToggleItem ********
draw(float a)172 void ToggleItem::draw(float a)
173 {
174 	MenuItem::draw(a);
175 	glTranslated(0.4, 0.0, 0.0);
176 
177 	if (!m_is_on)
178 		glColor4f(0.0, 0.0, 0.0, 0.15*a);
179 	drawText("on");
180 
181 	glTranslated(0.1, 0.0, 0.0);
182 
183 	glColor4f(0.0, 0.0, 0.0, 0.5*a);
184 	if (m_is_on)
185 		glColor4f(0.0, 0.0, 0.0, 0.15*a);
186 	drawText("off");
187 
188 	glTranslated(-0.5, 0.0, 0.0);
189 }
190 
onSelect()191 void ToggleItem::onSelect()
192 {
193     MenuItem::onSelect();
194 	m_is_on = !m_is_on;
195 	sendUserEvent(m_eventCode);
196 }
197 
198 // ******** ChoicesItem ********
draw(float a)199 void ChoicesItem::draw(float a)
200 {
201 	MenuItem::draw(a);
202 	glTranslated(0.4, 0.0, 0.0);
203 	drawText((*m_currChoice).first);
204 	glTranslated(-0.4, 0.0, 0.0);
205 }
206 
onSelect()207 void ChoicesItem::onSelect()
208 {
209     MenuItem::onSelect();
210     ++m_currChoice;
211 	if (m_currChoice == m_choices.end())
212 		m_currChoice = m_choices.begin();
213 	sendUserEvent((*m_currChoice).second);
214 }
215 
addChoice(const string & choiceName,int eventCode)216 void ChoicesItem::addChoice(const string & choiceName, int eventCode)
217 {
218 	m_choices.push_back(make_pair(choiceName, eventCode));
219 	// Set the iterator to point to the first choice that we add.
220 	m_currChoice = m_choices.begin();
221 }
222 
getCurrentChoice() const223 string ChoicesItem::getCurrentChoice() const
224 {
225     return m_currChoice->first;
226 }
227 
setChoice(const std::string & choiceName)228 void ChoicesItem::setChoice(const std::string & choiceName)
229 {
230 	std::vector<std::pair<std::string, int> >::const_iterator ci;
231 	for(ci = m_choices.begin(); ci != m_choices.end(); ci++) {
232 		if( ci->first == choiceName ) {
233 			m_currChoice = ci;
234             this->sendUserEvent(ci->second);
235             return;
236 		}
237 	}
238 }
239 
240 // ******** ChangeMenuItem ********
onSelect()241 void ChangeMenuItem::onSelect()
242 {
243     MenuItem::onSelect();
244 	m_parent->pushOptionsSet(m_menuname);
245 }
246 
247 // ******** SeparatorItem ********
draw(float a)248 void SeparatorItem::draw(float a)
249 {
250 	glBegin(GL_QUADS);
251 		glColor4f(0.0, 0.0, 0.0, 0.0*a);
252 		glVertex2f(0.0, 0.04);
253 		glVertex2f(0.6, 0.04);
254 		glVertex2f(0.6, 0.055);
255 		glColor4f(0.0, 0.0, 0.0, 0.3*a);
256 		glVertex2f(0.0, 0.055);
257 	glEnd();
258 
259 	glTranslated(0.0, 0.07, 0.0);
260 }
261 
262 // End of file menuitem.cpp
263 
264