]> Shamusworld >> Repos - apple2/blob - src/gui/diskwindow.cpp
Converted to SDL 2, added fullscreen toggle.
[apple2] / src / gui / diskwindow.cpp
1 //
2 // DISKWINDOW.CPP
3 //
4 // Graphical User Interface disk 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/02/2009  Created this file
12 //
13
14 /*
15 IDEA: Make a recently used file list when ejecting a disk, either here or in
16       another window.
17 */
18
19 #include "diskwindow.h"
20 #include "floppy.h"
21 #include "text.h"
22 #include "button.h"
23 //#include "guimisc.h"                                                          // Various support functions
24 //#include <algorithm>
25
26 // Debug support...
27 //#define DESTRUCTOR_TESTING
28
29 // Rendering experiment...
30 //BAH
31 //#define USE_COVERAGE_LISTS
32
33 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
34 #define MASK_R 0xFF000000
35 #define MASK_G 0x00FF0000
36 #define MASK_B 0x0000FF00
37 #define MASK_A 0x000000FF
38 #else
39 #define MASK_R 0x000000FF
40 #define MASK_G 0x0000FF00
41 #define MASK_B 0x00FF0000
42 #define MASK_A 0xFF000000
43 #endif
44
45 //
46 // DiskWindow class implementation
47 //
48 // NOTE: FG/BG colors are hard-wired
49 //
50
51 DiskWindow::DiskWindow(FloppyDrive * fdp, uint32_t x/*= 0*/, uint32_t y/*= 0*/): Window(x, y, 200, 140, NULL), floppyDrive(fdp)
52 {
53 //Could probably move this into the initializer list as well...
54 //      closeButton = new Button(w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this);
55 //      list.push_back(closeButton);
56
57         name1 = new Text(4, 4, floppyDrive->GetImageName(0), 0xFF00FF00, 0xFF23239F, this);
58         name2 = new Text(4, 24, floppyDrive->GetImageName(1), 0xFF00FF00, 0xFF23239F, this);
59
60         AddElement(name1);
61         AddElement(name2);
62
63         load1 = new Button(4, 44, "Load1", this);
64         eject1 = new Button(4, 64, "Eject1", this);
65         load2 = new Button(4, 88, "Load2", this);
66         eject2 = new Button(4, 108, "Eject2", this);
67
68         load1->SetVisible(false);
69         load2->SetVisible(false);
70
71         AddElement(load1);
72         AddElement(eject1);
73         AddElement(load2);
74         AddElement(eject2);
75
76         newDisk1 = new Button(4, 132, "NewDisk1", this);
77         newDisk2 = new Button(4, 152, "NewDisk2", this);
78         writeProtect1 = new Button(4, 176, "WriteProt1", this);
79         writeProtect2 = new Button(4, 196, "WriteProt2", this);
80         swap = new Button(4, 220, "Swap Disks", this);
81
82         writeProtect1->SetText((floppyDrive->DiskIsWriteProtected(0) ? "no write" : "write"));
83         writeProtect2->SetText((floppyDrive->DiskIsWriteProtected(1) ? "no write" : "write"));
84
85         AddElement(newDisk1);
86         AddElement(newDisk2);
87         AddElement(writeProtect1);
88         AddElement(writeProtect2);
89         AddElement(swap);
90
91         // In spite of this, it's still blanking out the background...
92         // Actually, come to think of it, it's got a stale backbuffer when
93         // the GUI comes in again... !!! FIX !!!
94 #warning !!! FIX !!!
95         SetBackgroundDraw(false);
96 //      CreateBackstore();
97         Draw(); // Can we do this in the constructor??? Mebbe.
98 }
99
100 DiskWindow::~DiskWindow()
101 {
102 #ifdef DESTRUCTOR_TESTING
103 printf("Inside ~DiskWindow()...\n");
104 #endif
105 }
106
107 void DiskWindow::HandleKey(SDL_Scancode key)
108 {
109         Window::HandleKey(key);
110 #if 0
111         if (key == SDLK_ESCAPE)
112         {
113                 SDL_Event event;
114                 event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
115                 SDL_PushEvent(&event);
116         }
117
118         // Handle the items this window contains...
119         for(uint32_t i=0; i<list.size(); i++)
120                 list[i]->HandleKey(key);
121 #endif
122 }
123
124 void DiskWindow::HandleMouseMove(uint32_t x, uint32_t y)
125 {
126         Window::HandleMouseMove(x, y);
127 #if 0
128         // Handle the items this window contains...
129         for(uint32_t i=0; i<list.size(); i++)
130                 // Make coords relative to upper right corner of this window...
131                 list[i]->HandleMouseMove(x - extents.x, y - extents.y);
132 #endif
133 }
134
135 void DiskWindow::HandleMouseButton(uint32_t x, uint32_t y, bool mouseDown)
136 {
137         Window::HandleMouseButton(x, y, mouseDown);
138 #if 0
139 #if 1
140         // Handle the items this window contains...
141         for(uint32_t i=0; i<list.size(); i++)
142                 // Make coords relative to upper right corner of this window...
143                 list[i]->HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
144 #else //? This works in draggablewindow2...
145         // Handle the items this window contains...
146         for(uint32_t i=0; i<list.size(); i++)
147         {
148                 // Make coords relative to upper right corner of this window...
149                 list[i]->HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
150
151                 if (list[i]->Inside(x - extents.x, y - extents.y))
152                         clicked = false;
153         }
154 #endif
155 #endif
156 }
157
158 void DiskWindow::Draw(void)
159 {
160         Window::Draw();
161 #if 0
162         // These are *always* top level and parentless, so no need to traverse up through
163         // the parent chain...
164         SDL_FillRect(screen, &extents, bgColor);
165
166         // Handle the items this window contains...
167         for(uint32_t i=0; i<list.size(); i++)
168                 list[i]->Draw();
169
170         needToRefreshScreen = true;
171 #endif
172 }
173
174 void DiskWindow::Notify(Element * e)
175 {
176 /*      if (e == closeButton)
177         {
178                 SDL_Event event;
179                 event.type = SDL_USEREVENT;
180                 event.user.code = WINDOW_CLOSE;
181                 event.user.data1 = (void *)this;
182                 SDL_PushEvent(&event);
183         }*/
184         if (e == load1)
185         {
186                 // Load up file selector, etc... BLEAH
187                 // If load was successful, then hide load and show eject, else, fuggetaboutit
188         }
189         else if (e == eject1)
190         {
191                 floppyDrive->EjectImage(0);
192
193                 // Housekeeping
194                 eject1->SetVisible(false);
195                 load1->SetVisible(true);
196                 name1->SetText("");
197                 Draw();
198         }
199         else if (e == load2)
200         {
201                 // Load up file selector, etc... BLEAH
202                 // If load was successful, then hide load and show eject, else, fuggetaboutit
203         }
204         else if (e == eject2)
205         {
206                 floppyDrive->EjectImage(1);
207
208                 // Housekeeping
209                 eject2->SetVisible(false);
210                 load2->SetVisible(true);
211                 name2->SetText("");
212                 Draw();
213         }
214         else if (e == newDisk1)
215         {
216                 if (!floppyDrive->DriveIsEmpty(0))
217                 {
218                         // Put up a warning and give user a chance to exit this potentially
219                         // disastrous action
220 // Now, how to do this? Notify() isn't asynchronous...
221 // And until we return from here, there is no GUI main loop to show any dialogs!
222 /*
223 what you could do is like this way:
224
225 -- have a callback function for after the intermediate window gets dismissed
226 -- have a separate GUI thread
227 -- have a 2nd GUI object and run that loop to completion
228
229
230 */
231                 }
232
233                 floppyDrive->SaveImage(0);
234                 floppyDrive->CreateBlankImage(0);
235
236                 // Housekeeping
237                 eject1->SetVisible(true);
238                 load1->SetVisible(false);
239                 name1->SetText(floppyDrive->GetImageName(0));
240                 Draw();
241         }
242         else if (e == newDisk2)
243         {
244                 if (!floppyDrive->DriveIsEmpty(1))
245                 {
246                         // Put up a warning and give user a chance to exit this potentially
247                         // disastrous action
248                 }
249
250                 floppyDrive->SaveImage(1);
251                 floppyDrive->CreateBlankImage(1);
252
253                 // Housekeeping
254                 eject2->SetVisible(true);
255                 load2->SetVisible(false);
256                 name2->SetText(floppyDrive->GetImageName(1));
257                 Draw();
258         }
259         else if (e == writeProtect1)
260         {
261                 floppyDrive->SetWriteProtect((floppyDrive->DiskIsWriteProtected(0) ? false : true), 0);
262 //                      floppyDrive->SetWriteProtect(false, 0);
263 //              else
264 //                      floppyDrive->SetWriteProtect(true, 0);
265
266                 // Housekeeping
267                 writeProtect1->SetText((floppyDrive->DiskIsWriteProtected(0) ? "no write" : "write"));
268                 Draw();
269         }
270         else if (e == writeProtect2)
271         {
272                 floppyDrive->SetWriteProtect((floppyDrive->DiskIsWriteProtected(1) ? false : true), 1);
273
274                 // Housekeeping
275                 writeProtect2->SetText((floppyDrive->DiskIsWriteProtected(1) ? "no write" : "write"));
276                 Draw();
277         }
278         else if (e == swap)
279         {
280                 floppyDrive->SwapImages();
281
282                 // Housekeeping
283                 name1->SetText(floppyDrive->GetImageName(0));
284                 name2->SetText(floppyDrive->GetImageName(1));
285                 Draw();
286         }
287 }