blob: 5be58dcf3f2deedb7c1ebdb17c008b4c2ca2fb65 [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 {
thatf6ed8fc2015-02-14 20:23:16 +010076 mFont = LoadAttrFont(child, "resource");
77 mTextColor = LoadAttrColor(child, "color", mTextColor);
Vojtech Bocek85932342013-04-01 22:11:33 +020078 }
79
80 // Load the placement
81 LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW);
82
83 child = node->first_node("colors");
84 if (child)
85 {
86 attr = child->first_attribute("line");
87 if (attr)
88 ConvertStrToColor(attr->value(), &mLineColor);
89
90 attr = child->first_attribute("slider");
91 if (attr)
92 ConvertStrToColor(attr->value(), &mSliderColor);
93 }
94
Vojtech Bocek18d7c982014-08-04 17:19:28 +020095 child = node->first_node("resource");
96 if (child)
97 {
thatf6ed8fc2015-02-14 20:23:16 +010098 mBackgroundImage = LoadAttrImage(child, "background");
99 mHandleImage = LoadAttrImage(child, "handle");
100 mHandleHoverImage = LoadAttrImage(child, "handlehover");
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200101 }
102
Vojtech Bocek85932342013-04-01 22:11:33 +0200103 child = node->first_node("data");
104 if (child)
105 {
106 attr = child->first_attribute("variable");
107 if (attr)
108 mVariable = attr->value();
109
110 attr = child->first_attribute("min");
111 if (attr)
112 {
113 mMinStr = gui_parse_text(attr->value());
114 mMin = atoi(mMinStr.c_str());
115 }
116
117 attr = child->first_attribute("max");
118 if (attr)
119 {
120 mMaxStr = gui_parse_text(attr->value());
121 mMax = atoi(mMaxStr.c_str());
122 }
123
124 if (mMin > mMax)
125 mMin = mMax;
126
127 attr = child->first_attribute("default");
128 if (attr)
129 {
130 string parsevalue = gui_parse_text(attr->value());
131 int def = atoi(parsevalue.c_str());
132
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500133 if (def < mMin)
134 def = mMin;
135 else if (def > mMax)
136 def = mMax;
Vojtech Bocek85932342013-04-01 22:11:33 +0200137 DataManager::SetValue(mVariable, def);
138 }
139
140 attr = child->first_attribute("showrange");
141 if (attr)
142 mShowRange = atoi(attr->value());
143
144 attr = child->first_attribute("showcurr");
145 if (attr)
146 mShowCurr = atoi(attr->value());
147
148 attr = child->first_attribute("changeondrag");
149 if (attr)
150 mChangeOnDrag = atoi(attr->value());
151 }
152
153 child = node->first_node("dimensions");
154 if (child)
155 {
156 attr = child->first_attribute("lineh");
157 if (attr)
158 {
159 string parsevalue = gui_parse_text(attr->value());
Ethan Yonker63e414f2015-02-06 15:44:39 -0600160 mLineH = scale_theme_y(atoi(parsevalue.c_str()));
Vojtech Bocek85932342013-04-01 22:11:33 +0200161 }
162
163 attr = child->first_attribute("linepadding");
164 if (attr)
165 {
166 string parsevalue = gui_parse_text(attr->value());
Ethan Yonker63e414f2015-02-06 15:44:39 -0600167 mPadding = scale_theme_x(atoi(parsevalue.c_str()));
Ethan Yonkerc56ab4c2014-12-08 22:16:54 -0600168 mLinePadding = mPadding;
Vojtech Bocek85932342013-04-01 22:11:33 +0200169 }
170
171 attr = child->first_attribute("sliderw");
172 if (attr)
173 {
174 string parsevalue = gui_parse_text(attr->value());
Ethan Yonker63e414f2015-02-06 15:44:39 -0600175 mSliderW = scale_theme_x(atoi(parsevalue.c_str()));
Vojtech Bocek85932342013-04-01 22:11:33 +0200176 }
177
178 attr = child->first_attribute("sliderh");
179 if (attr)
180 {
181 string parsevalue = gui_parse_text(attr->value());
Ethan Yonker63e414f2015-02-06 15:44:39 -0600182 mSliderH = scale_theme_y(atoi(parsevalue.c_str()));
Vojtech Bocek85932342013-04-01 22:11:33 +0200183 }
184 }
185
thatf6ed8fc2015-02-14 20:23:16 +0100186 mFontHeight = mFont->GetHeight();
Vojtech Bocek85932342013-04-01 22:11:33 +0200187
188 if(mShowCurr)
189 {
190 int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
191 mValueStr = new char[maxLen+1];
192 }
193
194 loadValue(true);
195
Vojtech Bocek85932342013-04-01 22:11:33 +0200196 if (mShowRange)
197 {
198 int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
199 mLinePadding += textW;
200 }
201
202 SetRenderPos(mRenderX, mRenderY, mRenderW);
203}
204
205GUISliderValue::~GUISliderValue()
206{
207 delete mLabel;
208 delete mAction;
209 delete[] mValueStr;
210}
211
212void GUISliderValue::loadValue(bool force)
213{
214 if(!mVariable.empty())
215 {
216 int value = DataManager::GetIntValue(mVariable);
217 if(mValue == value && !force)
218 return;
219
220 mValue = value;
221 }
222
223 mValue = std::max(mValue, mMin);
224 mValue = std::min(mValue, mMax);
225 mValuePct = pctFromValue(mValue);
226 mRendered = false;
227}
228
229int GUISliderValue::SetRenderPos(int x, int y, int w, int h)
230{
231 mRenderX = x;
232 mRenderY = y;
233 if (w || h)
234 {
235 mRenderW = w;
236 mRenderH = h;
237 }
238
239 mRenderH = mSliderH;
240 if(mShowCurr)
241 mRenderH += mFontHeight;
242
243 if (mLabel)
244 {
245 int lw, lh;
246 mLabel->GetCurrentBounds(lw, lh);
247 int textX = mRenderX + (mRenderW/2 - lw/2);
248
249 mLabel->SetRenderPos(textX, mRenderY);
250
251 y += lh;
252 mRenderH += lh;
253 }
254
255 mSliderY = y;
Vojtech Bocek85932342013-04-01 22:11:33 +0200256
257 mActionX = mRenderX;
258 mActionY = mRenderY;
259 mActionW = mRenderW;
260 mActionH = mRenderH;
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200261
262 if(mBackgroundImage && mBackgroundImage->GetResource())
263 {
thatf6ed8fc2015-02-14 20:23:16 +0100264 mLineW = mBackgroundImage->GetWidth();
265 mLineH = mBackgroundImage->GetHeight();
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200266 }
267 else
268 mLineW = mRenderW - (mLinePadding * 2);
269
270 mLineY = y + (mSliderH/2 - mLineH/2);
271 mLineX = mRenderX + (mRenderW/2 - mLineW/2);
Vojtech Bocek85932342013-04-01 22:11:33 +0200272
273 return 0;
274}
275
276int GUISliderValue::measureText(const std::string& str)
277{
278 void* fontResource = NULL;
279 if (mFont) fontResource = mFont->GetResource();
280
281 return gr_measureEx(str.c_str(), fontResource);
282}
283
284int GUISliderValue::Render(void)
285{
286 if (!isConditionTrue())
287 {
288 mRendered = false;
289 return 0;
290 }
291
292 if(mLabel)
293 {
294 int w, h;
295 mLabel->GetCurrentBounds(w, h);
296 if (w != mLabelW) {
297 mLabelW = w;
298 int textX = mRenderX + (mRenderW/2 - mLabelW/2);
299 mLabel->SetRenderPos(textX, mRenderY);
300 }
301 int res = mLabel->Render();
302 if(res < 0)
303 return res;
304 }
305
306 // line
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200307 if(mBackgroundImage && mBackgroundImage->GetResource())
308 {
309 gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY);
310 }
311 else
312 {
313 gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
314 gr_fill(mLineX, mLineY, mLineW, mLineH);
315 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200316
317 // slider
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200318 uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100;
Vojtech Bocek85932342013-04-01 22:11:33 +0200319
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200320 if(mHandleImage && mHandleImage->GetResource())
321 {
322 gr_surface s = mHandleImage->GetResource();
323 if(mDragging && mHandleHoverImage && mHandleHoverImage->GetResource())
324 s = mHandleHoverImage->GetResource();
325 gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2));
326 }
327 else
328 {
329 gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
330 gr_fill(sliderX, mSliderY, mSliderW, mSliderH);
331 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200332
333 void *fontResource = NULL;
334 if(mFont) fontResource = mFont->GetResource();
335 gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha);
336 if(mShowRange)
337 {
338 int rangeY = (mLineY - mLineH/2) - mFontHeight/2;
339 gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource);
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200340 gr_textEx(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource);
Vojtech Bocek85932342013-04-01 22:11:33 +0200341 }
342
343 if(mValueStr && mShowCurr)
344 {
345 sprintf(mValueStr, "%d", mValue);
346 int textW = measureText(mValueStr);
347 gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource);
348 }
349
350 mRendered = true;
351 return 0;
352}
353
354int GUISliderValue::Update(void)
355{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500356 if (!isConditionTrue())
357 return mRendered ? 2 : 0;
358 if (!mRendered)
359 return 2;
Vojtech Bocek85932342013-04-01 22:11:33 +0200360
361 if(mLabel)
362 return mLabel->Update();
363 return 0;
364}
365
366int GUISliderValue::valueFromPct(float pct)
367{
368 int range = abs(mMax - mMin);
369 return mMin + (pct * range) / 100;
370}
371
372float GUISliderValue::pctFromValue(int value)
373{
374 return float((value - mMin) * 100) / abs(mMax - mMin);
375}
376
377int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y)
378{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500379 if (!isConditionTrue())
380 return -1;
Vojtech Bocek85932342013-04-01 22:11:33 +0200381
Vojtech Bocek85932342013-04-01 22:11:33 +0200382 switch (state)
383 {
384 case TOUCH_START:
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200385 if (x >= mLineX && x <= mLineX + mLineW &&
Vojtech Bocek85932342013-04-01 22:11:33 +0200386 y >= mRenderY && y <= mRenderY + mRenderH)
387 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200388 mDragging = true;
Vojtech Bocek85932342013-04-01 22:11:33 +0200389 }
390 // no break
391 case TOUCH_DRAG:
392 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200393 if (!mDragging) return 0;
Vojtech Bocek85932342013-04-01 22:11:33 +0200394
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200395 x = std::max(mLineX + mSliderW/2, x);
396 x = std::min(mLineX + mLineW - mSliderW/2, x);
Vojtech Bocek85932342013-04-01 22:11:33 +0200397
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200398 mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW));
Vojtech Bocek85932342013-04-01 22:11:33 +0200399 int newVal = valueFromPct(mValuePct);
400 if (newVal != mValue) {
401 mRendered = false;
402 mValue = newVal;
403 if (mChangeOnDrag) {
404 if (!mVariable.empty())
405 DataManager::SetValue(mVariable, mValue);
406 if (mAction)
407 mAction->doActions();
408 }
409 }
410 break;
411 }
412 case TOUCH_RELEASE:
413 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200414 if (!mDragging) return 0;
415 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +0200416
417 if (!mVariable.empty())
418 DataManager::SetValue(mVariable, mValue);
419 if (mAction)
420 mAction->doActions();
421 break;
422 }
423 case TOUCH_REPEAT:
424 case TOUCH_HOLD:
425 break;
426 }
427 return 0;
428}
429
Vojtech Bocek07220562014-02-08 02:05:33 +0100430int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value)
Vojtech Bocek85932342013-04-01 22:11:33 +0200431{
Vojtech Bocek07220562014-02-08 02:05:33 +0100432 GUIObject::NotifyVarChange(varName, value);
433
Vojtech Bocek85932342013-04-01 22:11:33 +0200434 if (mLabel)
435 mLabel->NotifyVarChange(varName, value);
436 if (varName == mVariable) {
437 int newVal = atoi(value.c_str());
438 if(newVal != mValue) {
439 mValue = newVal;
440 mValuePct = pctFromValue(mValue);
441 mRendered = false;
442 }
443 }
444 return 0;
445}
446
447void GUISliderValue::SetPageFocus(int inFocus)
448{
449 if (inFocus)
450 loadValue();
451}