1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #include "CGUIFileOpenDialog.h"
\r
7 #include "IGUISkin.h"
\r
8 #include "IGUIEnvironment.h"
\r
9 #include "IVideoDriver.h"
\r
10 #include "IGUIButton.h"
\r
11 #include "IGUIStaticText.h"
\r
12 #include "IGUIFont.h"
\r
13 #include "IGUIFontBitmap.h"
\r
14 #include "IFileList.h"
\r
22 const s32 FOD_WIDTH = 350;
\r
23 const s32 FOD_HEIGHT = 250;
\r
27 CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title,
\r
28 IGUIEnvironment* environment, IGUIElement* parent, s32 id,
\r
29 bool restoreCWD, io::path::char_type* startDir)
\r
30 : IGUIFileOpenDialog(environment, parent, id,
\r
31 core::rect<s32>((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2,
\r
32 (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2,
\r
33 (parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH,
\r
34 (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)),
\r
35 FileNameText(0), FileList(0), Dragging(false)
\r
38 IGUIElement::setDebugName("CGUIFileOpenDialog");
\r
43 FileSystem = Environment?Environment->getFileSystem():0;
\r
50 RestoreDirectory = FileSystem->getWorkingDirectory();
\r
53 StartDirectory = startDir;
\r
54 FileSystem->changeWorkingDirectoryTo(startDir);
\r
60 IGUISpriteBank* sprites = 0;
\r
61 video::SColor color(255,255,255,255);
\r
62 IGUISkin* skin = Environment->getSkin();
\r
65 sprites = skin->getSpriteBank();
\r
66 color = skin->getColor(EGDC_WINDOW_SYMBOL);
\r
69 const s32 buttonw = skin ? skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) : 2;
\r
70 const s32 posx = RelativeRect.getWidth() - buttonw - 4;
\r
72 CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
\r
73 L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close");
\r
74 CloseButton->setSubElement(true);
\r
75 CloseButton->setTabStop(false);
\r
76 if (sprites && skin)
\r
78 CloseButton->setSpriteBank(sprites);
\r
79 CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
\r
80 CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
\r
82 CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
83 CloseButton->grab();
\r
85 OKButton = Environment->addButton(
\r
86 core::rect<s32>(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50),
\r
87 this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK");
\r
88 OKButton->setSubElement(true);
\r
89 OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
92 CancelButton = Environment->addButton(
\r
93 core::rect<s32>(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75),
\r
94 this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel");
\r
95 CancelButton->setSubElement(true);
\r
96 CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
97 CancelButton->grab();
\r
99 FileBox = Environment->addListBox(core::rect<s32>(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true);
\r
100 FileBox->setSubElement(true);
\r
101 FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
\r
104 FileNameText = Environment->addEditBox(0, core::rect<s32>(10, 30, RelativeRect.getWidth()-90, 50), true, this);
\r
105 FileNameText->setSubElement(true);
\r
106 FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
107 FileNameText->grab();
\r
116 CGUIFileOpenDialog::~CGUIFileOpenDialog()
\r
119 CloseButton->drop();
\r
125 CancelButton->drop();
\r
131 FileNameText->drop();
\r
135 // revert to original CWD if path was set in constructor
\r
136 if (RestoreDirectory.size())
\r
137 FileSystem->changeWorkingDirectoryTo(RestoreDirectory);
\r
138 FileSystem->drop();
\r
146 //! returns the filename of the selected file. Returns NULL, if no file was selected.
\r
147 const wchar_t* CGUIFileOpenDialog::getFileName() const
\r
149 return FileNameW.c_str();
\r
152 const io::path& CGUIFileOpenDialog::getFileNameP() const
\r
157 //! Returns the directory of the selected file. Returns NULL, if no directory was selected.
\r
158 const io::path& CGUIFileOpenDialog::getDirectoryName() const
\r
160 return FileDirectoryFlat;
\r
163 const wchar_t* CGUIFileOpenDialog::getDirectoryNameW() const
\r
165 return FileDirectoryFlatW.c_str();
\r
168 void CGUIFileOpenDialog::setFileName(const irr::io::path& name)
\r
171 pathToStringW(FileNameW, FileName);
\r
174 void CGUIFileOpenDialog::setDirectoryName(const irr::io::path& name)
\r
176 FileDirectory = name;
\r
177 FileDirectoryFlat = name;
\r
178 FileSystem->flattenFilename (FileDirectoryFlat );
\r
179 pathToStringW(FileDirectoryFlatW, FileDirectoryFlat);
\r
182 //! called if an event happened.
\r
183 bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
\r
187 switch(event.EventType)
\r
189 case EET_GUI_EVENT:
\r
190 switch(event.GUIEvent.EventType)
\r
192 case EGET_ELEMENT_FOCUS_LOST:
\r
195 case EGET_BUTTON_CLICKED:
\r
196 if (event.GUIEvent.Caller == CloseButton ||
\r
197 event.GUIEvent.Caller == CancelButton)
\r
204 if (event.GUIEvent.Caller == OKButton )
\r
206 if ( FileDirectory != L"" )
\r
208 sendSelectedEvent( EGET_DIRECTORY_SELECTED );
\r
210 if ( FileName != L"" )
\r
212 sendSelectedEvent( EGET_FILE_SELECTED );
\r
219 case EGET_LISTBOX_CHANGED:
\r
221 s32 selected = FileBox->getSelected();
\r
222 if (FileList && FileSystem)
\r
224 if (FileList->isDirectory(selected))
\r
227 setDirectoryName(FileList->getFullFileName(selected));
\r
231 setDirectoryName("");
\r
232 setFileName(FileList->getFullFileName(selected));
\r
239 case EGET_LISTBOX_SELECTED_AGAIN:
\r
241 const s32 selected = FileBox->getSelected();
\r
242 if (FileList && FileSystem)
\r
244 if (FileList->isDirectory(selected))
\r
246 setDirectoryName(FileList->getFullFileName(selected));
\r
247 FileSystem->changeWorkingDirectoryTo(FileDirectory );
\r
253 setFileName(FileList->getFullFileName(selected));
\r
259 case EGET_EDITBOX_ENTER:
\r
260 if (event.GUIEvent.Caller == FileNameText)
\r
262 io::path dir( FileNameText->getText () );
\r
263 if ( FileSystem->changeWorkingDirectoryTo( dir ) )
\r
275 case EET_MOUSE_INPUT_EVENT:
\r
276 switch(event.MouseInput.Event)
\r
278 case EMIE_MOUSE_WHEEL:
\r
279 return FileBox->OnEvent(event);
\r
280 case EMIE_LMOUSE_PRESSED_DOWN:
\r
281 DragStart.X = event.MouseInput.X;
\r
282 DragStart.Y = event.MouseInput.Y;
\r
285 case EMIE_LMOUSE_LEFT_UP:
\r
288 case EMIE_MOUSE_MOVED:
\r
290 if ( !event.MouseInput.isLeftPressed () )
\r
295 // gui window should not be dragged outside its parent
\r
297 if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
\r
298 event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
\r
299 event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
\r
300 event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
\r
304 move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
\r
305 DragStart.X = event.MouseInput.X;
\r
306 DragStart.Y = event.MouseInput.Y;
\r
318 return IGUIElement::OnEvent(event);
\r
322 //! draws the element and its children
\r
323 void CGUIFileOpenDialog::draw()
\r
328 IGUISkin* skin = Environment->getSkin();
\r
330 core::rect<s32> rect = AbsoluteRect;
\r
332 rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
\r
333 rect, &AbsoluteClippingRect);
\r
337 rect.UpperLeftCorner.X += 2;
\r
338 rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
\r
340 IGUIFont* font = skin->getFont(EGDF_WINDOW);
\r
342 font->draw(Text.c_str(), rect,
\r
343 skin->getColor(EGDC_ACTIVE_CAPTION),
\r
344 false, true, &AbsoluteClippingRect);
\r
347 IGUIElement::draw();
\r
350 void CGUIFileOpenDialog::pathToStringW(irr::core::stringw& result, const irr::io::path& p)
\r
352 core::multibyteToWString(result, p);
\r
355 //! fills the listbox with files.
\r
356 void CGUIFileOpenDialog::fillListBox()
\r
358 IGUISkin *skin = Environment->getSkin();
\r
360 if (!FileSystem || !FileBox || !skin)
\r
368 FileList = FileSystem->createFileList();
\r
373 for (u32 i=0; i < FileList->getFileCount(); ++i)
\r
375 pathToStringW(s, FileList->getFileName(i));
\r
376 FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
\r
382 setDirectoryName(FileSystem->getWorkingDirectory());
\r
383 pathToStringW(s, FileDirectory);
\r
384 FileNameText->setText(s.c_str());
\r
388 //! sends the event that the file has been selected.
\r
389 void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type)
\r
392 event.EventType = EET_GUI_EVENT;
\r
393 event.GUIEvent.Caller = this;
\r
394 event.GUIEvent.Element = 0;
\r
395 event.GUIEvent.EventType = type;
\r
396 Parent->OnEvent(event);
\r
400 //! sends the event that the file choose process has been cancelled
\r
401 void CGUIFileOpenDialog::sendCancelEvent()
\r
404 event.EventType = EET_GUI_EVENT;
\r
405 event.GUIEvent.Caller = this;
\r
406 event.GUIEvent.Element = 0;
\r
407 event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
\r
408 Parent->OnEvent(event);
\r
411 } // end namespace gui
\r
412 } // end namespace irr
\r