]> git.mxchange.org Git - flightgear.git/commitdiff
Started a new FGMenuBar class to handle a different XML-configurable
authordavid <david>
Thu, 16 Jan 2003 18:06:27 +0000 (18:06 +0000)
committerdavid <david>
Thu, 16 Jan 2003 18:06:27 +0000 (18:06 +0000)
menubar.  This one allows regular command bindings, with the
(temporary) condition that every menu item must have a unique text
label.  The new menubar is disabled by default; to enable it,
configure --with-new-menubar.

configure.ac
src/GUI/Makefile.am
src/GUI/gui.cxx
src/GUI/gui.h
src/GUI/gui_funcs.cxx
src/GUI/menubar.cxx [new file with mode: 0644]
src/GUI/menubar.hxx [new file with mode: 0644]
src/GUI/mouse.cxx
src/GUI/new_gui.cxx
src/GUI/new_gui.hxx
src/Input/input.cxx

index 56c7987bec01feb190a9c7cab7b4f7e9dc6a0189..e5fd840d5920cc16a3b90986d73a64205547385d 100644 (file)
@@ -71,7 +71,7 @@ AM_CONDITIONAL(ENABLE_NETWORK_OLK, test "x$with_network_olk" != "xno")
 
 # Specify if we want to use WeatherCM instead of FGEnvironment.
 # default to with_weathercm=no
-AC_ARG_WITH(new-environment, [  --with-weathercm        Use WeatherCM instead of FGEnvironment])
+AC_ARG_WITH(weathercm, [  --with-weathercm        Use WeatherCM instead of FGEnvironment])
 if test "x$with_weathercm" = "xyes" ; then
     echo "Building with WeatherCM"
     AC_DEFINE([FG_WEATHERCM], 1,
@@ -81,6 +81,17 @@ else
 fi
 AM_CONDITIONAL(ENABLE_WEATHERCM, test "x$with_weathercm" = "xyes")
 
+dnl Specify if we want the new XML menu; default to the old one
+AC_ARG_WITH(new-menubar, [  --with-new-menubar        Use the new XML menu bar])
+if test "x$with_new_menubar" = "xyes" ; then
+    echo "Building with new menubar"
+else
+    AC_DEFINE([FG_OLD_MENUBAR], 1,
+              [Define to build with old menubar])
+    echo "Building with old menubar"
+fi
+AM_CONDITIONAL(ENABLE_WEATHERCM, test "x$with_weathercm" = "xyes")
+
 dnl Thread related checks
 AC_ARG_WITH(threads, [  --with-threads          Include tile loading threads [default=no]])
 if test "x$with_threads" = "xyes"; then
@@ -610,6 +621,12 @@ else
     echo "Using FGEnvironment"
 fi
 
+if test "x$with_new_menubar" != "x"; then
+    echo "Using new menubar"
+else
+    echo "Defaulting to old menubar"
+fi
+
 if test "x$with_threads" = "xyes"; then
     echo "threads: yes"
 else
index 5ca85815f53b86a8b8e2e6f4724ad0769acce782..8cb594c554d5e825daee4440bb157674795e9721 100644 (file)
@@ -8,6 +8,7 @@ endif
 
 libGUI_a_SOURCES = \
         new_gui.cxx new_gui.hxx \
+       menubar.cxx menubar.hxx \
        gui.cxx gui.h gui_funcs.cxx \
        gui_local.cxx gui_local.hxx \
        mouse.cxx \
index a0bc37319fa4a6af01548f4d8bdd708f77a903ca..eee417c6c853f8d7cf94aeb7a2d19f278cbbf9c7 100644 (file)
@@ -63,6 +63,7 @@ extern void ConfirmExitDialogInit(void);
 
 puFont guiFnt = 0;
 fntTexFont *guiFntHandle = 0;
+#if defined(FG_OLD_MENUBAR)
 int gui_menu_on = 0;
 puMenuBar    *mainMenuBar = 0;
 //static puButton     *hideMenuButton = 0;
@@ -162,7 +163,7 @@ void destroyMenu(void) {
            free(Menu[i].submenu[j]);
     }
 }
-
+#endif
 
 
 
@@ -238,6 +239,7 @@ void guiInit()
 
     mkDialogInit();
 
+#if defined(FG_OLD_MENUBAR)
     initMenu();
     
     // Set up menu bar toggle
@@ -246,4 +248,5 @@ void guiInit()
     if (!strcmp(fgGetString("/sim/flight-model"), "ada")) {
         guiToggleMenu(); // Menu off by default
     }
+#endif
 }
index b368a9a5c1313fbfb364b48474dfc201161f7624..10a7a0e1f5ba846f9cd91a5e15dc18a690280592 100644 (file)
@@ -44,7 +44,9 @@
 
 // gui.cxx
 extern void guiInit();
+#if defined (FG_OLD_MENUBAR)
 extern void guiToggleMenu(void);
+#endif
 extern void mkDialog(const char *txt);
 extern void guiErrorMessage(const char *txt);
 extern void guiErrorMessage(const char *txt, const sg_throwable &throwable);
index d124c00464c128f5f3f5edc612be42e20a651cbc..6f64d99d619842b7dfaefab54621d1658ee2e9c9 100644 (file)
@@ -119,7 +119,9 @@ extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
                          GLfloat x_end, GLfloat y_end );
 #endif
 
+#if defined(FG_OLD_MENUBAR)
 extern puMenuBar    *mainMenuBar;
+#endif
 
 puDialogBox  *dialogBox = 0;
 puFrame      *dialogFrame = 0;
@@ -245,6 +247,7 @@ void guiErrorMessage (const char *txt, const sg_throwable &throwable)
       mkDialog(msg.c_str());
 }
 
+#if defined(FG_OLD_MENUBAR)
 // Toggle the Menu and Mouse display state
 void guiToggleMenu(void)
 {
@@ -264,6 +267,7 @@ void guiToggleMenu(void)
     }
     gui_menu_on = ~gui_menu_on;
 }
+#endif // FG_OLD_MENUBAR
 
 // Intercept the Escape Key
 void ConfirmExitDialog(void)
@@ -423,12 +427,14 @@ void guiTogglePanel(puObject *cb)
   fgReshape(fgGetInt("/sim/startup/xsize"),
            fgGetInt("/sim/startup/ysize"));
 }
-    
+
+#if defined(FG_OLD_MENUBAR)    
 //void MenuHideMenuCb(puObject *cb)
 void hideMenuCb (puObject *cb)
 {
     guiToggleMenu();
 }
+#endif
 
 void goodBye(puObject *)
 {
@@ -586,10 +592,12 @@ void fgHiResDump()
         fgSetBool("/sim/freeze/master", true);
     }
 
+#if defined(FG_OLD_MENUBAR)
     if(gui_menu_on) {
         show_menu = true;
         guiToggleMenu();
     }
+#endif
        
     if ( !puCursorIsHidden() ) {
         show_pu_cursor = true;
@@ -750,8 +758,10 @@ void fgHiResDump()
 
     delete [] filename;
 
+#if defined(FG_OLD_MENUBAR)
     if( show_menu )
         guiToggleMenu();
+#endif
 
     if ( show_pu_cursor ) {
         puShowCursor();
@@ -811,7 +821,9 @@ void printScreen ( puObject *obj ) {
        puHideCursor();
     }
     // BusyCursor( 0 );
+#if defined(FG_OLD_MENUBAR)
     mainMenuBar->hide();
+#endif
 
     CGlPrinter p( CGlPrinter::PRINT_BITMAP );
     int cur_width = fgGetInt("/sim/startup/xsize");
@@ -819,9 +831,11 @@ void printScreen ( puObject *obj ) {
     p.Begin( "FlightGear", cur_width*3, cur_height*3 );
        p.End( hiResScreenCapture(3) );
 
+#if defined(FG_OLD_MENUBAR)
     if( gui_menu_on ) {
        mainMenuBar->reveal();
     }
+#endif
     // BusyCursor(1);
     if ( show_pu_cursor ) {
        puShowCursor();
@@ -856,7 +870,9 @@ void fgDumpSnapShot () {
         fgSetBool("/sim/freeze/master", true);
     }
 
+#if defined(FG_OLD_MENUBAR)
     mainMenuBar->hide();
+#endif
     TurnCursorOff();
     if ( !puCursorIsHidden() ) {
        show_pu_cursor = true;
@@ -900,9 +916,11 @@ void fgDumpSnapShot () {
     }
 
     TurnCursorOn();
+#if defined(FG_OLD_MENUBAR)
     if( gui_menu_on ) {
        mainMenuBar->reveal();
     }
+#endif
 
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
diff --git a/src/GUI/menubar.cxx b/src/GUI/menubar.cxx
new file mode 100644 (file)
index 0000000..95981de
--- /dev/null
@@ -0,0 +1,146 @@
+#include <string.h>
+#include <iostream>
+#include <plib/pu.h>
+#include <simgear/debug/logstream.hxx>
+
+#include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
+
+#include "new_gui.hxx"
+#include "menubar.hxx"
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Static functions.
+////////////////////////////////////////////////////////////////////////
+
+
+static void
+menu_callback (puObject * object)
+{
+    NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
+    gui->getMenuBar()->fireItem(object);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGMenuBar.
+////////////////////////////////////////////////////////////////////////
+
+
+FGMenuBar::FGMenuBar ()
+    : _visible(false),
+      _menuBar(0)
+{
+}
+
+FGMenuBar::~FGMenuBar ()
+{
+    hide();
+    delete _menuBar;            // FIXME: check if PUI owns the pointer
+
+                                // Delete all those bindings
+    map<string,vector<FGBinding *> >::iterator it;
+    it = _bindings.begin();
+    while (it != _bindings.end()) {
+        for (int i = 0; i < it->second.size(); i++)
+            delete it->second[i];
+    }
+}
+
+void
+FGMenuBar::init ()
+{
+    if (_menuBar != 0)          // FIXME: check if PUI owns the pointer
+        delete _menuBar;
+    make_menubar();
+}
+
+void
+FGMenuBar::show ()
+{
+    if (_menuBar != 0) {
+        _menuBar->reveal();
+        _visible = true;
+    } else {
+        SG_LOG(SG_GENERAL, SG_ALERT, "No menu bar to show");
+        _visible = false;
+    }
+}
+
+void
+FGMenuBar::hide ()
+{
+    if (_menuBar != 0) {
+        _menuBar->hide();
+    } else {
+        SG_LOG(SG_GENERAL, SG_ALERT, "No menu bar to show");
+    }
+    _visible = false;
+}
+
+bool
+FGMenuBar::isVisible () const
+{
+    return _visible;
+}
+
+bool
+FGMenuBar::fireItem (puObject * item)
+{
+    const char * name = item->getLegend();
+    vector<FGBinding *> &bindings = _bindings[name];
+
+    for (int i = 0; i < bindings.size(); i++)
+        bindings[i]->fire();
+}
+
+void
+FGMenuBar::make_menu (SGPropertyNode_ptr node)
+{
+    const char * name = strdup(node->getStringValue("label"));
+    vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
+
+    int array_size = item_nodes.size() + 1;
+
+    char ** items = new char*[array_size];
+    puCallback * callbacks = new puCallback[array_size];
+
+    for (int i = 0, j = item_nodes.size() - 1;
+         i < item_nodes.size();
+         i++, j--) {
+        
+                                // Set up the PUI entries for this item
+        items[j] = strdup((char *)item_nodes[i]->getStringValue("label"));
+        callbacks[j] = menu_callback;
+
+                                // Load all the bindings for this item
+        vector<SGPropertyNode_ptr> binding_nodes =
+            item_nodes[i]->getChildren("binding");
+        for (int k = 0; k < binding_nodes.size(); k++)
+            _bindings[items[j]].push_back(new FGBinding(binding_nodes[k]));
+    }
+
+    items[item_nodes.size()] = 0;
+    callbacks[item_nodes.size()] = 0;
+
+    _menuBar->add_submenu(name, items, callbacks);
+}
+
+void
+FGMenuBar::make_menubar ()
+{
+    _menuBar = new puMenuBar;
+    SGPropertyNode props;
+
+    fgLoadProps("gui/menubar.xml", &props);
+    vector<SGPropertyNode_ptr> menu_nodes = props.getChildren("menu");
+    for (int i = 0; i < menu_nodes.size(); i++)
+        make_menu(menu_nodes[i]);
+
+    _menuBar->close();
+}
+
+// end of menubar.cxx
diff --git a/src/GUI/menubar.hxx b/src/GUI/menubar.hxx
new file mode 100644 (file)
index 0000000..9c3929e
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef __MENUBAR_HXX
+#define __MENUBAR_HXX 1
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include <simgear/compiler.h>  // for SG_USING_STD
+
+#include <plib/pu.h>
+
+#include <map>
+SG_USING_STD(map);
+
+#include <vector>
+SG_USING_STD(vector);
+
+
+class puMenuBar;
+class puObject;
+class FGBinding;
+
+
+/**
+ * XML-configured PUI menu bar.
+ */
+class FGMenuBar
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    FGMenuBar ();
+
+
+    /**
+     * Destructor.
+     */
+    virtual ~FGMenuBar ();
+
+
+    /**
+     * Initialize the menu bar from $FG_ROOT/gui/menubar.xml
+     */
+    virtual void init ();
+
+    
+    /**
+     * Make the menu bar visible.
+     */
+    virtual void show ();
+
+
+    /**
+     * Make the menu bar invisible.
+     */
+    virtual void hide ();
+
+
+    /**
+     * Test whether the menu bar is visible.
+     */
+    virtual bool isVisible () const;
+
+
+    /**
+     * IGNORE THIS METHOD!!!
+     *
+     * This is necessary only because plib does not provide any easy
+     * way to attach user data to a menu item.  FlightGear should not
+     * have to know about PUI internals, but this method allows the
+     * callback to pass the menu item one-shot on to the current menu.
+     */
+    virtual bool fireItem (puObject * item);
+
+
+private:
+
+    void make_menu (SGPropertyNode_ptr node);
+    void make_menubar ();
+
+    bool _visible;
+    puMenuBar * _menuBar;
+    map<string,vector<FGBinding *> > _bindings;
+};
+
+#endif // __MENUBAR_HXX
index f033068e0c70c8158bcb78dd8e299e6a79016cfd..d33f8da39a3f08c2f13f35a95a466a3f5288ba13 100644 (file)
@@ -323,7 +323,9 @@ void CenterView( void ) {
        glutSetCursor(GLUT_CURSOR_INHERIT);
 
        // Is this necessary ??
+#if defined(FG_OLD_MENU)
        if( !gui_menu_on )   TurnCursorOff();
+#endif
 
        glutWarpPointer( _savedX, _savedY );
     }
@@ -368,6 +370,7 @@ void guiMotionFunc ( int x, int y )
     wh = MOUSE_YSIZE;
 
     if (mouse_mode == MOUSE_POINTER) {
+#if defined(FG_OLD_MENU)
         // TURN MENU ON IF MOUSE AT TOP
         if( y < 1 ) {
             if( !gui_menu_on )
@@ -378,6 +381,7 @@ void guiMotionFunc ( int x, int y )
             if( gui_menu_on )
                 guiToggleMenu();                       
         }
+#endif
         puMouse ( x, y ) ;
         glutPostRedisplay () ;
     } else {
@@ -620,11 +624,13 @@ void guiMouseFunc(int button, int updown, int x, int y)
 #endif // NO_SMOOTH_MOUSE_VIEW
 #endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW
                     glutSetCursor(GLUT_CURSOR_INHERIT);
-                    
+
+#if defined(FG_OLD_MENU)                    
 #if defined(WIN32_CURSOR_TWEAKS_OFF)
                     if(!gui_menu_on)
                         TurnCursorOff();
 #endif // WIN32_CURSOR_TWEAKS_OFF
+#endif // FG_OLD_MENU
                     break;
             } // end switch (mouse_mode)
             glutWarpPointer( x, y );
index 90cff403d7c2ea9a346ea9d5448a1a6f6a6bc3f2..e7c6f939f575e01348a5057e64659307055b3e11 100644 (file)
@@ -11,6 +11,8 @@ SG_USING_STD(vector);
 #include <simgear/misc/exception.hxx>
 #include <Main/fg_props.hxx>
 
+#include "menubar.hxx"
+
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -257,20 +259,27 @@ GUIWidget::PropertyObject::PropertyObject (const char * n,
 
 
 NewGUI::NewGUI ()
-    : _current_widget(0)
+    : _menubar(new FGMenuBar),
+      _current_widget(0)
 {
 }
 
 NewGUI::~NewGUI ()
 {
+    delete _menubar;
 }
 
 void
 NewGUI::init ()
 {
-    char path[1024];
-    ulMakePath(path, getenv("FG_ROOT"), "gui");
-    readDir(path);
+    char path1[1024];
+    char path2[1024];
+    ulMakePath(path1, getenv("FG_ROOT"), "gui");
+    ulMakePath(path2, path1, "dialogs");
+    readDir(path2);
+#if !defined(FG_OLD_MENUBAR)
+    _menubar->init();
+#endif
 }
 
 void
@@ -300,6 +309,12 @@ NewGUI::getCurrentWidget ()
     return _current_widget;
 }
 
+FGMenuBar *
+NewGUI::getMenuBar ()
+{
+    return _menubar;
+}
+
 void
 NewGUI::readDir (const char * path)
 {
index 91a6aa3dfcec00471b8759beede0014b7af311f2..6b5b0b9e028b297a93fb61c0f1e35aa582073666 100644 (file)
@@ -22,6 +22,7 @@ SG_USING_STD(map);
 #include <Main/fg_props.hxx>
 #include <Input/input.hxx>
 
+class FGMenuBar;
 class GUIWidget;
 
 
@@ -133,11 +134,14 @@ public:
     virtual void setCurrentWidget (GUIWidget * widget);
     virtual GUIWidget * getCurrentWidget ();
 
+    virtual FGMenuBar * getMenuBar ();
+
 
 private:
 
     void readDir (const char * path);
 
+    FGMenuBar * _menubar;
     GUIWidget * _current_widget;
     map<string,SGPropertyNode_ptr> _widgets;
 
index 59d874bdb027f79343335d97c98c0f92d516d43c..7a5cbaedc8c90f1fa882fe11ad9b986472337eef 100644 (file)
@@ -335,7 +335,9 @@ FGInput::doKey (int k, int modifiers, int x, int y)
         }
         case 256+GLUT_KEY_F10: // F10 toggles menu on and off...
             SG_LOG(SG_INPUT, SG_INFO, "Invoking call back function");
+#if defined(FG_OLD_MENUBAR)
             guiToggleMenu();
+#endif
             return;
         case 256+GLUT_KEY_F11: // F11 Altitude Dialog.
             SG_LOG(SG_INPUT, SG_INFO, "Invoking Altitude call back function");