Jad
22-06-2011 22:02:56
I decided to write my own instead of copying the one in the LayoutEditor (although i did copy the layout of the dialog
). Just wanted to share it with you 
Note that you need to build a couple of boost libraries (filesystem and system) to use the code. More info here
Dialog.h
Dialog.cpp
Dialog.layout
And finally an example of using it:


Note that you need to build a couple of boost libraries (filesystem and system) to use the code. More info here
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <boost\filesystem.hpp>
#include <boost\function.hpp>
#include <MyGUI.h>
class Dialog
{
public:
Dialog(const std::string& name);
const std::string& getName();
void update();
void setVisible(bool set);
void setDialogTitle(const std::string& title);
void setButtonCaption(const std::string& caption);
void addFileExtension(const std::string& ext);
void setDefaultExtension(int index);
void setUserString(const std::string& value);
const std::string& getUserString();
void eventEndDialog(boost::function<void(Dialog*, const std::string&)> method);
private:
void windowCloseCallback(MyGUI::Window* _sender, const std::string& _name);
void itemAcceptedCallback(MyGUI::ListBox* _sender, size_t _index);
void itemSelectedCallback(MyGUI::ListBox* _sender, size_t _index);
void recentPathSelectedCallback(MyGUI::ComboBox* _sender, size_t _index);
void endDialogCallback(MyGUI::Widget* _sender);
void windowResizeCallback(MyGUI::Widget* _sender, const std::string& _key, const std::string& _value);
void extensionChangeCallback(MyGUI::ComboBox* _sender, size_t _index);
void updatePathList(boost::filesystem::path my_path);
//static int nDialogs;
//int mDialogIndex;
//void (GUIManager::*mUserMethod)(const std::string&, const std::string&);
std::string mName;
std::string mUserString;
// user callback
boost::function<void(Dialog*, const std::string&)> mUserMethod;
// widgets
MyGUI::Window* mWindow;
MyGUI::List* mPathList;
MyGUI::Edit* mFileEdit;
MyGUI::Button* mButton;
MyGUI::ComboBox* mRecentCombo;
MyGUI::ComboBox* mExtensionCombo;
boost::filesystem::path mCurrentPath; // current viewed directory
std::vector<boost::filesystem::path> mPath_set; // list of paths in the viewed directory
boost::filesystem::path* mSelectedFile;
std::vector<boost::filesystem::path> mRecentPaths;
};
#endif // DIALOG_H
Dialog.cpp
#include "Dialog.h"
using namespace boost::filesystem;
//int Dialog::nDialogs = 0;
Dialog::Dialog(const std::string& name) :
mName(name),
mWindow(0),
mPathList(0),
mFileEdit(0),
mButton(0),
mRecentCombo(0),
mExtensionCombo(0),
mSelectedFile(0),
mUserMethod(0)
{
// load dialog layout
MyGUI::VectorWidgetPtr widgets = MyGUI::LayoutManager::getInstance().loadLayout("Dialog.layout");
mWindow = (MyGUI::Window*)*widgets.begin();
mWindow->eventWindowButtonPressed += MyGUI::newDelegate(this, &Dialog::windowCloseCallback);
mWindow->setVisible(false);
mPathList = (MyGUI::List*)mWindow->findWidget("List");
mPathList->eventListSelectAccept += MyGUI::newDelegate(this, &Dialog::itemAcceptedCallback);
mPathList->eventListChangePosition += MyGUI::newDelegate(this, &Dialog::itemSelectedCallback);
mFileEdit = (MyGUI::Edit*)mWindow->findWidget("Edit");
mButton = (MyGUI::Button*)mWindow->findWidget("Confirm");
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Dialog::endDialogCallback);
mRecentCombo = (MyGUI::ComboBox*)mWindow->findWidget("Recent");
mRecentCombo->eventComboChangePosition += MyGUI::newDelegate(this, &Dialog::recentPathSelectedCallback);
mExtensionCombo = (MyGUI::ComboBox*)mWindow->findWidget("Extension");
mExtensionCombo->eventComboChangePosition += MyGUI::newDelegate(this, &Dialog::extensionChangeCallback);
mExtensionCombo->addItem("All files \".\"");
mExtensionCombo->setIndexSelected(0);
}
//==========================================================================
// User closed Dialog window
//==========================================================================
void Dialog::windowCloseCallback(MyGUI::Window* _sender, const std::string& _name)
{
mWindow->setVisible(false);
}
//==========================================================================
// User selected a path (double-clicked)
//==========================================================================
void Dialog::itemAcceptedCallback(MyGUI::ListBox* _sender, size_t _index)
{
if (_index == 0) // user clicked on the "[...]", so back up a directory
{
updatePathList(mCurrentPath.parent_path().string());
}
// it's a folder, open it
else if (is_directory(mPath_set[_index-1]))
{
updatePathList(mPath_set[_index-1]);
}
// it's a file, notify user and quit
else
{
endDialogCallback(0);
}
}
//==========================================================================
// User selected a path (single click)
//==========================================================================
void Dialog::itemSelectedCallback(MyGUI::ListBox* _sender, size_t _index)
{
// make sure it's a file
if (_index != 0 && !is_directory(mPath_set[_index-1]))
{
// mark as selected
mSelectedFile = &mPath_set[_index-1];
mFileEdit->setCaption(mPathList->getItemNameAt(_index));
}
}
//==========================================================================
// User re-opened a recently visited folder
//==========================================================================
void Dialog::recentPathSelectedCallback(MyGUI::ComboBox* _sender, size_t _index)
{
updatePathList(mRecentPaths[_index].parent_path());
}
//==========================================================================
// Dialog's closed
//==========================================================================
void Dialog::endDialogCallback(MyGUI::Widget* _sender)
{
// last minute fix --forgot to account for the user entering the filename himself
// Note that since the Dialog has no idea if the user should be creating a new file, it doesn't check if the
// file exists or not. That's your job.
std::string filename = mFileEdit->getCaption();
// make sure it has an extension
if (mExtensionCombo->getIndexSelected() != 0)
{
std::string extension = mExtensionCombo->getCaption();
if (filename.length() > extension.length())
{
if(!filename.compare(filename.length() - extension.length(), extension.length(), extension))
filename.append(extension);
}
else
filename.append(extension);
}
mSelectedFile = new path(mPath_set[0].parent_path().append(filename.begin(), filename.end()));
//--
if (mSelectedFile)
{
// notify user of selected file (empty string if none)
if (mUserMethod)
{
mUserMethod(this, mSelectedFile->string());
}
// update recently visited paths
bool newEntry = true;
for (size_t i = 0; i < mRecentPaths.size(); i++)
{
if (*mSelectedFile == mRecentPaths)
{
newEntry = false;
break;
}
}
if (newEntry)
{
mRecentPaths.push_back(*mSelectedFile);
mRecentCombo->addItem(mSelectedFile->parent_path().string());
}
// close dialog
mWindow->setVisible(false);
}
// follow up of the fix
delete mSelectedFile;
mSelectedFile = 0;
}
//==========================================================================
// called when a new extension is set
//==========================================================================
void Dialog::extensionChangeCallback(MyGUI::ComboBox* _sender, size_t _index)
{
update();
}
//==========================================================================
// Set callback for when a file is selected
//==========================================================================
void Dialog::eventEndDialog(boost::function<void(Dialog*, const std::string&)> method)
{
mUserMethod = method;
}
//==========================================================================
// get dialog name
//==========================================================================
const std::string& Dialog::getName()
{
return mName;
}
//==========================================================================
// Must be called once dialog is initialized with the functions below
//==========================================================================
void Dialog::update()
{
updatePathList(current_path());
}
//==========================================================================
// show/hide dialog
//==========================================================================
void Dialog::setVisible(bool set)
{
mWindow->setVisible(set);
}
//==========================================================================
// set dialog window title
//==========================================================================
void Dialog::setDialogTitle(const std::string& title)
{
mWindow->setCaption(title);
}
//==========================================================================
// set button caption (ie: save, load, save as..)
//==========================================================================
void Dialog::setButtonCaption(const std::string& caption)
{
mButton->setCaption(caption);
}
//==========================================================================
// Attaches a string to this dialog that can be retrieved later.
// Handy for using the same Dialog for different things
//==========================================================================
void Dialog::setUserString(const std::string& value)
{
mUserString = value;
}
//==========================================================================
// Return user string
//==========================================================================
const std::string& Dialog::getUserString()
{
return mUserString;
}
//==========================================================================
// Add an extension to the extension combobox
//==========================================================================
void Dialog::addFileExtension(const std::string& ext)
{
mExtensionCombo->addItem(ext);
mExtensionCombo->setIndexSelected(0); // MyGUI appears to reset
// the selected item to ITEM_NONE
// whenever a new item is added
}
//==========================================================================
// If this isn't called, the default is show all files.
//==========================================================================
void Dialog::setDefaultExtension(int index)
{
mExtensionCombo->setIndexSelected(index + 1);
}
//==========================================================================
// Sort paths alphabetically (folders first, files last)
//==========================================================================
bool sortFunction(boost::filesystem::path p1, boost::filesystem::path p2)
{
bool d1 = is_directory(p1);
bool d2 = is_directory(p2);
if (d1 && d2)
return (p1.filename() < p2.filename());
else if (d1)
return true;
else if (d2)
return false;
else
return (p1.filename() < p2.filename());
}
//==========================================================================
// Update the paths in the dialog
// my_path; parent directory
// Note: this function is slow. Mainly because i'm lazy.
//==========================================================================
void Dialog::updatePathList(path my_path)
{
mCurrentPath = my_path;
mPathList->removeAllItems();
mPath_set.clear();
mPathList->addItem("[...]");
std::vector<path> temp_paths;
try
{
copy(directory_iterator(mCurrentPath), directory_iterator(), back_inserter(temp_paths));
}
catch(const filesystem_error& ex)
{
// the user probably backed up too far. Jackass.
mCurrentPath = current_path().parent_path();
copy(directory_iterator(mCurrentPath), directory_iterator(), back_inserter(temp_paths));
}
// some shitty OSs don't sort paths..
sort(temp_paths.begin(), temp_paths.end(), sortFunction);
// extension
std::string ext = mExtensionCombo->getCaption();
for (size_t i = 0; i < temp_paths.size(); i++)
{
// folder
if (is_directory(temp_paths))
{
mPath_set.push_back(temp_paths);
mPathList->addItem('[' + temp_paths.filename() + ']');
}
// file
else
{
// filter to extension (if any)
if (mExtensionCombo->getIndexSelected() != 0)
{
if (temp_paths.extension() == ext)
{
mPathList->addItem(temp_paths.filename());
mPath_set.push_back(temp_paths);
}
}
else
{
mPathList->addItem(temp_paths.filename());
mPath_set.push_back(temp_paths);
}
}
}
}
Dialog.layout
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout" version="3.2.0">
<Widget type="Window" skin="WindowCSX" position="40 44 505 351" layer="Main" name="DialogWindow">
<Widget type="ListBox" skin="ListBox" position="5 35 485 246" align="Stretch" name="List"/>
<Widget type="ComboBox" skin="ComboBox" position="5 3 485 30" align="HStretch Top" name="Recent"/>
<Widget type="Button" skin="Button" position="400 285 90 26" align="Right Bottom" name="Confirm"/>
<Widget type="EditBox" skin="EditBox" position="5 285 285 26" align="HStretch Bottom" name="Edit"/>
<Widget type="ComboBox" skin="ComboBox" position="300 285 95 26" align="Right Bottom" name="Extension"/>
</Widget>
</MyGUI>
And finally an example of using it:
mDialog = new Dialog;
mDialog->setDialogTitle("Save file");
mDialog->setButtonCaption("Save");
mDialog->addFileExtension(".h");
mDialog->addFileExtension(".cpp");
// callback
boost::function<void(Dialog*, const std::string&)> my_function = boost::bind(&My_Class::openSaveDialogCallback, this, _1, _2);
mDialog->eventEndDialog(my_function);
mDialog->update();