]> git.mxchange.org Git - flightgear.git/blob - src/GUI/FGWindowsMenuBar.cxx
GUI support for VIA/Discontinuity
[flightgear.git] / src / GUI / FGWindowsMenuBar.cxx
1 #include "FGWindowsMenuBar.hxx"
2
3 #include <windows.h>
4 #include <cstring>
5
6 #include <boost/foreach.hpp>
7 #include <boost/lexical_cast.hpp>
8
9 #include <osgViewer/Viewer>
10 #include <osgViewer/GraphicsWindow>
11 #include <osgViewer/api/Win32/GraphicsWindowWin32>
12
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>
18
19 #include <Main/fg_props.hxx>
20 #include <Main/globals.hxx>
21 #include <Viewer/renderer.hxx>
22
23 #include <iostream>
24
25 using namespace simgear;
26
27 namespace {
28
29 HWND getMainViewerHWND()
30 {
31         osgViewer::Viewer::Windows windows;
32         if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) {
33                 return 0;
34         }
35
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")) {
40             continue;
41         }
42         
43         osgViewer::GraphicsWindowWin32* platformWin = 
44             static_cast<osgViewer::GraphicsWindowWin32*>(*it);
45         return platformWin->getHWND();
46     }
47     
48     return 0;
49 }
50
51 bool labelIsSeparator(const std::string& s)
52 {
53     std::string t = "---";
54     if (s.compare(0, t.length(), t) == 0)
55         return true;
56     else 
57         return false;
58 }
59
60 LRESULT CALLBACK menubarWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
61 {
62         SG_LOG(SG_GENERAL, SG_INFO, "called window proc");
63
64
65         return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
66
67
68 } // of anonymous namespace
69
70 //
71
72 class FGWindowsMenuBar::WindowsMenuBarPrivate
73 {
74 public:
75   WindowsMenuBarPrivate();
76   ~WindowsMenuBarPrivate();
77
78   void fireBindingsForItem(UINT commandId)
79   {
80     fireBindingList(itemBindings[commandId]);
81   }
82   
83   HWND mainWindow;
84   HMENU menuBar;
85   bool visible;
86   WNDPROC baseMenuProc;
87
88   typedef std::vector<SGBindingList> MenuItemBindings;
89   MenuItemBindings itemBindings;
90
91 };
92
93 FGWindowsMenuBar::FGWindowsMenuBar() : 
94   p(new WindowsMenuBarPrivate)
95 {
96   
97 }
98
99 FGWindowsMenuBar::~FGWindowsMenuBar()
100 {
101   
102 }
103
104 FGWindowsMenuBar::WindowsMenuBarPrivate::WindowsMenuBarPrivate() :
105         visible(true)
106 {
107         mainWindow = getMainViewerHWND();
108         menuBar = 0;
109 }
110   
111 FGWindowsMenuBar::WindowsMenuBarPrivate::~WindowsMenuBarPrivate()
112 {
113         if (menuBar) {
114                 SetMenu(mainWindow, NULL);
115                 DestroyMenu(menuBar);
116         }
117 }
118
119 void FGWindowsMenuBar::init()
120 {    
121     int menuIndex = 0;
122     SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true);
123     
124     p->menuBar = CreateMenu();
125 //      p->baseMenuProc = (WNDPROC) ::SetWindowLongPtr((HWND) p->mainWindow, GWL_WNDPROC, (LONG_PTR) menubarWindowProc);
126
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();
132         
133         if (!n->hasValue("enabled")) {
134             n->setBoolValue("enabled", true);
135         }
136
137         bool enabled = n->getBoolValue("enabled");
138
139                 UINT flags = MF_POPUP;
140                 AppendMenu(p->menuBar, flags, (UINT) menuItems, label.c_str());
141       
142         // submenu
143         int subMenuIndex = 0;
144         SGPropertyNode* menuNode = n;
145         BOOST_FOREACH(SGPropertyNode_ptr n2, menuNode->getChildren("item")) {
146         
147             if (!n2->hasValue("enabled")) {
148                 n2->setBoolValue("enabled", true);
149             }
150
151             std::string l2 = getLocalizedLabel(n2);
152             std::string label2 = strutils::simplify(l2).c_str();
153             std::string shortcut = n2->getStringValue("key");
154             
155             SGBindingList bl = readBindingList(n->getChildren("binding"), globals->get_props());
156                         UINT commandId = p->itemBindings.size();
157                         p->itemBindings.push_back(bl);
158
159             if (labelIsSeparator(label2)) {
160                 AppendMenu(menuItems, MF_SEPARATOR, NULL, NULL);
161             } else {
162                 if (!shortcut.empty()) {
163                     label2 += "\t"+shortcut;
164                 }
165                 BOOL enabled = n2->getBoolValue("enabled");
166
167                                 UINT flags = MF_STRING;
168                                 AppendMenu(menuItems, flags, commandId, label2.c_str());
169             }
170             subMenuIndex++;
171         }
172         menuIndex++;
173     }
174
175         show();
176 }
177
178 bool FGWindowsMenuBar::isVisible() const
179 {
180     return p->visible;
181 }
182
183 void FGWindowsMenuBar::show()
184
185     SetMenu(p->mainWindow, p->menuBar);
186         p->visible = true;
187 }
188
189 void FGWindowsMenuBar::hide()
190 {
191     SetMenu(p->mainWindow, NULL);
192         p->visible = false;
193 }
194
195 #if 0
196 LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg,
197                            WPARAM wParam, LPARAM lParam)
198 {
199     switch(Msg)
200     {
201         case WM_COMMAND:
202                 switch(LOWORD(wParam))
203                 {
204                 case MY_MENU:
205                         MessageBox(hwnd, "Menu Item Selected = Large", "Message", MB_OK);
206                         break;
207                 }
208                 return 0;
209
210     case WM_DESTROY:
211         PostQuitMessage(WM_QUIT);
212         break;
213
214     default:
215         return DefWindowProc(hwnd, Msg, wParam, lParam);
216     }
217
218     return 0;
219 }
220 #endif