1
0
Fork 0
flightgear/src/GUI/FGWindowsMenuBar.cxx

221 lines
4.9 KiB
C++
Raw Normal View History

#include "FGWindowsMenuBar.hxx"
#include <windows.h>
#include <cstring>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <osgViewer/Viewer>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/api/Win32/GraphicsWindowWin32>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/SGBinding.hxx>
#include <simgear/misc/strutils.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Viewer/renderer.hxx>
#include <iostream>
using namespace simgear;
namespace {
HWND getMainViewerHWND()
{
osgViewer::Viewer::Windows windows;
if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) {
return 0;
}
globals->get_renderer()->getViewer()->getWindows(windows);
osgViewer::Viewer::Windows::const_iterator it = windows.begin();
for(; it != windows.end(); ++it) {
if (strcmp((*it)->className(), "GraphicsWindowWin32")) {
continue;
}
osgViewer::GraphicsWindowWin32* platformWin =
static_cast<osgViewer::GraphicsWindowWin32*>(*it);
return platformWin->getHWND();
}
return 0;
}
bool labelIsSeparator(const std::string& s)
{
std::string t = "---";
if (s.compare(0, t.length(), t) == 0)
return true;
else
return false;
}
LRESULT CALLBACK menubarWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SG_LOG(SG_GENERAL, SG_INFO, "called window proc");
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
} // of anonymous namespace
//
class FGWindowsMenuBar::WindowsMenuBarPrivate
{
public:
WindowsMenuBarPrivate();
~WindowsMenuBarPrivate();
void fireBindingsForItem(UINT commandId)
{
fireBindingList(itemBindings[commandId]);
}
HWND mainWindow;
HMENU menuBar;
bool visible;
WNDPROC baseMenuProc;
typedef std::vector<SGBindingList> MenuItemBindings;
MenuItemBindings itemBindings;
};
FGWindowsMenuBar::FGWindowsMenuBar() :
p(new WindowsMenuBarPrivate)
{
}
FGWindowsMenuBar::~FGWindowsMenuBar()
{
}
FGWindowsMenuBar::WindowsMenuBarPrivate::WindowsMenuBarPrivate() :
visible(true)
{
mainWindow = getMainViewerHWND();
menuBar = 0;
}
FGWindowsMenuBar::WindowsMenuBarPrivate::~WindowsMenuBarPrivate()
{
if (menuBar) {
SetMenu(mainWindow, NULL);
DestroyMenu(menuBar);
}
}
void FGWindowsMenuBar::init()
{
int menuIndex = 0;
SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true);
p->menuBar = CreateMenu();
// p->baseMenuProc = (WNDPROC) ::SetWindowLongPtr((HWND) p->mainWindow, GWL_WNDPROC, (LONG_PTR) menubarWindowProc);
BOOST_FOREACH(SGPropertyNode_ptr n, props->getChildren("menu")) {
// synchronise menu with properties
std::string l = getLocalizedLabel(n);
std::string label = strutils::simplify(l).c_str();
HMENU menuItems = CreatePopupMenu();
if (!n->hasValue("enabled")) {
n->setBoolValue("enabled", true);
}
bool enabled = n->getBoolValue("enabled");
UINT flags = MF_POPUP;
AppendMenu(p->menuBar, flags, (UINT) menuItems, label.c_str());
// submenu
int subMenuIndex = 0;
SGPropertyNode* menuNode = n;
BOOST_FOREACH(SGPropertyNode_ptr n2, menuNode->getChildren("item")) {
if (!n2->hasValue("enabled")) {
n2->setBoolValue("enabled", true);
}
std::string l2 = getLocalizedLabel(n2);
std::string label2 = strutils::simplify(l2).c_str();
std::string shortcut = n2->getStringValue("key");
SGBindingList bl = readBindingList(n->getChildren("binding"), globals->get_props());
UINT commandId = p->itemBindings.size();
p->itemBindings.push_back(bl);
if (labelIsSeparator(label2)) {
AppendMenu(menuItems, MF_SEPARATOR, NULL, NULL);
} else {
if (!shortcut.empty()) {
label2 += "\t"+shortcut;
}
BOOL enabled = n2->getBoolValue("enabled");
UINT flags = MF_STRING;
AppendMenu(menuItems, flags, commandId, label2.c_str());
}
subMenuIndex++;
}
menuIndex++;
}
show();
}
bool FGWindowsMenuBar::isVisible() const
{
return p->visible;
}
void FGWindowsMenuBar::show()
{
SetMenu(p->mainWindow, p->menuBar);
p->visible = true;
}
void FGWindowsMenuBar::hide()
{
SetMenu(p->mainWindow, NULL);
p->visible = false;
}
#if 0
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case MY_MENU:
MessageBox(hwnd, "Menu Item Selected = Large", "Message", MB_OK);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
return 0;
}
#endif