blob: 3ae6b98556137abc31857dca7b896ccb27e2272d [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
Vojtech Bocekede51c52014-02-07 23:58:09 +010028GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node)
Vojtech Bocek85932342013-04-01 22:11:33 +020029{
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;
Vojtech Bocek18d7c982014-08-04 17:19:28 +020048 mBackgroundImage = NULL;
49 mHandleImage = NULL;
50 mHandleHoverImage = NULL;
51 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +020052
53 mLabel = NULL;
54 ConvertStrToColor("white", &mTextColor);
55 ConvertStrToColor("white", &mLineColor);
56 ConvertStrToColor("blue", &mSliderColor);
57
58 if (!node)
59 {
60 LOGERR("GUISliderValue created without XML node\n");
61 return;
62 }
63
64 mLabel = new GUIText(node);
65 if(mLabel->Render() < 0)
66 {
67 delete mLabel;
68 mLabel = NULL;
69 }
70
71 mAction = new GUIAction(node);
72
73 child = node->first_node("font");
74 if (child)
75 {
76 attr = child->first_attribute("resource");
77 if (attr)
78 mFont = PageManager::FindResource(attr->value());
79
80 attr = child->first_attribute("color");
81 if (attr)
82 {
83 std::string color = attr->value();
84 ConvertStrToColor(color, &mTextColor);
85 }
86 }
87
88 // Load the placement
89 LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW);
90
91 child = node->first_node("colors");
92 if (child)
93 {
94 attr = child->first_attribute("line");
95 if (attr)
96 ConvertStrToColor(attr->value(), &mLineColor);
97
98 attr = child->first_attribute("slider");
99 if (attr)
100 ConvertStrToColor(attr->value(), &mSliderColor);
101 }
102
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200103 child = node->first_node("resource");
104 if (child)
105 {
106 attr = child->first_attribute("background");
107 if(attr)
108 mBackgroundImage = PageManager::FindResource(attr->value());
109
110 attr = child->first_attribute("handle");
111 if(attr)
112 mHandleImage = PageManager::FindResource(attr->value());
113
114 attr = child->first_attribute("handlehover");
115 if(attr)
116 mHandleHoverImage = PageManager::FindResource(attr->value());
117 }
118
Vojtech Bocek85932342013-04-01 22:11:33 +0200119 child = node->first_node("data");
120 if (child)
121 {
122 attr = child->first_attribute("variable");
123 if (attr)
124 mVariable = attr->value();
125
126 attr = child->first_attribute("min");
127 if (attr)
128 {
129 mMinStr = gui_parse_text(attr->value());
130 mMin = atoi(mMinStr.c_str());
131 }
132
133 attr = child->first_attribute("max");
134 if (attr)
135 {
136 mMaxStr = gui_parse_text(attr->value());
137 mMax = atoi(mMaxStr.c_str());
138 }
139
140 if (mMin > mMax)
141 mMin = mMax;
142
143 attr = child->first_attribute("default");
144 if (attr)
145 {
146 string parsevalue = gui_parse_text(attr->value());
147 int def = atoi(parsevalue.c_str());
148
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500149 if (def < mMin)
150 def = mMin;
151 else if (def > mMax)
152 def = mMax;
Vojtech Bocek85932342013-04-01 22:11:33 +0200153 DataManager::SetValue(mVariable, def);
154 }
155
156 attr = child->first_attribute("showrange");
157 if (attr)
158 mShowRange = atoi(attr->value());
159
160 attr = child->first_attribute("showcurr");
161 if (attr)
162 mShowCurr = atoi(attr->value());
163
164 attr = child->first_attribute("changeondrag");
165 if (attr)
166 mChangeOnDrag = atoi(attr->value());
167 }
168
169 child = node->first_node("dimensions");
170 if (child)
171 {
172 attr = child->first_attribute("lineh");
173 if (attr)
174 {
175 string parsevalue = gui_parse_text(attr->value());
176 mLineH = atoi(parsevalue.c_str());
177 }
178
179 attr = child->first_attribute("linepadding");
180 if (attr)
181 {
182 string parsevalue = gui_parse_text(attr->value());
183 mPadding = atoi(parsevalue.c_str());
Ethan Yonkerc56ab4c2014-12-08 22:16:54 -0600184 mLinePadding = mPadding;
Vojtech Bocek85932342013-04-01 22:11:33 +0200185 }
186
187 attr = child->first_attribute("sliderw");
188 if (attr)
189 {
190 string parsevalue = gui_parse_text(attr->value());
191 mSliderW = atoi(parsevalue.c_str());
192 }
193
194 attr = child->first_attribute("sliderh");
195 if (attr)
196 {
197 string parsevalue = gui_parse_text(attr->value());
198 mSliderH = atoi(parsevalue.c_str());
199 }
200 }
201
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200202 mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
Vojtech Bocek85932342013-04-01 22:11:33 +0200203
204 if(mShowCurr)
205 {
206 int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
207 mValueStr = new char[maxLen+1];
208 }
209
210 loadValue(true);
211
Vojtech Bocek85932342013-04-01 22:11:33 +0200212 if (mShowRange)
213 {
214 int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
215 mLinePadding += textW;
216 }
217
218 SetRenderPos(mRenderX, mRenderY, mRenderW);
219}
220
221GUISliderValue::~GUISliderValue()
222{
223 delete mLabel;
224 delete mAction;
225 delete[] mValueStr;
226}
227
228void GUISliderValue::loadValue(bool force)
229{
230 if(!mVariable.empty())
231 {
232 int value = DataManager::GetIntValue(mVariable);
233 if(mValue == value && !force)
234 return;
235
236 mValue = value;
237 }
238
239 mValue = std::max(mValue, mMin);
240 mValue = std::min(mValue, mMax);
241 mValuePct = pctFromValue(mValue);
242 mRendered = false;
243}
244
245int GUISliderValue::SetRenderPos(int x, int y, int w, int h)
246{
247 mRenderX = x;
248 mRenderY = y;
249 if (w || h)
250 {
251 mRenderW = w;
252 mRenderH = h;
253 }
254
255 mRenderH = mSliderH;
256 if(mShowCurr)
257 mRenderH += mFontHeight;
258
259 if (mLabel)
260 {
261 int lw, lh;
262 mLabel->GetCurrentBounds(lw, lh);
263 int textX = mRenderX + (mRenderW/2 - lw/2);
264
265 mLabel->SetRenderPos(textX, mRenderY);
266
267 y += lh;
268 mRenderH += lh;
269 }
270
271 mSliderY = y;
Vojtech Bocek85932342013-04-01 22:11:33 +0200272
273 mActionX = mRenderX;
274 mActionY = mRenderY;
275 mActionW = mRenderW;
276 mActionH = mRenderH;
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200277
278 if(mBackgroundImage && mBackgroundImage->GetResource())
279 {
280 mLineW = gr_get_width(mBackgroundImage->GetResource());
281 mLineH = gr_get_height(mBackgroundImage->GetResource());
282 }
283 else
284 mLineW = mRenderW - (mLinePadding * 2);
285
286 mLineY = y + (mSliderH/2 - mLineH/2);
287 mLineX = mRenderX + (mRenderW/2 - mLineW/2);
Vojtech Bocek85932342013-04-01 22:11:33 +0200288
289 return 0;
290}
291
292int GUISliderValue::measureText(const std::string& str)
293{
294 void* fontResource = NULL;
295 if (mFont) fontResource = mFont->GetResource();
296
297 return gr_measureEx(str.c_str(), fontResource);
298}
299
300int GUISliderValue::Render(void)
301{
302 if (!isConditionTrue())
303 {
304 mRendered = false;
305 return 0;
306 }
307
308 if(mLabel)
309 {
310 int w, h;
311 mLabel->GetCurrentBounds(w, h);
312 if (w != mLabelW) {
313 mLabelW = w;
314 int textX = mRenderX + (mRenderW/2 - mLabelW/2);
315 mLabel->SetRenderPos(textX, mRenderY);
316 }
317 int res = mLabel->Render();
318 if(res < 0)
319 return res;
320 }
321
322 // line
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200323 if(mBackgroundImage && mBackgroundImage->GetResource())
324 {
325 gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY);
326 }
327 else
328 {
329 gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
330 gr_fill(mLineX, mLineY, mLineW, mLineH);
331 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200332
333 // slider
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200334 uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100;
Vojtech Bocek85932342013-04-01 22:11:33 +0200335
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200336 if(mHandleImage && mHandleImage->GetResource())
337 {
338 gr_surface s = mHandleImage->GetResource();
339 if(mDragging && mHandleHoverImage && mHandleHoverImage->GetResource())
340 s = mHandleHoverImage->GetResource();
341 gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2));
342 }
343 else
344 {
345 gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
346 gr_fill(sliderX, mSliderY, mSliderW, mSliderH);
347 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200348
349 void *fontResource = NULL;
350 if(mFont) fontResource = mFont->GetResource();
351 gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha);
352 if(mShowRange)
353 {
354 int rangeY = (mLineY - mLineH/2) - mFontHeight/2;
355 gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource);
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200356 gr_textEx(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource);
Vojtech Bocek85932342013-04-01 22:11:33 +0200357 }
358
359 if(mValueStr && mShowCurr)
360 {
361 sprintf(mValueStr, "%d", mValue);
362 int textW = measureText(mValueStr);
363 gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource);
364 }
365
366 mRendered = true;
367 return 0;
368}
369
370int GUISliderValue::Update(void)
371{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500372 if (!isConditionTrue())
373 return mRendered ? 2 : 0;
374 if (!mRendered)
375 return 2;
Vojtech Bocek85932342013-04-01 22:11:33 +0200376
377 if(mLabel)
378 return mLabel->Update();
379 return 0;
380}
381
382int GUISliderValue::valueFromPct(float pct)
383{
384 int range = abs(mMax - mMin);
385 return mMin + (pct * range) / 100;
386}
387
388float GUISliderValue::pctFromValue(int value)
389{
390 return float((value - mMin) * 100) / abs(mMax - mMin);
391}
392
393int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y)
394{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500395 if (!isConditionTrue())
396 return -1;
Vojtech Bocek85932342013-04-01 22:11:33 +0200397
Vojtech Bocek85932342013-04-01 22:11:33 +0200398 switch (state)
399 {
400 case TOUCH_START:
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200401 if (x >= mLineX && x <= mLineX + mLineW &&
Vojtech Bocek85932342013-04-01 22:11:33 +0200402 y >= mRenderY && y <= mRenderY + mRenderH)
403 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200404 mDragging = true;
Vojtech Bocek85932342013-04-01 22:11:33 +0200405 }
406 // no break
407 case TOUCH_DRAG:
408 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200409 if (!mDragging) return 0;
Vojtech Bocek85932342013-04-01 22:11:33 +0200410
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200411 x = std::max(mLineX + mSliderW/2, x);
412 x = std::min(mLineX + mLineW - mSliderW/2, x);
Vojtech Bocek85932342013-04-01 22:11:33 +0200413
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200414 mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW));
Vojtech Bocek85932342013-04-01 22:11:33 +0200415 int newVal = valueFromPct(mValuePct);
416 if (newVal != mValue) {
417 mRendered = false;
418 mValue = newVal;
419 if (mChangeOnDrag) {
420 if (!mVariable.empty())
421 DataManager::SetValue(mVariable, mValue);
422 if (mAction)
423 mAction->doActions();
424 }
425 }
426 break;
427 }
428 case TOUCH_RELEASE:
429 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200430 if (!mDragging) return 0;
431 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +0200432
433 if (!mVariable.empty())
434 DataManager::SetValue(mVariable, mValue);
435 if (mAction)
436 mAction->doActions();
437 break;
438 }
439 case TOUCH_REPEAT:
440 case TOUCH_HOLD:
441 break;
442 }
443 return 0;
444}
445
Vojtech Bocek07220562014-02-08 02:05:33 +0100446int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value)
Vojtech Bocek85932342013-04-01 22:11:33 +0200447{
Vojtech Bocek07220562014-02-08 02:05:33 +0100448 GUIObject::NotifyVarChange(varName, value);
449
Vojtech Bocek85932342013-04-01 22:11:33 +0200450 if (mLabel)
451 mLabel->NotifyVarChange(varName, value);
452 if (varName == mVariable) {
453 int newVal = atoi(value.c_str());
454 if(newVal != mValue) {
455 mValue = newVal;
456 mValuePct = pctFromValue(mValue);
457 mRendered = false;
458 }
459 }
460 return 0;
461}
462
463void GUISliderValue::SetPageFocus(int inFocus)
464{
465 if (inFocus)
466 loadValue();
467}