123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- // Copyright (C) 2002-2012 Nikolaus Gebhardt
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- #include "CGUIFileOpenDialog.h"
- #ifdef _IRR_COMPILE_WITH_GUI_
- #include <locale.h>
- #include "IGUISkin.h"
- #include "IGUIEnvironment.h"
- #include "IVideoDriver.h"
- #include "IGUIButton.h"
- #include "IGUIStaticText.h"
- #include "IGUIFont.h"
- #include "IGUIFontBitmap.h"
- #include "IFileList.h"
- #include "os.h"
- namespace irr
- {
- namespace gui
- {
- const s32 FOD_WIDTH = 350;
- const s32 FOD_HEIGHT = 250;
- //! constructor
- CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title,
- IGUIEnvironment* environment, IGUIElement* parent, s32 id,
- bool restoreCWD, io::path::char_type* startDir)
- : IGUIFileOpenDialog(environment, parent, id,
- core::rect<s32>((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2,
- (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2,
- (parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH,
- (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)),
- FileNameText(0), FileList(0), Dragging(false)
- {
- #ifdef _DEBUG
- IGUIElement::setDebugName("CGUIFileOpenDialog");
- #endif
- Text = title;
- FileSystem = Environment?Environment->getFileSystem():0;
- if (FileSystem)
- {
- FileSystem->grab();
- if (restoreCWD)
- RestoreDirectory = FileSystem->getWorkingDirectory();
- if (startDir)
- {
- StartDirectory = startDir;
- FileSystem->changeWorkingDirectoryTo(startDir);
- }
- }
- else
- return;
- IGUISpriteBank* sprites = 0;
- video::SColor color(255,255,255,255);
- IGUISkin* skin = Environment->getSkin();
- if (skin)
- {
- sprites = skin->getSpriteBank();
- color = skin->getColor(EGDC_WINDOW_SYMBOL);
- }
- const s32 buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
- const s32 posx = RelativeRect.getWidth() - buttonw - 4;
- CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
- L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close");
- CloseButton->setSubElement(true);
- CloseButton->setTabStop(false);
- if (sprites)
- {
- CloseButton->setSpriteBank(sprites);
- CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
- CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
- }
- CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- CloseButton->grab();
- OKButton = Environment->addButton(
- core::rect<s32>(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50),
- this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK");
- OKButton->setSubElement(true);
- OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- OKButton->grab();
- CancelButton = Environment->addButton(
- core::rect<s32>(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75),
- this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel");
- CancelButton->setSubElement(true);
- CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- CancelButton->grab();
- FileBox = Environment->addListBox(core::rect<s32>(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true);
- FileBox->setSubElement(true);
- FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
- FileBox->grab();
- FileNameText = Environment->addEditBox(0, core::rect<s32>(10, 30, RelativeRect.getWidth()-90, 50), true, this);
- FileNameText->setSubElement(true);
- FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- FileNameText->grab();
- setTabGroup(true);
- fillListBox();
- }
- //! destructor
- CGUIFileOpenDialog::~CGUIFileOpenDialog()
- {
- if (CloseButton)
- CloseButton->drop();
- if (OKButton)
- OKButton->drop();
- if (CancelButton)
- CancelButton->drop();
- if (FileBox)
- FileBox->drop();
- if (FileNameText)
- FileNameText->drop();
- if (FileSystem)
- {
- // revert to original CWD if path was set in constructor
- if (RestoreDirectory.size())
- FileSystem->changeWorkingDirectoryTo(RestoreDirectory);
- FileSystem->drop();
- }
- if (FileList)
- FileList->drop();
- }
- //! returns the filename of the selected file. Returns NULL, if no file was selected.
- const wchar_t* CGUIFileOpenDialog::getFileName() const
- {
- return FileName.c_str();
- }
- //! Returns the directory of the selected file. Returns NULL, if no directory was selected.
- const io::path& CGUIFileOpenDialog::getDirectoryName()
- {
- FileSystem->flattenFilename ( FileDirectory );
- return FileDirectory;
- }
- //! called if an event happened.
- bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
- {
- if (isEnabled())
- {
- switch(event.EventType)
- {
- case EET_GUI_EVENT:
- switch(event.GUIEvent.EventType)
- {
- case EGET_ELEMENT_FOCUS_LOST:
- Dragging = false;
- break;
- case EGET_BUTTON_CLICKED:
- if (event.GUIEvent.Caller == CloseButton ||
- event.GUIEvent.Caller == CancelButton)
- {
- sendCancelEvent();
- remove();
- return true;
- }
- else
- if (event.GUIEvent.Caller == OKButton )
- {
- if ( FileDirectory != L"" )
- {
- sendSelectedEvent( EGET_DIRECTORY_SELECTED );
- }
- if ( FileName != L"" )
- {
- sendSelectedEvent( EGET_FILE_SELECTED );
- remove();
- return true;
- }
- }
- break;
- case EGET_LISTBOX_CHANGED:
- {
- s32 selected = FileBox->getSelected();
- if (FileList && FileSystem)
- {
- if (FileList->isDirectory(selected))
- {
- FileName = L"";
- FileDirectory = FileList->getFullFileName(selected);
- }
- else
- {
- FileDirectory = L"";
- FileName = FileList->getFullFileName(selected);
- }
- return true;
- }
- }
- break;
- case EGET_LISTBOX_SELECTED_AGAIN:
- {
- const s32 selected = FileBox->getSelected();
- if (FileList && FileSystem)
- {
- if (FileList->isDirectory(selected))
- {
- FileDirectory = FileList->getFullFileName(selected);
- FileSystem->changeWorkingDirectoryTo(FileList->getFileName(selected));
- fillListBox();
- FileName = "";
- }
- else
- {
- FileName = FileList->getFullFileName(selected);
- }
- return true;
- }
- }
- break;
- case EGET_EDITBOX_ENTER:
- if (event.GUIEvent.Caller == FileNameText)
- {
- io::path dir( FileNameText->getText () );
- if ( FileSystem->changeWorkingDirectoryTo( dir ) )
- {
- fillListBox();
- FileName = L"";
- }
- return true;
- }
- break;
- default:
- break;
- }
- break;
- case EET_MOUSE_INPUT_EVENT:
- switch(event.MouseInput.Event)
- {
- case EMIE_MOUSE_WHEEL:
- return FileBox->OnEvent(event);
- case EMIE_LMOUSE_PRESSED_DOWN:
- DragStart.X = event.MouseInput.X;
- DragStart.Y = event.MouseInput.Y;
- Dragging = true;
- Environment->setFocus(this);
- return true;
- case EMIE_LMOUSE_LEFT_UP:
- Dragging = false;
- return true;
- case EMIE_MOUSE_MOVED:
- if ( !event.MouseInput.isLeftPressed () )
- Dragging = false;
- if (Dragging)
- {
- // gui window should not be dragged outside its parent
- if (Parent)
- if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
- event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
- event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
- event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
- return true;
- move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
- DragStart.X = event.MouseInput.X;
- DragStart.Y = event.MouseInput.Y;
- return true;
- }
- break;
- default:
- break;
- }
- default:
- break;
- }
- }
- return IGUIElement::OnEvent(event);
- }
- //! draws the element and its children
- void CGUIFileOpenDialog::draw()
- {
- if (!IsVisible)
- return;
- IGUISkin* skin = Environment->getSkin();
- core::rect<s32> rect = AbsoluteRect;
- rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
- rect, &AbsoluteClippingRect);
- if (Text.size())
- {
- rect.UpperLeftCorner.X += 2;
- rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
- IGUIFont* font = skin->getFont(EGDF_WINDOW);
- if (font)
- font->draw(Text.c_str(), rect,
- skin->getColor(EGDC_ACTIVE_CAPTION),
- false, true, &AbsoluteClippingRect);
- }
- IGUIElement::draw();
- }
- //! Writes attributes of the element.
- /* Not sure if this will really work out properly. Saving paths can be
- rather problematic. */
- void CGUIFileOpenDialog::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
- {
- IGUIFileOpenDialog::serializeAttributes(out,options);
- out->addString("StartDirectory", StartDirectory.c_str());
- out->addBool("RestoreDirectory", (RestoreDirectory.size()!=0));
- }
- //! Reads attributes of the element
- /* Note that thiese paths changes will happen at arbitrary places upon
- load of the gui description. This may be undesired. */
- void CGUIFileOpenDialog::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
- {
- StartDirectory = in->getAttributeAsString("StartDirectory");
- const bool restore = in->getAttributeAsBool("RestoreDirectory");
- if (restore)
- RestoreDirectory = FileSystem->getWorkingDirectory();
- else
- RestoreDirectory = "";
- if (StartDirectory.size())
- FileSystem->changeWorkingDirectoryTo(StartDirectory);
- IGUIFileOpenDialog::deserializeAttributes(in,options);
- }
- //! fills the listbox with files.
- void CGUIFileOpenDialog::fillListBox()
- {
- IGUISkin *skin = Environment->getSkin();
- if (!FileSystem || !FileBox || !skin)
- return;
- if (FileList)
- FileList->drop();
- FileBox->clear();
- FileList = FileSystem->createFileList();
- core::stringw s;
- #if !defined(_IRR_WINDOWS_CE_PLATFORM_)
- setlocale(LC_ALL,"");
- #endif
- if (FileList)
- {
- for (u32 i=0; i < FileList->getFileCount(); ++i)
- {
- #ifndef _IRR_WCHAR_FILESYSTEM
- const c8 *cs = (const c8 *)FileList->getFileName(i).c_str();
- wchar_t *ws = new wchar_t[strlen(cs) + 1];
- int len = mbstowcs(ws,cs,strlen(cs));
- ws[len] = 0;
- s = ws;
- delete [] ws;
- #else
- s = FileList->getFileName(i).c_str();
- #endif
- FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
- }
- }
- if (FileNameText)
- {
- #ifndef _IRR_WCHAR_FILESYSTEM
- const c8 *cs = (const c8 *)FileSystem->getWorkingDirectory().c_str();
- wchar_t *ws = new wchar_t[strlen(cs) + 1];
- int len = mbstowcs(ws,cs,strlen(cs));
- ws[len] = 0;
- s = ws;
- delete [] ws;
- #else
- s = FileSystem->getWorkingDirectory();
- #endif
- FileDirectory = s;
- FileNameText->setText(s.c_str());
- }
- }
- //! sends the event that the file has been selected.
- void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type)
- {
- SEvent event;
- event.EventType = EET_GUI_EVENT;
- event.GUIEvent.Caller = this;
- event.GUIEvent.Element = 0;
- event.GUIEvent.EventType = type;
- Parent->OnEvent(event);
- }
- //! sends the event that the file choose process has been canceld
- void CGUIFileOpenDialog::sendCancelEvent()
- {
- SEvent event;
- event.EventType = EET_GUI_EVENT;
- event.GUIEvent.Caller = this;
- event.GUIEvent.Element = 0;
- event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
- Parent->OnEvent(event);
- }
- } // end namespace gui
- } // end namespace irr
- #endif // _IRR_COMPILE_WITH_GUI_
|