1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2010-2012 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