]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/gui_funcs.cxx
Some autopilot fixes
[flightgear.git] / src / GUI / gui_funcs.cxx
index ff6971549c1aee4ee53375dd35a3f5bff543618c..6cd2a95bf4d15953e3bb5439f50a047f42dfce2a 100644 (file)
@@ -42,6 +42,8 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/screen/screen-dump.hxx>
+#include <simgear/structure/event_mgr.hxx>
+#include <simgear/props/props_io.hxx>
 
 #include <Cockpit/panel.hxx>
 #include <Main/globals.hxx>
 #include <Main/fg_os.hxx>
 #include <Main/renderer.hxx>
 #include <Main/viewmgr.hxx>
+#include <Main/WindowSystemAdapter.hxx>
+#include <Main/CameraGroup.hxx>
 #include <GUI/new_gui.hxx>
 
+
 #ifdef _WIN32
 #  include <shellapi.h>
 #endif
@@ -151,50 +156,60 @@ void guiErrorMessage (const char *txt, const sg_throwable &throwable)
 the Gui callback functions 
 ____________________________________________________________________*/
 
+void helpCb()
+{
+    openBrowser( "Docs/index.html" );
+}
 
-// Hier Neu :-) This is my newly added code
-// Added by David Findlay <nedz@bigpond.com>
-// on Sunday 3rd of December
-
-
-void helpCb ()
+bool openBrowser(string address)
 {
-    string command;
-       
-    SGPath path( globals->get_fg_root() );
-    path.append( "Docs/index.html" );
-       
+    bool ok = true;
+
+    // do not resolve addresses with given protocol, i.e. "http://...", "ftp://..."
+    if (address.find("://")==string::npos)
+    {
+        // resolve local file path
+        SGPath path(address);
+        path = globals->resolve_maybe_aircraft_path(address);
+        if (!path.isNull())
+            address = path.str();
+        else
+        {
+            mkDialog ("Sorry, file not found!");
+            SG_LOG(SG_GENERAL, SG_ALERT, "openBrowser: Cannot find requested file '"  
+                    << address << "'.");
+            return false;
+        }
+    }
+
 #ifndef _WIN32
 
-    command = globals->get_browser();
+    string command = globals->get_browser();
     string::size_type pos;
     if ((pos = command.find("%u", 0)) != string::npos)
-        command.replace(pos, 2, path.str());
+        command.replace(pos, 2, address);
     else
-        command += " " + path.str();
+        command += " " + address;
 
     command += " &";
-    system( command.c_str() );
+    ok = (system( command.c_str() ) == 0);
 
 #else // _WIN32
 
     // Look for favorite browser
-    char Dummy[1024], ExecName[1024], browserParameter[1024];
     char win32_name[1024];
 # ifdef __CYGWIN__
-    cygwin32_conv_to_full_win32_path(path.c_str(),win32_name);
+    cygwin32_conv_to_full_win32_path(address.c_str(),win32_name);
 # else
-    strncpy(win32_name,path.c_str(), 1024);
+    strncpy(win32_name,address.c_str(), 1024);
 # endif
-    Dummy[0] = 0;
-    FindExecutable(win32_name, Dummy, ExecName);
-    snprintf(browserParameter, 1024, "file:///%s", win32_name);
-    ShellExecute ( NULL, "open", ExecName, browserParameter, Dummy,
+    ShellExecute ( NULL, "open", win32_name, NULL, NULL,
                    SW_SHOWNORMAL ) ;
 
 #endif
-       
-    mkDialog ("Help started in your web browser window.");
+
+    mkDialog("The file is shown in your web browser window.");
+    return ok;
 }
 
 #if defined( TR_HIRES_SNAP)
@@ -321,7 +336,7 @@ void fgHiResDump()
         int curColumn = trGet(tr, TR_CURRENT_COLUMN);
         // int curRow =  trGet(tr, TR_CURRENT_ROW);
 
-        renderer->update( false );
+        renderer->update();
         // OSGFIXME
 //         if ( do_hud )
 //             fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
@@ -406,9 +421,134 @@ void fgHiResDumpWrapper () {
     fgHiResDump();
 }
 
+namespace
+{
+    using namespace flightgear;
+
+    class GUISnapShotOperation : 
+        public GraphicsContextOperation
+    {
+    public:
+
+        // start new snap shot
+        static bool start()
+        {
+            // allow only one snapshot at a time
+            if (_snapShotOp.valid())
+                return false;
+            _snapShotOp = new GUISnapShotOperation();
+            /* register with graphics context so actual snap shot is done
+             * in the graphics context (thread) */
+            osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
+            WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
+            osg::GraphicsContext* gc = 0;
+            if (guiCamera)
+                gc = guiCamera->getGraphicsContext();
+            if (gc) {
+                gc->add(_snapShotOp.get());
+            } else {
+                wsa->windows[0]->gc->add(_snapShotOp.get());
+            }
+            return true;
+        }
+
+    private:
+        // constructor to be executed in main loop's thread
+        GUISnapShotOperation() :
+            flightgear::GraphicsContextOperation(std::string("GUI snap shot")),
+            _master_freeze(fgGetNode("/sim/freeze/master", true)),
+            _freeze(_master_freeze->getBoolValue()),
+            _result(false),
+            _mouse(fgGetMouseCursor())
+        {
+            if (!_freeze)
+                _master_freeze->setBoolValue(true);
+
+            fgSetMouseCursor(MOUSE_CURSOR_NONE);
+
+            string dir = fgGetString("/sim/paths/screenshot-dir");
+            if (dir.empty())
+                dir = fgGetString("/sim/fg-current");
+
+            _path.set(dir + '/');
+            if (_path.create_dir( 0755 )) {
+                SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '"
+                        << dir << "'. Trying home directory.");
+                dir = fgGetString("/sim/fg-home");
+            }
+
+            char filename[24];
+            static int count = 1;
+            while (count < 1000) {
+                snprintf(filename, 24, "fgfs-screen-%03d.png", count++);
+
+                SGPath p(dir);
+                p.append(filename);
+                if (!p.exists()) {
+                    _path.set(p.str());
+                    break;
+                }
+            }
+
+            _xsize = fgGetInt("/sim/startup/xsize");
+            _ysize = fgGetInt("/sim/startup/ysize");
+
+            FGRenderer *renderer = globals->get_renderer();
+            renderer->resize(_xsize, _ysize);
+            globals->get_event_mgr()->addTask("SnapShotTimer",
+                    this, &GUISnapShotOperation::timerExpired,
+                    0.1, false);
+        }
+
+        // to be executed in graphics context (maybe separate thread)
+        void run(osg::GraphicsContext* gc)
+        {
+            _result = sg_glDumpWindow(_path.c_str(),
+                                     _xsize,
+                                     _ysize);
+        }
+
+        // timer method, to be executed in main loop's thread
+        virtual void timerExpired()
+        {
+            if (isFinished())
+            {
+                globals->get_event_mgr()->removeTask("SnapShotTimer");
+
+                fgSetString("/sim/paths/screenshot-last", _path.c_str());
+                fgSetBool("/sim/signals/screenshot", _result);
+
+                fgSetMouseCursor(_mouse);
+
+                if ( !_freeze )
+                    _master_freeze->setBoolValue(false);
+
+                _snapShotOp = 0;
+            }
+        }
+    
+        static osg::ref_ptr<GUISnapShotOperation> _snapShotOp;
+        SGPropertyNode_ptr _master_freeze;
+        bool _freeze;
+        bool _result;
+        int _mouse;
+        int _xsize, _ysize;
+        SGPath _path;
+    };
+
+}
+
+osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp;
 
 // do a screen snap shot
-bool fgDumpSnapShot () {
+bool fgDumpSnapShot ()
+{
+#if 1
+    // start snap shot operation, while needs to be executed in
+    // graphics context
+    return GUISnapShotOperation::start();
+#else
+    // obsolete code => remove when new code is stable
     static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master");
 
     bool freeze = master_freeze->getBoolValue();
@@ -455,7 +595,7 @@ bool fgDumpSnapShot () {
         }
     }
 
-    int result = sg_glDumpWindow(path.c_str(),
+    bool result = sg_glDumpWindow(path.c_str(),
                                  fgGetInt("/sim/startup/xsize"),
                                  fgGetInt("/sim/startup/ysize"));
 
@@ -467,7 +607,8 @@ bool fgDumpSnapShot () {
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
     }
-    return result != 0;
+    return result;
+#endif
 }
 
 // do an entire scenegraph dump
@@ -555,5 +696,22 @@ void fgDumpTerrainBranch()
     }
 }
 
+void fgPrintVisibleSceneInfoCommand()
+{
+    static const SGPropertyNode *master_freeze
+        = fgGetNode("/sim/freeze/master");
+
+    bool freeze = master_freeze->getBoolValue();
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", true);
+    }
+
+    flightgear::printVisibleSceneInfo(globals->get_renderer());
+
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", false);
+    }
+}
+