blob: 3974c37d06601754092e7e6492db9980f1639504 [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
Ethan Yonker21ff02a2015-02-18 14:35:00 -060073 child = FindNode(node, "font");
Vojtech Bocek85932342013-04-01 22:11:33 +020074 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
Ethan Yonker21ff02a2015-02-18 14:35:00 -060081 LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW);
Vojtech Bocek85932342013-04-01 22:11:33 +020082
Ethan Yonker21ff02a2015-02-18 14:35:00 -060083 child = FindNode(node, "colors");
Vojtech Bocek85932342013-04-01 22:11:33 +020084 if (child)
85 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -060086 mLineColor = LoadAttrColor(child, "line");
87 mSliderColor = LoadAttrColor(child, "slider");
Vojtech Bocek85932342013-04-01 22:11:33 +020088 }
89
Ethan Yonker21ff02a2015-02-18 14:35:00 -060090 child = FindNode(node, "resource");
Vojtech Bocek18d7c982014-08-04 17:19:28 +020091 if (child)
92 {
thatf6ed8fc2015-02-14 20:23:16 +010093 mBackgroundImage = LoadAttrImage(child, "background");
94 mHandleImage = LoadAttrImage(child, "handle");
95 mHandleHoverImage = LoadAttrImage(child, "handlehover");
Vojtech Bocek18d7c982014-08-04 17:19:28 +020096 }
97
Ethan Yonker21ff02a2015-02-18 14:35:00 -060098 child = FindNode(node, "data");
Vojtech Bocek85932342013-04-01 22:11:33 +020099 if (child)
100 {
101 attr = child->first_attribute("variable");
102 if (attr)
103 mVariable = attr->value();
104
105 attr = child->first_attribute("min");
106 if (attr)
107 {
108 mMinStr = gui_parse_text(attr->value());
109 mMin = atoi(mMinStr.c_str());
110 }
111
112 attr = child->first_attribute("max");
113 if (attr)
114 {
115 mMaxStr = gui_parse_text(attr->value());
116 mMax = atoi(mMaxStr.c_str());
117 }
118
119 if (mMin > mMax)
120 mMin = mMax;
121
122 attr = child->first_attribute("default");
123 if (attr)
124 {
125 string parsevalue = gui_parse_text(attr->value());
126 int def = atoi(parsevalue.c_str());
127
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500128 if (def < mMin)
129 def = mMin;
130 else if (def > mMax)
131 def = mMax;
Vojtech Bocek85932342013-04-01 22:11:33 +0200132 DataManager::SetValue(mVariable, def);
133 }
134
135 attr = child->first_attribute("showrange");
136 if (attr)
137 mShowRange = atoi(attr->value());
138
139 attr = child->first_attribute("showcurr");
140 if (attr)
141 mShowCurr = atoi(attr->value());
142
143 attr = child->first_attribute("changeondrag");
144 if (attr)
145 mChangeOnDrag = atoi(attr->value());
146 }
147
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600148 child = FindNode(node, "dimensions");
Vojtech Bocek85932342013-04-01 22:11:33 +0200149 if (child)
150 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600151 mLineH = LoadAttrIntScaleY(child, "lineh", mLineH);
152 mLinePadding = LoadAttrIntScaleX(child, "linepadding", mLinePadding);
153 mSliderW = LoadAttrIntScaleX(child, "sliderw", mSliderW);
154 mSliderH = LoadAttrIntScaleY(child, "sliderh", mSliderH);
Vojtech Bocek85932342013-04-01 22:11:33 +0200155 }
156
thatf6ed8fc2015-02-14 20:23:16 +0100157 mFontHeight = mFont->GetHeight();
Vojtech Bocek85932342013-04-01 22:11:33 +0200158
159 if(mShowCurr)
160 {
161 int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
162 mValueStr = new char[maxLen+1];
163 }
164
165 loadValue(true);
166
Vojtech Bocek85932342013-04-01 22:11:33 +0200167 if (mShowRange)
168 {
169 int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
170 mLinePadding += textW;
171 }
172
173 SetRenderPos(mRenderX, mRenderY, mRenderW);
174}
175
176GUISliderValue::~GUISliderValue()
177{
178 delete mLabel;
179 delete mAction;
180 delete[] mValueStr;
181}
182
183void GUISliderValue::loadValue(bool force)
184{
185 if(!mVariable.empty())
186 {
187 int value = DataManager::GetIntValue(mVariable);
188 if(mValue == value && !force)
189 return;
190
191 mValue = value;
192 }
193
194 mValue = std::max(mValue, mMin);
195 mValue = std::min(mValue, mMax);
196 mValuePct = pctFromValue(mValue);
197 mRendered = false;
198}
199
200int GUISliderValue::SetRenderPos(int x, int y, int w, int h)
201{
202 mRenderX = x;
203 mRenderY = y;
204 if (w || h)
205 {
206 mRenderW = w;
207 mRenderH = h;
208 }
209
210 mRenderH = mSliderH;
211 if(mShowCurr)
212 mRenderH += mFontHeight;
213
214 if (mLabel)
215 {
216 int lw, lh;
217 mLabel->GetCurrentBounds(lw, lh);
218 int textX = mRenderX + (mRenderW/2 - lw/2);
219
220 mLabel->SetRenderPos(textX, mRenderY);
221
222 y += lh;
223 mRenderH += lh;
224 }
225
226 mSliderY = y;
Vojtech Bocek85932342013-04-01 22:11:33 +0200227
228 mActionX = mRenderX;
229 mActionY = mRenderY;
230 mActionW = mRenderW;
231 mActionH = mRenderH;
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200232
233 if(mBackgroundImage && mBackgroundImage->GetResource())
234 {
thatf6ed8fc2015-02-14 20:23:16 +0100235 mLineW = mBackgroundImage->GetWidth();
236 mLineH = mBackgroundImage->GetHeight();
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200237 }
238 else
239 mLineW = mRenderW - (mLinePadding * 2);
240
241 mLineY = y + (mSliderH/2 - mLineH/2);
242 mLineX = mRenderX + (mRenderW/2 - mLineW/2);
Vojtech Bocek85932342013-04-01 22:11:33 +0200243
244 return 0;
245}
246
247int GUISliderValue::measureText(const std::string& str)
248{
249 void* fontResource = NULL;
250 if (mFont) fontResource = mFont->GetResource();
251
252 return gr_measureEx(str.c_str(), fontResource);
253}
254
255int GUISliderValue::Render(void)
256{
257 if (!isConditionTrue())
258 {
259 mRendered = false;
260 return 0;
261 }
262
263 if(mLabel)
264 {
265 int w, h;
266 mLabel->GetCurrentBounds(w, h);
267 if (w != mLabelW) {
268 mLabelW = w;
269 int textX = mRenderX + (mRenderW/2 - mLabelW/2);
270 mLabel->SetRenderPos(textX, mRenderY);
271 }
272 int res = mLabel->Render();
273 if(res < 0)
274 return res;
275 }
276
277 // line
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200278 if(mBackgroundImage && mBackgroundImage->GetResource())
279 {
280 gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY);
281 }
282 else
283 {
284 gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
285 gr_fill(mLineX, mLineY, mLineW, mLineH);
286 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200287
288 // slider
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200289 uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100;
Vojtech Bocek85932342013-04-01 22:11:33 +0200290
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200291 if(mHandleImage && mHandleImage->GetResource())
292 {
293 gr_surface s = mHandleImage->GetResource();
294 if(mDragging && mHandleHoverImage && mHandleHoverImage->GetResource())
295 s = mHandleHoverImage->GetResource();
296 gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2));
297 }
298 else
299 {
300 gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
301 gr_fill(sliderX, mSliderY, mSliderW, mSliderH);
302 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200303
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);
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200311 gr_textEx(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource);
Vojtech Bocek85932342013-04-01 22:11:33 +0200312 }
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{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500327 if (!isConditionTrue())
328 return mRendered ? 2 : 0;
329 if (!mRendered)
330 return 2;
Vojtech Bocek85932342013-04-01 22:11:33 +0200331
332 if(mLabel)
333 return mLabel->Update();
334 return 0;
335}
336
337int GUISliderValue::valueFromPct(float pct)
338{
339 int range = abs(mMax - mMin);
340 return mMin + (pct * range) / 100;
341}
342
343float GUISliderValue::pctFromValue(int value)
344{
345 return float((value - mMin) * 100) / abs(mMax - mMin);
346}
347
348int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y)
349{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500350 if (!isConditionTrue())
351 return -1;
Vojtech Bocek85932342013-04-01 22:11:33 +0200352
Vojtech Bocek85932342013-04-01 22:11:33 +0200353 switch (state)
354 {
355 case TOUCH_START:
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200356 if (x >= mLineX && x <= mLineX + mLineW &&
Vojtech Bocek85932342013-04-01 22:11:33 +0200357 y >= mRenderY && y <= mRenderY + mRenderH)
358 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200359 mDragging = true;
Vojtech Bocek85932342013-04-01 22:11:33 +0200360 }
361 // no break
362 case TOUCH_DRAG:
363 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200364 if (!mDragging) return 0;
Vojtech Bocek85932342013-04-01 22:11:33 +0200365
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200366 x = std::max(mLineX + mSliderW/2, x);
367 x = std::min(mLineX + mLineW - mSliderW/2, x);
Vojtech Bocek85932342013-04-01 22:11:33 +0200368
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200369 mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW));
Vojtech Bocek85932342013-04-01 22:11:33 +0200370 int newVal = valueFromPct(mValuePct);
371 if (newVal != mValue) {
372 mRendered = false;
373 mValue = newVal;
374 if (mChangeOnDrag) {
375 if (!mVariable.empty())
376 DataManager::SetValue(mVariable, mValue);
377 if (mAction)
378 mAction->doActions();
379 }
380 }
381 break;
382 }
383 case TOUCH_RELEASE:
384 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200385 if (!mDragging) return 0;
386 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +0200387
388 if (!mVariable.empty())
389 DataManager::SetValue(mVariable, mValue);
390 if (mAction)
391 mAction->doActions();
392 break;
393 }
394 case TOUCH_REPEAT:
395 case TOUCH_HOLD:
396 break;
397 }
398 return 0;
399}
400
Vojtech Bocek07220562014-02-08 02:05:33 +0100401int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value)
Vojtech Bocek85932342013-04-01 22:11:33 +0200402{
Vojtech Bocek07220562014-02-08 02:05:33 +0100403 GUIObject::NotifyVarChange(varName, value);
404
Vojtech Bocek85932342013-04-01 22:11:33 +0200405 if (mLabel)
406 mLabel->NotifyVarChange(varName, value);
407 if (varName == mVariable) {
408 int newVal = atoi(value.c_str());
409 if(newVal != mValue) {
410 mValue = newVal;
411 mValuePct = pctFromValue(mValue);
412 mRendered = false;
413 }
414 }
415 return 0;
416}
417
418void GUISliderValue::SetPageFocus(int inFocus)
419{
420 if (inFocus)
421 loadValue();
422}