Started a new FGMenuBar class to handle a different XML-configurable
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.
This commit is contained in:
parent
af4f1894c9
commit
9d726c1bd8
11 changed files with 310 additions and 8 deletions
19
configure.ac
19
configure.ac
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
@ -424,11 +428,13 @@ void guiTogglePanel(puObject *cb)
|
|||
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);
|
||||
|
|
146
src/GUI/menubar.cxx
Normal file
146
src/GUI/menubar.cxx
Normal file
|
@ -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"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Static functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static void
|
||||
menu_callback (puObject * object)
|
||||
{
|
||||
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
|
||||
gui->getMenuBar()->fireItem(object);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
88
src/GUI/menubar.hxx
Normal file
88
src/GUI/menubar.hxx
Normal file
|
@ -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
|
|
@ -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 {
|
||||
|
@ -621,10 +625,12 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
#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 );
|
||||
|
|
|
@ -11,6 +11,8 @@ SG_USING_STD(vector);
|
|||
#include <simgear/misc/exception.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include "menubar.hxx"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue