blob: d369aceb95e8c5559040ca881eb20b34e3e289ae [file] [log] [blame]
Vojtech Bocek85932342013-04-01 22:11:33 +02001// slidervalue.cpp - GUISliderValue object
2
3#include <stdarg.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <fcntl.h>
8#include <sys/reboot.h>
9#include <sys/stat.h>
10#include <sys/time.h>
11#include <sys/mman.h>
12#include <sys/types.h>
13#include <sys/ioctl.h>
14#include <time.h>
15#include <unistd.h>
16#include <stdlib.h>
17
18#include <string>
19
20extern "C" {
21#include "../twcommon.h"
22#include "../minuitwrp/minui.h"
23}
24
25#include "rapidxml.hpp"
26#include "objects.hpp"
27
28GUISliderValue::GUISliderValue(xml_node<>* node) : Conditional(node)
29{
30 xml_attribute<>* attr;
31 xml_node<>* child;
32
33 mMin = 0;
34 mMax = 100;
35 mValue = 0;
36 mLineH = 2;
37 mLinePadding = 10;
38 mSliderW = 5;
39 mSliderH = 30;
40 mLineX = 0;
41 mLineY = 0;
42 mValueStr = NULL;
43 mAction = NULL;
44 mShowCurr = true;
45 mShowRange = false;
46 mChangeOnDrag = false;
47 mRendered = false;
48
49 mLabel = NULL;
50 ConvertStrToColor("white", &mTextColor);
51 ConvertStrToColor("white", &mLineColor);
52 ConvertStrToColor("blue", &mSliderColor);
53
54 if (!node)
55 {
56 LOGERR("GUISliderValue created without XML node\n");
57 return;
58 }
59
60 mLabel = new GUIText(node);
61 if(mLabel->Render() < 0)
62 {
63 delete mLabel;
64 mLabel = NULL;
65 }
66
67 mAction = new GUIAction(node);
68
69 child = node->first_node("font");
70 if (child)
71 {
72 attr = child->first_attribute("resource");
73 if (attr)
74 mFont = PageManager::FindResource(attr->value());
75
76 attr = child->first_attribute("color");
77 if (attr)
78 {
79 std::string color = attr->value();
80 ConvertStrToColor(color, &mTextColor);
81 }
82 }
83
84 // Load the placement
85 LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW);
86
87 child = node->first_node("colors");
88 if (child)
89 {
90 attr = child->first_attribute("line");
91 if (attr)
92 ConvertStrToColor(attr->value(), &mLineColor);
93
94 attr = child->first_attribute("slider");
95 if (attr)
96 ConvertStrToColor(attr->value(), &mSliderColor);
97 }
98
99 child = node->first_node("data");
100 if (child)
101 {
102 attr = child->first_attribute("variable");
103 if (attr)
104 mVariable = attr->value();
105
106 attr = child->first_attribute("min");
107 if (attr)
108 {
109 mMinStr = gui_parse_text(attr->value());
110 mMin = atoi(mMinStr.c_str());
111 }
112
113 attr = child->first_attribute("max");
114 if (attr)
115 {
116 mMaxStr = gui_parse_text(attr->value());
117 mMax = atoi(mMaxStr.c_str());
118 }
119
120 if (mMin > mMax)
121 mMin = mMax;
122
123 attr = child->first_attribute("default");
124 if (attr)
125 {
126 string parsevalue = gui_parse_text(attr->value());
127 int def = atoi(parsevalue.c_str());
128
129 if (def < mMin) def = mMin;
130 else if (def > mMax) def = mMax;
131 DataManager::SetValue(mVariable, def);
132 }
133
134 attr = child->first_attribute("showrange");
135 if (attr)
136 mShowRange = atoi(attr->value());
137
138 attr = child->first_attribute("showcurr");
139 if (attr)
140 mShowCurr = atoi(attr->value());
141
142 attr = child->first_attribute("changeondrag");
143 if (attr)
144 mChangeOnDrag = atoi(attr->value());
145 }
146
147 child = node->first_node("dimensions");
148 if (child)
149 {
150 attr = child->first_attribute("lineh");
151 if (attr)
152 {
153 string parsevalue = gui_parse_text(attr->value());
154 mLineH = atoi(parsevalue.c_str());
155 }
156
157 attr = child->first_attribute("linepadding");
158 if (attr)
159 {
160 string parsevalue = gui_parse_text(attr->value());
161 mPadding = atoi(parsevalue.c_str());
162 }
163
164 attr = child->first_attribute("sliderw");
165 if (attr)
166 {
167 string parsevalue = gui_parse_text(attr->value());
168 mSliderW = atoi(parsevalue.c_str());
169 }
170
171 attr = child->first_attribute("sliderh");
172 if (attr)
173 {
174 string parsevalue = gui_parse_text(attr->value());
175 mSliderH = atoi(parsevalue.c_str());
176 }
177 }
178
179 gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL);
180
181 if(mShowCurr)
182 {
183 int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
184 mValueStr = new char[maxLen+1];
185 }
186
187 loadValue(true);
188
189 mLinePadding = mPadding;
190 if (mShowRange)
191 {
192 int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
193 mLinePadding += textW;
194 }
195
196 SetRenderPos(mRenderX, mRenderY, mRenderW);
197}
198
199GUISliderValue::~GUISliderValue()
200{
201 delete mLabel;
202 delete mAction;
203 delete[] mValueStr;
204}
205
206void GUISliderValue::loadValue(bool force)
207{
208 if(!mVariable.empty())
209 {
210 int value = DataManager::GetIntValue(mVariable);
211 if(mValue == value && !force)
212 return;
213
214 mValue = value;
215 }
216
217 mValue = std::max(mValue, mMin);
218 mValue = std::min(mValue, mMax);
219 mValuePct = pctFromValue(mValue);
220 mRendered = false;
221}
222
223int GUISliderValue::SetRenderPos(int x, int y, int w, int h)
224{
225 mRenderX = x;
226 mRenderY = y;
227 if (w || h)
228 {
229 mRenderW = w;
230 mRenderH = h;
231 }
232
233 mRenderH = mSliderH;
234 if(mShowCurr)
235 mRenderH += mFontHeight;
236
237 if (mLabel)
238 {
239 int lw, lh;
240 mLabel->GetCurrentBounds(lw, lh);
241 int textX = mRenderX + (mRenderW/2 - lw/2);
242
243 mLabel->SetRenderPos(textX, mRenderY);
244
245 y += lh;
246 mRenderH += lh;
247 }
248
249 mSliderY = y;
250 mLineY = (y + mSliderH/2) - (mLineH/2);
251
252 mLineX = mRenderX + mLinePadding;
253
254 mActionX = mRenderX;
255 mActionY = mRenderY;
256 mActionW = mRenderW;
257 mActionH = mRenderH;
258 lineW = mRenderW - (mLinePadding * 2);
259
260 return 0;
261}
262
263int GUISliderValue::measureText(const std::string& str)
264{
265 void* fontResource = NULL;
266 if (mFont) fontResource = mFont->GetResource();
267
268 return gr_measureEx(str.c_str(), fontResource);
269}
270
271int GUISliderValue::Render(void)
272{
273 if (!isConditionTrue())
274 {
275 mRendered = false;
276 return 0;
277 }
278
279 if(mLabel)
280 {
281 int w, h;
282 mLabel->GetCurrentBounds(w, h);
283 if (w != mLabelW) {
284 mLabelW = w;
285 int textX = mRenderX + (mRenderW/2 - mLabelW/2);
286 mLabel->SetRenderPos(textX, mRenderY);
287 }
288 int res = mLabel->Render();
289 if(res < 0)
290 return res;
291 }
292
293 // line
294 gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
295 gr_fill(mLineX, mLineY, lineW, mLineH);
296
297 // slider
298 uint32_t sliderX = (mValuePct*lineW)/100 + mLineX;
299 sliderX -= mSliderW/2;
300
301 gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
302 gr_fill(sliderX, mSliderY, mSliderW, mSliderH);
303
304 void *fontResource = NULL;
305 if(mFont) fontResource = mFont->GetResource();
306 gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha);
307 if(mShowRange)
308 {
309 int rangeY = (mLineY - mLineH/2) - mFontHeight/2;
310 gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource);
311 gr_textEx(mLineX + lineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource);
312 }
313
314 if(mValueStr && mShowCurr)
315 {
316 sprintf(mValueStr, "%d", mValue);
317 int textW = measureText(mValueStr);
318 gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource);
319 }
320
321 mRendered = true;
322 return 0;
323}
324
325int GUISliderValue::Update(void)
326{
327 if (!isConditionTrue()) return mRendered ? 2 : 0;
328 if (!mRendered) return 2;
329
330 if(mLabel)
331 return mLabel->Update();
332 return 0;
333}
334
335int GUISliderValue::valueFromPct(float pct)
336{
337 int range = abs(mMax - mMin);
338 return mMin + (pct * range) / 100;
339}
340
341float GUISliderValue::pctFromValue(int value)
342{
343 return float((value - mMin) * 100) / abs(mMax - mMin);
344}
345
346int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y)
347{
348 if (!isConditionTrue()) return -1;
349
350 static bool dragging = false;
351 switch (state)
352 {
353 case TOUCH_START:
354 if (x >= mRenderX && x <= mRenderX + mRenderW &&
355 y >= mRenderY && y <= mRenderY + mRenderH)
356 {
357 dragging = true;
358 }
359 // no break
360 case TOUCH_DRAG:
361 {
362 if (!dragging) return 0;
363
364 x = std::max(mLineX, x);
365 x = std::min(mLineX + lineW, x);
366
367 mValuePct = float(((x - mLineX) * 100) / lineW);
368 int newVal = valueFromPct(mValuePct);
369 if (newVal != mValue) {
370 mRendered = false;
371 mValue = newVal;
372 if (mChangeOnDrag) {
373 if (!mVariable.empty())
374 DataManager::SetValue(mVariable, mValue);
375 if (mAction)
376 mAction->doActions();
377 }
378 }
379 break;
380 }
381 case TOUCH_RELEASE:
382 {
383 if (!dragging) return 0;
384 dragging = false;
385
386 if (!mVariable.empty())
387 DataManager::SetValue(mVariable, mValue);
388 if (mAction)
389 mAction->doActions();
390 break;
391 }
392 case TOUCH_REPEAT:
393 case TOUCH_HOLD:
394 break;
395 }
396 return 0;
397}
398
399int GUISliderValue::NotifyVarChange(std::string varName, std::string value)
400{
401 if (mLabel)
402 mLabel->NotifyVarChange(varName, value);
403 if (varName == mVariable) {
404 int newVal = atoi(value.c_str());
405 if(newVal != mValue) {
406 mValue = newVal;
407 mValuePct = pctFromValue(mValue);
408 mRendered = false;
409 }
410 }
411 return 0;
412}
413
414void GUISliderValue::SetPageFocus(int inFocus)
415{
416 if (inFocus)
417 loadValue();
418}