1 /*******************************************************************************
2  * pvmenu.cpp
3  *
4  * This module implements menu-related routines for the Windows build of POV.
5  *
6  * Author: Christopher J. Cason.
7  *
8  * ---------------------------------------------------------------------------
9  * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
10  * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
11  *
12  * POV-Ray is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Affero General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * POV-Ray is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Affero General Public License for more details.
21  *
22  * You should have received a copy of the GNU Affero General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  * ---------------------------------------------------------------------------
25  * POV-Ray is based on the popular DKB raytracer version 2.12.
26  * DKBTrace was originally written by David K. Buck.
27  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
28  * ---------------------------------------------------------------------------
29  * $File: //depot/public/povray/3.x/windows/pvmenu.cpp $
30  * $Revision: #1 $
31  * $Change: 6069 $
32  * $DateTime: 2013/11/06 11:59:40 $
33  * $Author: chrisc $
34  *******************************************************************************/
35 
36 // REMOVAL OF NON-EXPERT MENUS (August 1998) ... the 'non-expert menus' option
37 // was removed. This leaves some of this code redundant, but here it is anyhow ...
38 
39 #define POVWIN_FILE
40 #define _WIN32_IE COMMONCTRL_VERSION
41 
42 #include <windows.h>
43 #include <commctrl.h>
44 #include <setjmp.h>
45 #include <string.h>
46 
47 #include "pvengine.h"
48 #include "resource.h"
49 #include "pvedit.h"
50 #include "pvdisplay.h"
51 
52 #ifdef RTR_SUPPORT
53   #include "rtrsupport.h"
54 #endif
55 
56 // this must be the last file included
57 #include "syspovdebug.h"
58 
59 namespace povwin
60 {
61 
62 bool                    MenuBarDraw = false ;
63 char                    WindowList[MAX_EDITORS + 1][_MAX_PATH];
64 HMENU                   hMainMenu ;
65 HMENU                   hMenuBar ;
66 HMENU                   hPopupMenus ;
67 HMENU                   hFileMenu ;
68 HMENU                   hEditMenu ;
69 HMENU                   hRenderMenu ;
70 HMENU                   hOptionsMenu ;
71 HMENU                   hToolsMenu ;
72 HMENU                   hPluginsMenu ;
73 HMENU                   hHelpMenu ;
74 HMENU                   hOldRenderwinMenu ;
75 HMENU                   hNewRenderwinMenu ;
76 HMENU                   hVidcapMenu ;
77 HACCEL                  hAccelerators ;
78 
79 extern HWND             main_window ;
80 extern HWND             toolbar_window ;
81 extern bool             RenderwinIsChild ;
82 extern bool             preserve_bitmap ;
83 extern bool             rendering ;
84 extern bool             render_auto_close ;
85 extern bool             IsVista ;
86 extern unsigned         renderwin_8bits ;
87 
PVEnableMenuItem(UINT idItem,UINT state)88 bool PVEnableMenuItem (UINT idItem, UINT state)
89 {
90   EnableMenuItem (hPopupMenus, idItem, state) ;
91   EnableMenuItem (hMenuBar, idItem, state) ;
92   SendMessage (toolbar_window, TB_ENABLEBUTTON, idItem, MAKELONG (state == MF_ENABLED, 0)) ;
93   if (idItem == CM_RENDERCLOSE)
94   {
95     SendMessage (toolbar_window, TB_HIDEBUTTON, CM_RENDERSHOW, MAKELONG (state == MF_ENABLED, 0)) ;
96     SendMessage (toolbar_window, TB_HIDEBUTTON, CM_RENDERCLOSE, MAKELONG (state != MF_ENABLED, 0)) ;
97   }
98   return (true) ;
99 }
100 
PVCheckMenuItem(UINT idItem,UINT state)101 bool PVCheckMenuItem (UINT idItem, UINT state)
102 {
103   CheckMenuItem (hPopupMenus, idItem, state) ;
104   CheckMenuItem (hMenuBar, idItem, state) ;
105   return (true) ;
106 }
107 
PVCheckMenuRadioItem(UINT idFirst,UINT idLast,UINT idItem)108 bool PVCheckMenuRadioItem (UINT idFirst, UINT idLast, UINT idItem)
109 {
110   CheckMenuRadioItem (hPopupMenus, idFirst, idLast, idItem, MF_BYCOMMAND) ;
111   CheckMenuRadioItem (hMenuBar, idFirst, idLast, idItem, MF_BYCOMMAND) ;
112   return (true) ;
113 }
114 
PVModifyMenu(UINT idItem,UINT flags,UINT idNewItem,LPCSTR lpNewItem)115 bool PVModifyMenu (UINT idItem, UINT flags, UINT idNewItem, LPCSTR lpNewItem)
116 {
117   ModifyMenu (hPopupMenus, idItem, flags, idNewItem, lpNewItem) ;
118   ModifyMenu (hMenuBar, idItem, flags, idNewItem, lpNewItem) ;
119   MenuBarDraw = true ;
120   return (true) ;
121 }
122 
PVDeleteMenuItem(UINT idItem)123 bool PVDeleteMenuItem (UINT idItem)
124 {
125   DeleteMenu (hPopupMenus, idItem, MF_BYCOMMAND) ;
126   DeleteMenu (hMenuBar, idItem, MF_BYCOMMAND) ;
127   return (true) ;
128 }
129 
find_menuitem(HMENU hMenu,LPCSTR title)130 int find_menuitem (HMENU hMenu, LPCSTR title)
131 {
132   int         max = GetMenuItemCount (hMenu) ;
133   char        str [256] ;
134 
135   if (title[0] == '\0')
136     return (-1);
137   for (int i = 0 ; i < 64 ; i++)
138     if (GetMenuString (hMenu, i, str, sizeof (str) - 1, MF_BYPOSITION) > 0)
139       if (strcmp (title, str) == 0)
140         return (i) ;
141   return (-1) ;
142 }
143 
init_menus(void)144 void init_menus (void)
145 {
146   hPopupMenus = LoadMenu (hInstance, MAKEINTRESOURCE (POPUP_MENUS32)) ;
147   hAccelerators = LoadAccelerators (hInstance, MAKEINTRESOURCE (PVENGINE_MENU)) ;
148   hMenuBar = LoadMenu (hInstance, MAKEINTRESOURCE (PVENGINE_MENU32)) ;
149   hFileMenu = GetSubMenu (hMenuBar, 0) ;
150   hEditMenu = GetSubMenu (hMenuBar, 1) ;
151   hRenderMenu = GetSubMenu (hMenuBar, 2) ;
152   hOptionsMenu = GetSubMenu (hMenuBar, 3) ;
153   hToolsMenu = GetSubMenu (hMenuBar, 4) ;
154   hHelpMenu = GetSubMenu (hMenuBar, 5) ;
155   hOldRenderwinMenu = GetSubMenu (hPopupMenus, 2) ;
156   hNewRenderwinMenu = GetSubMenu (hPopupMenus, 3) ;
157 
158   int n = find_menuitem(hOptionsMenu, "&Other Settings") ;
159   assert(n != -1) ;
160   hVidcapMenu = GetSubMenu(GetSubMenu(hOptionsMenu, n), 0) ;
161 
162   n = find_menuitem(hOptionsMenu, "GU&I-Extensions") ;
163   assert(n != -1) ;
164   hPluginsMenu = GetSubMenu(hOptionsMenu, n);
165 
166   if (!IsVista)
167   {
168     RemoveMenu (hRenderMenu, CM_RENDERPRIORITY_BACKGROUND, MF_BYCOMMAND);
169     RemoveMenu (hPopupMenus, CM_RENDERPRIORITY_BACKGROUND, MF_BYCOMMAND);
170   }
171 
172 #if POV_RAY_IS_OFFICIAL != 1
173   n = find_menuitem(hOptionsMenu, "&Update Checks") ;
174   assert(n != -1) ;
175   RemoveMenu (hOptionsMenu, n, MF_BYPOSITION);
176   RemoveMenu (hHelpMenu, CM_CHECKUPDATENOW, MF_BYCOMMAND);
177 #endif
178 }
179 
set_newuser_menu(HMENU hMenu,UINT ID,bool hide,bool separator)180 void set_newuser_menu (HMENU hMenu, UINT ID, bool hide, bool separator)
181 {
182   if (GetMenuItemID (hMenu, 0) != ID)
183   {
184     if (hide)
185       return ;
186     if (separator)
187       InsertMenu (hMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, NULL) ;
188     InsertMenu (hMenu, 0, MF_BYPOSITION, ID, "&Help On This Menu") ;
189   }
190   else
191   {
192     if (!hide)
193       return ;
194     DeleteMenu (hMenu, 0, MF_BYPOSITION) ;
195     if (separator)
196       DeleteMenu (hMenu, 0, MF_BYPOSITION) ;
197   }
198 }
199 
set_newuser_menus(bool hide)200 void set_newuser_menus (bool hide)
201 {
202   set_newuser_menu (hFileMenu, CM_FILEMENUHELP, hide, true) ;
203   set_newuser_menu (hEditMenu, CM_EDITMENUHELP, hide, true) ;
204   set_newuser_menu (hRenderMenu, CM_RENDERMENUHELP, hide, true) ;
205   set_newuser_menu (hOptionsMenu, CM_OPTIONSMENUHELP, hide, true) ;
206   set_newuser_menu (hToolsMenu, CM_TOOLSMENUHELP, hide, false) ;
207   set_newuser_menu (hToolsMenu, CM_WINDOWMENUHELP, hide, true) ;
208   set_newuser_menu (GetSubMenu (hPopupMenus, 0), CM_MESSAGEWINMENUHELP, hide, true) ;
209   set_newuser_menu (GetSubMenu (hPopupMenus, 1), CM_RENDERWINMENUHELP, hide, true) ;
210   EditPassOnMessage (NULL, HIDE_NEWUSER_HELP_MESSAGE, hide, 0, NULL) ;
211 }
212 
clear_menu(HMENU hMenu)213 void clear_menu (HMENU hMenu)
214 {
215   while (RemoveMenu (hMenu, 0, MF_BYPOSITION)) ;
216 }
217 
setup_menus(bool have_editor)218 void setup_menus (bool have_editor)
219 {
220   if (have_editor)
221     AppendMenu (hOptionsMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetOptionsMenu), "&Editor Window") ;
222 
223 #ifdef RTR_SUPPORT
224   std::vector<std::string> vidSources;
225   size_t numSources = GetVideoSourceNames(vidSources);
226   if (numSources > 0)
227   {
228     DeleteMenu (hVidcapMenu, 0, MF_BYPOSITION) ;
229     if (numSources > CM_LASTVIDEOSOURCE - CM_FIRSTVIDEOSOURCE + 1)
230       numSources = CM_LASTVIDEOSOURCE - CM_FIRSTVIDEOSOURCE + 1 ;
231     for (int i = 0; i < numSources; i++)
232       InsertMenu (hVidcapMenu, -1, MF_BYPOSITION, CM_FIRSTVIDEOSOURCE + i, vidSources[i].c_str()) ;
233     CheckMenuRadioItem(hVidcapMenu, CM_FIRSTVIDEOSOURCE, CM_LASTVIDEOSOURCE, CM_FIRSTVIDEOSOURCE, MF_BYCOMMAND);
234     int n = find_menuitem (hVidcapMenu, GetVideoSourceName().c_str());
235     if (n != -1)
236       CheckMenuRadioItem(hVidcapMenu, CM_FIRSTVIDEOSOURCE, CM_LASTVIDEOSOURCE, CM_FIRSTVIDEOSOURCE + n, MF_BYCOMMAND);
237     else
238       SetVideoSourceName(vidSources[0].c_str());
239   }
240 #endif
241 
242   DrawMenuBar (main_window) ;
243 }
244 
245 // build the menu displayed when the message window is selected
build_main_menu(HMENU hMenu,bool have_editor)246 void build_main_menu (HMENU hMenu, bool have_editor)
247 {
248   clear_menu (hMenu) ;
249   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) (have_editor ? EditGetMenu (GetFileMenu) : hFileMenu), "&File") ;
250   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hEditMenu, "&Edit") ;
251   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hRenderMenu, "&Render") ;
252   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hOptionsMenu, "&Options") ;
253   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hToolsMenu, "&Tools") ;
254   if (EditGetMenu (GetWindowMenu) != NULL)
255     AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetWindowMenu), "&Window") ;
256   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hHelpMenu, "&Help") ;
257   DrawMenuBar (main_window) ;
258 }
259 
260 // build the menu displayed when an editor window is selected
build_editor_menu(HMENU hMenu)261 void build_editor_menu (HMENU hMenu)
262 {
263   clear_menu (hMenu) ;
264   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetFileMenu), "&File") ;
265   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetEditMenu), "&Edit") ;
266   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetSearchMenu), "Se&arch") ;
267   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetTextMenu), "&Text") ;
268   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetOptionsMenu), "E&ditor") ;
269   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetInsertMenu), "&Insert") ;
270   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hRenderMenu, "&Render") ;
271   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hOptionsMenu, "&Options") ;
272   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hToolsMenu, "Too&ls") ;
273   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) EditGetMenu (GetWindowMenu), "&Window") ;
274   AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hHelpMenu, "&Help") ;
275   DrawMenuBar (main_window) ;
276 }
277 
278 }
279