diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp new file mode 100644 index 0000000..47d71b7 --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp | |||
@@ -0,0 +1,446 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "CGUIFileOpenDialog.h" | ||
6 | #ifdef _IRR_COMPILE_WITH_GUI_ | ||
7 | |||
8 | #include <locale.h> | ||
9 | |||
10 | #include "IGUISkin.h" | ||
11 | #include "IGUIEnvironment.h" | ||
12 | #include "IVideoDriver.h" | ||
13 | #include "IGUIButton.h" | ||
14 | #include "IGUIStaticText.h" | ||
15 | #include "IGUIFont.h" | ||
16 | #include "IGUIFontBitmap.h" | ||
17 | #include "IFileList.h" | ||
18 | #include "os.h" | ||
19 | |||
20 | namespace irr | ||
21 | { | ||
22 | namespace gui | ||
23 | { | ||
24 | |||
25 | const s32 FOD_WIDTH = 350; | ||
26 | const s32 FOD_HEIGHT = 250; | ||
27 | |||
28 | |||
29 | //! constructor | ||
30 | CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title, | ||
31 | IGUIEnvironment* environment, IGUIElement* parent, s32 id, | ||
32 | bool restoreCWD, io::path::char_type* startDir) | ||
33 | : IGUIFileOpenDialog(environment, parent, id, | ||
34 | core::rect<s32>((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2, | ||
35 | (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2, | ||
36 | (parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH, | ||
37 | (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)), | ||
38 | FileNameText(0), FileList(0), Dragging(false) | ||
39 | { | ||
40 | #ifdef _DEBUG | ||
41 | IGUIElement::setDebugName("CGUIFileOpenDialog"); | ||
42 | #endif | ||
43 | |||
44 | Text = title; | ||
45 | |||
46 | FileSystem = Environment?Environment->getFileSystem():0; | ||
47 | |||
48 | if (FileSystem) | ||
49 | { | ||
50 | FileSystem->grab(); | ||
51 | |||
52 | if (restoreCWD) | ||
53 | RestoreDirectory = FileSystem->getWorkingDirectory(); | ||
54 | if (startDir) | ||
55 | { | ||
56 | StartDirectory = startDir; | ||
57 | FileSystem->changeWorkingDirectoryTo(startDir); | ||
58 | } | ||
59 | } | ||
60 | else | ||
61 | return; | ||
62 | |||
63 | IGUISpriteBank* sprites = 0; | ||
64 | video::SColor color(255,255,255,255); | ||
65 | IGUISkin* skin = Environment->getSkin(); | ||
66 | if (skin) | ||
67 | { | ||
68 | sprites = skin->getSpriteBank(); | ||
69 | color = skin->getColor(EGDC_WINDOW_SYMBOL); | ||
70 | } | ||
71 | |||
72 | const s32 buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); | ||
73 | const s32 posx = RelativeRect.getWidth() - buttonw - 4; | ||
74 | |||
75 | CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1, | ||
76 | L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close"); | ||
77 | CloseButton->setSubElement(true); | ||
78 | CloseButton->setTabStop(false); | ||
79 | if (sprites) | ||
80 | { | ||
81 | CloseButton->setSpriteBank(sprites); | ||
82 | CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color); | ||
83 | CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color); | ||
84 | } | ||
85 | CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); | ||
86 | CloseButton->grab(); | ||
87 | |||
88 | OKButton = Environment->addButton( | ||
89 | core::rect<s32>(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50), | ||
90 | this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK"); | ||
91 | OKButton->setSubElement(true); | ||
92 | OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); | ||
93 | OKButton->grab(); | ||
94 | |||
95 | CancelButton = Environment->addButton( | ||
96 | core::rect<s32>(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75), | ||
97 | this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel"); | ||
98 | CancelButton->setSubElement(true); | ||
99 | CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); | ||
100 | CancelButton->grab(); | ||
101 | |||
102 | FileBox = Environment->addListBox(core::rect<s32>(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true); | ||
103 | FileBox->setSubElement(true); | ||
104 | FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); | ||
105 | FileBox->grab(); | ||
106 | |||
107 | FileNameText = Environment->addEditBox(0, core::rect<s32>(10, 30, RelativeRect.getWidth()-90, 50), true, this); | ||
108 | FileNameText->setSubElement(true); | ||
109 | FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); | ||
110 | FileNameText->grab(); | ||
111 | |||
112 | setTabGroup(true); | ||
113 | |||
114 | fillListBox(); | ||
115 | } | ||
116 | |||
117 | |||
118 | //! destructor | ||
119 | CGUIFileOpenDialog::~CGUIFileOpenDialog() | ||
120 | { | ||
121 | if (CloseButton) | ||
122 | CloseButton->drop(); | ||
123 | |||
124 | if (OKButton) | ||
125 | OKButton->drop(); | ||
126 | |||
127 | if (CancelButton) | ||
128 | CancelButton->drop(); | ||
129 | |||
130 | if (FileBox) | ||
131 | FileBox->drop(); | ||
132 | |||
133 | if (FileNameText) | ||
134 | FileNameText->drop(); | ||
135 | |||
136 | if (FileSystem) | ||
137 | { | ||
138 | // revert to original CWD if path was set in constructor | ||
139 | if (RestoreDirectory.size()) | ||
140 | FileSystem->changeWorkingDirectoryTo(RestoreDirectory); | ||
141 | FileSystem->drop(); | ||
142 | } | ||
143 | |||
144 | if (FileList) | ||
145 | FileList->drop(); | ||
146 | } | ||
147 | |||
148 | |||
149 | //! returns the filename of the selected file. Returns NULL, if no file was selected. | ||
150 | const wchar_t* CGUIFileOpenDialog::getFileName() const | ||
151 | { | ||
152 | return FileName.c_str(); | ||
153 | } | ||
154 | |||
155 | //! Returns the directory of the selected file. Returns NULL, if no directory was selected. | ||
156 | const io::path& CGUIFileOpenDialog::getDirectoryName() | ||
157 | { | ||
158 | FileSystem->flattenFilename ( FileDirectory ); | ||
159 | return FileDirectory; | ||
160 | } | ||
161 | |||
162 | |||
163 | //! called if an event happened. | ||
164 | bool CGUIFileOpenDialog::OnEvent(const SEvent& event) | ||
165 | { | ||
166 | if (isEnabled()) | ||
167 | { | ||
168 | switch(event.EventType) | ||
169 | { | ||
170 | case EET_GUI_EVENT: | ||
171 | switch(event.GUIEvent.EventType) | ||
172 | { | ||
173 | case EGET_ELEMENT_FOCUS_LOST: | ||
174 | Dragging = false; | ||
175 | break; | ||
176 | case EGET_BUTTON_CLICKED: | ||
177 | if (event.GUIEvent.Caller == CloseButton || | ||
178 | event.GUIEvent.Caller == CancelButton) | ||
179 | { | ||
180 | sendCancelEvent(); | ||
181 | remove(); | ||
182 | return true; | ||
183 | } | ||
184 | else | ||
185 | if (event.GUIEvent.Caller == OKButton ) | ||
186 | { | ||
187 | if ( FileDirectory != L"" ) | ||
188 | { | ||
189 | sendSelectedEvent( EGET_DIRECTORY_SELECTED ); | ||
190 | } | ||
191 | if ( FileName != L"" ) | ||
192 | { | ||
193 | sendSelectedEvent( EGET_FILE_SELECTED ); | ||
194 | remove(); | ||
195 | return true; | ||
196 | } | ||
197 | } | ||
198 | break; | ||
199 | |||
200 | case EGET_LISTBOX_CHANGED: | ||
201 | { | ||
202 | s32 selected = FileBox->getSelected(); | ||
203 | if (FileList && FileSystem) | ||
204 | { | ||
205 | if (FileList->isDirectory(selected)) | ||
206 | { | ||
207 | FileName = L""; | ||
208 | FileDirectory = FileList->getFullFileName(selected); | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | FileDirectory = L""; | ||
213 | FileName = FileList->getFullFileName(selected); | ||
214 | } | ||
215 | return true; | ||
216 | } | ||
217 | } | ||
218 | break; | ||
219 | |||
220 | case EGET_LISTBOX_SELECTED_AGAIN: | ||
221 | { | ||
222 | const s32 selected = FileBox->getSelected(); | ||
223 | if (FileList && FileSystem) | ||
224 | { | ||
225 | if (FileList->isDirectory(selected)) | ||
226 | { | ||
227 | FileDirectory = FileList->getFullFileName(selected); | ||
228 | FileSystem->changeWorkingDirectoryTo(FileList->getFileName(selected)); | ||
229 | fillListBox(); | ||
230 | FileName = ""; | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | FileName = FileList->getFullFileName(selected); | ||
235 | } | ||
236 | return true; | ||
237 | } | ||
238 | } | ||
239 | break; | ||
240 | case EGET_EDITBOX_ENTER: | ||
241 | if (event.GUIEvent.Caller == FileNameText) | ||
242 | { | ||
243 | io::path dir( FileNameText->getText () ); | ||
244 | if ( FileSystem->changeWorkingDirectoryTo( dir ) ) | ||
245 | { | ||
246 | fillListBox(); | ||
247 | FileName = L""; | ||
248 | } | ||
249 | return true; | ||
250 | } | ||
251 | break; | ||
252 | default: | ||
253 | break; | ||
254 | } | ||
255 | break; | ||
256 | case EET_MOUSE_INPUT_EVENT: | ||
257 | switch(event.MouseInput.Event) | ||
258 | { | ||
259 | case EMIE_MOUSE_WHEEL: | ||
260 | return FileBox->OnEvent(event); | ||
261 | case EMIE_LMOUSE_PRESSED_DOWN: | ||
262 | DragStart.X = event.MouseInput.X; | ||
263 | DragStart.Y = event.MouseInput.Y; | ||
264 | Dragging = true; | ||
265 | Environment->setFocus(this); | ||
266 | return true; | ||
267 | case EMIE_LMOUSE_LEFT_UP: | ||
268 | Dragging = false; | ||
269 | return true; | ||
270 | case EMIE_MOUSE_MOVED: | ||
271 | |||
272 | if ( !event.MouseInput.isLeftPressed () ) | ||
273 | Dragging = false; | ||
274 | |||
275 | if (Dragging) | ||
276 | { | ||
277 | // gui window should not be dragged outside its parent | ||
278 | if (Parent) | ||
279 | if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || | ||
280 | event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || | ||
281 | event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || | ||
282 | event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) | ||
283 | |||
284 | return true; | ||
285 | |||
286 | move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); | ||
287 | DragStart.X = event.MouseInput.X; | ||
288 | DragStart.Y = event.MouseInput.Y; | ||
289 | return true; | ||
290 | } | ||
291 | break; | ||
292 | default: | ||
293 | break; | ||
294 | } | ||
295 | default: | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | return IGUIElement::OnEvent(event); | ||
301 | } | ||
302 | |||
303 | |||
304 | //! draws the element and its children | ||
305 | void CGUIFileOpenDialog::draw() | ||
306 | { | ||
307 | if (!IsVisible) | ||
308 | return; | ||
309 | |||
310 | IGUISkin* skin = Environment->getSkin(); | ||
311 | |||
312 | core::rect<s32> rect = AbsoluteRect; | ||
313 | |||
314 | rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), | ||
315 | rect, &AbsoluteClippingRect); | ||
316 | |||
317 | if (Text.size()) | ||
318 | { | ||
319 | rect.UpperLeftCorner.X += 2; | ||
320 | rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; | ||
321 | |||
322 | IGUIFont* font = skin->getFont(EGDF_WINDOW); | ||
323 | if (font) | ||
324 | font->draw(Text.c_str(), rect, | ||
325 | skin->getColor(EGDC_ACTIVE_CAPTION), | ||
326 | false, true, &AbsoluteClippingRect); | ||
327 | } | ||
328 | |||
329 | IGUIElement::draw(); | ||
330 | } | ||
331 | |||
332 | |||
333 | //! Writes attributes of the element. | ||
334 | /* Not sure if this will really work out properly. Saving paths can be | ||
335 | rather problematic. */ | ||
336 | void CGUIFileOpenDialog::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | ||
337 | { | ||
338 | IGUIFileOpenDialog::serializeAttributes(out,options); | ||
339 | |||
340 | out->addString("StartDirectory", StartDirectory.c_str()); | ||
341 | out->addBool("RestoreDirectory", (RestoreDirectory.size()!=0)); | ||
342 | } | ||
343 | |||
344 | |||
345 | //! Reads attributes of the element | ||
346 | /* Note that thiese paths changes will happen at arbitrary places upon | ||
347 | load of the gui description. This may be undesired. */ | ||
348 | void CGUIFileOpenDialog::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | ||
349 | { | ||
350 | StartDirectory = in->getAttributeAsString("StartDirectory"); | ||
351 | const bool restore = in->getAttributeAsBool("RestoreDirectory"); | ||
352 | if (restore) | ||
353 | RestoreDirectory = FileSystem->getWorkingDirectory(); | ||
354 | else | ||
355 | RestoreDirectory = ""; | ||
356 | if (StartDirectory.size()) | ||
357 | FileSystem->changeWorkingDirectoryTo(StartDirectory); | ||
358 | |||
359 | IGUIFileOpenDialog::deserializeAttributes(in,options); | ||
360 | } | ||
361 | |||
362 | |||
363 | //! fills the listbox with files. | ||
364 | void CGUIFileOpenDialog::fillListBox() | ||
365 | { | ||
366 | IGUISkin *skin = Environment->getSkin(); | ||
367 | |||
368 | if (!FileSystem || !FileBox || !skin) | ||
369 | return; | ||
370 | |||
371 | if (FileList) | ||
372 | FileList->drop(); | ||
373 | |||
374 | FileBox->clear(); | ||
375 | |||
376 | FileList = FileSystem->createFileList(); | ||
377 | core::stringw s; | ||
378 | |||
379 | #if !defined(_IRR_WINDOWS_CE_PLATFORM_) | ||
380 | setlocale(LC_ALL,""); | ||
381 | #endif | ||
382 | |||
383 | if (FileList) | ||
384 | { | ||
385 | for (u32 i=0; i < FileList->getFileCount(); ++i) | ||
386 | { | ||
387 | #ifndef _IRR_WCHAR_FILESYSTEM | ||
388 | const c8 *cs = (const c8 *)FileList->getFileName(i).c_str(); | ||
389 | wchar_t *ws = new wchar_t[strlen(cs) + 1]; | ||
390 | int len = mbstowcs(ws,cs,strlen(cs)); | ||
391 | ws[len] = 0; | ||
392 | s = ws; | ||
393 | delete [] ws; | ||
394 | #else | ||
395 | s = FileList->getFileName(i).c_str(); | ||
396 | #endif | ||
397 | FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE)); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | if (FileNameText) | ||
402 | { | ||
403 | #ifndef _IRR_WCHAR_FILESYSTEM | ||
404 | const c8 *cs = (const c8 *)FileSystem->getWorkingDirectory().c_str(); | ||
405 | wchar_t *ws = new wchar_t[strlen(cs) + 1]; | ||
406 | int len = mbstowcs(ws,cs,strlen(cs)); | ||
407 | ws[len] = 0; | ||
408 | s = ws; | ||
409 | delete [] ws; | ||
410 | #else | ||
411 | s = FileSystem->getWorkingDirectory(); | ||
412 | #endif | ||
413 | |||
414 | FileDirectory = s; | ||
415 | FileNameText->setText(s.c_str()); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | |||
420 | //! sends the event that the file has been selected. | ||
421 | void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type) | ||
422 | { | ||
423 | SEvent event; | ||
424 | event.EventType = EET_GUI_EVENT; | ||
425 | event.GUIEvent.Caller = this; | ||
426 | event.GUIEvent.Element = 0; | ||
427 | event.GUIEvent.EventType = type; | ||
428 | Parent->OnEvent(event); | ||
429 | } | ||
430 | |||
431 | |||
432 | //! sends the event that the file choose process has been canceld | ||
433 | void CGUIFileOpenDialog::sendCancelEvent() | ||
434 | { | ||
435 | SEvent event; | ||
436 | event.EventType = EET_GUI_EVENT; | ||
437 | event.GUIEvent.Caller = this; | ||
438 | event.GUIEvent.Element = 0; | ||
439 | event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED; | ||
440 | Parent->OnEvent(event); | ||
441 | } | ||
442 | |||
443 | } // end namespace gui | ||
444 | } // end namespace irr | ||
445 | |||
446 | #endif // _IRR_COMPILE_WITH_GUI_ | ||