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