1 #include "FGWindowsMenuBar.hxx"
6 #include <boost/foreach.hpp>
7 #include <boost/lexical_cast.hpp>
9 #include <osgViewer/Viewer>
10 #include <osgViewer/GraphicsWindow>
11 #include <osgViewer/api/Win32/GraphicsWindowWin32>
13 #include <simgear/props/props.hxx>
14 #include <simgear/props/props_io.hxx>
15 #include <simgear/debug/logstream.hxx>
16 #include <simgear/structure/SGBinding.hxx>
17 #include <simgear/misc/strutils.hxx>
19 #include <Main/fg_props.hxx>
20 #include <Main/globals.hxx>
21 #include <Viewer/renderer.hxx>
25 using namespace simgear;
29 HWND getMainViewerHWND()
31 osgViewer::Viewer::Windows windows;
32 if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) {
36 globals->get_renderer()->getViewer()->getWindows(windows);
37 osgViewer::Viewer::Windows::const_iterator it = windows.begin();
38 for(; it != windows.end(); ++it) {
39 if (strcmp((*it)->className(), "GraphicsWindowWin32")) {
43 osgViewer::GraphicsWindowWin32* platformWin =
44 static_cast<osgViewer::GraphicsWindowWin32*>(*it);
45 return platformWin->getHWND();
51 bool labelIsSeparator(const std::string& s)
53 std::string t = "---";
54 if (s.compare(0, t.length(), t) == 0)
60 LRESULT CALLBACK menubarWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
62 SG_LOG(SG_GENERAL, SG_INFO, "called window proc");
65 return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
68 } // of anonymous namespace
72 class FGWindowsMenuBar::WindowsMenuBarPrivate
75 WindowsMenuBarPrivate();
76 ~WindowsMenuBarPrivate();
78 void fireBindingsForItem(UINT commandId)
80 fireBindingList(itemBindings[commandId]);
88 typedef std::vector<SGBindingList> MenuItemBindings;
89 MenuItemBindings itemBindings;
93 FGWindowsMenuBar::FGWindowsMenuBar() :
94 p(new WindowsMenuBarPrivate)
99 FGWindowsMenuBar::~FGWindowsMenuBar()
104 FGWindowsMenuBar::WindowsMenuBarPrivate::WindowsMenuBarPrivate() :
107 mainWindow = getMainViewerHWND();
111 FGWindowsMenuBar::WindowsMenuBarPrivate::~WindowsMenuBarPrivate()
114 SetMenu(mainWindow, NULL);
115 DestroyMenu(menuBar);
119 void FGWindowsMenuBar::init()
122 SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true);
124 p->menuBar = CreateMenu();
125 // p->baseMenuProc = (WNDPROC) ::SetWindowLongPtr((HWND) p->mainWindow, GWL_WNDPROC, (LONG_PTR) menubarWindowProc);
127 BOOST_FOREACH(SGPropertyNode_ptr n, props->getChildren("menu")) {
128 // synchronise menu with properties
129 std::string l = getLocalizedLabel(n);
130 std::string label = strutils::simplify(l).c_str();
131 HMENU menuItems = CreatePopupMenu();
133 if (!n->hasValue("enabled")) {
134 n->setBoolValue("enabled", true);
137 bool enabled = n->getBoolValue("enabled");
139 UINT flags = MF_POPUP;
140 AppendMenu(p->menuBar, flags, (UINT) menuItems, label.c_str());
143 int subMenuIndex = 0;
144 SGPropertyNode* menuNode = n;
145 BOOST_FOREACH(SGPropertyNode_ptr n2, menuNode->getChildren("item")) {
147 if (!n2->hasValue("enabled")) {
148 n2->setBoolValue("enabled", true);
151 std::string l2 = getLocalizedLabel(n2);
152 std::string label2 = strutils::simplify(l2).c_str();
153 std::string shortcut = n2->getStringValue("key");
155 SGBindingList bl = readBindingList(n->getChildren("binding"), globals->get_props());
156 UINT commandId = p->itemBindings.size();
157 p->itemBindings.push_back(bl);
159 if (labelIsSeparator(label2)) {
160 AppendMenu(menuItems, MF_SEPARATOR, NULL, NULL);
162 if (!shortcut.empty()) {
163 label2 += "\t"+shortcut;
165 BOOL enabled = n2->getBoolValue("enabled");
167 UINT flags = MF_STRING;
168 AppendMenu(menuItems, flags, commandId, label2.c_str());
178 bool FGWindowsMenuBar::isVisible() const
183 void FGWindowsMenuBar::show()
185 SetMenu(p->mainWindow, p->menuBar);
189 void FGWindowsMenuBar::hide()
191 SetMenu(p->mainWindow, NULL);
196 LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg,
197 WPARAM wParam, LPARAM lParam)
202 switch(LOWORD(wParam))
205 MessageBox(hwnd, "Menu Item Selected = Large", "Message", MB_OK);
211 PostQuitMessage(WM_QUIT);
215 return DefWindowProc(hwnd, Msg, wParam, lParam);