blob: 3aaffcc05e402fd77a9c9e4be59e090a43b78562 [file] [log] [blame]
Matt Mowere04eee72016-12-31 00:38:57 -06001/*
2 Copyright 2017 TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
Vojtech Bocek85932342013-04-01 22:11:33 +020019// slidervalue.cpp - GUISliderValue object
20
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <fcntl.h>
26#include <sys/reboot.h>
27#include <sys/stat.h>
28#include <sys/time.h>
29#include <sys/mman.h>
30#include <sys/types.h>
31#include <sys/ioctl.h>
32#include <time.h>
33#include <unistd.h>
34#include <stdlib.h>
35
36#include <string>
37
38extern "C" {
39#include "../twcommon.h"
Vojtech Bocek85932342013-04-01 22:11:33 +020040}
Ethan Yonkerfbb43532015-12-28 21:54:50 +010041#include "../minuitwrp/minui.h"
Vojtech Bocek85932342013-04-01 22:11:33 +020042
43#include "rapidxml.hpp"
44#include "objects.hpp"
45
Vojtech Bocekede51c52014-02-07 23:58:09 +010046GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node)
Vojtech Bocek85932342013-04-01 22:11:33 +020047{
48 xml_attribute<>* attr;
49 xml_node<>* child;
50
51 mMin = 0;
52 mMax = 100;
53 mValue = 0;
54 mLineH = 2;
55 mLinePadding = 10;
56 mSliderW = 5;
57 mSliderH = 30;
58 mLineX = 0;
59 mLineY = 0;
60 mValueStr = NULL;
61 mAction = NULL;
62 mShowCurr = true;
63 mShowRange = false;
64 mChangeOnDrag = false;
65 mRendered = false;
Vojtech Bocek18d7c982014-08-04 17:19:28 +020066 mBackgroundImage = NULL;
67 mHandleImage = NULL;
68 mHandleHoverImage = NULL;
69 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +020070
71 mLabel = NULL;
72 ConvertStrToColor("white", &mTextColor);
73 ConvertStrToColor("white", &mLineColor);
74 ConvertStrToColor("blue", &mSliderColor);
75
76 if (!node)
77 {
78 LOGERR("GUISliderValue created without XML node\n");
79 return;
80 }
81
82 mLabel = new GUIText(node);
Matt Mowera8a89d12016-12-30 18:10:37 -060083 if (mLabel->Render() < 0)
Vojtech Bocek85932342013-04-01 22:11:33 +020084 {
85 delete mLabel;
86 mLabel = NULL;
87 }
88
89 mAction = new GUIAction(node);
90
Ethan Yonker21ff02a2015-02-18 14:35:00 -060091 child = FindNode(node, "font");
Vojtech Bocek85932342013-04-01 22:11:33 +020092 if (child)
93 {
thatf6ed8fc2015-02-14 20:23:16 +010094 mFont = LoadAttrFont(child, "resource");
95 mTextColor = LoadAttrColor(child, "color", mTextColor);
Vojtech Bocek85932342013-04-01 22:11:33 +020096 }
97
98 // Load the placement
Ethan Yonker21ff02a2015-02-18 14:35:00 -060099 LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW);
Vojtech Bocek85932342013-04-01 22:11:33 +0200100
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600101 child = FindNode(node, "colors");
Vojtech Bocek85932342013-04-01 22:11:33 +0200102 if (child)
103 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600104 mLineColor = LoadAttrColor(child, "line");
105 mSliderColor = LoadAttrColor(child, "slider");
Vojtech Bocek85932342013-04-01 22:11:33 +0200106 }
107
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600108 child = FindNode(node, "resource");
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200109 if (child)
110 {
thatf6ed8fc2015-02-14 20:23:16 +0100111 mBackgroundImage = LoadAttrImage(child, "background");
112 mHandleImage = LoadAttrImage(child, "handle");
113 mHandleHoverImage = LoadAttrImage(child, "handlehover");
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200114 }
115
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600116 child = FindNode(node, "data");
Vojtech Bocek85932342013-04-01 22:11:33 +0200117 if (child)
118 {
119 attr = child->first_attribute("variable");
120 if (attr)
121 mVariable = attr->value();
122
123 attr = child->first_attribute("min");
124 if (attr)
125 {
126 mMinStr = gui_parse_text(attr->value());
127 mMin = atoi(mMinStr.c_str());
128 }
129
130 attr = child->first_attribute("max");
131 if (attr)
132 {
133 mMaxStr = gui_parse_text(attr->value());
134 mMax = atoi(mMaxStr.c_str());
135 }
136
137 if (mMin > mMax)
138 mMin = mMax;
139
140 attr = child->first_attribute("default");
141 if (attr)
142 {
143 string parsevalue = gui_parse_text(attr->value());
144 int def = atoi(parsevalue.c_str());
145
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500146 if (def < mMin)
147 def = mMin;
148 else if (def > mMax)
149 def = mMax;
Vojtech Bocek85932342013-04-01 22:11:33 +0200150 DataManager::SetValue(mVariable, def);
151 }
152
153 attr = child->first_attribute("showrange");
154 if (attr)
155 mShowRange = atoi(attr->value());
156
157 attr = child->first_attribute("showcurr");
158 if (attr)
159 mShowCurr = atoi(attr->value());
160
161 attr = child->first_attribute("changeondrag");
162 if (attr)
163 mChangeOnDrag = atoi(attr->value());
164 }
165
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600166 child = FindNode(node, "dimensions");
Vojtech Bocek85932342013-04-01 22:11:33 +0200167 if (child)
168 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600169 mLineH = LoadAttrIntScaleY(child, "lineh", mLineH);
170 mLinePadding = LoadAttrIntScaleX(child, "linepadding", mLinePadding);
171 mSliderW = LoadAttrIntScaleX(child, "sliderw", mSliderW);
172 mSliderH = LoadAttrIntScaleY(child, "sliderh", mSliderH);
Vojtech Bocek85932342013-04-01 22:11:33 +0200173 }
174
Ethan Yonker58f21322018-08-24 11:17:36 -0500175 if (mFont && mFont->GetResource())
176 mFontHeight = mFont->GetHeight();
177 else
178 mFontHeight = 0;
Vojtech Bocek85932342013-04-01 22:11:33 +0200179
Matt Mowera8a89d12016-12-30 18:10:37 -0600180 if (mShowCurr)
Vojtech Bocek85932342013-04-01 22:11:33 +0200181 {
182 int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
183 mValueStr = new char[maxLen+1];
184 }
185
186 loadValue(true);
187
Vojtech Bocek85932342013-04-01 22:11:33 +0200188 if (mShowRange)
189 {
190 int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
191 mLinePadding += textW;
192 }
193
194 SetRenderPos(mRenderX, mRenderY, mRenderW);
195}
196
197GUISliderValue::~GUISliderValue()
198{
199 delete mLabel;
200 delete mAction;
201 delete[] mValueStr;
202}
203
204void GUISliderValue::loadValue(bool force)
205{
Matt Mowera8a89d12016-12-30 18:10:37 -0600206 if (!mVariable.empty())
Vojtech Bocek85932342013-04-01 22:11:33 +0200207 {
208 int value = DataManager::GetIntValue(mVariable);
Matt Mowera8a89d12016-12-30 18:10:37 -0600209 if (mValue == value && !force)
Vojtech Bocek85932342013-04-01 22:11:33 +0200210 return;
211
212 mValue = value;
213 }
214
215 mValue = std::max(mValue, mMin);
216 mValue = std::min(mValue, mMax);
217 mValuePct = pctFromValue(mValue);
218 mRendered = false;
219}
220
221int GUISliderValue::SetRenderPos(int x, int y, int w, int h)
222{
223 mRenderX = x;
224 mRenderY = y;
225 if (w || h)
226 {
227 mRenderW = w;
228 mRenderH = h;
229 }
230
231 mRenderH = mSliderH;
Matt Mowera8a89d12016-12-30 18:10:37 -0600232 if (mShowCurr)
Vojtech Bocek85932342013-04-01 22:11:33 +0200233 mRenderH += mFontHeight;
234
235 if (mLabel)
236 {
237 int lw, lh;
238 mLabel->GetCurrentBounds(lw, lh);
239 int textX = mRenderX + (mRenderW/2 - lw/2);
240
241 mLabel->SetRenderPos(textX, mRenderY);
242
243 y += lh;
244 mRenderH += lh;
245 }
246
247 mSliderY = y;
Vojtech Bocek85932342013-04-01 22:11:33 +0200248
249 mActionX = mRenderX;
250 mActionY = mRenderY;
251 mActionW = mRenderW;
252 mActionH = mRenderH;
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200253
Matt Mowera8a89d12016-12-30 18:10:37 -0600254 if (mBackgroundImage && mBackgroundImage->GetResource())
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200255 {
thatf6ed8fc2015-02-14 20:23:16 +0100256 mLineW = mBackgroundImage->GetWidth();
257 mLineH = mBackgroundImage->GetHeight();
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200258 }
259 else
260 mLineW = mRenderW - (mLinePadding * 2);
261
262 mLineY = y + (mSliderH/2 - mLineH/2);
263 mLineX = mRenderX + (mRenderW/2 - mLineW/2);
Vojtech Bocek85932342013-04-01 22:11:33 +0200264
265 return 0;
266}
267
268int GUISliderValue::measureText(const std::string& str)
269{
270 void* fontResource = NULL;
271 if (mFont) fontResource = mFont->GetResource();
272
Ethan Yonkerfbb43532015-12-28 21:54:50 +0100273 return gr_ttf_measureEx(str.c_str(), fontResource);
Vojtech Bocek85932342013-04-01 22:11:33 +0200274}
275
276int GUISliderValue::Render(void)
277{
278 if (!isConditionTrue())
279 {
280 mRendered = false;
281 return 0;
282 }
283
Matt Mowera8a89d12016-12-30 18:10:37 -0600284 if (mLabel)
Vojtech Bocek85932342013-04-01 22:11:33 +0200285 {
286 int w, h;
287 mLabel->GetCurrentBounds(w, h);
288 if (w != mLabelW) {
289 mLabelW = w;
290 int textX = mRenderX + (mRenderW/2 - mLabelW/2);
291 mLabel->SetRenderPos(textX, mRenderY);
292 }
293 int res = mLabel->Render();
Matt Mowera8a89d12016-12-30 18:10:37 -0600294 if (res < 0)
Vojtech Bocek85932342013-04-01 22:11:33 +0200295 return res;
296 }
297
298 // line
Matt Mowera8a89d12016-12-30 18:10:37 -0600299 if (mBackgroundImage && mBackgroundImage->GetResource())
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200300 {
301 gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY);
302 }
303 else
304 {
305 gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
306 gr_fill(mLineX, mLineY, mLineW, mLineH);
307 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200308
309 // slider
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200310 uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100;
Vojtech Bocek85932342013-04-01 22:11:33 +0200311
Matt Mowera8a89d12016-12-30 18:10:37 -0600312 if (mHandleImage && mHandleImage->GetResource())
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200313 {
314 gr_surface s = mHandleImage->GetResource();
Matt Mowera8a89d12016-12-30 18:10:37 -0600315 if (mDragging && mHandleHoverImage && mHandleHoverImage->GetResource())
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200316 s = mHandleHoverImage->GetResource();
317 gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2));
318 }
319 else
320 {
321 gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
322 gr_fill(sliderX, mSliderY, mSliderW, mSliderH);
323 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200324
325 void *fontResource = NULL;
Matt Mowera8a89d12016-12-30 18:10:37 -0600326 if (mFont) fontResource = mFont->GetResource();
Vojtech Bocek85932342013-04-01 22:11:33 +0200327 gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha);
Matt Mowera8a89d12016-12-30 18:10:37 -0600328 if (mShowRange)
Vojtech Bocek85932342013-04-01 22:11:33 +0200329 {
330 int rangeY = (mLineY - mLineH/2) - mFontHeight/2;
Ethan Yonkerb7a54a32015-10-05 10:16:27 -0500331 gr_textEx_scaleW(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource, mRenderW, TOP_LEFT, 0);
332 gr_textEx_scaleW(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource, mRenderW, TOP_LEFT, 0);
Vojtech Bocek85932342013-04-01 22:11:33 +0200333 }
334
Matt Mowera8a89d12016-12-30 18:10:37 -0600335 if (mValueStr && mShowCurr)
Vojtech Bocek85932342013-04-01 22:11:33 +0200336 {
337 sprintf(mValueStr, "%d", mValue);
338 int textW = measureText(mValueStr);
Ethan Yonkerb7a54a32015-10-05 10:16:27 -0500339 gr_textEx_scaleW(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource, mRenderW, TOP_LEFT, 0);
Vojtech Bocek85932342013-04-01 22:11:33 +0200340 }
341
342 mRendered = true;
343 return 0;
344}
345
346int GUISliderValue::Update(void)
347{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500348 if (!isConditionTrue())
349 return mRendered ? 2 : 0;
350 if (!mRendered)
351 return 2;
Vojtech Bocek85932342013-04-01 22:11:33 +0200352
Matt Mowera8a89d12016-12-30 18:10:37 -0600353 if (mLabel)
Vojtech Bocek85932342013-04-01 22:11:33 +0200354 return mLabel->Update();
355 return 0;
356}
357
358int GUISliderValue::valueFromPct(float pct)
359{
360 int range = abs(mMax - mMin);
361 return mMin + (pct * range) / 100;
362}
363
364float GUISliderValue::pctFromValue(int value)
365{
366 return float((value - mMin) * 100) / abs(mMax - mMin);
367}
368
369int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y)
370{
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500371 if (!isConditionTrue())
372 return -1;
Vojtech Bocek85932342013-04-01 22:11:33 +0200373
Vojtech Bocek85932342013-04-01 22:11:33 +0200374 switch (state)
375 {
376 case TOUCH_START:
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200377 if (x >= mLineX && x <= mLineX + mLineW &&
Vojtech Bocek85932342013-04-01 22:11:33 +0200378 y >= mRenderY && y <= mRenderY + mRenderH)
379 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200380 mDragging = true;
Vojtech Bocek85932342013-04-01 22:11:33 +0200381 }
382 // no break
383 case TOUCH_DRAG:
384 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200385 if (!mDragging) return 0;
Vojtech Bocek85932342013-04-01 22:11:33 +0200386
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200387 x = std::max(mLineX + mSliderW/2, x);
388 x = std::min(mLineX + mLineW - mSliderW/2, x);
Vojtech Bocek85932342013-04-01 22:11:33 +0200389
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200390 mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW));
Vojtech Bocek85932342013-04-01 22:11:33 +0200391 int newVal = valueFromPct(mValuePct);
392 if (newVal != mValue) {
393 mRendered = false;
394 mValue = newVal;
395 if (mChangeOnDrag) {
396 if (!mVariable.empty())
397 DataManager::SetValue(mVariable, mValue);
398 if (mAction)
399 mAction->doActions();
400 }
401 }
402 break;
403 }
404 case TOUCH_RELEASE:
405 {
Vojtech Bocek18d7c982014-08-04 17:19:28 +0200406 if (!mDragging) return 0;
407 mDragging = false;
Vojtech Bocek85932342013-04-01 22:11:33 +0200408
409 if (!mVariable.empty())
410 DataManager::SetValue(mVariable, mValue);
411 if (mAction)
412 mAction->doActions();
413 break;
414 }
415 case TOUCH_REPEAT:
416 case TOUCH_HOLD:
417 break;
418 }
419 return 0;
420}
421
Vojtech Bocek07220562014-02-08 02:05:33 +0100422int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value)
Vojtech Bocek85932342013-04-01 22:11:33 +0200423{
Vojtech Bocek07220562014-02-08 02:05:33 +0100424 GUIObject::NotifyVarChange(varName, value);
425
Vojtech Bocek85932342013-04-01 22:11:33 +0200426 if (mLabel)
427 mLabel->NotifyVarChange(varName, value);
428 if (varName == mVariable) {
429 int newVal = atoi(value.c_str());
Matt Mowera8a89d12016-12-30 18:10:37 -0600430 if (newVal != mValue) {
Vojtech Bocek85932342013-04-01 22:11:33 +0200431 mValue = newVal;
432 mValuePct = pctFromValue(mValue);
433 mRendered = false;
434 }
435 }
436 return 0;
437}
438
439void GUISliderValue::SetPageFocus(int inFocus)
440{
441 if (inFocus)
442 loadValue();
443}