221 lines
4.9 KiB
C++
221 lines
4.9 KiB
C++
|
#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
|