]> Shamusworld >> Repos - apple2/blob - src/gui/element.cpp
Set eol-style to native to keep things sane.
[apple2] / src / gui / element.cpp
1 //
2 // ELEMENT.CPP
3 //
4 // Graphical User Interface base class
5 // by James L. Hammons
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  02/02/2006  Created this file
12 // JLH  02/13/2006  Added backbuffer and rendering functions
13 // JLH  03/02/2006  Moved backbuffer destruction to destructor, added parent
14 //                  corner discovery
15 //
16
17 #include "element.h"
18
19 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
20 #define MASK_R 0xFF000000
21 #define MASK_G 0x00FF0000
22 #define MASK_B 0x0000FF00
23 #define MASK_A 0x000000FF
24 #else
25 #define MASK_R 0x000000FF
26 #define MASK_G 0x0000FF00
27 #define MASK_B 0x00FF0000
28 #define MASK_A 0xFF000000
29 #endif
30
31 //#define DEBUG_ELEMENT
32
33 #ifdef DEBUG_ELEMENT
34 #include "log.h"
35 #endif
36
37 // Initialize class variables
38
39 SDL_Surface * Element::screen = NULL;
40 bool Element::needToRefreshScreen = false;
41
42 Element::Element(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*/,
43         Element * parentElement/*= NULL*/):     parent(parentElement), backstore(NULL)
44 {
45         extents.x = x,
46         extents.y = y,
47         extents.w = w,
48         extents.h = h;
49 }
50
51 Element::Element(uint32 x, uint32 y, uint32 w, uint32 h,
52         uint8 fgR/*= 0xFF*/, uint8 fgG/*= 0xFF*/, uint8 fgB/*= 0xFF*/, uint8 fgA/*= 0xFF*/,
53         uint8 bgR/*= 0x00*/, uint8 bgG/*= 0x00*/, uint8 bgB/*= 0x00*/, uint8 bgA/*= 0xFF*/,
54         Element * parentElement/*= NULL*/): parent(parentElement), backstore(NULL)
55 {
56         extents.x = x,
57         extents.y = y,
58         extents.w = w,
59         extents.h = h;
60
61         // This *should* allow us to store our colors in an endian safe way... :-/
62         uint8 * c = (uint8 *)&fgColor;
63         c[0] = fgR, c[1] = fgG, c[2] = fgB, c[3] = fgA;
64         c = (uint8 *)&bgColor;
65         c[0] = bgR, c[1] = bgG, c[2] = bgB, c[3] = bgA;
66 }
67
68 Element::~Element()
69 {
70         if (backstore)
71         {
72                 RestoreScreenFromBackstore();
73                 SDL_FreeSurface(backstore);
74                 needToRefreshScreen = true;
75         }
76 }
77
78 bool Element::Inside(uint32 x, uint32 y)
79 {
80         return (x >= (uint32)extents.x && x < (uint32)(extents.x + extents.w)
81                 && y >= (uint32)extents.y && y < (uint32)(extents.y + extents.h) ? true : false);
82 }
83
84 //Badly named--!!! FIX !!!
85 //SDL_Rect Element::GetParentCorner(void)
86 SDL_Rect Element::GetScreenCoords(void)
87 {
88         SDL_Rect rect;
89         rect.x = extents.x, rect.y = extents.y;
90
91         // First, traverse the parent tree to get the absolute screen address...
92
93         Element * currentParent = parent;
94
95         while (currentParent)
96         {
97                 rect.x += currentParent->extents.x;
98                 rect.y += currentParent->extents.y;
99                 currentParent = currentParent->parent;
100         }
101
102         return rect;
103 }
104
105 #if 0
106 //May use this in the future...
107 SDL_Rect Element::GetParentRect(void)
108 {
109         // If there is no parent, then return the entire screen as the parent's
110         // rectangle.
111
112         SDL_Rect rect;
113         rect.x = 0, rect.y = 0, rect.w = screen->w, rect.h = screen->h;
114
115         if (parent)
116         {
117                 rect.x = parent->extents.x;
118                 rect.y = parent->extents.y;
119                 rect.w = parent->extents.w;
120                 rect.h = parent->extents.h;
121         }
122
123         return rect;
124 }
125 #endif
126
127 void Element::CreateBackstore(void)
128 {
129         backstore = SDL_CreateRGBSurface(SDL_SWSURFACE, extents.w, extents.h, 32,
130                 MASK_R, MASK_G, MASK_B, 0x00);
131         SDL_BlitSurface(screen, &extents, backstore, NULL);
132 }
133
134 void Element::RestoreScreenFromBackstore(void)
135 {
136         SDL_Rect r;
137
138         r.x = extents.x;
139         r.y = extents.y;
140         SDL_BlitSurface(backstore, NULL, screen, &r);
141 }
142
143 //
144 // Class methods
145 //
146
147 void Element::SetScreen(SDL_Surface * s)
148 {
149         screen = s;
150 }
151
152 bool Element::ScreenNeedsRefreshing(void)
153 {
154         return needToRefreshScreen;
155 }
156
157 void Element::ScreenWasRefreshed(void)
158 {
159         needToRefreshScreen = false;
160 }