blob: a4c5ecb7c497fcc0e1630e92298c39758f0d322f [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001// button.cpp - GUIButton 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 "../common.h"
22#include "../minuitwrp/minui.h"
23#include "../recovery_ui.h"
24}
25
26#include "rapidxml.hpp"
27#include "objects.hpp"
28
29GUIButton::GUIButton(xml_node<>* node)
30 : Conditional(node)
31{
32 xml_attribute<>* attr;
33 xml_node<>* child;
34
35 mButtonImg = NULL;
36 mButtonIcon = NULL;
37 mButtonLabel = NULL;
38 mAction = NULL;
39 mRendered = false;
Dees_Troy1a7a6672013-02-15 09:39:07 -060040 hasHighlightColor = false;
41 renderHighlight = false;
Dees_Troy51a0e822012-09-05 15:24:24 -040042
43 if (!node) return;
44
45 // Three of the four can be loaded directly from the node
46 mButtonImg = new GUIImage(node);
47 mButtonLabel = new GUIText(node);
48 mAction = new GUIAction(node);
49
50 if (mButtonImg->Render() < 0)
51 {
52 LOGE("Unable to locate button image\n");
53 delete mButtonImg;
54 mButtonImg = NULL;
55 }
56 if (mButtonLabel->Render() < 0)
57 {
58 delete mButtonLabel;
59 mButtonLabel = NULL;
60 }
61
62 // The icon is a special case
63 child = node->first_node("icon");
64 if (child)
65 {
66 attr = child->first_attribute("resource");
67 if (attr)
68 mButtonIcon = PageManager::FindResource(attr->value());
69 }
70
Dees_Troy1a7a6672013-02-15 09:39:07 -060071 memset(&mHighlightColor, 0, sizeof(COLOR));
72 child = node->first_node("highlight");
73 if (child) {
74 attr = child->first_attribute("color");
75 if (attr) {
76 hasHighlightColor = true;
77 std::string color = attr->value();
78 ConvertStrToColor(color, &mHighlightColor);
79 }
80 }
81
Dees_Troy51a0e822012-09-05 15:24:24 -040082 int x, y, w, h;
83 if (mButtonImg) mButtonImg->GetRenderPos(x, y, w, h);
84 SetRenderPos(x, y, w, h);
85 return;
86}
87
88GUIButton::~GUIButton()
89{
90 if (mButtonImg) delete mButtonImg;
91 if (mButtonLabel) delete mButtonLabel;
92 if (mAction) delete mAction;
93 if (mButtonIcon) delete mButtonIcon;
94}
95
96int GUIButton::Render(void)
97{
98 if (!isConditionTrue())
99 {
100 mRendered = false;
101 return 0;
102 }
103
104 int ret = 0;
105
106 if (mButtonImg) ret = mButtonImg->Render();
107 if (ret < 0) return ret;
108 if (mButtonIcon && mButtonIcon->GetResource())
109 gr_blit(mButtonIcon->GetResource(), 0, 0, mIconW, mIconH, mIconX, mIconY);
110 if (mButtonLabel) ret = mButtonLabel->Render();
111 if (ret < 0) return ret;
Dees_Troy1a7a6672013-02-15 09:39:07 -0600112 if (renderHighlight && hasHighlightColor) {
113 gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
114 gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
115 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400116 mRendered = true;
117 return ret;
118}
119
120int GUIButton::Update(void)
121{
122 if (!isConditionTrue()) return (mRendered ? 2 : 0);
123 if (!mRendered) return 2;
124
125 int ret = 0, ret2 = 0;
126
Dees_Troy4d12f962012-10-19 13:13:15 -0400127 if (mButtonImg) ret = mButtonImg->Update();
Dees_Troy51a0e822012-09-05 15:24:24 -0400128 if (ret < 0) return ret;
129
130 if (ret == 0)
131 {
132 if (mButtonLabel) ret2 = mButtonLabel->Update();
133 if (ret2 < 0) return ret2;
134 if (ret2 > ret) ret = ret2;
135 }
136 else if (ret == 1)
137 {
138 // The button re-rendered, so everyone else is a render
139 if (mButtonIcon && mButtonIcon->GetResource())
140 gr_blit(mButtonIcon->GetResource(), 0, 0, mIconW, mIconH, mIconX, mIconY);
141 if (mButtonLabel) ret = mButtonLabel->Render();
142 if (ret < 0) return ret;
143 ret = 1;
144 }
145 else
146 {
147 // Aparently, the button needs a background update
148 ret = 2;
149 }
150 return ret;
151}
152
153int GUIButton::SetRenderPos(int x, int y, int w, int h)
154{
155 mRenderX = x;
156 mRenderY = y;
157 if (w || h)
158 {
159 mRenderW = w;
160 mRenderH = h;
161 }
162
163 mIconW = 0; mIconH = 0;
164 if (mButtonIcon && mButtonIcon->GetResource())
165 {
166 mIconW = gr_get_width(mButtonIcon->GetResource());
167 mIconH = gr_get_height(mButtonIcon->GetResource());
168 }
169
170 mTextH = 0;
171 mTextW = 0;
172 mIconX = mRenderX + ((mRenderW - mIconW) / 2);
173 if (mButtonLabel) mButtonLabel->GetCurrentBounds(mTextW, mTextH);
174 if (mTextW)
175 {
176 // As a special case, we'll allow large text which automatically moves it to the right.
177 if (mTextW > mRenderW)
178 {
179 mTextX = mRenderW + mRenderX + 5;
180 mRenderW += mTextW + 5;
181 }
182 else
183 {
184 mTextX = mRenderX + ((mRenderW - mTextW) / 2);
185 }
186 }
187
188 if (mIconH == 0 || mTextH == 0 || mIconH + mTextH > mRenderH)
189 {
190 mIconY = mRenderY + (mRenderH / 2) - (mIconH / 2);
191 mTextY = mRenderY + (mRenderH / 2) - (mTextH / 2);
192 }
193 else
194 {
195 int divisor = mRenderH - (mIconH + mTextH);
196 mIconY = mRenderY + (divisor / 3);
197 mTextY = mRenderY + (divisor * 2 / 3) + mIconH;
198 }
199
200 if (mButtonLabel) mButtonLabel->SetRenderPos(mTextX, mTextY);
201 if (mAction) mAction->SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
202 SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
203 return 0;
204}
205
206int GUIButton::NotifyTouch(TOUCH_STATE state, int x, int y)
207{
Dees_Troy4d12f962012-10-19 13:13:15 -0400208 static int last_state = 0;
209
210 if (!isConditionTrue()) return -1;
211 if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH || state == TOUCH_RELEASE) {
212 if (last_state == 1) {
213 last_state = 0;
214 if (mButtonLabel != NULL)
215 mButtonLabel->isHighlighted = false;
216 if (mButtonImg != NULL)
217 mButtonImg->isHighlighted = false;
Dees_Troy1a7a6672013-02-15 09:39:07 -0600218 renderHighlight = false;
Dees_Troy4d12f962012-10-19 13:13:15 -0400219 mRendered = false;
220 }
221 } else {
222 if (last_state == 0) {
223 last_state = 1;
224 if (mButtonLabel != NULL)
225 mButtonLabel->isHighlighted = true;
226 if (mButtonImg != NULL)
227 mButtonImg->isHighlighted = true;
Dees_Troy1a7a6672013-02-15 09:39:07 -0600228 renderHighlight = true;
Dees_Troy4d12f962012-10-19 13:13:15 -0400229 mRendered = false;
230 }
231 }
232 if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH)
233 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400234 return (mAction ? mAction->NotifyTouch(state, x, y) : 1);
235}
236