* 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 Menu;
|
||||||
class MenuItem;
|
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 {
|
enum menu_item_type {
|
||||||
@@ -52,6 +53,9 @@ public:
|
|||||||
void SetHelpText(const char* text);
|
void SetHelpText(const char* text);
|
||||||
const char* HelpText() const { return fHelpText; }
|
const char* HelpText() const { return fHelpText; }
|
||||||
|
|
||||||
|
void SetShortcut(char key);
|
||||||
|
char Shortcut() const { return fShortcut; }
|
||||||
|
|
||||||
const char* Label() const { return fLabel; }
|
const char* Label() const { return fLabel; }
|
||||||
Menu* Submenu() const { return fSubMenu; }
|
Menu* Submenu() const { return fSubMenu; }
|
||||||
|
|
||||||
@@ -70,6 +74,7 @@ private:
|
|||||||
Menu* fSubMenu;
|
Menu* fSubMenu;
|
||||||
const void* fData;
|
const void* fData;
|
||||||
const char* fHelpText;
|
const char* fHelpText;
|
||||||
|
char fShortcut;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -122,13 +127,23 @@ public:
|
|||||||
{ fChoiceText = text; }
|
{ fChoiceText = text; }
|
||||||
const char* ChoiceText() const { return fChoiceText; }
|
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:
|
private:
|
||||||
friend class MenuItem;
|
friend class MenuItem;
|
||||||
void Draw(MenuItem* item);
|
void Draw(MenuItem* item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct shortcut {
|
||||||
|
shortcut* next;
|
||||||
|
shortcut_hook function;
|
||||||
|
char key;
|
||||||
|
};
|
||||||
|
|
||||||
const char* fTitle;
|
const char* fTitle;
|
||||||
const char* fChoiceText;
|
const char* fChoiceText;
|
||||||
int32 fCount;
|
int32 fCount;
|
||||||
@@ -136,6 +151,7 @@ private:
|
|||||||
MenuItemList fItems;
|
MenuItemList fItems;
|
||||||
menu_type fType;
|
menu_type fType;
|
||||||
MenuItem* fSuperItem;
|
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
|
/*! This sets a help text that is shown when the item is
|
||||||
* selected.
|
selected.
|
||||||
* Note, unlike the label, the string is not copied, it's
|
Note, unlike the label, the string is not copied, it's
|
||||||
* just referenced and has to stay valid as long as the
|
just referenced and has to stay valid as long as the
|
||||||
* item's menu is being used.
|
item's menu is being used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
MenuItem::SetHelpText(const char *text)
|
MenuItem::SetHelpText(const char* text)
|
||||||
{
|
{
|
||||||
fHelpText = text;
|
fHelpText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MenuItem::SetMenu(Menu *menu)
|
MenuItem::SetShortcut(char key)
|
||||||
|
{
|
||||||
|
fShortcut = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MenuItem::SetMenu(Menu* menu)
|
||||||
{
|
{
|
||||||
fMenu = menu;
|
fMenu = menu;
|
||||||
}
|
}
|
||||||
@@ -175,14 +181,15 @@ MenuItem::SetMenu(Menu *menu)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
Menu::Menu(menu_type type, const char *title)
|
Menu::Menu(menu_type type, const char* title)
|
||||||
:
|
:
|
||||||
fTitle(title),
|
fTitle(title),
|
||||||
fChoiceText(NULL),
|
fChoiceText(NULL),
|
||||||
fCount(0),
|
fCount(0),
|
||||||
fIsHidden(true),
|
fIsHidden(true),
|
||||||
fType(type),
|
fType(type),
|
||||||
fSuperItem(NULL)
|
fSuperItem(NULL),
|
||||||
|
fShortcuts(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +206,7 @@ Menu::~Menu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem *
|
MenuItem*
|
||||||
Menu::ItemAt(int32 index)
|
Menu::ItemAt(int32 index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= fCount)
|
if (index < 0 || index >= fCount)
|
||||||
@@ -218,13 +225,12 @@ Menu::ItemAt(int32 index)
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Menu::IndexOf(MenuItem *searchedItem)
|
Menu::IndexOf(MenuItem* searchedItem)
|
||||||
{
|
{
|
||||||
MenuItemIterator iterator = ItemIterator();
|
|
||||||
MenuItem *item;
|
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while ((item = iterator.Next()) != NULL) {
|
MenuItemIterator iterator = ItemIterator();
|
||||||
|
while (MenuItem* item = iterator.Next()) {
|
||||||
if (item == searchedItem)
|
if (item == searchedItem)
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
@@ -242,13 +248,11 @@ Menu::CountItems() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem *
|
MenuItem*
|
||||||
Menu::FindItem(const char *label)
|
Menu::FindItem(const char* label)
|
||||||
{
|
{
|
||||||
MenuItemIterator iterator = ItemIterator();
|
MenuItemIterator iterator = ItemIterator();
|
||||||
MenuItem *item;
|
while (MenuItem* item = iterator.Next()) {
|
||||||
|
|
||||||
while ((item = iterator.Next()) != NULL) {
|
|
||||||
if (item->Label() != NULL && !strcmp(item->Label(), label))
|
if (item->Label() != NULL && !strcmp(item->Label(), label))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -257,13 +261,11 @@ Menu::FindItem(const char *label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem *
|
MenuItem*
|
||||||
Menu::FindMarked()
|
Menu::FindMarked()
|
||||||
{
|
{
|
||||||
MenuItemIterator iterator = ItemIterator();
|
MenuItemIterator iterator = ItemIterator();
|
||||||
MenuItem *item;
|
while (MenuItem* item = iterator.Next()) {
|
||||||
|
|
||||||
while ((item = iterator.Next()) != NULL) {
|
|
||||||
if (item->IsMarked())
|
if (item->IsMarked())
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -272,14 +274,13 @@ Menu::FindMarked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem *
|
MenuItem*
|
||||||
Menu::FindSelected(int32 *_index)
|
Menu::FindSelected(int32* _index)
|
||||||
{
|
{
|
||||||
MenuItemIterator iterator = ItemIterator();
|
|
||||||
MenuItem *item;
|
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while ((item = iterator.Next()) != NULL) {
|
MenuItemIterator iterator = ItemIterator();
|
||||||
|
while (MenuItem* item = iterator.Next()) {
|
||||||
if (item->IsSelected()) {
|
if (item->IsSelected()) {
|
||||||
if (_index != NULL)
|
if (_index != NULL)
|
||||||
*_index = index;
|
*_index = index;
|
||||||
@@ -294,7 +295,7 @@ Menu::FindSelected(int32 *_index)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Menu::AddItem(MenuItem *item)
|
Menu::AddItem(MenuItem* item)
|
||||||
{
|
{
|
||||||
item->fMenu = this;
|
item->fMenu = this;
|
||||||
fItems.Add(item);
|
fItems.Add(item);
|
||||||
@@ -305,7 +306,7 @@ Menu::AddItem(MenuItem *item)
|
|||||||
status_t
|
status_t
|
||||||
Menu::AddSeparatorItem()
|
Menu::AddSeparatorItem()
|
||||||
{
|
{
|
||||||
MenuItem *item = new(nothrow) MenuItem();
|
MenuItem* item = new(std::nothrow) MenuItem();
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -316,16 +317,14 @@ Menu::AddSeparatorItem()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem *
|
MenuItem*
|
||||||
Menu::RemoveItemAt(int32 index)
|
Menu::RemoveItemAt(int32 index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= fCount)
|
if (index < 0 || index >= fCount)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
MenuItemIterator iterator = ItemIterator();
|
MenuItemIterator iterator = ItemIterator();
|
||||||
MenuItem *item;
|
while (MenuItem* item = iterator.Next()) {
|
||||||
|
|
||||||
while ((item = iterator.Next()) != NULL) {
|
|
||||||
if (index-- == 0) {
|
if (index-- == 0) {
|
||||||
RemoveItem(item);
|
RemoveItem(item);
|
||||||
return item;
|
return item;
|
||||||
@@ -337,7 +336,7 @@ Menu::RemoveItemAt(int32 index)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Menu::RemoveItem(MenuItem *item)
|
Menu::RemoveItem(MenuItem* item)
|
||||||
{
|
{
|
||||||
item->fMenu = NULL;
|
item->fMenu = NULL;
|
||||||
fItems.Remove(item);
|
fItems.Remove(item);
|
||||||
@@ -346,10 +345,51 @@ Menu::RemoveItem(MenuItem *item)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Menu::Draw(MenuItem *item)
|
Menu::AddShortcut(char key, shortcut_hook function)
|
||||||
{
|
{
|
||||||
if (!IsHidden())
|
Menu::shortcut* shortcut = new(std::nothrow) struct Menu::shortcut;
|
||||||
platform_update_menu_item(this, item);
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -415,9 +463,9 @@ size_to_string(off_t size, char* buffer, size_t bufferSize)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
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) {
|
if (super == NULL) {
|
||||||
// huh?
|
// huh?
|
||||||
return true;
|
return true;
|
||||||
@@ -434,7 +482,7 @@ user_menu_boot_volume(Menu *menu, MenuItem *item)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
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;
|
ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output;
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -520,7 +568,7 @@ save_syslog_to_volume(Directory* directory)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
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();
|
gKernelArgs.keep_debug_output_buffer = item->IsMarked();
|
||||||
return true;
|
return true;
|
||||||
@@ -528,7 +576,7 @@ debug_menu_toggle_debug_syslog(Menu *menu, MenuItem *item)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
debug_menu_save_syslog(Menu *menu, MenuItem *item)
|
debug_menu_save_syslog(Menu* menu, MenuItem* item)
|
||||||
{
|
{
|
||||||
Directory* volume = (Directory*)item->Data();
|
Directory* volume = (Directory*)item->Data();
|
||||||
|
|
||||||
@@ -543,17 +591,17 @@ debug_menu_save_syslog(Menu *menu, MenuItem *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Menu *
|
static Menu*
|
||||||
add_boot_volume_menu(Directory *bootVolume)
|
add_boot_volume_menu(Directory* bootVolume)
|
||||||
{
|
{
|
||||||
Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
|
Menu* menu = new(std::nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
|
||||||
MenuItem *item;
|
MenuItem* item;
|
||||||
void *cookie;
|
void* cookie;
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
|
|
||||||
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
||||||
Directory *volume;
|
Directory* volume;
|
||||||
while (gRoot->GetNextNode(cookie, (Node **)&volume) == B_OK) {
|
while (gRoot->GetNextNode(cookie, (Node**)&volume) == B_OK) {
|
||||||
// only list bootable volumes
|
// only list bootable volumes
|
||||||
if (!is_bootable(volume))
|
if (!is_bootable(volume))
|
||||||
continue;
|
continue;
|
||||||
@@ -601,11 +649,11 @@ add_boot_volume_menu(Directory *bootVolume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Menu *
|
static Menu*
|
||||||
add_safe_mode_menu()
|
add_safe_mode_menu()
|
||||||
{
|
{
|
||||||
Menu *safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
|
Menu* safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
|
||||||
MenuItem *item;
|
MenuItem* item;
|
||||||
|
|
||||||
safeMenu->AddItem(item = new(nothrow) MenuItem("Safe mode"));
|
safeMenu->AddItem(item = new(nothrow) MenuItem("Safe mode"));
|
||||||
item->SetData(B_SAFEMODE_SAFE_MODE);
|
item->SetData(B_SAFEMODE_SAFE_MODE);
|
||||||
@@ -704,11 +752,11 @@ add_save_debug_syslog_menu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Menu *
|
static Menu*
|
||||||
add_debug_menu()
|
add_debug_menu()
|
||||||
{
|
{
|
||||||
Menu *menu = new(nothrow) Menu(STANDARD_MENU, "Debug Options");
|
Menu* menu = new(std::nothrow) Menu(STANDARD_MENU, "Debug Options");
|
||||||
MenuItem *item;
|
MenuItem* item;
|
||||||
|
|
||||||
#if DEBUG_SPINLOCK_LATENCIES
|
#if DEBUG_SPINLOCK_LATENCIES
|
||||||
item = new(std::nothrow) MenuItem("Disable latency checks");
|
item = new(std::nothrow) MenuItem("Disable latency checks");
|
||||||
@@ -766,22 +814,21 @@ add_debug_menu()
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_safe_mode_options(Menu *menu)
|
apply_safe_mode_options(Menu* menu)
|
||||||
{
|
{
|
||||||
MenuItemIterator iterator = menu->ItemIterator();
|
|
||||||
MenuItem *item;
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
int32 pos = 0;
|
int32 pos = 0;
|
||||||
|
|
||||||
buffer[0] = '\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()
|
if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked()
|
||||||
|| item->Data() == NULL || (uint32)pos > sizeof(buffer))
|
|| item->Data() == NULL || (uint32)pos > sizeof(buffer))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t totalBytes = snprintf(buffer + pos, sizeof(buffer) - pos,
|
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);
|
pos += std::min(totalBytes, sizeof(buffer) - pos - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,7 +837,7 @@ apply_safe_mode_options(Menu *menu)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
user_menu_reboot(Menu *menu, MenuItem *item)
|
user_menu_reboot(Menu* menu, MenuItem* item)
|
||||||
{
|
{
|
||||||
platform_exit();
|
platform_exit();
|
||||||
return true;
|
return true;
|
||||||
@@ -798,25 +845,25 @@ user_menu_reboot(Menu *menu, MenuItem *item)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
user_menu(Directory **_bootVolume)
|
user_menu(Directory** _bootVolume)
|
||||||
{
|
{
|
||||||
Menu *menu = new(nothrow) Menu(MAIN_MENU);
|
Menu* menu = new(std::nothrow) Menu(MAIN_MENU);
|
||||||
Menu *safeModeMenu = NULL;
|
Menu* safeModeMenu = NULL;
|
||||||
Menu *debugMenu = NULL;
|
Menu* debugMenu = NULL;
|
||||||
MenuItem *item;
|
MenuItem* item;
|
||||||
|
|
||||||
TRACE(("user_menu: enter\n"));
|
TRACE(("user_menu: enter\n"));
|
||||||
|
|
||||||
// Add boot volume
|
// 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_boot_volume_menu(*_bootVolume)));
|
||||||
|
|
||||||
// Add safe mode
|
// 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()));
|
safeModeMenu = add_safe_mode_menu()));
|
||||||
|
|
||||||
// add debug 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()));
|
debugMenu = add_debug_menu()));
|
||||||
|
|
||||||
// Add platform dependent menus
|
// Add platform dependent menus
|
||||||
@@ -824,20 +871,22 @@ user_menu(Directory **_bootVolume)
|
|||||||
|
|
||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
|
|
||||||
menu->AddItem(item = new(nothrow) MenuItem("Reboot"));
|
menu->AddItem(item = new(std::nothrow) MenuItem("Reboot"));
|
||||||
item->SetTarget(user_menu_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) {
|
if (*_bootVolume == NULL) {
|
||||||
item->SetEnabled(false);
|
item->SetEnabled(false);
|
||||||
menu->ItemAt(0)->Select(true);
|
menu->ItemAt(0)->Select(true);
|
||||||
}
|
} else
|
||||||
|
item->SetShortcut('b');
|
||||||
|
|
||||||
menu->Run();
|
menu->Run();
|
||||||
|
|
||||||
// See if a new boot device has been selected, and propagate that back
|
// See if a new boot device has been selected, and propagate that back
|
||||||
if (item->Data() != NULL)
|
if (item->Data() != NULL)
|
||||||
*_bootVolume = (Directory *)item->Data();
|
*_bootVolume = (Directory*)item->Data();
|
||||||
|
|
||||||
apply_safe_mode_options(safeModeMenu);
|
apply_safe_mode_options(safeModeMenu);
|
||||||
apply_safe_mode_options(debugMenu);
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -38,6 +38,9 @@ static const console_color kArrowColor = GRAY;
|
|||||||
static int32 sMenuOffset = 0;
|
static int32 sMenuOffset = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void run_menu(Menu* menu);
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
menu_height()
|
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
|
static void
|
||||||
run_menu(Menu *menu)
|
run_menu(Menu* menu)
|
||||||
{
|
{
|
||||||
sMenuOffset = 0;
|
sMenuOffset = 0;
|
||||||
menu->Show();
|
menu->Show();
|
||||||
@@ -413,43 +456,25 @@ run_menu(Menu *menu)
|
|||||||
}
|
}
|
||||||
} else if (key == TEXT_CONSOLE_KEY_RETURN
|
} else if (key == TEXT_CONSOLE_KEY_RETURN
|
||||||
|| key == TEXT_CONSOLE_KEY_SPACE) {
|
|| key == TEXT_CONSOLE_KEY_SPACE) {
|
||||||
// leave the menu
|
if (invoke_item(menu, item, selected, key))
|
||||||
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);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (key == TEXT_CONSOLE_KEY_ESCAPE
|
||||||
} else if (key == TEXT_CONSOLE_KEY_ESCAPE && menu->Type() != MAIN_MENU)
|
&& menu->Type() != MAIN_MENU) {
|
||||||
// escape key was hit
|
// escape key was hit
|
||||||
break;
|
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();
|
menu->Hide();
|
||||||
|
|||||||
Reference in New Issue
Block a user