aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CGUIFileOpenDialog.cpp446
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
20namespace irr
21{
22namespace gui
23{
24
25const s32 FOD_WIDTH = 350;
26const s32 FOD_HEIGHT = 250;
27
28
29//! constructor
30CGUIFileOpenDialog::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
119CGUIFileOpenDialog::~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.
150const 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.
156const io::path& CGUIFileOpenDialog::getDirectoryName()
157{
158 FileSystem->flattenFilename ( FileDirectory );
159 return FileDirectory;
160}
161
162
163//! called if an event happened.
164bool 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
305void 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
335rather problematic. */
336void 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
347load of the gui description. This may be undesired. */
348void 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.
364void 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.
421void 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
433void 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_