]> Shamusworld >> Repos - apple2/blob - src/gui/window.cpp
Moved stuff into trunk (part 2)...
[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 #define USE_COVERAGE_LISTS
26
27 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
28 #define MASK_R 0xFF000000
29 #define MASK_G 0x00FF0000
30 #define MASK_B 0x0000FF00
31 #define MASK_A 0x000000FF
32 #else
33 #define MASK_R 0x000000FF
34 #define MASK_G 0x0000FF00
35 #define MASK_B 0x00FF0000
36 #define MASK_A 0xFF000000
37 #endif
38
39 //
40 // Window class implementation
41 //
42 // NOTE: FG/BG colors are hard-wired
43 //
44
45 Window::Window(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*/,
46         void (* f)(Element *)/*= NULL*/):
47         Element(x, y, w, h, 0x4D, 0xFF, 0x84, 0xFF, 0x1F, 0x84, 0x84, 0xFF), handler(f),
48         cbWidth((closeBox[0] << 8) | closeBox[1]), cbHeight((closeBox[2] << 8) | closeBox[3]),
49         cbUp(SDL_CreateRGBSurfaceFrom(&closeBox[4], cbWidth, cbHeight, 32, cbWidth * 4,
50                 MASK_R, MASK_G, MASK_B, MASK_A)),
51         cbDown(SDL_CreateRGBSurfaceFrom(&closeBoxDown[4], cbWidth, cbHeight, 32, cbWidth * 4,
52                 MASK_R, MASK_G, MASK_B, MASK_A)),
53         cbHover(SDL_CreateRGBSurfaceFrom(&closeBoxHover[4], cbWidth, cbHeight, 32, cbWidth * 4,
54                 MASK_R, MASK_G, MASK_B, MASK_A))
55 {
56 //Could probably move this into the initializer list as well...
57         closeButton = new Button(w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this);
58         list.push_back(closeButton);
59
60         CreateBackstore();
61         Draw(); // Can we do this in the constructor??? Mebbe.
62 }
63
64 Window::~Window()
65 {
66 #ifdef DESTRUCTOR_TESTING
67 printf("Inside ~Window()...\n");
68 #endif
69         for(uint32 i=0; i<list.size(); i++)
70                 if (list[i])
71                         delete list[i];
72
73         SDL_FreeSurface(cbUp);
74         SDL_FreeSurface(cbDown);
75         SDL_FreeSurface(cbHover);
76 }
77
78 void Window::HandleKey(SDLKey key)
79 {
80         if (key == SDLK_ESCAPE)
81         {
82                 SDL_Event event;
83                 event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
84                 SDL_PushEvent(&event);
85         }
86
87         // Handle the items this window contains...
88         for(uint32 i=0; i<list.size(); i++)
89                 list[i]->HandleKey(key);
90 }
91
92 void Window::HandleMouseMove(uint32 x, uint32 y)
93 {
94         // Handle the items this window contains...
95         for(uint32 i=0; i<list.size(); i++)
96                 // Make coords relative to upper right corner of this window...
97                 list[i]->HandleMouseMove(x - extents.x, y - extents.y);
98 }
99
100 void Window::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
101 {
102         // Handle the items this window contains...
103         for(uint32 i=0; i<list.size(); i++)
104                 // Make coords relative to upper right corner of this window...
105                 list[i]->HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
106 }
107
108 void Window::Draw(void)
109 {
110 #ifdef USE_COVERAGE_LISTS
111         // These are *always* top level and parentless, so no need to traverse up through
112         // the parent chain...
113         for(std::list<SDL_Rect>::iterator i=coverList.begin(); i!=coverList.end(); i++)
114                 SDL_FillRect(screen, &(*i), bgColor);
115
116         // Handle the items this window contains...
117         for(uint32 i=0; i<list.size(); i++)
118                 list[i]->Draw();
119 #else
120         // These are *always* top level and parentless, so no need to traverse up through
121         // the parent chain...
122         SDL_FillRect(screen, &extents, bgColor);
123
124         // Handle the items this window contains...
125         for(uint32 i=0; i<list.size(); i++)
126                 list[i]->Draw();
127 #endif
128
129 //Prolly don't need this since the close button will do this for us...
130         needToRefreshScreen = true;
131 }
132
133 void Window::Notify(Element * e)
134 {
135         if (e == closeButton)
136         {
137                 SDL_Event event;
138                 event.type = SDL_USEREVENT;
139                 event.user.code = WINDOW_CLOSE;
140                 event.user.data1 = (void *)this;
141                 SDL_PushEvent(&event);
142         }
143 }
144
145 void Window::AddElement(Element * e)
146 {
147         list.push_back(e);
148 }