1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12
13 ////////////////////////////////////////////////////
14 //
15 // Slider Bar functions
16 //
17 ////////////////////////////////////////////////////
18
Add(const SliderBarFloat & item)19 SliderBarFloat* SliderBarFloat::Add(const SliderBarFloat& item)
20 {
21 SliderBarFloat* pItem = new SliderBarFloat(item);
22
23 pItem->minus = HeldButton::Add(HeldButton(item.window, CVec3(item.x - (item.width - item.height) / 2, item.y, item.z + 0.01), CVec2(item.height, item.height), WhiteDarker, SliderBarFloat::Decrement, pItem));
24 pItem->plus = HeldButton::Add(HeldButton(item.window, CVec3(item.x + (item.width - item.height) / 2, item.y, item.z + 0.01), CVec2(item.height, item.height), WhiteDarker, SliderBarFloat::Increment, pItem));
25
26 item.window->menuItems.push_back(pItem);
27 return pItem;
28 }
29
Increment(void * data)30 void SliderBarFloat::Increment(void* data)
31 {
32 SliderBarFloat* bar = (SliderBarFloat*)data;
33
34 bar->pos += pow(10, -bar->decimals);
35
36 if (bar->pos > bar->max)
37 bar->pos = bar->max;
38
39 (*bar->target) = bar->pos;
40
41 bar->func(bar->funcExtra);
42 }
43
Decrement(void * data)44 void SliderBarFloat::Decrement(void* data)
45 {
46 SliderBarFloat* bar = (SliderBarFloat*)data;
47
48 bar->pos -= pow(10, -bar->decimals);
49
50 if (bar->pos < bar->min)
51 bar->pos = bar->min;
52
53 (*bar->target) = bar->pos;
54
55 bar->func(bar->funcExtra);
56 }
57
58 // Updates the slider bar
Update()59 bool SliderBarFloat::Update()
60 {
61 float totalDistance = this->max - this->min;
62
63 // In case something caused us to change
64 float diff = this->pos - *this->target;
65 if (diff > totalDistance / 1000 || diff < -totalDistance / 1000)
66 this->pos = *this->target;
67
68 /////////////////////////////////////////////////////////////////////////////////////////////
69 // The slider itself
70
71 if (!PositivePressed())
72 this->status = 0;
73
74 if (this->status == 2)
75 {
76 float x = CursorX() - this->oldX;
77 float t = x / (this->width - this->height * 3);
78 this->pos = (t + 0.5) * (max - min) + min;
79
80 // Cap it!
81 if (this->pos < min)
82 this->pos = min;
83
84 if (this->pos > max)
85 this->pos = max;
86
87 (*this->target) = this->pos;
88
89 this->func(this->funcExtra);
90
91 return true;
92 }
93
94 int status;
95
96 // We don't care as much if the cursor isn't being triggered
97 if (PositiveTriggered())
98 status = 2;
99 else
100 status = 1;
101
102 // Normalize it between -0.5 and 0.5
103 float t = (float)(this->pos - min) / (max - min) - 0.5;
104
105 // And scale it to find the center of the slider
106 float x = t * (this->width - this->height * 3);
107
108 // See if we just hit something
109 if (CursorColliding(this->x + x, this->y, this->height, this->height))
110 this->status = status;
111 else
112 this->status = 0;
113
114 if (this->status == 2)
115 this->oldX = CursorX() - x;
116
117 return (this->status == 0);
118 }
119
120 // Draws the slider bar
Draw()121 void SliderBarFloat::Draw()
122 {
123 // The connection
124 DrawQuad(position, CVec2(this->width - this->height / 3, this->height / 4), CVec4(0, 0, 0));
125
126 // Handle the buttons
127 if (this->pos <= min)
128 {
129 this->pos = min;
130 this->minus->status = -1;
131 }
132 else if (this->minus->status < 0)
133 this->minus->status = 0;
134
135 if (this->pos >= max)
136 {
137 this->pos = max;
138 this->plus->status = -1;
139 }
140 else if (this->plus->status < 0)
141 this->plus->status = 0;
142
143 // Just to be nice, update the slider's button positions
144 this->minus->x = this->x - (this->width - this->height) / 2;
145 this->minus->y = this->y;
146
147 this->plus->x = this->x + (this->width - this->height) / 2;
148 this->plus->y = this->y;
149
150 /////////////////////////////////////////////////////////////////////////////////////////////
151
152 // Normalize it between -0.5 and 0.5
153 float t = (float)(this->pos - min) / (max - min) - 0.5;
154
155 // And scale it to find the center of the slider
156 float x = t * (this->width - this->height * 3);
157
158 float color = 0.8 - 0.2 * this->status;
159
160 DrawBox(CVec3(this->x + x, this->y, this->z + 0.002), CVec2(this->height, this->height), CVec4(color, color, color));
161
162 char buffer[30];
163 switch (this->decimals)
164 {
165 case 0:
166 sprintf(buffer, "%.0f", this->pos);
167 break;
168 case 1:
169 sprintf(buffer, "%.1f", this->pos);
170 break;
171 case 2:
172 sprintf(buffer, "%.2f", this->pos);
173 break;
174 case 3:
175 sprintf(buffer, "%.3f", this->pos);
176 break;
177 case 4:
178 sprintf(buffer, "%.4f", this->pos);
179 break;
180 case 5:
181 sprintf(buffer, "%.5f", this->pos);
182 break;
183 case 6:
184 sprintf(buffer, "%.6f", this->pos);
185 break;
186 case 7:
187 sprintf(buffer, "%.7f", this->pos);
188 break;
189 case 8:
190 sprintf(buffer, "%.8f", this->pos);
191 break;
192 case 9:
193 sprintf(buffer, "%.9f", this->pos);
194 break;
195 case 10:
196 sprintf(buffer, "%.10f", this->pos);
197 break;
198 default:
199 OSHalt("Invalid number of decimal places specified!");
200 break;
201 }
202
203 DrawTextCenter(buffer, CVec3(this->x + x, this->y, this->z + 0.003), CVec2(this->height, this->height * 0.7), CVec4(0, 0, 0));
204
205 // Make sure we have the right arrow textures!
206 this->minus->tex = GetTexture(CW_TEXTURE_SLIDERLEFT);
207 this->plus->tex = GetTexture(CW_TEXTURE_SLIDERRIGHT);
208 }
209
210 // Resets the slider
Reset()211 void SliderBarFloat::Reset()
212 {
213 if (this->status > 0)
214 this->status = 0;
215
216 float totalDistance = this->max - this->min;
217
218 // In case something caused us to change
219 float diff = this->pos - *this->target;
220 if (diff > totalDistance / 1000 || diff < -totalDistance / 1000)
221 this->pos = *this->target;
222 }
223