13#include <simgear/debug/BufferedLogCallback.hxx>
14#include <simgear/nasal/cppbind/NasalObject.hxx>
15#include <simgear/props/props_io.hxx>
16#include <simgear/scene/tsync/terrasync.hxx>
17#include <simgear/structure/SGBinding.hxx>
29using namespace std::string_literals;
48 SGSharedPtr<FGPUICompatDialog>
dialog()
const
50 return _dialog.lock();
56 SGWeakPtr<FGPUICompatDialog> _dialog;
71 return nasal::to_nasal(c, dialog._root);
78 return ctx.to_nasal(SGSharedPtr<FGPUICompatDialog::DialogPeer>(
89 using NasalGUIDialog = nasal::Ghost<SGSharedPtr<FGPUICompatDialog>>;
90 NasalGUIDialog::init(
"gui.xml.CompatDialog")
103 .method(
"close", &FGPUICompatDialog::requestClose);
106 using NasalDialogPeer = nasal::Ghost<SGSharedPtr<DialogPeer>>;
107 NasalDialogPeer::init(
"CompatDialogPeer")
108 .bases<nasal::ObjectRef>()
111 nasal::Hash dialogHash = compatModule.createHash(
"Dialog");
119 _needsRelayout(false)
121 _module =
"__dlg:" + props->getStringValue(
"name",
"[unnamed]");
122 _name = props->getStringValue(
"name",
"[unnamed]");
133 _peer->callMethod<
void>(
"onClose");
136 _props->setIntValue(
"lastx",
getX());
137 _props->setIntValue(
"lasty",
getY());
143 const auto s = _nasal_close->getStringValue();
144 nas->createModule(_module.c_str(), _module.c_str(), s.c_str(), s.length(), _props);
146 nas->deleteModule(_module.c_str());
149 _root->recursiveOnDelete();
156 _windowType = _props->getStringValue(
"type",
"dialog");
157 _uiVersion =
static_cast<uint32_t
>(_props->getIntValue(
"ui-version", 0));
163 nasal::Hash guiModule{nas->getModule(
"gui"), ctx};
164 if (guiModule.isNil()) {
165 throw sg_exception(
"Can't initialize PUICompat Nasal");
168 using SelfRef = SGSharedPtr<FGPUICompatDialog>;
169 using PeerRef = SGSharedPtr<DialogPeer>;
171 auto f = guiModule.get<std::function<PeerRef(std::string, SelfRef)>>(
"_createDialogPeer");
173 SG_LOG(SG_GUI, SG_DEV_ALERT,
"PUICompat module loaded incorrectly");
177 _peer = f(_windowType, SelfRef{
this});
178 _peer->setDialog(
this);
179 _peer->
callMethod<
void>(
"init", nas->wrappedPropsNode(_props));
181 SGPropertyNode*
nasal = _props->getNode(
"nasal");
183 _nasal_close =
nasal->getNode(
"close");
184 SGPropertyNode* open =
nasal->getNode(
"open");
186 const auto s = open->getStringValue();
187 nas->createModule(_module.c_str(), _module.c_str(), s.c_str(), s.length(), _props);
191 _peer->callMethod<
void>(
"didBuild");
192 }
catch (std::exception& e) {
193 SG_LOG(SG_GUI, SG_ALERT,
"Failed to build dialog:" << e.what());
212 SGPropertyNode* nasalNode = _props->getNode(
"nasal");
216 auto callbackNode = nasalNode->getChild(
name);
218 SG_LOG(SG_GUI, SG_DEV_ALERT,
"FGPUICompatDialog::runCallback: no Nasal callback '" <<
name <<
"' defined on dialog " << _name);
222 auto s = callbackNode->getStringValue();
223 auto fileName = _module.c_str();
224 nas->handleCommand(_module.c_str(), fileName, s.c_str(), args.get());
229 return _name.c_str();
234 _root->recursiveUpdateValues(objectName);
239 _root->recursiveApply(objectName);
244 _root->recursiveUpdate();
246 if (_needsRelayout) {
251void FGPUICompatDialog::display(SGPropertyNode* props)
254 _root->setDialog(
this);
262 _needsRelayout =
false;
265 const double ratio =
fgGetDouble(
"/sim/rendering/gui-pixel-ratio", 1.0);
266 const int physicalWidth =
fgGetInt(
"/sim/startup/xsize"),
267 physicalHeight =
fgGetInt(
"/sim/startup/ysize");
268 const int screenw =
static_cast<int>(physicalWidth / ratio),
269 screenh =
static_cast<int>(physicalHeight / ratio);
271 bool userx = _props->hasValue(
"x");
272 bool usery = _props->hasValue(
"y");
273 bool userw = _props->hasValue(
"width");
274 bool userh = _props->hasValue(
"height");
276 int px, py, savex, savey;
278 const int pw = _props->getIntValue(
"width", -1);
279 const int ph = _props->getIntValue(
"height", -1);
280 px = savex = _props->getIntValue(
"x", (screenw - pw) / 2);
281 py = savey = _props->getIntValue(
"y", (screenh - ph) / 2);
287 px = screenw - pw + px;
289 py = screenh - ph + py;
292 _geometry = SGRectd{
static_cast<double>(px),
static_cast<double>(py),
293 static_cast<double>(pw),
static_cast<double>(ph)};
294 _peer->callMethod<
void>(
"geometryChanged");
299 return _geometry.x();
304 return _geometry.y();
309 return _geometry.width();
314 return _geometry.height();
332void FGPUICompatDialog::requestClose()
343 const auto res =
"dialog-"s + _name;
352 _peer->callMethod<
void>(
"titleChanged");
357 return _root->widgetByName(
name);
naRef f_dialogRootObject(FGPUICompatDialog &dialog, naContext c)
naRef f_makeDialogPeer(const nasal::CallContext &ctx)
naRef f_dialogCanResize(FGPUICompatDialog &dialog, naContext c)
static naRef f_dialogModuleHash(FGPUICompatDialog &dialog, naContext c)
naRef propNodeGhostCreate(naContext c, SGPropertyNode *n)
SGSharedPtr< PUICompatObject > PUICompatObjectRef
Class for retrieving translated strings.
FGDialog(SGPropertyNode *props, std::string translationDomain="core")
Construct a new GUI widget configured by a property tree.
std::string translationDomain() const noexcept
Return the translation domain of the dialog.
bool isFlagSet(WindowFlags f) const
naRef callMethod(naRef code, naRef self, int argc, naRef *args, naRef locals)
naRef getModule(const std::string &moduleName) const
void setDialog(FGPUICompatDialog *dlg)
SGSharedPtr< FGPUICompatDialog > dialog() const
An XML-configured dialog box.
std::string nasalModule() const
void runCallback(const std::string &name, SGPropertyNode_ptr args) override
virtual const char * getName()
std::string nameString() const
friend naRef f_dialogRootObject(FGPUICompatDialog &dialog, naContext c)
const std::string & windowType() const
void update() override
Update state.
static void setupGhost(nasal::Hash &compatModule)
std::string title() const
void setTitle(const std::string &s)
virtual void bringToFront()
FGPUICompatDialog(SGPropertyNode *props, std::string translationDomain="core")
Construct a new GUI widget configured by a property tree.
void relayout()
Recompute the dialog's layout.
friend naRef f_makeDialogPeer(const nasal::CallContext &ctx)
void close() override
Close the dialog.
uint32_t uiVersion() const
return the UI XML syntax version used by this dialog.
PUICompatObjectRef widgetByName(const std::string &name) const
find the dialog widget with the specified name, or nullptr.
virtual void applyValues(const std::string &objectName="")
Apply the values of all GUI objects with a specific name, or all if an empty name is given (default).
virtual ~FGPUICompatDialog()
Destructor.
virtual void updateValues(const std::string &objectName="")
Update the values of all GUI objects with a specific name, or all if an empty name is given (default)...
Class for retrieving translated strings.
std::string get(const std::string &resource, const std::string &basicId, int index=0) const
Get a single translation.
XML-configured GUI subsystem.
virtual bool closeDialog(const std::string &name)
Close a named dialog, if it is open.
static PUICompatObjectRef createForType(const std::string &type, SGPropertyNode_ptr config)
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
double fgGetDouble(const char *name, double defaultValue)
Get a double value for a property.