]> Shamusworld >> Repos - apple2/blob - src/gui/window.cpp
28c0212a4b6466ab350993823f3523ccafb4b8c8
[apple2] / src / gui / window.cpp
1 //
2 // WINDOW.CPP
3 //
4 // Graphical User Interface window class
5 // by James L. Hammons
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  02/03/2006  Created this file
12 // JLH  02/09/2006  Fixed various problems with the class implementation
13 // JLH  02/14/2006  Added window rendering
14 //
15
16 #include "window.h"
17 #include "button.h"
18 #include "guimisc.h"                                                            // Various support functions
19 #include <algorithm>
20
21 // Debug support...
22 //#define DESTRUCTOR_TESTING
23
24 // Rendering experiment...
25 //BAH
26 //#define USE_COVERAGE_LISTS
27
28 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
29 #define MASK_R 0xFF000000
30 #define MASK_G 0x00FF0000
31 #define MASK_B 0x0000FF00
32 #define MASK_A 0x000000FF
33 #else
34 #define MASK_R 0x000000FF
35 #define MASK_G 0x0000FF00
36 #define MASK_B 0x00FF0000
37 #define MASK_A 0xFF000000
38 #endif
39
40 //
41 // Window class implementation
42 //
43 // NOTE: FG/BG colors are hard-wired
44 //
45
46 Window::Window(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*/,
47         void (* f)(Element *)/*= NULL*/):
48         Element(x, y, w, h, 0x4D, 0xFF, 0x84, 0xFF, 0x1F, 0x84, 0x84, 0xFF), handler(f),
49         cbWidth((closeBox[0] << 8) | closeBox[1]), cbHeight((closeBox[2] << 8) | closeBox[3]),
50         cbUp(SDL_CreateRGBSurfaceFrom(&closeBox[4], cbWidth, cbHeight, 32, cbWidth * 4,
51                 MASK_R, MASK_G, MASK_B, MASK_A)),
52         cbDown(SDL_CreateRGBSurfaceFrom(&closeBoxDown[4], cbWidth, cbHeight, 32, cbWidth * 4,
53                 MASK_R, MASK_G, MASK_B, MASK_A)),
54         cbHover(SDL_CreateRGBSurfaceFrom(&closeBoxHover[4], cbWidth, cbHeight, 32, cbWidth * 4,
55                 MASK_R, MASK_G, MASK_B, MASK_A)), drawBackground(true)
56 {
57 //Could probably move this into the initializer list as well...
58 //      closeButton = new Button(w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this);
59 //      list.push_back(closeButton);
60
61         CreateBackstore();
62         Draw(); // Can we do this in the constructor??? Mebbe.
63 }
64
65 Window::~Window()
66 {
67 #ifdef DESTRUCTOR_TESTING
68 printf("Inside ~Window()...\n");
69 #endif
70         for(uint32 i=0; i<list.size(); i++)
71                 if (list[i])
72                         delete list[i];
73
74         SDL_FreeSurface(cbUp);
75         SDL_FreeSurface(cbDown);
76         SDL_FreeSurface(cbHover);
77 }
78
79 void Window::HandleKey(SDLKey key)
80 {
81         if (key == SDLK_ESCAPE)
82         {
83                 SDL_Event event;
84                 event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
85                 SDL_PushEvent(&event);
86         }
87
88         // Handle the items this window contains...
89         for(uint32 i=0; i<list.size(); i++)
90                 list[i]->HandleKey(key);
91 }
92
93 void Window::HandleMouseMove(uint32 x, uint32 y)
94 {
95         // Handle the items this window contains...
96         for(uint32 i=0; i<list.size(); i++)
97                 // Make coords relative to upper right corner of this window...
98                 list[i]->HandleMouseMove(x - extents.x, y - extents.y);
99 }
100
101 void Window::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
102 {
103 #if 1
104         // Handle the items this window contains...
105         for(uint32 i=0; i<list.size(); i++)
106                 // Make coords relative to upper right corner of this window...
107                 list[i]->HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
108 #else //? This works in draggablewindow2...
109         // Handle the items this window contains...
110         for(uint32 i=0; i<list.size(); i++)
111         {
112                 // Make coords relative to upper right corner of this window...
113                 list[i]->HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
114
115                 if (list[i]->Inside(x - extents.x, y - extents.y))
116                         clicked = false;
117         }
118 #endif
119 }
120
121 void Window::Draw(void)
122 {
123 #ifdef USE_COVERAGE_LISTS
124         // These are *always* top level and parentless, so no need to traverse up through
125         // the parent chain...
126         for(std::list<SDL_Rect>::iterator i=coverList.begin(); i!=coverList.end(); i++)
127                 SDL_FillRect(screen, &(*i), bgColor);
128
129         // Handle the items this window contains...
130         for(uint32 i=0; i<list.size(); i++)
131                 list[i]->Draw();
132 #else
133         if (drawBackground)
134         {
135                 // These are *always* top level and parentless, so no need to traverse up through
136                 // the parent chain...
137                 SDL_FillRect(screen, &extents, bgColor);
138         }
139         else
140                 RestoreScreenFromBackstore();
141
142         // Handle the items this window contains...
143         for(uint32 i=0; i<list.size(); i++)
144                 list[i]->Draw();
145 #endif
146
147 //Prolly don't need this since the close button will do this for us...
148 //Close button isn't mandatory anymore...
149         needToRefreshScreen = true;
150 }
151
152 // This is only called if a close button has been added
153 void Window::Notify(Element * e)
154 {
155         if (e == closeButton)
156         {
157                 SDL_Event event;
158                 event.type = SDL_USEREVENT;
159                 event.user.code = WINDOW_CLOSE;
160                 event.user.data1 = (void *)this;
161                 SDL_PushEvent(&event);
162         }
163 }
164
165 void Window::AddElement(Element * e)
166 {
167         list.push_back(e);
168 }
169
170 void Window::AddCloseButton(void)
171 {
172         // Only allow this to happen once!
173         if (closeButton == NULL)
174         {
175                 closeButton = new Button(extents.w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this);
176                 list.push_back(closeButton);
177         }
178 }
179
180 void Window::SetBackgroundDraw(bool state)
181 {
182         drawBackground = state;
183 }