1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "ultima/nuvie/core/nuvie_defs.h"
24 #include "ultima/nuvie/gui/gui_button.h"
25 #include "ultima/nuvie/gui/gui_load_image.h"
26
27 namespace Ultima {
28 namespace Nuvie {
29
30 /* the check marks bitmap */
31 Graphics::ManagedSurface *checkmarks = NULL;
32
33
GUI_Button(void * data,int x,int y,Graphics::ManagedSurface * image,Graphics::ManagedSurface * image2,GUI_CallBack * callback,bool free_surfaces)34 GUI_Button:: GUI_Button(void *data, int x, int y, Graphics::ManagedSurface *image,
35 Graphics::ManagedSurface *image2, GUI_CallBack *callback, bool free_surfaces)
36 : GUI_Widget(data, x, y, image->w, image->h) {
37 callback_object = callback;
38
39 button = image;
40 button2 = image2;
41 freebutton = free_surfaces;
42 for (int i = 0; i < 3; ++i) {
43 pressed[i] = 0;
44 }
45 enabled = 1;
46 buttonFont = NULL;
47 freefont = 0;
48 flatbutton = 0;
49 is_checkable = 0;
50 checked = 0;
51 is_highlighted = false;
52 }
53
GUI_Button(void * data,int x,int y,int w,int h,GUI_CallBack * callback)54 GUI_Button:: GUI_Button(void *data, int x, int y, int w, int h,
55 GUI_CallBack *callback)
56 : GUI_Widget(data, x, y, w, h) {
57 callback_object = callback;
58
59 button = NULL;
60 button2 = NULL;
61 freebutton = 0;
62 for (int i = 0; i < 3; ++i) {
63 pressed[i] = 0;
64 }
65 enabled = 1;
66 buttonFont = NULL;
67 freefont = 0;
68 flatbutton = 0;
69 is_checkable = 0;
70 checked = 0;
71 is_highlighted = false;
72 }
73
GUI_Button(void * data,int x,int y,int w,int h,const char * text,GUI_Font * font,int alignment,int is_checkbutton,GUI_CallBack * callback,int flat)74 GUI_Button::GUI_Button(void *data, int x, int y, int w, int h, const char *text,
75 GUI_Font *font, int alignment, int is_checkbutton,
76 GUI_CallBack *callback, int flat)
77 : GUI_Widget(data, x, y, w, h) {
78 callback_object = callback;
79
80 if (font != NULL) {
81 buttonFont = font;
82 freefont = 0;
83 } else {
84 buttonFont = new GUI_Font();
85 freefont = 1;
86 }
87 flatbutton = flat;
88 freebutton = 1;
89 button = NULL;
90 button2 = NULL;
91
92 is_checkable = is_checkbutton;
93 checked = 0;
94 is_highlighted = false;
95 /*
96 if (is_checkable &&(checkmarks==NULL))
97 {
98 checkmarks=GUI_LoadImage(checker_w,checker_h,checker_pal,checker_data);
99 SDL_SetColorKey(checkmarks,SDL_SRCCOLORKEY,0);
100 }
101 */
102 ChangeTextButton(-1, -1, -1, -1, text, alignment);
103
104 for (int i = 0; i < 3; ++i) {
105 pressed[i] = 0;
106 }
107 enabled = 1;
108 }
109
~GUI_Button()110 GUI_Button::~GUI_Button() {
111 if (freebutton) {
112 if (button)
113 SDL_FreeSurface(button);
114 if (button2)
115 SDL_FreeSurface(button2);
116 }
117 if (freefont)
118 delete buttonFont;
119 }
120
121 /* Resize/reposition/change text */
ChangeTextButton(int x,int y,int w,int h,const char * text,int alignment)122 void GUI_Button::ChangeTextButton(int x, int y, int w, int h, const char *text, int alignment) {
123 if (x != -1 || y != -1) {
124 assert(x >= 0 && y >= 0);
125 area.moveTo(x, y);
126 }
127
128 if (w != -1 || h != -1) {
129 assert(w >= 0 && h >= 0);
130 area.setWidth(w);
131 area.setHeight(h);
132 }
133
134 if (freebutton) {
135 if (button)
136 SDL_FreeSurface(button);
137 if (button2)
138 SDL_FreeSurface(button2);
139 if (flatbutton) {
140 button = CreateTextButtonImage(BUTTON2D_UP, text, alignment);
141 button2 = CreateTextButtonImage(BUTTON2D_DOWN, text, alignment);
142 } else {
143 button = CreateTextButtonImage(BUTTON3D_UP, text, alignment);
144 button2 = CreateTextButtonImage(BUTTON3D_DOWN, text, alignment);
145 }
146 }
147 }
148
149 /* Show the widget */
Display(bool full_redraw)150 void GUI_Button:: Display(bool full_redraw) {
151 Common::Rect src, dest = area;
152
153 if (button) {
154 if ((button2 != NULL) && ((pressed[0]) == 1 || is_highlighted))
155 SDL_BlitSurface(button2, NULL, surface, &dest);
156 else
157 SDL_BlitSurface(button, NULL, surface, &dest);
158 }
159 if (is_checkable) {
160 src.left = 8 - (checked * 8);
161 src.top = 0;
162 src.setWidth(8);
163 src.setHeight(10);
164 dest.left += 4;
165 dest.top += 4;
166 dest.setWidth(8);
167 dest.setHeight(10);
168 SDL_BlitSurface(checkmarks, &src, surface, &dest);
169 }
170 if (!enabled) {
171 uint8 *pointer;
172 int pixel = SDL_MapRGB(surface->format, 0, 0, 0);
173 uint8 bytepp = surface->format.bytesPerPixel;
174
175 if (!SDL_LockSurface(surface)) {
176 for (int y = 0; y < area.height(); y += 2) {
177 pointer = (uint8 *)surface->getPixels() + surface->pitch * (area.top + y) + (area.left * bytepp);
178 for (int x = 0; x<area.width() >> 1; x++) {
179 switch (bytepp) {
180 case 1:
181 *((uint8 *)(pointer)) = (uint8)pixel;
182 pointer += 2;
183 break;
184 case 2:
185 *((uint16 *)(pointer)) = (uint16)pixel;
186 pointer += 4;
187 break;
188 case 3: /* Format/endian independent */
189 uint8 r, g, b;
190
191 r = (pixel >> surface->format.rShift) & 0xFF;
192 g = (pixel >> surface->format.gShift) & 0xFF;
193 b = (pixel >> surface->format.bShift) & 0xFF;
194 *((pointer) + surface->format.rShift / 8) = r;
195 *((pointer) + surface->format.gShift / 8) = g;
196 *((pointer) + surface->format.bShift / 8) = b;
197 pointer += 6;
198 break;
199 case 4:
200 *((uint32 *)(pointer)) = (uint32)pixel;
201 pointer += 8;
202 break;
203 }
204 }
205 }
206 SDL_UnlockSurface(surface);
207 }
208 }
209
210 DisplayChildren();
211 }
212
213 /* Mouse hits activate us */
MouseDown(int x,int y,Shared::MouseButton btn)214 GUI_status GUI_Button:: MouseDown(int x, int y, Shared::MouseButton btn) {
215 // if(btn == SDL_BUTTON_WHEELUP || btn == SDL_BUTTON_WHEELDOWN)
216 // return GUI_PASS;
217 if (enabled && (btn == Shared::BUTTON_LEFT || btn == Shared::BUTTON_RIGHT)) {
218 pressed[0] = 1;
219 Redraw();
220 }
221 return GUI_YUM;
222 }
223
MouseUp(int x,int y,Shared::MouseButton btn)224 GUI_status GUI_Button::MouseUp(int x, int y, Shared::MouseButton btn) {
225 // if (btn==SDL_BUTTON_WHEELUP || btn==SDL_BUTTON_WHEELDOWN)
226 // return GUI_PASS;
227 if ((btn == Shared::BUTTON_LEFT || btn == Shared::BUTTON_RIGHT) && (pressed[0])) {
228 pressed[0] = 0;
229 return Activate_button(x, y, btn);
230 }
231 return GUI_YUM;
232 }
233
Activate_button(int x,int y,Shared::MouseButton btn)234 GUI_status GUI_Button::Activate_button(int x, int y, Shared::MouseButton btn) {
235 if (x >= 0 && y >= 0) {
236 if (callback_object && callback_object->callback(BUTTON_CB, this, widget_data) == GUI_QUIT)
237 return GUI_QUIT;
238 }
239 Redraw();
240 return GUI_YUM;
241 }
242
MouseMotion(int x,int y,uint8 state)243 GUI_status GUI_Button::MouseMotion(int x, int y, uint8 state) {
244 if ((pressed[0] == 1) && ((x < 0) || (y < 0))) {
245 pressed[0] = 2;
246 Redraw();
247 }
248 if ((pressed[0] == 2) && (x >= 0) && (y >= 0)) {
249 pressed[0] = 1;
250 Redraw();
251 }
252 return GUI_YUM;
253 }
254
Disable()255 void GUI_Button::Disable() {
256 enabled = 0;
257 Redraw();
258 }
259
Enable(int flag)260 void GUI_Button::Enable(int flag) {
261 enabled = flag;
262 Redraw();
263 }
264
CreateTextButtonImage(int style,const char * text,int alignment)265 Graphics::ManagedSurface *GUI_Button::CreateTextButtonImage(int style, const char *text, int alignment) {
266 Common::Rect fillrect;
267 int th, tw;
268 int tx = 0, ty = 0;
269 char *duptext = 0;
270
271 Graphics::ManagedSurface *img = new Graphics::ManagedSurface(area.width(), area.height(),
272 Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
273
274 if (img == NULL)
275 return NULL;
276
277 uint32 color1 = SDL_MapRGB(img->format, BL_R, BL_G, BL_B);
278 uint32 color2 = SDL_MapRGB(img->format, BS_R, BS_G, BS_B);
279 uint32 color3 = SDL_MapRGB(img->format, BF_R, BF_G, BF_B);
280 uint32 color4 = SDL_MapRGB(img->format, BI2_R, BI2_G, BI2_B);
281
282
283 buttonFont->setColoring(0, 0, 0);
284 buttonFont->setTransparency(true);
285 buttonFont->textExtent(text, &tw, &th);
286 if (tw > (area.width() - (4 + is_checkable * 16))) {
287 int n = (area.width() - (4 + is_checkable * 16)) / buttonFont->charWidth();
288 duptext = new char[n + 1];
289 strncpy(duptext, text, n);
290 duptext[n] = 0;
291 text = duptext;
292 buttonFont->textExtent(text, &tw, &th);
293 }
294 if (th > (area.height() - 4)) {
295 text = "";
296 }
297 switch (alignment) {
298 case BUTTON_TEXTALIGN_LEFT:
299 tx = 4 + (is_checkable * 16);
300 break;
301 case BUTTON_TEXTALIGN_CENTER:
302 tx = (area.width() - tw) >> 1;
303 break;
304 case BUTTON_TEXTALIGN_RIGHT:
305 tx = area.width() - 5 - tw;
306 break;
307 }
308 ty = (area.height() - th) >> 1;
309
310 if (!area.isEmpty()) {
311 switch (style) {
312 case BUTTON3D_UP:
313 fillrect = Common::Rect(area.width(), 2);
314 SDL_FillRect(img, &fillrect, color1);
315 fillrect.moveTo(0, area.height() - 2);
316 SDL_FillRect(img, &fillrect, color2);
317
318 fillrect = Common::Rect(2, area.height());
319 SDL_FillRect(img, &fillrect, color1);
320 fillrect.moveTo(area.width() - 2, 0);
321 SDL_FillRect(img, &fillrect, color2);
322
323 fillrect.setHeight(1);
324 fillrect.setWidth(1);
325 SDL_FillRect(img, &fillrect, color1);
326 fillrect.moveTo(1, area.height() - 1);
327 SDL_FillRect(img, &fillrect, color2);
328
329 fillrect = Common::Rect(2, 2, area.width() - 2, area.height() - 2);
330 SDL_FillRect(img, &fillrect, color3);
331
332 buttonFont->textOut(img, tx, ty, text);
333 break;
334 case BUTTON3D_DOWN:
335 fillrect = Common::Rect(area.width(), area.height());
336 SDL_FillRect(img, &fillrect, color3);
337 buttonFont->textOut(img, tx + 1, ty + 1, text);
338 break;
339 case BUTTON2D_UP:
340 fillrect = Common::Rect(area.width(), area.height());
341 SDL_FillRect(img, &fillrect, color3);
342 buttonFont->textOut(img, tx, ty, text);
343 break;
344 case BUTTON2D_DOWN:
345 fillrect = Common::Rect(area.width(), area.height());
346 SDL_FillRect(img, &fillrect, color4);
347 buttonFont->setTransparency(false);
348 buttonFont->setColoring(BI1_R, BI1_G, BI1_B, BI2_R, BI2_G, BI2_B);
349 buttonFont->textOut(img, tx, ty, text);
350 break;
351 }
352 }
353
354 delete[] duptext;
355
356 return img;
357 }
358
359 } // End of namespace Nuvie
360 } // End of namespace Ultima
361