From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- .../source/Irrlicht/CGUIFileOpenDialog.cpp | 446 +++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp') diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp new file mode 100644 index 0000000..47d71b7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp @@ -0,0 +1,446 @@ +// 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 + +#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((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(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(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(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(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(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(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 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_ -- cgit v1.1