2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 ///////////////////////////////////////////////////////////////////////////////
7 // $Source: r:/t2repos/thief2/src/editor/menus.cpp,v $
9 // $Date: 1999/10/29 19:18:50 $
12 // @Note (toml 08-03-97): This is a temporary solution that will have to be
13 // rethought when dynamic menus are supported. No sub-menus right now
32 // Must be last header
35 ///////////////////////////////////////////////////////////////////////////////
37 #define kMenuCommandBase 1000
44 unsigned NewCommand(const char *);
45 const char * Lookup(unsigned);
49 cDynArray
<const char *> m_CommandTexts
;
52 ///////////////////////////////////////
54 inline cMenuCommands::~cMenuCommands()
59 ///////////////////////////////////////
61 inline unsigned cMenuCommands::NewCommand(const char * pszCommand
)
63 m_CommandTexts
.Append(strdup(pszCommand
));
64 return kMenuCommandBase
+ m_CommandTexts
.Size() - 1;
67 ///////////////////////////////////////
69 inline const char * cMenuCommands::Lookup(unsigned id
)
71 unsigned index
= id
- kMenuCommandBase
;
72 if (index
< m_CommandTexts
.Size())
73 return m_CommandTexts
[index
];
78 ///////////////////////////////////////
80 void cMenuCommands::ClearAll()
82 for (int i
= 0; i
< m_CommandTexts
.Size(); i
++)
83 free((void *)(m_CommandTexts
[i
]));
84 m_CommandTexts
.SetSize(0);
87 ///////////////////////////////////////////////////////////////////////////////
95 void BeginMenu(const char * = NULL
);
96 void AddItem(const char *, unsigned id
);
100 void AttachToWindow(HWND hWnd
);
101 void DetachFromWindow();
105 cWinMenu
* GetMenuByNumber(int number
);
110 cDynArray
<cWinMenu
*> m_Menus
;
111 cDynArray
<int> m_MenuStack
;
115 ///////////////////////////////////////
117 inline cMenuSet::cMenuSet()
123 ///////////////////////////////////////
125 inline cMenuSet::~cMenuSet()
130 ///////////////////////////////////////
132 inline void cMenuSet::BeginMenu(const char * pszSubMenuName
)
134 cWinMenu
* pMenu
= new cWinMenu();
137 m_Menus
.Append(pMenu
);
139 m_MenuStack
.Append(m_iCurrentMenu
);
141 int oldMenu
= m_iCurrentMenu
;
143 m_iCurrentMenu
= (int)m_Menus
.Size() - 1;
145 if (m_iCurrentMenu
!= 0)
146 m_Menus
[oldMenu
]->AppendMenu(MF_POPUP
, (uint
)(HMENU
)(*pMenu
), pszSubMenuName
);
150 ///////////////////////////////////////
152 inline void cMenuSet::EndMenu()
154 m_iCurrentMenu
= m_MenuStack
[m_MenuStack
.Size() - 1];
155 m_MenuStack
.SetSize(m_MenuStack
.Size() - 1);
158 ///////////////////////////////////////
160 inline void cMenuSet::AddItem(const char * pszMenuItemName
, unsigned id
)
162 if (m_Menus
.Size() != 0)
163 m_Menus
[m_iCurrentMenu
]->AppendMenu(MF_STRING
, id
, pszMenuItemName
);
166 ///////////////////////////////////////
168 inline void cMenuSet::AddSeparator()
170 if (m_Menus
.Size() != 0)
171 m_Menus
[m_iCurrentMenu
]->AppendMenu(MF_SEPARATOR
, 0, 0);
174 ///////////////////////////////////////
176 void cMenuSet::AttachToWindow(HWND hWnd
)
178 if (m_Menus
.Size() == 0)
185 SetMenu(m_hWnd
, NULL
);
189 SetMenu(m_hWnd
, *(m_Menus
[0]));
192 ///////////////////////////////////////
194 void cMenuSet::DetachFromWindow()
197 SetMenu(m_hWnd
, NULL
);
201 ///////////////////////////////////////
203 void cMenuSet::DestroyAll()
205 if (m_Menus
.Size() == 0)
208 int iFirst
= (m_hWnd
) ? 1 : 0;
210 for (int i
= iFirst
; i
< m_Menus
.Size(); i
++)
215 m_MenuStack
.SetSize(0);
219 ///////////////////////////////////////
221 cWinMenu
* cMenuSet::GetMenuByNumber(int number
)
223 return (m_Menus
[number
]);
226 ///////////////////////////////////////////////////////////////////////////////
228 typedef cStrHashTable
<BOOL
> cMenusInProgress
;
230 ///////////////////////////////////////////////////////////////////////////////
232 static cMenuCommands g_MenuCommands
;
233 static cMenuSet g_MenuSet
;
235 ///////////////////////////////////////////////////////////////////////////////
237 #define kMaxMenuConfigEntry 512
239 void ParseMenu(const char * pszMenuText
, const char * pszMenuTag
, cMenuSet
& menuSet
, cMenusInProgress
& menusInProgress
)
242 BOOL foundMenu
= config_get_raw(pszMenuTag
,
243 menuDefStr
.GetBuffer(kMaxMenuConfigEntry
),
244 kMaxMenuConfigEntry
);
245 menuDefStr
.ReleaseBuffer();
248 if (foundMenu
&& !menuDefStr
.IsEmpty())
250 if (menusInProgress
.Lookup(pszMenuTag
, &foundMenu
))
253 menusInProgress
.Insert(pszMenuTag
, TRUE
);
254 menuSet
.BeginMenu(pszMenuText
);
256 cStr
continuationMenuTag(pszMenuTag
);
257 int iCurrentPart
= 0;
259 continuationMenuTag
+= "_0";
263 int indexNextEntry
= 0;
264 int indexSemicolon
= 0;
270 while (menuDefStr
[indexNextEntry
])
273 indexSemicolon
= indexNextEntry
+ menuDefStr
.SpanExcluding("|", indexNextEntry
);
275 // If the string is non-zero, deal with it
276 if (indexSemicolon
- indexNextEntry
!= 0)
278 menuDefStr
.Mid(menuEntry
, indexNextEntry
, indexSemicolon
- indexNextEntry
);
280 int indexColon
= menuEntry
.Find(':');
281 if (indexColon
!= -1)
283 menuEntry
.Mid(menuText
, 0, indexColon
);
284 menuEntry
.Mid(menuValue
, indexColon
+ 1, menuEntry
.GetLength() - (indexColon
+ 1));
288 menuText
= menuEntry
;
289 menuValue
= menuEntry
;
294 if (menuValue
.Find("menu_") == 0)
296 ParseMenu(menuText
, menuValue
, menuSet
, menusInProgress
);
298 else if (menuText
.Find("sep") == 0)
300 menuSet
.AddSeparator();
304 menuSet
.AddItem(menuText
, g_MenuCommands
.NewCommand(menuValue
));
313 // Skip to the next non-semicolon
314 indexNextEntry
= indexSemicolon
+ menuDefStr
.SpanIncluding("|", indexSemicolon
);
317 continuationMenuTag
[continuationMenuTag
.GetLength() - 1] = '0' + iCurrentPart
;
319 foundMenu
= config_get_raw(continuationMenuTag
,
320 menuDefStr
.GetBuffer(kMaxMenuConfigEntry
),
321 kMaxMenuConfigEntry
);
322 menuDefStr
.ReleaseBuffer();
326 menusInProgress
.Delete(pszMenuTag
);
329 menuSet
.AddItem(pszMenuText
, 0);
332 ///////////////////////////////////////////////////////////////////////////////
334 BOOL
CreateMenu(const char * pszMenuTag
)
336 cMenusInProgress menusInProgress
;
338 ParseMenu(NULL
, pszMenuTag
, g_MenuSet
, menusInProgress
);
343 ///////////////////////////////////////////////////////////////////////////////
345 void SetMainMenu(const char * pszName
)
349 HWND hWnd
= pWinApp
->GetMainWnd();
351 g_MenuSet
.DetachFromWindow();
352 g_MenuSet
.DestroyAll();
353 g_MenuCommands
.ClearAll();
359 menuNameStr
= "menu_";
360 menuNameStr
+= pszName
;
364 CreateMenu(menuNameStr
);
366 g_MenuSet
.AttachToWindow(hWnd
);
370 ///////////////////////////////////////////////////////////////////////////////
372 void MenuCommand(unsigned id
)
374 const char * pszMenuCommand
= g_MenuCommands
.Lookup(id
);
378 CommandExecute((char *)pszMenuCommand
);
382 ///////////////////////////////////////////////////////////////////////////////
384 // Sets an exclusive radio-button style bullet beside a menu item
388 void SetRadioCheckmark (int menu
, int firstPos
, int lastPos
, int checkPos
)
390 g_MenuSet
.GetMenuByNumber(menu
)->CheckMenuRadioItem (firstPos
, lastPos
, checkPos
, MF_BYPOSITION
);