MenuShortcut::MenuShortcut()
{
_Key = 0;
}
MenuShortcut::MenuShortcut(const String &S)
{
_Shift = S.StartsWith("Shift+");
_Ctrl = S.StartsWith("Ctrl+");
_Alt = S.StartsWith("Alt+");
Vector<String> Result;
S.Partition('+', Result);
String StringKey = Result.Last();
if(StringKey.Length() == 1 && StringKey[0] >= 'A' && StringKey[0] <= 'Z')
{
_Key = KEY_A + UINT(StringKey[0]) - UINT('A');
}
else if(StringKey.Length() == 1 && StringKey[0] >= '0' && StringKey[0] <= '9')
{
_Key = KEY_0 + UINT(StringKey[0]) - UINT('0');
}
else if(StringKey == "Enter")
{
_Key = KEY_ENTER;
}
else if(StringKey == "End")
{
_Key = KEY_END;
}
else if(StringKey == "Pause")
{
_Key = KEY_PAUSE;
}
else if(StringKey == "Left")
{
_Key = KEY_LEFT;
}
else if(StringKey == "Right")
{
_Key = KEY_RIGHT;
}
else if(StringKey == "Up")
{
_Key = KEY_UP;
}
else if(StringKey == "Down")
{
_Key = KEY_DOWN;
}
else
{
SignalError(String("Invalid Menu Shortcut: ") + S);
}
}
void MenuShortcut::Dispatch(InputManager &I, UINT Id)
{
if(_Key != 0)
{
if( (!_Shift || I.KeyCheck(KEY_SHIFT)) &&
(!_Ctrl || I.KeyCheck(KEY_CTRL)) )
{
if(I.KeyCheckOnce(_Key))
{
I.PushEvent(InputEvent(InputEventMenu, Id));
}
}
}
}
MenuEntry::MenuEntry()
{
_SubMenu = NULL;
}
MenuEntry::MenuEntry(Menu *SubMenu, const String &Name, UINT Id)
{
_SubMenu = SubMenu;
_Name = Name;
_Id = Id;
Vector<String> Partition;
Name.Partition('\t', Partition);
if(Partition.Length() == 2)
{
_Shortcut = MenuShortcut(Partition.Last());
}
}
MenuEntry::~MenuEntry()
{
FreeMemory();
}
void MenuEntry::FreeMemory()
{
}
void MenuEntry::DispatchKeyboardShortcuts(InputManager &I)
{
if(_SubMenu != NULL)
{
_SubMenu->DispatchKeyboardShortcuts(I);
}
else
{
_Shortcut.Dispatch(I, _Id);
}
}
Menu::Menu()
{
_Handle = NULL;
}
Menu::Menu(HMENU Handle)
{
_Handle = Handle;
}
Menu::~Menu()
{
FreeMemory();
}
void Menu::FreeMemory()
{
for(UINT Index = 0; Index < _Entries.Length(); Index++)
{
_Entries[Index].FreeMemory();
}
_Entries.FreeMemory();
if(_Handle != NULL)
{
DestroyMenu(_Handle);
_Handle = NULL;
}
}
Menu& Menu::AddSubMenu(ApplicationWindow &WM, UINT Id, const String &Name)
{
HMENU NewHandle = CreatePopupMenu();
Assert(NewHandle != NULL, "CreatePopupMenu failed");
_Entries.PushEnd(MenuEntry(new Menu(NewHandle), Name, Id));
BOOL Success = AppendMenu(_Handle, MF_POPUP, UINT_PTR(NewHandle), Name.CString());
Assert(Success != 0, "AppendMenu failed");
Success = DrawMenuBar(WM.Handle());
Assert(Success != 0, "DrawMenuBar failed");
return _Entries.Last().SubMenu();
}
void Menu::AddSeperator(ApplicationWindow &WM, UINT Id)
{
BOOL Success = AppendMenu(_Handle, MF_SEPARATOR, Id, NULL);
Assert(Success != 0, "SetMenu failed");
Success = DrawMenuBar(WM.Handle());
Assert(Success != 0, "DrawMenuBar failed");
}
void Menu::AddString(ApplicationWindow &WM, UINT Id, const String &Name)
{
BOOL Success = AppendMenu(_Handle, MF_STRING, Id, Name.CString());
Assert(Success != 0, "SetMenu failed");
Success = DrawMenuBar(WM.Handle());
Assert(Success != 0, "DrawMenuBar failed");
_Entries.PushEnd(MenuEntry(NULL, Name, Id));
}
void Menu::SetItemName(ApplicationWindow &WM, UINT Id, const String &Name)
{
String NameCopy = Name;
MENUITEMINFO Info;
Info.cbSize = sizeof(MENUITEMINFO);
Info.fMask = MIIM_STRING;
Info.dwTypeData = NameCopy.CString();
BOOL Success = SetMenuItemInfo(_Handle, Id, FALSE, &Info);
Assert(Success != 0, "SetMenuItemInfo failed");
}
void Menu::SetItemState(ApplicationWindow &WM, UINT Id, bool Enabled, bool Checked)
{
MENUITEMINFO Info;
Info.cbSize = sizeof(MENUITEMINFO);
Info.fMask = MIIM_STATE;
Info.fState = 0;
if(Enabled)
{
Info.fState |= MFS_ENABLED;
}
else
{
Info.fState |= MFS_DISABLED;
}
if(Checked)
{
Info.fState |= MFS_CHECKED;
}
else
{
}
BOOL Success = SetMenuItemInfo(_Handle, Id, FALSE, &Info);
Assert(Success != 0, "SetMenuItemInfo failed");
}
bool Menu::HasSubMenu(const String &Name)
{
for(UINT Index = 0; Index < _Entries.Length(); Index++)
{
MenuEntry &CurEntry = _Entries[Index];
if(CurEntry.Name() == Name)
{
return true;
}
}
return false;
}
Menu& Menu::GetSubMenu(const String &Name)
{
for(UINT Index = 0; Index < _Entries.Length(); Index++)
{
MenuEntry &CurEntry = _Entries[Index];
if(CurEntry.Name() == Name)
{
return CurEntry.SubMenu();
}
}
SignalError("Sub menu not found");
return _Entries[0].SubMenu();
}
void Menu::DispatchKeyboardShortcuts(InputManager &I)
{
for(UINT Index = 0; Index < _Entries.Length(); Index++)
{
MenuEntry &CurEntry = _Entries[Index];
CurEntry.DispatchKeyboardShortcuts(I);
}
}
void MenuInterface::Init(ApplicationWindow &WM)
{
HMENU MenuBarHandle = CreateMenu();
Assert(MenuBarHandle != NULL, "CreateMenu failed");
BOOL Success = SetMenu(WM.Handle(), MenuBarHandle);
Assert(Success != 0, "SetMenu failed");
Success = DrawMenuBar(WM.Handle());
Assert(Success != 0, "DrawMenuBar failed");
_MenuBar = new Menu(MenuBarHandle);
}
void MenuInterface::DispatchKeyboardShortcuts(InputManager &I)
{
if(_MenuBar != NULL)
{
_MenuBar->DispatchKeyboardShortcuts(I);
}
}