1 /*
2 Copyright (C) 2004 by James Gregory
3 Part of the GalaxyHack project
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY.
9
10 See the COPYING file for more details.
11 */
12
13 #include "DragWindow.h"
14 #include "Globals.h"
15
16 #include <boost/filesystem/operations.hpp>
17 #include <boost/filesystem/exception.hpp>
18
DragWindow(int ix,int iy,int iParentID,int flags)19 DragWindow::DragWindow(int ix, int iy, int iParentID, int flags):
20 GenWindow_Base(ix, iy, iParentID, flags), bDrag(0) {}
21
InitRects()22 void DragWindow::InitRects() {
23 //shuffle away from edges if we have been created partially off screen
24 if (rect.x < smallBorderSize)
25 rect.x = smallBorderSize;
26 if (rect.y < smallBorderSize)
27 rect.y = smallBorderSize;
28 if (rect.x + rect.w + smallBorderSize > globalSettings.screenWidth)
29 rect.x = globalSettings.screenWidth - rect.w - smallBorderSize;
30 if (rect.y + rect.h + smallBorderSize > globalSettings.screenHeight)
31 rect.y = globalSettings.screenHeight - rect.h - smallBorderSize;
32
33 InitBorder();
34
35 closeRect.x = rect.x + rect.w - genPictures[GENPIC_CLOSEBOX]->w;
36 closeRect.y = rect.y;
37 closeRect.w = genPictures[GENPIC_CLOSEBOX]->w;
38 closeRect.h = genPictures[GENPIC_CLOSEBOX]->h;
39 }
40
AddSideTitle(int nSide)41 void DragWindow::AddSideTitle(int nSide) {
42 string outputStr = sides[nSide].name + ":";
43
44 theText.push_back(WindowText(outputStr, true));
45 theText.push_back(WindowText(""));
46 }
47
AddGroupTitle(int nSide,int nGroup)48 void DragWindow::AddGroupTitle(int nSide, int nGroup) {
49 char output[32];
50
51 sprintf(output, "%s Group %d:", sides[nSide].name.c_str(), nGroup + 1);
52
53 theText.push_back(WindowText(output, true));
54 theText.push_back(WindowText(""));
55 }
56
DrawSelf()57 void DragWindow::DrawSelf() {
58 if (visible) {
59 GenWindow_Base::DrawSelf();
60
61 if (!cantClose)
62 JSDL.Blt(genPictures[GENPIC_CLOSEBOX], closeRect);
63
64 int x = rect.x + smallBorderSize;
65 int y = rect.y + smallBorderSize;
66
67 for (int i = 0; i != theText.size(); ++i) {
68 if (theText[i].bold)
69 boldFonts.BlitString(x, y, 0, theText[i]);
70 else
71 normalFonts.BlitString(x, y, 0, theText[i]);
72 y+= lineGap;
73 }
74 }
75 }
76
MouseD(Uint8 button,Uint16 x,Uint16 y)77 bool DragWindow::MouseD(Uint8 button, Uint16 x, Uint16 y) {
78 if (!visible)
79 return false;
80
81 bool ret = GenWindow_Base::MouseD(button, x, y);
82
83 if (ret == true) {
84 if (button == SDL_BUTTON_LEFT) {
85 //close box?
86 if (!cantClose
87 && x >= closeRect.x
88 && x < closeRect.x + closeRect.w
89 && y >= closeRect.y
90 && y < closeRect.y + closeRect.h)
91 closed = true;
92 else if (!bStatic) { //start drag
93 bDrag = true;
94 saveMousePosx = x;
95 saveMousePosy = y;
96 }
97 }
98 }
99
100 return ret;
101 }
102
MouseM(Uint8 state,Uint16 x,Uint16 y)103 bool DragWindow::MouseM(Uint8 state, Uint16 x, Uint16 y) {
104 //drag
105 if (bDrag && state & SDL_BUTTON(1)) {
106 int distx = x - saveMousePosx;
107 int disty = y - saveMousePosy;
108
109 Move(distx, disty);
110
111 bDrag = true;
112 saveMousePosx = x;
113 saveMousePosy = y;
114 return true;
115 }
116
117 bDrag = false;
118 return false;
119 }
120
Move(int distx,int disty)121 void DragWindow::Move(int distx, int disty) {
122 GenWindow_Base::Move(distx, disty);
123
124 closeRect.x+= distx;
125
126 closeRect.y+= disty;
127 }
128
129
InfoString(const string & iTheString)130 InfoString::InfoString(const string& iTheString):
131 DragWindow(0, 0, none_constant, 0), theString(iTheString) {
132 //width
133 int longest = 0;
134 int currentLength = 0;
135 int newlines = 0;
136
137 for (int i = 0; i != theString.size(); ++i) {
138 if (theString[i] == '\n') {
139 if (currentLength > longest)
140 longest = currentLength;
141
142 currentLength = 0;
143 ++newlines;
144 }
145 else
146 ++currentLength;
147 }
148
149 //one last time
150 if (currentLength > longest)
151 longest = currentLength;
152
153 //overall dimensions
154 rect.w = (longest + 1) * normalLetterWidth;
155 rect.h = (newlines + 1) * lineGap;
156
157 //if just one line, make room for the close cross
158 if (newlines == 0)
159 rect.w+= genPictures[GENPIC_CLOSEBOX]->w;
160
161 CentreWindow();
162
163 InitRects();
164 anInfoString = 1;
165 }
166
~InfoString()167 InfoString::~InfoString() {
168 anInfoString = 0;
169 }
170
DrawSelf()171 void InfoString::DrawSelf() {
172 DragWindow::DrawSelf();
173
174 int x = rect.x + smallBorderSize;
175 int y = rect.y + smallBorderSize;
176
177
178 normalFonts.BlitString(x, y, 0, theString);
179 }
180
181 ///
182
183
Slider(int ix,int iy,int iSliderVar,int iVarMin,int iVarMax,int iParentID,int flags)184 Slider::Slider(int ix, int iy, int iSliderVar, int iVarMin, int iVarMax, int iParentID, int flags):
185 DragWindow(ix, iy, iParentID, flags), varPointer(&sliderVar), sliderVar(iSliderVar) {
186 Init(iVarMin, iVarMax);
187 }
188
Slider(int ix,int iy,int * iVarPointer,int iVarMin,int iVarMax,int iParentID,int flags)189 Slider::Slider(int ix, int iy, int* iVarPointer, int iVarMin, int iVarMax, int iParentID, int flags):
190 DragWindow(ix, iy, iParentID, flags), varPointer(iVarPointer) {
191 Init(iVarMin, iVarMax);
192 }
193
Init(int iVarMin,int iVarMax)194 void Slider::Init(int iVarMin, int iVarMax) {
195 shadowVar = *varPointer;
196 bSliderDrag = 0;
197 varMin = iVarMin;
198 varMax = iVarMax;
199
200 rect.w = sliderWinWidth;
201 rect.h = sliderWinHeight;
202 InitRects();
203
204 ruleLength = rect.w - (lineGap << 1);
205
206 middle = rect.y + (rect.h >> 1) + (lineGap >> 1);
207 }
208
MouseD(Uint8 button,Uint16 x,Uint16 y)209 bool Slider::MouseD(Uint8 button, Uint16 x, Uint16 y) {
210 //note not DragWindow::MouseD
211 bool ret = GenWindow_Base::MouseD(button, x, y);
212
213 //slider start drag?
214 if (button == SDL_BUTTON_LEFT
215 && x > sliderRect.x
216 && x < sliderRect.x + sliderRect.w
217 && y > sliderRect.y
218 && y < sliderRect.y + sliderRect.h) {
219 bSliderDrag = true;
220 saveMousePosx = x;
221 } else
222 //check for the window start drag
223 ret = DragWindow::MouseD(button, x, y);
224
225 return ret;
226 }
227
MouseM(Uint8 state,Uint16 x,Uint16 y)228 bool Slider::MouseM(Uint8 state, Uint16 x, Uint16 y) {
229 bool ret = false;
230
231 //slider drag
232 if (bSliderDrag && state & SDL_BUTTON(1)) {
233 int dPos = x - saveMousePosx;
234 sliderRect.x+= dPos;
235
236 //add to the value
237 shadowVar += dPos * (varMax - varMin) / ruleLength;
238
239 if (shadowVar > varMax)
240 shadowVar = varMax;
241 else if (shadowVar < varMin)
242 shadowVar = varMin;
243
244 *varPointer = static_cast<int>(shadowVar);
245
246 bSliderDrag = true;
247 saveMousePosx = x;
248 ret = true;
249 } else {
250 bSliderDrag = false;
251 ret = DragWindow::MouseM(state, x, y);
252 }
253
254 //work out middle /after/ any dragging of us or a parent
255 middle = rect.y + (rect.h >> 1) + (lineGap >> 1);
256
257 return ret;
258 }
259
DrawSelf()260 void Slider::DrawSelf() {
261 DragWindow::DrawSelf();
262
263 //draw a line down the centre
264 SDL_Rect tempRect;
265
266 tempRect.x = rect.x + lineGap;
267 tempRect.y = middle;
268 tempRect.w = static_cast<Uint16>(ruleLength);
269 tempRect.h = smallBorderSize;
270
271 JSDL.BltFill(tempRect,veryDarkGold);
272
273 //we have to rework out position each time because something
274 //other than us might have changed it
275 //strange ordering to avoid casting, theVar/varMax * ruleLength makes more sense
276 int leftPos = rect.x + lineGap + (ruleLength * (*varPointer - varMin) / (varMax - varMin));
277 sliderRect.x = leftPos;
278 sliderRect.y = middle - (sliderHeight >> 1);
279 sliderRect.w = sliderWidth;
280 sliderRect.h = sliderHeight;
281
282 JSDL.BltFill(sliderRect, gold);
283 }
284
285
SliderWithUnits(int ix,int iy,int iSliderVar,int iVarMin,int iVarMax,const string & iVarName,const string & iVarUnits,int iParentID,int flags)286 SliderWithUnits::SliderWithUnits(int ix, int iy, int iSliderVar, int iVarMin, int iVarMax, const string& iVarName, const string& iVarUnits, int iParentID, int flags):
287 Slider(ix, iy, iSliderVar, iVarMin, iVarMax, iParentID, flags), varName(iVarName), varUnits(iVarUnits) {}
288
SliderWithUnits(int ix,int iy,int * iVarPointer,int iVarMin,int iVarMax,const string & iVarName,const string & iVarUnits,int iParentID,int flags)289 SliderWithUnits::SliderWithUnits(int ix, int iy, int* iVarPointer, int iVarMin, int iVarMax, const string& iVarName, const string& iVarUnits, int iParentID, int flags):
290 Slider(ix, iy, iVarPointer, iVarMin, iVarMax, iParentID, flags), varName(iVarName), varUnits(iVarUnits) {}
291
DrawSelf()292 void SliderWithUnits::DrawSelf() {
293 Slider::DrawSelf();
294
295 //in text
296 int x = rect.x + smallBorderSize;
297 int y = rect.y + smallBorderSize;
298 char output[48];
299 sprintf(output, "%s: %d %s", varName.c_str(), *varPointer, varUnits.c_str());
300 normalFonts.BlitString(x, y, 0, output);
301 }
302
DrawSelf()303 void StringInputBox::DrawSelf() {
304 DragWindow::DrawSelf();
305
306 int x = rect.x + bigBorderSize;
307 int y = rect.y + lineGap;
308 normalFonts.BlitString(x, y, 0, title);
309
310 x+= lineGap;
311 y+= lineGap;
312
313 normalFonts.BlitString(x, y, 0, theInput);
314 }
315
Keyboard(SDL_keysym & keysym)316 bool StringInputBox::Keyboard(SDL_keysym& keysym) {
317 switch (StringInput(keysym, theInput, maxTextInputLength)) {
318 //user escaped
319 case -1:
320 closed = true;
321 break;
322
323 //user hit enter
324 case 0:
325 userHitEnter = 1;
326 closed = true;
327 break;
328
329 //keep going
330 case 1:
331 break;
332 }
333
334 return true;
335 }
336
CopyBox(const string & iOldName,const string & iDirectory,int iParentID)337 CopyBox::CopyBox(const string& iOldName, const string& iDirectory, int iParentID):
338 StringInputBox(maxNameLength, iParentID, 0), oldName(iOldName), directoryName(iDirectory) {
339 title = "What would you like to call the copy?";
340 rect.x = 200;
341 rect.y = 200;
342 rect.w = 400;
343 rect.h = 100;
344
345 InitRects();
346 }
347
Keyboard(SDL_keysym & keysym)348 bool CopyBox::Keyboard(SDL_keysym& keysym) {
349 StringInputBox::Keyboard(keysym);
350
351 namespace fs = boost::filesystem;
352
353 if (userHitEnter) {
354 try {
355 fs::path sourcePath(directoryName + oldName + ".dat");
356 fs::path destPath(directoryName + theInput + ".dat");
357
358 fs::copy_file(sourcePath, destPath);
359 MessageWindows(WC_ExpensiveUpdate, 0, 0, parentID, myID);
360 } catch (fs::filesystem_error e) {
361 string errorStr = "\n";
362 errorStr += e.what();
363 CreateInfoString(errorStr);
364 }
365 }
366
367 return true;
368 }
369
370
LargeBlankDW(const string & iTitle)371 LargeBlankDW::LargeBlankDW(const string& iTitle):
372 DragWindow(0, 0, none_constant, 0) {
373 rect.w = 600;
374 rect.h = lineGap * 22;
375
376 CentreWindow();
377 InitRects();
378
379 theText.push_back(WindowText(iTitle, true));
380 }
381
382