* Added shortcut handling to the boot loader menu (in preparation of adopting
ticket #5312). * Added shortcut 'b' to continue booting, 'r' to reboot. * Consolidated asterisk style. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36310 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -13,7 +13,8 @@
|
||||
class Menu;
|
||||
class MenuItem;
|
||||
|
||||
typedef bool (*menu_item_hook)(Menu *, MenuItem *);
|
||||
typedef bool (*menu_item_hook)(Menu* menu, MenuItem* item);
|
||||
typedef void (*shortcut_hook)(char key);
|
||||
|
||||
|
||||
enum menu_item_type {
|
||||
@@ -52,6 +53,9 @@ public:
|
||||
void SetHelpText(const char* text);
|
||||
const char* HelpText() const { return fHelpText; }
|
||||
|
||||
void SetShortcut(char key);
|
||||
char Shortcut() const { return fShortcut; }
|
||||
|
||||
const char* Label() const { return fLabel; }
|
||||
Menu* Submenu() const { return fSubMenu; }
|
||||
|
||||
@@ -70,6 +74,7 @@ private:
|
||||
Menu* fSubMenu;
|
||||
const void* fData;
|
||||
const char* fHelpText;
|
||||
char fShortcut;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,13 +127,23 @@ public:
|
||||
{ fChoiceText = text; }
|
||||
const char* ChoiceText() const { return fChoiceText; }
|
||||
|
||||
void Run();
|
||||
void AddShortcut(char key, shortcut_hook function);
|
||||
shortcut_hook FindShortcut(char key) const;
|
||||
MenuItem* FindItemByShortcut(char key);
|
||||
|
||||
void Run();
|
||||
|
||||
private:
|
||||
friend class MenuItem;
|
||||
void Draw(MenuItem* item);
|
||||
|
||||
private:
|
||||
struct shortcut {
|
||||
shortcut* next;
|
||||
shortcut_hook function;
|
||||
char key;
|
||||
};
|
||||
|
||||
const char* fTitle;
|
||||
const char* fChoiceText;
|
||||
int32 fCount;
|
||||
@@ -136,6 +151,7 @@ private:
|
||||
MenuItemList fItems;
|
||||
menu_type fType;
|
||||
MenuItem* fSuperItem;
|
||||
shortcut* fShortcuts;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+125
-76
@@ -151,22 +151,28 @@ MenuItem::SetData(const void *data)
|
||||
}
|
||||
|
||||
|
||||
/** This sets a help text that is shown when the item is
|
||||
* selected.
|
||||
* Note, unlike the label, the string is not copied, it's
|
||||
* just referenced and has to stay valid as long as the
|
||||
* item's menu is being used.
|
||||
*/
|
||||
|
||||
/*! This sets a help text that is shown when the item is
|
||||
selected.
|
||||
Note, unlike the label, the string is not copied, it's
|
||||
just referenced and has to stay valid as long as the
|
||||
item's menu is being used.
|
||||
*/
|
||||
void
|
||||
MenuItem::SetHelpText(const char *text)
|
||||
MenuItem::SetHelpText(const char* text)
|
||||
{
|
||||
fHelpText = text;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetMenu(Menu *menu)
|
||||
MenuItem::SetShortcut(char key)
|
||||
{
|
||||
fShortcut = key;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetMenu(Menu* menu)
|
||||
{
|
||||
fMenu = menu;
|
||||
}
|
||||
@@ -175,14 +181,15 @@ MenuItem::SetMenu(Menu *menu)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Menu::Menu(menu_type type, const char *title)
|
||||
Menu::Menu(menu_type type, const char* title)
|
||||
:
|
||||
fTitle(title),
|
||||
fChoiceText(NULL),
|
||||
fCount(0),
|
||||
fIsHidden(true),
|
||||
fType(type),
|
||||
fSuperItem(NULL)
|
||||
fSuperItem(NULL),
|
||||
fShortcuts(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -199,7 +206,7 @@ Menu::~Menu()
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
MenuItem*
|
||||
Menu::ItemAt(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= fCount)
|
||||
@@ -218,13 +225,12 @@ Menu::ItemAt(int32 index)
|
||||
|
||||
|
||||
int32
|
||||
Menu::IndexOf(MenuItem *searchedItem)
|
||||
Menu::IndexOf(MenuItem* searchedItem)
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
int32 index = 0;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item == searchedItem)
|
||||
return index;
|
||||
|
||||
@@ -242,13 +248,11 @@ Menu::CountItems() const
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::FindItem(const char *label)
|
||||
MenuItem*
|
||||
Menu::FindItem(const char* label)
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item->Label() != NULL && !strcmp(item->Label(), label))
|
||||
return item;
|
||||
}
|
||||
@@ -257,13 +261,11 @@ Menu::FindItem(const char *label)
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
MenuItem*
|
||||
Menu::FindMarked()
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item->IsMarked())
|
||||
return item;
|
||||
}
|
||||
@@ -272,14 +274,13 @@ Menu::FindMarked()
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::FindSelected(int32 *_index)
|
||||
MenuItem*
|
||||
Menu::FindSelected(int32* _index)
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
int32 index = 0;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item->IsSelected()) {
|
||||
if (_index != NULL)
|
||||
*_index = index;
|
||||
@@ -294,7 +295,7 @@ Menu::FindSelected(int32 *_index)
|
||||
|
||||
|
||||
void
|
||||
Menu::AddItem(MenuItem *item)
|
||||
Menu::AddItem(MenuItem* item)
|
||||
{
|
||||
item->fMenu = this;
|
||||
fItems.Add(item);
|
||||
@@ -305,7 +306,7 @@ Menu::AddItem(MenuItem *item)
|
||||
status_t
|
||||
Menu::AddSeparatorItem()
|
||||
{
|
||||
MenuItem *item = new(nothrow) MenuItem();
|
||||
MenuItem* item = new(std::nothrow) MenuItem();
|
||||
if (item == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -316,16 +317,14 @@ Menu::AddSeparatorItem()
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
MenuItem*
|
||||
Menu::RemoveItemAt(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= fCount)
|
||||
return NULL;
|
||||
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (index-- == 0) {
|
||||
RemoveItem(item);
|
||||
return item;
|
||||
@@ -337,7 +336,7 @@ Menu::RemoveItemAt(int32 index)
|
||||
|
||||
|
||||
void
|
||||
Menu::RemoveItem(MenuItem *item)
|
||||
Menu::RemoveItem(MenuItem* item)
|
||||
{
|
||||
item->fMenu = NULL;
|
||||
fItems.Remove(item);
|
||||
@@ -346,10 +345,51 @@ Menu::RemoveItem(MenuItem *item)
|
||||
|
||||
|
||||
void
|
||||
Menu::Draw(MenuItem *item)
|
||||
Menu::AddShortcut(char key, shortcut_hook function)
|
||||
{
|
||||
if (!IsHidden())
|
||||
platform_update_menu_item(this, item);
|
||||
Menu::shortcut* shortcut = new(std::nothrow) struct Menu::shortcut;
|
||||
if (shortcut == NULL)
|
||||
return;
|
||||
|
||||
shortcut->key = key;
|
||||
shortcut->function = function;
|
||||
|
||||
shortcut->next = fShortcuts;
|
||||
fShortcuts = shortcut;
|
||||
}
|
||||
|
||||
|
||||
shortcut_hook
|
||||
Menu::FindShortcut(char key) const
|
||||
{
|
||||
if (key == 0)
|
||||
return NULL;
|
||||
|
||||
const Menu::shortcut* shortcut = fShortcuts;
|
||||
while (shortcut != NULL) {
|
||||
if (shortcut->key == key)
|
||||
return shortcut->function;
|
||||
|
||||
shortcut = shortcut->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
MenuItem*
|
||||
Menu::FindItemByShortcut(char key)
|
||||
{
|
||||
if (key == 0)
|
||||
return NULL;
|
||||
|
||||
MenuItemList::Iterator iterator = ItemIterator();
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item->Shortcut() == key)
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +400,14 @@ Menu::Run()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Menu::Draw(MenuItem* item)
|
||||
{
|
||||
if (!IsHidden())
|
||||
platform_update_menu_item(this, item);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -415,9 +463,9 @@ size_to_string(off_t size, char* buffer, size_t bufferSize)
|
||||
|
||||
|
||||
static bool
|
||||
user_menu_boot_volume(Menu *menu, MenuItem *item)
|
||||
user_menu_boot_volume(Menu* menu, MenuItem* item)
|
||||
{
|
||||
Menu *super = menu->Supermenu();
|
||||
Menu* super = menu->Supermenu();
|
||||
if (super == NULL) {
|
||||
// huh?
|
||||
return true;
|
||||
@@ -434,7 +482,7 @@ user_menu_boot_volume(Menu *menu, MenuItem *item)
|
||||
|
||||
|
||||
static bool
|
||||
debug_menu_display_syslog(Menu *menu, MenuItem *item)
|
||||
debug_menu_display_syslog(Menu* menu, MenuItem* item)
|
||||
{
|
||||
ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output;
|
||||
if (buffer == NULL)
|
||||
@@ -520,7 +568,7 @@ save_syslog_to_volume(Directory* directory)
|
||||
|
||||
|
||||
static bool
|
||||
debug_menu_toggle_debug_syslog(Menu *menu, MenuItem *item)
|
||||
debug_menu_toggle_debug_syslog(Menu* menu, MenuItem* item)
|
||||
{
|
||||
gKernelArgs.keep_debug_output_buffer = item->IsMarked();
|
||||
return true;
|
||||
@@ -528,7 +576,7 @@ debug_menu_toggle_debug_syslog(Menu *menu, MenuItem *item)
|
||||
|
||||
|
||||
static bool
|
||||
debug_menu_save_syslog(Menu *menu, MenuItem *item)
|
||||
debug_menu_save_syslog(Menu* menu, MenuItem* item)
|
||||
{
|
||||
Directory* volume = (Directory*)item->Data();
|
||||
|
||||
@@ -543,17 +591,17 @@ debug_menu_save_syslog(Menu *menu, MenuItem *item)
|
||||
}
|
||||
|
||||
|
||||
static Menu *
|
||||
add_boot_volume_menu(Directory *bootVolume)
|
||||
static Menu*
|
||||
add_boot_volume_menu(Directory* bootVolume)
|
||||
{
|
||||
Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
|
||||
MenuItem *item;
|
||||
void *cookie;
|
||||
Menu* menu = new(std::nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
|
||||
MenuItem* item;
|
||||
void* cookie;
|
||||
int32 count = 0;
|
||||
|
||||
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
||||
Directory *volume;
|
||||
while (gRoot->GetNextNode(cookie, (Node **)&volume) == B_OK) {
|
||||
Directory* volume;
|
||||
while (gRoot->GetNextNode(cookie, (Node**)&volume) == B_OK) {
|
||||
// only list bootable volumes
|
||||
if (!is_bootable(volume))
|
||||
continue;
|
||||
@@ -601,11 +649,11 @@ add_boot_volume_menu(Directory *bootVolume)
|
||||
}
|
||||
|
||||
|
||||
static Menu *
|
||||
static Menu*
|
||||
add_safe_mode_menu()
|
||||
{
|
||||
Menu *safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
|
||||
MenuItem *item;
|
||||
Menu* safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
|
||||
MenuItem* item;
|
||||
|
||||
safeMenu->AddItem(item = new(nothrow) MenuItem("Safe mode"));
|
||||
item->SetData(B_SAFEMODE_SAFE_MODE);
|
||||
@@ -704,11 +752,11 @@ add_save_debug_syslog_menu()
|
||||
}
|
||||
|
||||
|
||||
static Menu *
|
||||
static Menu*
|
||||
add_debug_menu()
|
||||
{
|
||||
Menu *menu = new(nothrow) Menu(STANDARD_MENU, "Debug Options");
|
||||
MenuItem *item;
|
||||
Menu* menu = new(std::nothrow) Menu(STANDARD_MENU, "Debug Options");
|
||||
MenuItem* item;
|
||||
|
||||
#if DEBUG_SPINLOCK_LATENCIES
|
||||
item = new(std::nothrow) MenuItem("Disable latency checks");
|
||||
@@ -766,22 +814,21 @@ add_debug_menu()
|
||||
|
||||
|
||||
static void
|
||||
apply_safe_mode_options(Menu *menu)
|
||||
apply_safe_mode_options(Menu* menu)
|
||||
{
|
||||
MenuItemIterator iterator = menu->ItemIterator();
|
||||
MenuItem *item;
|
||||
char buffer[2048];
|
||||
int32 pos = 0;
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
MenuItemIterator iterator = menu->ItemIterator();
|
||||
while (MenuItem* item = iterator.Next()) {
|
||||
if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked()
|
||||
|| item->Data() == NULL || (uint32)pos > sizeof(buffer))
|
||||
continue;
|
||||
|
||||
size_t totalBytes = snprintf(buffer + pos, sizeof(buffer) - pos,
|
||||
"%s true\n", (const char *)item->Data());
|
||||
"%s true\n", (const char*)item->Data());
|
||||
pos += std::min(totalBytes, sizeof(buffer) - pos - 1);
|
||||
}
|
||||
|
||||
@@ -790,7 +837,7 @@ apply_safe_mode_options(Menu *menu)
|
||||
|
||||
|
||||
static bool
|
||||
user_menu_reboot(Menu *menu, MenuItem *item)
|
||||
user_menu_reboot(Menu* menu, MenuItem* item)
|
||||
{
|
||||
platform_exit();
|
||||
return true;
|
||||
@@ -798,25 +845,25 @@ user_menu_reboot(Menu *menu, MenuItem *item)
|
||||
|
||||
|
||||
status_t
|
||||
user_menu(Directory **_bootVolume)
|
||||
user_menu(Directory** _bootVolume)
|
||||
{
|
||||
Menu *menu = new(nothrow) Menu(MAIN_MENU);
|
||||
Menu *safeModeMenu = NULL;
|
||||
Menu *debugMenu = NULL;
|
||||
MenuItem *item;
|
||||
Menu* menu = new(std::nothrow) Menu(MAIN_MENU);
|
||||
Menu* safeModeMenu = NULL;
|
||||
Menu* debugMenu = NULL;
|
||||
MenuItem* item;
|
||||
|
||||
TRACE(("user_menu: enter\n"));
|
||||
|
||||
// Add boot volume
|
||||
menu->AddItem(item = new(nothrow) MenuItem("Select boot volume",
|
||||
menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume",
|
||||
add_boot_volume_menu(*_bootVolume)));
|
||||
|
||||
// Add safe mode
|
||||
menu->AddItem(item = new(nothrow) MenuItem("Select safe mode options",
|
||||
menu->AddItem(item = new(std::nothrow) MenuItem("Select safe mode options",
|
||||
safeModeMenu = add_safe_mode_menu()));
|
||||
|
||||
// add debug menu
|
||||
menu->AddItem(item = new(nothrow) MenuItem("Select debug options",
|
||||
menu->AddItem(item = new(std::nothrow) MenuItem("Select debug options",
|
||||
debugMenu = add_debug_menu()));
|
||||
|
||||
// Add platform dependent menus
|
||||
@@ -824,20 +871,22 @@ user_menu(Directory **_bootVolume)
|
||||
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
menu->AddItem(item = new(nothrow) MenuItem("Reboot"));
|
||||
menu->AddItem(item = new(std::nothrow) MenuItem("Reboot"));
|
||||
item->SetTarget(user_menu_reboot);
|
||||
item->SetShortcut('r');
|
||||
|
||||
menu->AddItem(item = new(nothrow) MenuItem("Continue booting"));
|
||||
menu->AddItem(item = new(std::nothrow) MenuItem("Continue booting"));
|
||||
if (*_bootVolume == NULL) {
|
||||
item->SetEnabled(false);
|
||||
menu->ItemAt(0)->Select(true);
|
||||
}
|
||||
} else
|
||||
item->SetShortcut('b');
|
||||
|
||||
menu->Run();
|
||||
|
||||
// See if a new boot device has been selected, and propagate that back
|
||||
if (item->Data() != NULL)
|
||||
*_bootVolume = (Directory *)item->Data();
|
||||
*_bootVolume = (Directory*)item->Data();
|
||||
|
||||
apply_safe_mode_options(safeModeMenu);
|
||||
apply_safe_mode_options(debugMenu);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2009, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Copyright 2004-2010, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -38,6 +38,9 @@ static const console_color kArrowColor = GRAY;
|
||||
static int32 sMenuOffset = 0;
|
||||
|
||||
|
||||
static void run_menu(Menu* menu);
|
||||
|
||||
|
||||
static int32
|
||||
menu_height()
|
||||
{
|
||||
@@ -340,8 +343,48 @@ select_next_valid_item(Menu *menu, int32 selected)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
invoke_item(Menu* menu, MenuItem* item, int32& selected, char key)
|
||||
{
|
||||
// leave the menu
|
||||
if (item->Submenu() != NULL && key == TEXT_CONSOLE_KEY_RETURN) {
|
||||
int32 offset = sMenuOffset;
|
||||
menu->Hide();
|
||||
|
||||
run_menu(item->Submenu());
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
|
||||
// restore current menu
|
||||
sMenuOffset = offset;
|
||||
menu->FindSelected(&selected);
|
||||
menu->Show();
|
||||
draw_menu(menu);
|
||||
} else if (item->Type() == MENU_ITEM_MARKABLE) {
|
||||
// toggle state
|
||||
item->SetMarked(!item->IsMarked());
|
||||
print_item_at(selected, item);
|
||||
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
} else if (key == TEXT_CONSOLE_KEY_RETURN) {
|
||||
// the space key does not exit the menu, only return does
|
||||
if (menu->Type() == CHOICE_MENU
|
||||
&& item->Type() != MENU_ITEM_NO_CHOICE
|
||||
&& item->Type() != MENU_ITEM_TITLE)
|
||||
item->SetMarked(true);
|
||||
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run_menu(Menu *menu)
|
||||
run_menu(Menu* menu)
|
||||
{
|
||||
sMenuOffset = 0;
|
||||
menu->Show();
|
||||
@@ -413,43 +456,25 @@ run_menu(Menu *menu)
|
||||
}
|
||||
} else if (key == TEXT_CONSOLE_KEY_RETURN
|
||||
|| key == TEXT_CONSOLE_KEY_SPACE) {
|
||||
// leave the menu
|
||||
if (item->Submenu() != NULL && key == TEXT_CONSOLE_KEY_RETURN) {
|
||||
int32 offset = sMenuOffset;
|
||||
menu->Hide();
|
||||
|
||||
run_menu(item->Submenu());
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
|
||||
// restore current menu
|
||||
sMenuOffset = offset;
|
||||
menu->FindSelected(&selected);
|
||||
menu->Show();
|
||||
draw_menu(menu);
|
||||
} else if (item->Type() == MENU_ITEM_MARKABLE) {
|
||||
// toggle state
|
||||
item->SetMarked(!item->IsMarked());
|
||||
print_item_at(selected, item);
|
||||
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
} else if (key == TEXT_CONSOLE_KEY_RETURN) {
|
||||
// the space key does not exit the menu
|
||||
|
||||
if (menu->Type() == CHOICE_MENU
|
||||
&& item->Type() != MENU_ITEM_NO_CHOICE
|
||||
&& item->Type() != MENU_ITEM_TITLE)
|
||||
item->SetMarked(true);
|
||||
|
||||
if (item->Target() != NULL)
|
||||
(*item->Target())(menu, item);
|
||||
|
||||
if (invoke_item(menu, item, selected, key))
|
||||
break;
|
||||
}
|
||||
} else if (key == TEXT_CONSOLE_KEY_ESCAPE && menu->Type() != MAIN_MENU)
|
||||
} else if (key == TEXT_CONSOLE_KEY_ESCAPE
|
||||
&& menu->Type() != MAIN_MENU) {
|
||||
// escape key was hit
|
||||
break;
|
||||
} else {
|
||||
// Shortcut processing
|
||||
shortcut_hook function = menu->FindShortcut(key);
|
||||
if (function != NULL)
|
||||
function(key);
|
||||
else {
|
||||
item = menu->FindItemByShortcut(key);
|
||||
if (item != NULL && invoke_item(menu, item, selected,
|
||||
TEXT_CONSOLE_KEY_RETURN)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu->Hide();
|
||||
|
||||
Reference in New Issue
Block a user