factored out the EFFv2 saving into EFFImporter
[gemrb.git] / gemrb / core / GUI / Button.cpp
blob2410de24d0e27c77651bf4b3b0e765fd1c395cdd
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "GUI/Button.h"
23 #include "GUI/GameControl.h"
25 #include "defsounds.h"
26 #include "win32def.h"
28 #include "GameData.h"
29 #include "Interface.h"
30 #include "Palette.h"
31 #include "Variables.h"
32 #include "Video.h"
34 Button::Button()
36 Unpressed = Pressed = Selected = Disabled = NULL;
37 State = IE_GUI_BUTTON_UNPRESSED;
38 ResetEventHandler( ButtonOnPress );
39 ResetEventHandler( ButtonOnDoublePress );
40 ResetEventHandler( ButtonOnShiftPress );
41 ResetEventHandler( ButtonOnRightPress );
42 ResetEventHandler( ButtonOnDragDrop );
43 ResetEventHandler( ButtonOnDrag );
44 ResetEventHandler( MouseEnterButton );
45 ResetEventHandler( MouseLeaveButton );
46 ResetEventHandler( MouseOverButton );
47 //Text = ( char * ) calloc( 64, sizeof(char) );
48 Text = NULL;
49 hasText = false;
50 font = core->GetButtonFont();
51 normal_palette = NULL;
52 disabled_palette = font->GetPalette()->Copy();
53 for (int i = 0; i < 256; i++) {
54 disabled_palette->col[i].r = ( disabled_palette->col[i].r * 2 ) / 3;
55 disabled_palette->col[i].g = ( disabled_palette->col[i].g * 2 ) / 3;
56 disabled_palette->col[i].b = ( disabled_palette->col[i].b * 2 ) / 3;
58 Flags = IE_GUI_BUTTON_NORMAL;
59 ToggleState = false;
60 Picture = NULL;
61 Clipping = 1.0;
62 memset(&SourceRGB,0,sizeof(SourceRGB));
63 memset(&DestRGB,0,sizeof(DestRGB));
64 memset( borders, 0, sizeof( borders ));
65 starttime = 0;
67 Button::~Button()
69 Video* video = core->GetVideoDriver();
70 video->FreeSprite( Disabled );
71 video->FreeSprite( Selected );
72 video->FreeSprite( Pressed );
73 video->FreeSprite( Unpressed );
74 video->FreeSprite( Picture );
75 ClearPictureList();
76 if (Text) {
77 free( Text );
79 gamedata->FreePalette( normal_palette);
80 gamedata->FreePalette( disabled_palette);
82 /** Sets the 'type' Image of the Button to 'img'.
83 'type' may assume the following values:
84 - IE_GUI_BUTTON_UNPRESSED
85 - IE_GUI_BUTTON_PRESSED
86 - IE_GUI_BUTTON_SELECTED
87 - IE_GUI_BUTTON_DISABLED */
88 void Button::SetImage(unsigned char type, Sprite2D* img)
90 switch (type) {
91 case IE_GUI_BUTTON_UNPRESSED:
92 case IE_GUI_BUTTON_LOCKED:
93 case IE_GUI_BUTTON_LOCKED_PRESSED:
94 core->GetVideoDriver()->FreeSprite( Unpressed );
95 Unpressed = img;
96 break;
98 case IE_GUI_BUTTON_SECOND:
99 case IE_GUI_BUTTON_PRESSED:
100 core->GetVideoDriver()->FreeSprite( Pressed );
101 Pressed = img;
102 break;
104 case IE_GUI_BUTTON_SELECTED:
105 core->GetVideoDriver()->FreeSprite( Selected );
106 Selected = img;
107 break;
109 case IE_GUI_BUTTON_DISABLED:
110 case IE_GUI_BUTTON_THIRD:
111 core->GetVideoDriver()->FreeSprite( Disabled );
112 Disabled = img;
113 break;
115 Changed = true;
118 /** make SourceRGB go closer to DestRGB */
119 void Button::CloseUpColor()
121 if (!starttime) return;
122 //using the realtime timer, because i don't want to
123 //handle Game at this point
124 unsigned long newtime;
126 Changed = true;
127 GetTime( newtime );
128 if (newtime<starttime) {
129 return;
131 SourceRGB.r = (SourceRGB.r + DestRGB.r) / 2;
132 SourceRGB.g = (SourceRGB.g + DestRGB.g) / 2;
133 SourceRGB.b = (SourceRGB.b + DestRGB.b) / 2;
134 SourceRGB.a = (SourceRGB.a + DestRGB.a) / 2;
135 if (SourceRGB.r == DestRGB.r &&
136 SourceRGB.g == DestRGB.g &&
137 SourceRGB.b == DestRGB.b &&
138 SourceRGB.a == DestRGB.a) {
139 starttime = 0;
140 return;
142 starttime = newtime + 40;
145 /** Draws the Control on the Output Display */
146 void Button::Draw(unsigned short x, unsigned short y)
148 if (!Changed && !(Owner->Flags&WF_FLOAT) ) {
149 return;
151 Changed = false;
152 if (XPos == 65535 || Width == 0) {
153 return;
156 Video * video = core->GetVideoDriver();
158 // Button image
159 if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) {
160 Sprite2D* Image = NULL;
162 switch (State) {
163 case IE_GUI_BUTTON_UNPRESSED:
164 case IE_GUI_BUTTON_LOCKED:
165 case IE_GUI_BUTTON_LOCKED_PRESSED:
166 Image = Unpressed;
167 break;
169 case IE_GUI_BUTTON_SECOND:
170 case IE_GUI_BUTTON_PRESSED:
171 Image = Pressed;
172 if (! Image)
173 Image = Unpressed;
174 break;
176 case IE_GUI_BUTTON_SELECTED:
177 Image = Selected;
178 if (! Image)
179 Image = Unpressed;
180 break;
182 case IE_GUI_BUTTON_DISABLED:
183 case IE_GUI_BUTTON_THIRD:
184 Image = Disabled;
185 if (! Image)
186 Image = Unpressed;
187 break;
189 if (Image) {
190 // FIXME: maybe it's useless...
191 int xOffs = ( Width / 2 ) - ( Image->Width / 2 );
192 int yOffs = ( Height / 2 ) - ( Image->Height / 2 );
194 video->BlitSprite( Image, x + XPos + xOffs, y + YPos + yOffs, true );
198 if (State == IE_GUI_BUTTON_PRESSED) {
199 //shift the writing/border a bit
200 x+= 2;
201 y+= 2;
204 // Button picture
205 if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) {
206 // Picture is drawn centered
207 int xOffs = ( Width / 2 ) - ( Picture->Width / 2 );
208 int yOffs = ( Height / 2 ) - ( Picture->Height / 2 );
209 if (Flags & IE_GUI_BUTTON_HORIZONTAL) {
210 xOffs += x + XPos + Picture->XPos;
211 yOffs += y + YPos + Picture->YPos;
212 video->BlitSprite( Picture, xOffs, yOffs, true );
213 Region r = Region( xOffs, yOffs + (int) (Picture->Height * Clipping), Picture->Width, (int) (Picture->Height*(1.0 - Clipping)) );
214 video->DrawRect( r, SourceRGB, true );
215 // do NOT uncomment this, you can't change Changed or invalidate things from
216 // the middle of Window::DrawWindow() -- it needs moving to somewhere else
217 //CloseUpColor();
219 else {
220 Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(Picture->Width * Clipping), Picture->Height );
221 video->BlitSprite( Picture, x + XPos + xOffs + Picture->XPos, y + YPos + yOffs + Picture->YPos, true, &r );
225 // Composite pictures (paperdolls/description icons)
226 if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) {
227 std::list<Sprite2D*>::iterator iter = PictureList.begin();
228 int xOffs = 0, yOffs = 0;
229 if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
230 // Center the hotspots of all pictures
231 xOffs = Width/2;
232 yOffs = Height/2;
233 } else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) {
234 // Display as-is
235 xOffs = 0;
236 yOffs = 0;
237 } else {
238 // Center the first picture, and align the rest to that
239 xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos;
240 yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos;
243 for (; iter != PictureList.end(); ++iter) {
244 video->BlitSprite( *iter, x + XPos + xOffs, y + YPos + yOffs, true );
248 // Button picture
249 if (AnimPicture) {
250 int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 );
251 int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 );
252 Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height );
254 if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
255 video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r );
256 } else {
257 video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r );
261 // Button label
262 if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) {
263 Palette* ppoi = normal_palette;
264 int align = 0;
266 if (State == IE_GUI_BUTTON_DISABLED)
267 ppoi = disabled_palette;
268 // FIXME: hopefully there's no button which sinks when selected
269 // AND has text label
270 //else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) {
272 if (Flags & IE_GUI_BUTTON_ALIGN_LEFT)
273 align |= IE_FONT_ALIGN_LEFT;
274 else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT)
275 align |= IE_FONT_ALIGN_RIGHT;
276 else
277 align |= IE_FONT_ALIGN_CENTER;
279 if (Flags & IE_GUI_BUTTON_ALIGN_TOP)
280 align |= IE_FONT_ALIGN_TOP;
281 else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM)
282 align |= IE_FONT_ALIGN_BOTTOM;
283 else
284 align |= IE_FONT_ALIGN_MIDDLE;
286 if (! (Flags & IE_GUI_BUTTON_MULTILINE)) {
287 align |= IE_FONT_SINGLE_LINE;
289 font->Print( Region( x + XPos, y + YPos, Width - 2, Height - 2),
290 ( unsigned char * ) Text, ppoi,
291 (ieByte) align, true );
294 if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) {
295 for (int i = 0; i < MAX_NUM_BORDERS; i++) {
296 ButtonBorder *fr = &borders[i];
297 if (! fr->enabled) continue;
299 Region r = Region( x + XPos + fr->dx1, y + YPos + fr->dy1, Width - (fr->dx1 + fr->dx2 + 1), Height - (fr->dy1 + fr->dy2 + 1) );
300 video->DrawRect( r, fr->color, fr->filled );
304 /** Sets the Button State */
305 void Button::SetState(unsigned char state)
307 if (state > IE_GUI_BUTTON_LOCKED_PRESSED) {// If wrong value inserted
308 return;
310 if (State != state) {
311 Changed = true;
312 State = state;
315 void Button::SetBorder(int index, int dx1, int dy1, int dx2, int dy2, const Color &color, bool enabled, bool filled)
317 if (index >= MAX_NUM_BORDERS)
318 return;
320 ButtonBorder *fr = &borders[index];
321 fr->dx1 = dx1;
322 fr->dy1 = dy1;
323 fr->dx2 = dx2;
324 fr->dy2 = dy2;
325 fr->color = color;
326 fr->enabled = enabled;
327 fr->filled = filled;
328 Changed = true;
331 void Button::EnableBorder(int index, bool enabled)
333 if (index >= MAX_NUM_BORDERS)
334 return;
336 if (borders[index].enabled != enabled) {
337 borders[index].enabled = enabled;
338 Changed = true;
342 void Button::SetFont(Font* newfont)
344 font = newfont;
346 /** Handling The default button (enter) */
347 void Button::OnSpecialKeyPress(unsigned char Key)
349 if (State != IE_GUI_BUTTON_DISABLED && State != IE_GUI_BUTTON_LOCKED) {
350 if (Key == GEM_RETURN) {
351 if (Flags & IE_GUI_BUTTON_DEFAULT ) {
352 RunEventHandler( ButtonOnPress );
353 return;
356 else if (Key == GEM_ESCAPE) {
357 if (Flags & IE_GUI_BUTTON_CANCEL ) {
358 RunEventHandler( ButtonOnPress );
359 return;
363 Control::OnSpecialKeyPress(Key);
366 /** Mouse Button Down */
367 void Button::OnMouseDown(unsigned short x, unsigned short y,
368 unsigned short Button, unsigned short Mod)
370 if (State == IE_GUI_BUTTON_DISABLED) {
371 Control::OnMouseDown(x,y,Button,Mod);
372 return;
375 if (core->GetDraggedItem () && !ButtonOnDragDrop) {
376 Control::OnMouseDown(x,y,Button,Mod);
377 return;
380 ScrollBar* scrlbr = (ScrollBar*) sb;
381 if (!scrlbr) {
382 Control *ctrl = Owner->GetScrollControl();
383 if (ctrl && (ctrl->ControlType == IE_GUI_SCROLLBAR)) {
384 scrlbr = (ScrollBar *) ctrl;
388 //Button == 1 means Left Mouse Button
389 switch(Button&GEM_MB_NORMAL) {
390 case GEM_MB_ACTION:
391 // We use absolute screen position here, so drag_start
392 // remains valid even after window/control is moved
393 drag_start.x = Owner->XPos + XPos + x;
394 drag_start.y = Owner->YPos + YPos + y;
396 if (State == IE_GUI_BUTTON_LOCKED) {
397 SetState( IE_GUI_BUTTON_LOCKED_PRESSED );
398 return;
400 SetState( IE_GUI_BUTTON_PRESSED );
401 if (Flags & IE_GUI_BUTTON_SOUND) {
402 core->PlaySound( DS_BUTTON_PRESSED );
404 if ((Button & GEM_MB_DOUBLECLICK) && ButtonOnDoublePress) {
405 RunEventHandler( ButtonOnDoublePress );
406 printMessage("Button","Doubleclick detected\n",GREEN);
408 break;
409 case GEM_MB_SCRLUP:
410 if (scrlbr) {
411 scrlbr->ScrollUp();
412 core->RedrawAll();
414 break;
415 case GEM_MB_SCRLDOWN:
416 if (scrlbr) {
417 scrlbr->ScrollDown();
418 core->RedrawAll();
420 break;
423 /** Mouse Button Up */
424 void Button::OnMouseUp(unsigned short x, unsigned short y,
425 unsigned short Button, unsigned short Mod)
427 if (State == IE_GUI_BUTTON_DISABLED) {
428 return;
431 //what was just dropped?
432 int dragtype = 0;
433 if (core->GetDraggedItem ()) dragtype=1;
434 if (core->GetDraggedPortrait ()) dragtype=2;
436 //if something was dropped, but it isn't handled here: it didn't happen
437 if (dragtype && !ButtonOnDragDrop)
438 return;
440 switch (State) {
441 case IE_GUI_BUTTON_PRESSED:
442 if (ToggleState) {
443 SetState( IE_GUI_BUTTON_SELECTED );
444 } else {
445 SetState( IE_GUI_BUTTON_UNPRESSED );
447 break;
448 case IE_GUI_BUTTON_LOCKED_PRESSED:
449 SetState( IE_GUI_BUTTON_LOCKED );
450 break;
453 //in case of dragged/dropped portraits, allow the event to happen even
454 //when we are out of bound
455 if (dragtype!=2) {
456 if (( x >= Width ) || ( y >= Height )) {
457 return;
460 if (Flags & IE_GUI_BUTTON_CHECKBOX) {
461 //checkbox
462 ToggleState = !ToggleState;
463 if (ToggleState)
464 SetState( IE_GUI_BUTTON_SELECTED );
465 else
466 SetState( IE_GUI_BUTTON_UNPRESSED );
467 if (VarName[0] != 0) {
468 ieDword tmp = 0;
469 core->GetDictionary()->Lookup( VarName, tmp );
470 tmp ^= Value;
471 core->GetDictionary()->SetAt( VarName, tmp );
472 Owner->RedrawControls( VarName, tmp );
474 } else {
475 if (Flags & IE_GUI_BUTTON_RADIOBUTTON) {
476 //radio button
477 ToggleState = true;
478 SetState( IE_GUI_BUTTON_SELECTED );
480 if (VarName[0] != 0) {
481 core->GetDictionary()->SetAt( VarName, Value );
482 Owner->RedrawControls( VarName, Value );
486 switch (dragtype) {
487 case 1:
488 RunEventHandler( ButtonOnDragDrop );
489 return;
490 case 2:
491 RunEventHandler( ButtonOnDragDropPortrait );
492 return;
495 if ((Button&GEM_MB_NORMAL) == GEM_MB_ACTION) {
496 if ((Mod & GEM_MOD_SHIFT) && ButtonOnShiftPress)
497 RunEventHandler( ButtonOnShiftPress );
498 else
499 RunEventHandler( ButtonOnPress );
500 } else {
501 if (Button == GEM_MB_MENU && ButtonOnRightPress)
502 RunEventHandler( ButtonOnRightPress );
506 void Button::OnMouseOver(unsigned short x, unsigned short y)
508 Owner->Cursor = IE_CURSOR_NORMAL;
509 if (State == IE_GUI_BUTTON_DISABLED) {
510 return;
513 if ( RunEventHandler( MouseOverButton )) {
514 //event handler destructed this object
515 return;
518 //well, no more flags for buttons, and the portraits we can perform action on
519 //are in fact 'draggable multiline pictures' (with image)
520 if ((Flags & IE_GUI_BUTTON_DISABLED_P) == IE_GUI_BUTTON_PORTRAIT) {
521 GameControl *gc = core->GetGameControl();
522 if (gc) {
523 Owner->Cursor = gc->GetDefaultCursor();
527 if (State == IE_GUI_BUTTON_LOCKED) {
528 return;
531 //portrait buttons are draggable and locked
532 if ((Flags & IE_GUI_BUTTON_DRAGGABLE) &&
533 (State == IE_GUI_BUTTON_PRESSED || State ==IE_GUI_BUTTON_LOCKED_PRESSED)) {
534 // We use absolute screen position here, so drag_start
535 // remains valid even after window/control is moved
536 int dx = Owner->XPos + XPos + x - drag_start.x;
537 int dy = Owner->YPos + YPos + y - drag_start.y;
538 core->GetDictionary()->SetAt( "DragX", dx );
539 core->GetDictionary()->SetAt( "DragY", dy );
540 drag_start.x = (ieWord) (drag_start.x + dx);
541 drag_start.y = (ieWord) (drag_start.y + dy);
542 RunEventHandler( ButtonOnDrag );
546 void Button::OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/)
548 if (State == IE_GUI_BUTTON_DISABLED) {
549 return;
552 if (MouseEnterButton !=0 && VarName[0] != 0) {
553 core->GetDictionary()->SetAt( VarName, Value );
556 RunEventHandler( MouseEnterButton );
559 void Button::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/)
561 if (State == IE_GUI_BUTTON_DISABLED) {
562 return;
565 if (MouseLeaveButton !=0 && VarName[0] != 0) {
566 core->GetDictionary()->SetAt( VarName, Value );
569 RunEventHandler( MouseLeaveButton );
573 /** Sets the Text of the current control */
574 int Button::SetText(const char* string, int /*pos*/)
576 free(Text);
577 Text = NULL;
578 if (string == NULL) {
579 hasText = false;
580 } else if (string[0] == 0) {
581 hasText = false;
582 } else {
583 Text = strndup( string, 255 );
584 if (Flags&IE_GUI_BUTTON_LOWERCASE)
585 strlwr( Text );
586 else if (Flags&IE_GUI_BUTTON_CAPS)
587 strupr( Text );
588 hasText = true;
590 Changed = true;
591 return 0;
594 /** Set Event Handler */
595 bool Button::SetEvent(int eventType, EventHandler handler)
597 Changed = true;
599 switch (eventType) {
600 case IE_GUI_BUTTON_ON_PRESS:
601 ButtonOnPress = handler;
602 break;
603 case IE_GUI_MOUSE_OVER_BUTTON:
604 MouseOverButton = handler;
605 break;
606 case IE_GUI_MOUSE_ENTER_BUTTON:
607 MouseEnterButton = handler;
608 break;
609 case IE_GUI_MOUSE_LEAVE_BUTTON:
610 MouseLeaveButton = handler;
611 break;
612 case IE_GUI_BUTTON_ON_SHIFT_PRESS:
613 ButtonOnShiftPress = handler;
614 break;
615 case IE_GUI_BUTTON_ON_RIGHT_PRESS:
616 ButtonOnRightPress = handler;
617 break;
618 case IE_GUI_BUTTON_ON_DRAG_DROP:
619 ButtonOnDragDrop = handler;
620 break;
621 case IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT:
622 ButtonOnDragDropPortrait = handler;
623 break;
624 case IE_GUI_BUTTON_ON_DRAG:
625 ButtonOnDrag = handler;
626 break;
627 case IE_GUI_BUTTON_ON_DOUBLE_PRESS:
628 ButtonOnDoublePress = handler;
629 break;
630 default:
631 return false;
634 return true;
637 /** Redraws a button from a given radio button group */
638 void Button::RedrawButton(const char* VariableName, unsigned int Sum)
640 if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
641 return;
643 if (State == IE_GUI_BUTTON_DISABLED) {
644 return;
646 if (Flags & IE_GUI_BUTTON_RADIOBUTTON) {
647 ToggleState = ( Sum == Value );
648 } //radio button, exact value
649 else if (Flags & IE_GUI_BUTTON_CHECKBOX) {
650 ToggleState = !!( Sum & Value );
651 } //checkbox, bitvalue
652 else {
653 return;
654 } //other buttons, nothing to redraw
655 if (ToggleState) {
656 SetState(IE_GUI_BUTTON_SELECTED);
657 } else {
658 SetState(IE_GUI_BUTTON_UNPRESSED);
661 /** Sets the Picture */
662 void Button::SetPicture(Sprite2D* newpic)
664 core->GetVideoDriver()->FreeSprite( Picture );
665 ClearPictureList();
666 Picture = newpic;
667 Changed = true;
668 Flags |= IE_GUI_BUTTON_PICTURE;
669 Owner->Invalidate();
672 /** Clears the list of Pictures */
673 void Button::ClearPictureList()
675 Video* video = core->GetVideoDriver();
676 for (std::list<Sprite2D*>::iterator iter = PictureList.begin();
677 iter != PictureList.end(); ++iter)
678 video->FreeSprite( *iter );
679 PictureList.clear();
680 Changed = true;
681 Owner->Invalidate();
684 /** Add picture to the end of the list of Pictures */
685 void Button::StackPicture(Sprite2D* Picture)
687 PictureList.push_back(Picture);
688 Changed = true;
689 Flags |= IE_GUI_BUTTON_PICTURE;
690 Owner->Invalidate();
693 bool Button::IsPixelTransparent(unsigned short x, unsigned short y)
695 // some buttons have hollow Image frame filled w/ Picture
696 // some buttons in BG2 are text only (if BAM == 'GUICTRL')
697 if (Picture || PictureList.size() || ! Unpressed) return false;
698 return Unpressed->IsPixelTransparent(x, y);
701 // Set palette used for drawing button label in normal state
702 void Button::SetTextColor(const Color &fore, const Color &back)
704 gamedata->FreePalette( normal_palette );
705 normal_palette = core->CreatePalette( fore, back );
706 Changed = true;
709 void Button::SetHorizontalOverlay(double clip, const Color &src, const Color &dest)
711 if ((Clipping>clip) || !(Flags&IE_GUI_BUTTON_HORIZONTAL) ) {
712 Flags |= IE_GUI_BUTTON_HORIZONTAL;
713 SourceRGB=src;
714 DestRGB=dest;
715 GetTime( starttime );
716 starttime += 40;
718 Clipping = clip;
719 Changed = true;