/* * Copyright 2008-2011, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Michael Pfeiffer */ #include "DefaultPartitionPage.h" #include #include #include #include #include #include #include #include #include #include #include #include #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "DefaultPartitionPage" enum { kMsgPartition = 'part', kMsgTimeout = 'time' }; // The timeout code to wait indefinitely // Note: The timeout is encoded in seconds, -1 indicates to wait indefinitely const int32 kTimeoutIndefinitely = -1; const int32 kDefaultTimeout = kTimeoutIndefinitely; struct TimeoutOption { int32 timeout; const char* label; }; static const TimeoutOption gTimeoutOptions[] = { { 0, B_TRANSLATE_MARK("Immediately")}, { 1, B_TRANSLATE_MARK("After one second")}, { 2, B_TRANSLATE_MARK("After two seconds")}, { 3, B_TRANSLATE_MARK("After three seconds")}, { 4, B_TRANSLATE_MARK("After four seconds")}, { 5, B_TRANSLATE_MARK("After five seconds")}, { 60, B_TRANSLATE_MARK("After one minute")}, { kTimeoutIndefinitely, B_TRANSLATE_MARK("Never")} }; #define kNumberOfTimeoutOptions \ (int32)(sizeof(gTimeoutOptions) / sizeof(TimeoutOption)) static int32 get_index_for_timeout(int32 timeout) { int32 defaultIndex = 0; for (int32 i = 0; i < kNumberOfTimeoutOptions; i ++) { if (gTimeoutOptions[i].timeout == timeout) return i; if (gTimeoutOptions[i].timeout == kDefaultTimeout) defaultIndex = i; } return defaultIndex; } static int32 get_timeout_for_index(int32 index) { if (index < 0) return gTimeoutOptions[0].timeout; if (index >= kNumberOfTimeoutOptions) return gTimeoutOptions[kNumberOfTimeoutOptions-1].timeout; return gTimeoutOptions[index].timeout; } const char* get_label_for_timeout(int32 timeout) { int32 index = get_index_for_timeout(timeout); return gTimeoutOptions[index].label; } // #pragma mark - DefaultPartitionPage::DefaultPartitionPage(BMessage* settings, BRect frame, const char* name) : WizardPageView(settings, frame, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE) { _BuildUI(); } DefaultPartitionPage::~DefaultPartitionPage() { } void DefaultPartitionPage::FrameResized(float width, float height) { WizardPageView::FrameResized(width, height); _Layout(); } void DefaultPartitionPage::AttachedToWindow() { fDefaultPartition->Menu()->SetTargetForItems(this); fTimeoutSlider->SetTarget(this); } void DefaultPartitionPage::MessageReceived(BMessage* msg) { switch (msg->what) { case kMsgPartition: { int32 index; msg->FindInt32("index", &index); fSettings->ReplaceInt32("defaultPartition", index); break; } case kMsgTimeout: { int32 sliderValue = fTimeoutSlider->Value(); int32 timeout = get_timeout_for_index(sliderValue); fSettings->ReplaceInt32("timeout", timeout); BString label; _GetTimeoutLabel(timeout, label); fTimeoutSlider->SetLabel(label.String()); break; } default: WizardPageView::MessageReceived(msg); } } void DefaultPartitionPage::_BuildUI() { const float kTextDistance = be_control_look->DefaultItemSpacing(); BRect rect(Bounds()); BString text; text << B_TRANSLATE_COMMENT("Default Partition", "Title") << "\n" << B_TRANSLATE("Please specify a default partition and a timeout.\n" "The boot menu will load the default partition after " "the timeout unless you select another partition. You " "can also have the boot menu wait indefinitely for you " "to select a partition.\n" "Keep the 'ALT' key pressed to disable the timeout at boot time."); fDescription = CreateDescription(rect, "description", text); MakeHeading(fDescription); AddChild(fDescription); LayoutDescriptionVertically(fDescription); rect.top = fDescription->Frame().bottom + kTextDistance; BPopUpMenu* popUpMenu = _CreatePopUpMenu(); fDefaultPartition = new BMenuField(rect, "partitions", B_TRANSLATE_COMMENT("Default Partition:", "Menu field label"), popUpMenu); float divider = be_plain_font->StringWidth(fDefaultPartition->Label()) + 3; fDefaultPartition->SetDivider(divider); AddChild(fDefaultPartition); fDefaultPartition->ResizeToPreferred(); // timeout slider rect.top = fDefaultPartition->Frame().bottom + kTextDistance; int32 timeout; fSettings->FindInt32("timeout", &timeout); BString timeoutLabel; _GetTimeoutLabel(timeout, timeoutLabel); int32 sliderValue = get_index_for_timeout(timeout); fTimeoutSlider = new BSlider(rect, "timeout", timeoutLabel.String(), new BMessage(kMsgTimeout), 0, kNumberOfTimeoutOptions-1, B_BLOCK_THUMB, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); fTimeoutSlider->SetModificationMessage(new BMessage(kMsgTimeout)); fTimeoutSlider->SetValue(sliderValue); fTimeoutSlider->SetLimitLabels(B_TRANSLATE("Immediately"), B_TRANSLATE("Never")); fTimeoutSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fTimeoutSlider->SetHashMarkCount(kNumberOfTimeoutOptions); fTimeoutSlider->ResizeToPreferred(); AddChild(fTimeoutSlider); _Layout(); } BPopUpMenu* DefaultPartitionPage::_CreatePopUpMenu() { int32 defaultPartitionIndex; fSettings->FindInt32("defaultPartition", &defaultPartitionIndex); BMenuItem* selectedItem = NULL; int32 selectedItemIndex = 0; BPopUpMenu* menu = new BPopUpMenu(B_TRANSLATE_COMMENT("Partitions", "Pop up menu title")); BMessage message; for (int32 i = 0; fSettings->FindMessage("partition", i, &message) == B_OK; i++) { bool show; if (message.FindBool("show", &show) != B_OK || !show) continue; BString name; message.FindString("name", &name); BMessage* msg = new BMessage(kMsgPartition); msg->AddInt32("index", i); BMenuItem* item = new BMenuItem(name.String(), msg); menu->AddItem(item); if (defaultPartitionIndex == i || selectedItem == NULL) { selectedItem = item; selectedItemIndex = i; } } fSettings->ReplaceInt32("defaultPartition", selectedItemIndex); selectedItem->SetMarked(true); return menu; } void DefaultPartitionPage::_GetTimeoutLabel(int32 timeout, BString& label) { const char* text = B_TRANSLATE_NOCOLLECT(get_label_for_timeout(timeout)); label = B_TRANSLATE("Timeout: %s"); label.ReplaceFirst("%s", text); } void DefaultPartitionPage::_Layout() { LayoutDescriptionVertically(fDescription); const float kTextDistance = be_control_look->DefaultItemSpacing(); float left = fDefaultPartition->Frame().left; float top = fDescription->Frame().bottom + kTextDistance; fDefaultPartition->MoveTo(left, top); top = fDefaultPartition->Frame().bottom + kTextDistance; fTimeoutSlider->MoveTo(left, top); }