1 // FileDialog -- generic FileDialog interface and Nasal wrapper
3 // Written by James Turner, started 2012.
5 // Copyright (C) 2012 James Turner <zakalawe@mac.com>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include "FileDialog.hxx"
28 #include <boost/shared_ptr.hpp>
29 #include <boost/weak_ptr.hpp>
31 #include <simgear/nasal/cppbind/Ghost.hxx>
33 #include <Main/globals.hxx>
34 #include <Scripting/NasalSys.hxx>
35 #include "PUIFileDialog.hxx"
38 #include "CocoaFileDialog.hxx"
41 #if defined(SG_WINDOWS)
42 #include "WindowsFileDialog.hxx"
45 FGFileDialog::FGFileDialog(Usage use) :
52 FGFileDialog::~FGFileDialog()
54 // ensure this is concrete so callback gets cleaned up.
57 void FGFileDialog::setTitle(const std::string& aText)
62 void FGFileDialog::setButton(const std::string& aText)
67 void FGFileDialog::setDirectory(const SGPath& aPath)
72 void FGFileDialog::setFilterPatterns(const string_list& patterns)
74 _filterPatterns = patterns;
77 void FGFileDialog::setPlaceholderName(const std::string& aName)
82 void FGFileDialog::setCallback(Callback* aCB)
87 void FGFileDialog::setShowHidden(bool show)
92 class NasalCallback : public FGFileDialog::Callback
95 NasalCallback(naRef f, naRef obj) :
99 FGNasalSys* sys = static_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
100 _gcKeys[0] = sys->gcSave(f);
101 _gcKeys[1] = sys->gcSave(obj);
104 virtual void onFileDialogDone(FGFileDialog* instance, const SGPath& aPath)
106 FGNasalSys* sys = static_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
108 naContext ctx = naNewContext();
110 args[0] = nasal::to_nasal(ctx, aPath);
112 sys->callMethod(func, object, 1, args, naNil() /* locals */);
118 FGNasalSys* sys = static_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
119 sys->gcRelease(_gcKeys[0]);
120 sys->gcRelease(_gcKeys[1]);
128 void FGFileDialog::setCallbackFromNasal(const nasal::CallContext& ctx)
130 // wrap up the naFunc in our callback type
131 naRef func = ctx.requireArg<naRef>(0);
132 naRef object = ctx.getArg<naRef>(1, naNil());
134 setCallback(new NasalCallback(func, object));
137 typedef boost::shared_ptr<FGFileDialog> FileDialogPtr;
138 typedef nasal::Ghost<FileDialogPtr> NasalFileDialog;
141 * Create new FGFileDialog and get ghost for it.
143 static naRef f_createFileDialog(naContext c, naRef me, int argc, naRef* args)
145 nasal::CallContext ctx(c, argc, args);
146 FGFileDialog::Usage usage = (FGFileDialog::Usage) ctx.requireArg<int>(0);
149 FileDialogPtr fd(new CocoaFileDialog(usage));
150 #elif defined(SG_WINDOWS)
151 FileDialogPtr fd(new WindowsFileDialog(usage));
153 FileDialogPtr fd(new PUIFileDialog(usage));
156 return nasal::to_nasal(c, fd);
159 void postinitNasalGUI(naRef globals, naContext c)
161 NasalFileDialog::init("gui._FileDialog")
162 .member("title", &FGFileDialog::getTitle, &FGFileDialog::setTitle)
163 .member("button", &FGFileDialog::getButton, &FGFileDialog::setButton)
164 .member("directory", &FGFileDialog::getDirectory, &FGFileDialog::setDirectory)
165 .member("show_hidden", &FGFileDialog::showHidden, &FGFileDialog::setShowHidden)
166 .member("placeholder", &FGFileDialog::getPlaceholder, &FGFileDialog::setPlaceholderName)
167 .member("pattern", &FGFileDialog::filterPatterns, &FGFileDialog::setFilterPatterns)
168 .method("open", &FGFileDialog::exec)
169 .method("close", &FGFileDialog::close)
170 .method("setCallback", &FGFileDialog::setCallbackFromNasal);
172 nasal::Hash guiModule = nasal::Hash(globals, c).get<nasal::Hash>("gui");
174 guiModule.set("FILE_DIALOG_OPEN_FILE", (int) FGFileDialog::USE_OPEN_FILE);
175 guiModule.set("FILE_DIALOG_SAVE_FILE", (int) FGFileDialog::USE_SAVE_FILE);
176 guiModule.set("FILE_DIALOG_CHOOSE_DIR", (int) FGFileDialog::USE_CHOOSE_DIR);
177 guiModule.set("_createFileDialog", f_createFileDialog);