/** * Sets Preferred size of the area's content. * May be different from the preferred size of the area. * Manual changes of PreferredContentSize are ignored unless * autoPreferredContentSize is set to false. */ void Area::SetPreferredContentSize(BSize preferred) { if (fChildArea == NULL) { fPreferredContentSize = preferred; if (fPreferredContentWidth == NULL) { fPreferredContentWidth = fLS->AddConstraint( -1.0, fLeft, 1.0, fRight, OperatorType(EQ), fPreferredContentSize.Width(), fShrinkPenalties.Width(), fGrowPenalties.Width()); fConstraints->AddItem(fPreferredContentWidth); fPreferredContentHeight = fLS->AddConstraint( -1.0, fTop, 1.0, fBottom, OperatorType(EQ), fPreferredContentSize.Height(), fShrinkPenalties.Height(), fGrowPenalties.Height()); fConstraints->AddItem(fPreferredContentHeight); } else { fPreferredContentWidth->SetRightSide(preferred.Width()); fPreferredContentHeight->SetRightSide(preferred.Height()); } } else fChildArea->SetPreferredContentSize(preferred); fLS->InvalidateLayout(); }
// SetExplicitMaxSize void BSpaceLayoutItem::SetExplicitMaxSize(BSize size) { if (size.IsWidthSet()) fMaxSize.width = size.width; if (size.IsHeightSet()) fMaxSize.height = size.height; InvalidateLayout(); }
// ComposeSize BSize BLayoutUtils::ComposeSize(BSize size, BSize layoutSize) { if (!size.IsWidthSet()) size.width = layoutSize.width; if (!size.IsHeightSet()) size.height = layoutSize.height; return size; }
void Area::SetShrinkPenalties(BSize shrink) { if (fChildArea == NULL) { fShrinkPenalties = shrink; if (fPreferredContentWidth != NULL) { fPreferredContentWidth->SetPenaltyNeg(shrink.Width()); fPreferredContentHeight->SetPenaltyNeg(shrink.Height()); } } else fChildArea->SetShrinkPenalties(shrink); fLS->InvalidateLayout(); }
/** * Initialize variables. */ void Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom, BView* content, BSize minContentSize) { fConstraints = new BList(2); fMaxContentSize = kMaxSize; fMaxContentWidth = NULL; fMaxContentHeight = NULL; fPreferredContentSize = kUndefinedSize; fShrinkPenalties = BSize(2, 2); fGrowPenalties = BSize(1, 1); fContentAspectRatio = 0; fContentAspectRatioC = NULL; fAutoPreferredContentSize = false; fPreferredContentWidth = NULL; fPreferredContentHeight = NULL; fChildArea = NULL; fAlignment = BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); fLeftInset = 0; fTopInset = 0; fRightInset = 0; fBottomInset = 0; fLeftConstraint = NULL; fTopConstraint = NULL; fRightConstraint = NULL; fBottomConstraint = NULL; fLS = ls; fLeft = left; fRight = right; fTop = top; fBottom = bottom; SetContent(content); fMinContentSize = minContentSize; // adds the two essential constraints of the area that make sure that the left x-tab is // really to the left of the right x-tab, and the top y-tab really above the bottom y-tab fMinContentWidth = ls->AddConstraint(-1.0, left, 1.0, right, OperatorType(GE), minContentSize.Width()); fConstraints->AddItem(fMinContentWidth); fMinContentHeight = ls->AddConstraint(-1.0, top, 1.0, bottom, OperatorType(GE), minContentSize.Height()); fConstraints->AddItem(fMinContentHeight); }
void Area::_UpdateMinSizeConstraint(BSize min) { float width = 0.; float height = 0.; if (min.width > 0) width = min.Width() + LeftInset() + RightInset(); if (min.height > 0) height = min.Height() + TopInset() + BottomInset(); fMinContentWidth->SetRightSide(width); fMinContentHeight->SetRightSide(height); }
void Area::SetGrowPenalties(BSize grow) { if (fChildArea == NULL) { fGrowPenalties = grow; if (fPreferredContentWidth != NULL) { fPreferredContentWidth->SetPenaltyPos(grow.Width()); fPreferredContentHeight->SetPenaltyPos(grow.Height()); } } else fChildArea->SetGrowPenalties(grow); fLS->InvalidateLayout(); }
status_t DataTranslationsWindow::_ShowConfigView(int32 id) { // Shows the config panel for the translator with the given id if (id < 0) return B_BAD_VALUE; BTranslatorRoster *roster = BTranslatorRoster::Default(); // fConfigView is NULL the first time this function // is called, prevent a segment fault if (fConfigView) fRightBox->RemoveChild(fConfigView); BMessage emptyMsg; BRect rect(0, 0, 200, 233); status_t ret = roster->MakeConfigurationView(id, &emptyMsg, &fConfigView, &rect); if (ret != B_OK) { fRightBox->RemoveChild(fConfigView); return ret; } BRect configRect(fRightBox->Bounds()); configRect.InsetBy(3, 3); configRect.bottom -= 45; float width = 0, height = 0; if ((fConfigView->Flags() & B_SUPPORTS_LAYOUT) != 0) { BSize configSize = fConfigView->ExplicitPreferredSize(); width = configSize.Width(); height = configSize.Height(); } else { fConfigView->GetPreferredSize(&width, &height); } float widen = max_c(0, width - configRect.Width()); float heighten = max_c(0, height - configRect.Height()); if (widen > 0 || heighten > 0) { ResizeBy(widen, heighten); configRect.right += widen; configRect.bottom += heighten; } fConfigView->MoveTo(configRect.left, configRect.top); fConfigView->ResizeTo(configRect.Width(), configRect.Height()); fConfigView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); // force config views to all have the same color fRightBox->AddChild(fConfigView); return B_OK; }
void TeamsWindow::Zoom(BPoint, float, float) { BSize preferredSize = fTeamsListView->PreferredSize(); ResizeBy(preferredSize.Width() - Bounds().Width(), 0.0); // if the new size would extend us past the screen border, // move sufficiently to the left to bring us back within the bounds // + a bit of extra margin so we're not flush against the edge. BScreen screen; float offset = screen.Frame().right - Frame().right; if (offset < 0) MoveBy(offset - 5.0, 0.0); }
void Area::_UpdateMinSizeConstraint(BSize min) { if (!fLayoutItem->IsVisible()) { fMinContentHeight->SetRightSide(-1); fMinContentWidth->SetRightSide(-1); return; } float width = 0.; float height = 0.; if (min.width > 0) width = min.Width() + LeftInset() + RightInset(); if (min.height > 0) height = min.Height() + TopInset() + BottomInset(); fMinContentWidth->SetRightSide(width); fMinContentHeight->SetRightSide(height); }
void TFilePanel::RestoreState() { BNode defaultingNode; if (DefaultStateSourceNode(kDefaultFilePanelTemplate, &defaultingNode, false)) { AttributeStreamFileNode streamNodeSource(&defaultingNode); RestoreWindowState(&streamNodeSource); PoseView()->Init(&streamNodeSource); } else { RestoreWindowState(NULL); PoseView()->Init(NULL); } // Finish UI creation now that the PoseView is initialized BLayoutItem* item = fBorderedView->GroupLayout()->AddView(0, fPoseView->TitleView()); BSize minSize = item->MinSize(); BSize maxSize = item->MaxSize(); item->SetExplicitMinSize(BSize(minSize.Width(), kTitleViewHeight)); item->SetExplicitMaxSize(BSize(maxSize.Width(), kTitleViewHeight)); BRect rect(fBorderedView->Frame()); rect.right = rect.left + kCountViewWidth; rect.top = rect.bottom + 1; rect.bottom = rect.top + PoseView()->HScrollBar()->Bounds().Height() - 1; PoseView()->CountView()->MoveTo(rect.LeftTop()); PoseView()->CountView()->ResizeTo(rect.Size()); PoseView()->CountView()->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); fBackView->AddChild(PoseView()->CountView(), fBorderedView); PoseView()->HScrollBar()->MoveBy(kCountViewWidth + 1, 0); PoseView()->HScrollBar()->ResizeBy(-kCountViewWidth - 1, 0); // The Be Book states that the BTitleView will have a name of "TitleView", // and so some apps will try to grab it by that name and move it around. // They don't need to, because resizing "PoseView" (really the BorderedView) // will resize the BTitleView as well. So just create a dummy view here // so that they don't get NULL when trying to find the view. BView* dummyTitleView = new BView(BRect(), "TitleView", B_FOLLOW_NONE, 0); fBackView->AddChild(dummyTitleView); dummyTitleView->Hide(); }
ThreeButtonsWindow(BRect frame) : BWindow(frame, "ALM Three Buttons", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { BButton* button1 = new BButton("A"); BButton* button2 = new BButton("B"); BButton* button3 = new BButton("C"); button1->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button1->SetExplicitMaxSize(BSize(500, 50)); button2->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button2->SetExplicitMaxSize(BSize(500, 500)); button3->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button3->SetExplicitMaxSize(BSize(500, 500)); // create a new BALMLayout and use it for this window fLayout = new BALMLayout(); SetLayout(fLayout); fLayout->AddView(button1, fLayout->Left(), fLayout->Top(), fLayout->Right(), NULL); fLayout->AddViewToBottom(button2); fLayout->AddViewToBottom(button3, fLayout->Bottom()); // test size limits BSize min = fLayout->MinSize(); BSize max = fLayout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); }
ThreeButtonsWindow(BRect frame) : BWindow(frame, "ALM Three Buttons", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { BButton* button1 = new BButton("A"); BButton* button2 = new BButton("B"); BButton* button3 = new BButton("C"); button1->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button1->SetExplicitMaxSize(BSize(500, 50)); button2->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button2->SetExplicitMaxSize(BSize(500, 500)); button3->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); button3->SetExplicitMaxSize(BSize(500, 500)); fLayout = new BALMLayout(0, 0); BALM::BALMLayoutBuilder(this, fLayout) .Add(button1, fLayout->Left(), fLayout->Top(), fLayout->Right()) .StartingAt(button1) .AddBelow(button2) .AddBelow(button3, fLayout->Bottom()); // test size limits BSize min = fLayout->MinSize(); BSize max = fLayout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); }
TableDemoWindow(BRect frame) : BWindow(frame, "ALM Table Demo", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { // create a new BALMLayout and use it for this window BALMLayout* layout = new BALMLayout(); SetLayout(layout); Column* c1 = layout->AddColumn(layout->Left(), layout->Right()); Row* r1 = layout->AddRow(layout->Top(), NULL); Row* r2 = layout->AddRow(r1->Bottom(), NULL); Row* r3 = layout->AddRow(r2->Bottom(), layout->Bottom()); BButton* b1 = new BButton("A1"); layout->AddView(b1, r1, c1); b1->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP)); BButton* b2 = new BButton("A2"); layout->AddView(b2, r2, c1); b2->SetExplicitAlignment(BAlignment( B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER)); BButton* b3 = new BButton("A3"); layout->AddView(b3, r3, c1); b3->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM)); // test size limits BSize min = layout->MinSize(); BSize max = layout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); }
StatusWindow(const char* text) : BWindow(BRect(0, 0, 10, 10), B_TRANSLATE("status"), B_MODAL_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, B_NO_WORKSPACE_ACTIVATION | B_NOT_ZOOMABLE | B_AVOID_FRONT | B_NOT_RESIZABLE) { BView* rootView = new BView(Bounds(), "root", B_FOLLOW_ALL, B_WILL_DRAW); AddChild(rootView); rootView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); float spacing = be_control_look->DefaultItemSpacing(); BALMLayout* layout = new BALMLayout(spacing); rootView->SetLayout(layout); layout->SetInset(spacing); BStringView* string = new BStringView("text", text); layout->AddView(string, layout->Left(), layout->Top(), layout->Right(), layout->Bottom()); BSize min = layout->MinSize(); ResizeTo(min.Width(), min.Height()); CenterOnScreen(); }
PinwheelWindow(BRect frame) : BWindow(frame, "ALM Pinwheel", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { button1 = new BButton("1"); button2 = new BButton("2"); button3 = new BButton("3"); button4 = new BButton("4"); textView1 = new BTextView("textView1"); textView1->SetText("5"); button1->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); button2->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); button3->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); button4->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); // create a new BALMLayout and use it for this window BALMLayout* layout = new BALMLayout(10, 10); BReference<XTab> xTabs[2]; BReference<YTab> yTabs[2]; layout->AddXTabs(xTabs, 2); layout->AddYTabs(yTabs, 2); BALM::BALMLayoutBuilder(this, layout) .SetInsets(5) .Add(textView1, xTabs[0], yTabs[0], xTabs[1], yTabs[1]) .StartingAt(textView1) .AddAbove(button1, layout->Top(), layout->Left()) .AddToRight(button2, layout->Right(), NULL, yTabs[1]) .AddBelow(button3, layout->Bottom(), xTabs[0]) .AddToLeft(button4, layout->Left(), yTabs[0]); // alternative setup /* SetLayout(layout); layout->SetInsets(5.); // create extra tabs BReference<XTab> x1 = layout->AddXTab(); BReference<XTab> x2 = layout->AddXTab(); BReference<YTab> y1 = layout->AddYTab(); BReference<YTab> y2 = layout->AddYTab(); layout->AddView(button1, layout->Left(), layout->Top(), x2, y1); layout->AddView(button2, x2, layout->Top(), layout->Right(), y2); layout->AddView(button3, x1, y2, layout->Right(), layout->Bottom()); layout->AddView(button4, layout->Left(), y1, x1, layout->Bottom()); layout->AddView(textView1, x1, y1, x2, y2); */ // test size limits BSize min = layout->MinSize(); BSize max = layout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); }
void Area::_UpdateMaxSizeConstraint(BSize max) { max.width += LeftInset() + RightInset(); max.height += TopInset() + BottomInset(); // we only need max constraints if the alignment is full height/width // otherwise we can just align the item in the free space BAlignment alignment = fLayoutItem->Alignment(); if (alignment.Vertical() == B_ALIGN_USE_FULL_HEIGHT) { if (fMaxContentHeight == NULL) { fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, kLE, max.Height()); fConstraints.AddItem(fMaxContentHeight); } else fMaxContentHeight->SetRightSide(max.Height()); } else { fConstraints.RemoveItem(fMaxContentHeight); delete fMaxContentHeight; fMaxContentHeight = NULL; } if (alignment.Horizontal() == B_ALIGN_USE_FULL_WIDTH) { if (fMaxContentWidth == NULL) { fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, kLE, max.Width()); fConstraints.AddItem(fMaxContentWidth); } else fMaxContentWidth->SetRightSide(max.Width()); } else { fConstraints.RemoveItem(fMaxContentWidth); delete fMaxContentWidth; fMaxContentWidth = NULL; } }
BSize ExtensionListView::MinSize() { if (!fMinSize.IsWidthSet()) { BFont font; GetFont(&font); fMinSize.width = font.StringWidth(".mmmmm"); font_height height; font.GetHeight(&height); fMinSize.height = (height.ascent + height.descent + height.leading) * 3; } return fMinSize; }
MusicCollectionWindow::MusicCollectionWindow(BRect frame, const char* title) : BWindow(frame, title, B_DOCUMENT_WINDOW, B_AVOID_FRONT) { BView* rootView = new BView(Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW); AddChild(rootView); rootView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fQueryField = new BTextControl("Search: ", "", NULL); fQueryField->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_USE_FULL_HEIGHT)); fQueryField->SetModificationMessage(new BMessage(kMsgQueryInput)); fCountView = new BStringView("Count View", "Count:"); fFileListView = new MusicFileListView("File List View"); fFileListView->SetInvocationMessage(new BMessage(kMsgItemInvoked)); BScrollView* scrollView = new BScrollView("list scroll", fFileListView, 0, true, true, B_PLAIN_BORDER); float spacing = be_control_look->DefaultItemSpacing() / 2; BALMLayout* layout = new BALMLayout(spacing); layout->SetInset(spacing); rootView->SetLayout(layout); layout->AddView(fQueryField, layout->Left(), layout->Top()); layout->AddViewToRight(fCountView, layout->Right()); layout->AddView(scrollView, layout->Left(), layout->AreaFor(fQueryField)->Bottom(), layout->Right(), layout->Bottom()); Area* area = layout->AreaFor(scrollView); area->SetLeftInset(0); area->SetRightInset(0); area->SetBottomInset(0); BSize min = layout->MinSize(); BSize max = layout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); fEntryViewInterface = new ListViewListener<FileListItem>(fFileListView, fCountView); fQueryHandler = new QueryHandler(fEntryViewInterface); AddHandler(fQueryHandler); fQueryReader = new QueryReader(fQueryHandler); fQueryHandler->SetReadThread(fQueryReader); // start initial query PostMessage(kMsgQueryInput); }
FolderConfigWindow::FolderConfigWindow(BRect parent, const BMessage& settings) : BWindow(BRect(0, 0, 300, 300), B_TRANSLATE("IMAP Folders"), B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, B_NO_WORKSPACE_ACTIVATION | B_NOT_ZOOMABLE | B_AVOID_FRONT), fSettings(settings) { BView* rootView = new BView(Bounds(), "root", B_FOLLOW_ALL, B_WILL_DRAW); AddChild(rootView); rootView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); float spacing = be_control_look->DefaultItemSpacing(); BALMLayout* layout = new BALMLayout(spacing); rootView->SetLayout(layout); layout->SetInset(spacing); fFolderListView = new EditListView(B_TRANSLATE("IMAP Folders")); fFolderListView->SetExplicitPreferredSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); fApplyButton = new BButton("Apply", B_TRANSLATE("Apply"), new BMessage(kMsgApplyButton)); fQuotaView = new BStringView("quota view", B_TRANSLATE("Failed to fetch available storage.")); fQuotaView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); layout->AddView(fFolderListView, layout->Left(), layout->Top(), layout->Right(), layout->Bottom()); GroupItem item = GroupItem(fQuotaView) / GroupItem(fFolderListView) / (GroupItem(BSpaceLayoutItem::CreateGlue()) | GroupItem(fApplyButton)); layout->BuildLayout(item); PostMessage(kMsgInit); BSize min = layout->MinSize(); BSize max = layout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); CenterIn(parent); }
ViewsWindow(BRect frame) : BWindow(frame, "ALM Views", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { BButton* button1 = new BButton("BButton"); BRadioButton* radioButton = new BRadioButton("BRadioButton", NULL); BButton* button3 = new BButton("3"); BButton* button4 = new BButton("4"); button4->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); BButton* button5 = new BButton("5"); BButton* button6 = new BButton("6"); BTextView* textView1 = new BTextView("textView1"); textView1->SetText("BTextView"); BStatusBar* statusBar = new BStatusBar("BStatusBar", "label", "trailing label"); statusBar->Update(50); BMenu* menu = new BMenu("Menu 1"); BMenuField* menu1 = new BMenuField("MenuField 1", menu); menu->AddItem(new BPopUpMenu("Menu 1")); BStringView* stringView1 = new BStringView("string 1", "string 1"); menu = new BMenu("Menu 2 + long text"); BMenuField* menu2 = new BMenuField("MenuField 2", menu); menu->AddItem(new BPopUpMenu("Menu 2")); BStringView* stringView2 = new BStringView("string 2", "string 2"); BALM::BALMLayout* layout = new BALMLayout(10, 10); BALM::BALMLayoutBuilder(this, layout) .SetInsets(10) .Add(button1, layout->Left(), layout->Top()) .StartingAt(button1) .AddToRight(radioButton) .AddToRight(BSpaceLayoutItem::CreateGlue()) .AddToRight(button3) .StartingAt(radioButton) .AddBelow(textView1, NULL, NULL, layout->RightOf(button3)) .AddBelow(button4) .AddToRight(button5, layout->Right()) .AddBelow(button6) .AddBelow(menu1, layout->AddYTab(), layout->Left(), layout->AddXTab()) .AddToRight(stringView1) .AddToRight(BSpaceLayoutItem::CreateGlue(), layout->Right()) .AddBelow(statusBar, NULL, layout->Left(), layout->Right()); // start over so that layout->RightOf() can return accurate results BALM::BALMLayoutBuilder(layout) .StartingAt(statusBar) .AddBelow(menu2, layout->Bottom(), layout->Left(), layout->RightOf(menu1)) .AddToRight(stringView2) .AddToRight(BSpaceLayoutItem::CreateGlue(), layout->Right()); layout->Solver()->AddConstraint(2, layout->TopOf(menu1), -1, layout->Bottom(), OperatorType(kEQ), 0); // test size limits BSize min = layout->MinSize(); BSize max = layout->MaxSize(); SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); }
Size2 OS_Haiku::get_window_size() const { BSize size = window->Size(); return Size2i(size.IntegerWidth() + 1, size.IntegerHeight() + 1); }
/*! \brief This function creates and updates the BPopUpMenu. * \details The created menu is updated every time the TimeRepresentation * changes. */ void CalendarControl::CreateMenu( void ) { // The whole menu will be created in fixed font. BFont fixedFont(be_fixed_font); BFont plainFont(be_plain_font); BRect rectangle; BPoint topLeftCorner( 0, 0 ); BSize rectSize; BString sb; // Which month shall we represent? map<int, BString> dayNames = fCalModule->GetDayNamesForLocalYearMonth( this->fRepresentedTime.tm_year, this->fRepresentedTime.tm_mon); map<int, DoubleNames> monthNames = fCalModule->GetMonthNamesForLocalYear( this->fRepresentedTime.tm_year); int daysInMonth = dayNames.size(); int daysInWeek = ( int )fCalModule->GetDaysInWeek(); // We need to determine the bounding rectangle for the menu. // For this, we need to obtain the maximum bounding rectangle for a string. font_height fontHeightStruct; fixedFont.GetHeight( &fontHeightStruct ); float fixedFontHeightString = fontHeightStruct.ascent + fontHeightStruct.descent + fontHeightStruct.leading + SPACING; plainFont.GetHeight( &fontHeightStruct ); float plainFontHeightString = fontHeightStruct.ascent + fontHeightStruct.descent + fontHeightStruct.leading + SPACING; // Now fixedFontHeightString is surely big enough to enclose every string in // height. How many lines will we need? One for name of month and year, // one for weekday names, and several more for the dates themselves. At the // bottom, there is an additional line for "Return to today" option. // tempDay is a running date in current month. Each day item will be initialized // from the tempDay. TimeRepresentation tempDay( this->fRepresentedTime ); tempDay.tm_mday = 1; int firstDayOfMonthWD = fCalModule->GetWeekDayForLocalDateAsInt( tempDay ); int firstDayOfWeek = ( int )fFirstDayOfEveryWeek; int firstDayOfMonthInFirstWeek = (firstDayOfMonthWD + daysInWeek - firstDayOfWeek) % daysInWeek; // This is the menu we're adding items to. if ( fDateSelector ) { BMenuItem* item = NULL; while ( fDateSelector->ItemAt( 0 ) ) { item = fDateSelector->RemoveItem( ( int32 )0 ); delete item; } } else { fDateSelector = new BMenu("⇩", B_ITEMS_IN_MATRIX ); } // Sanity check if ( !fDateSelector ) { // Panic! fLastError = B_NO_MEMORY; return; } fDateSelector->SetViewColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); fDateSelector->SetFont( &fixedFont ); topLeftCorner.x = SPACING + 5; topLeftCorner.y = SPACING; // Build the list of months. BPopUpMenu* listOfMonths = CreateMonthsMenu(monthNames); //----------------------------------------------------- // FIRST ROW. //----------------------------------------------------- /*---------------------------------------------------------------------------- * Adding months menu with option to scroll forward and backward *----------------------------------------------------------------------------*/ // Add the item to scroll list of months back BMessage* messageOfItem = new BMessage( kMonthDecreased ); DayItem* itemToAdd = new DayItem("‹", messageOfItem); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetServiceItem( true ); itemToAdd->SetFrontColor( fColorForServiceItems ); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); itemToAdd->SetEnabled( true ); rectSize.SetHeight( fixedFontHeightString ); rectSize.SetWidth( 25 ); // rectSize.SetWidth( ( float )fixedFont.StringWidth("‹") + SPACING ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); itemToAdd->SetTarget( this ); topLeftCorner.x += rectSize.Width() + SPACING; // Add the list of months BString longestMonth = monthNames[ 1 ].longName; for ( int i = 2; i < ( int )monthNames.size(); i++ ) { if ( ( ( BString )( monthNames[ i ].longName ) ).Length() > longestMonth.Length() ) { longestMonth = monthNames[i].longName; } } rectSize.SetHeight( plainFontHeightString ); rectSize.SetWidth( (float)plainFont.StringWidth( longestMonth.String() ) + 10 + SPACING ); fDateSelector->AddItem( listOfMonths, BRect(topLeftCorner, rectSize) ); topLeftCorner.x += rectSize.Width() + SPACING; // Add the item to scroll list of months forward. messageOfItem = new BMessage( kMonthIncreased ); if ( !messageOfItem ) { // Panic! fLastError = B_NO_MEMORY; return; } itemToAdd = new DayItem( "›", messageOfItem ); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetServiceItem(true); itemToAdd->SetFrontColor( fColorForServiceItems ); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); itemToAdd->SetEnabled( true ); rectSize.SetHeight( fixedFontHeightString ); rectSize.SetWidth( 25 ); // rectSize.SetWidth( ( float )fixedFont.StringWidth("›") + SPACING ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); itemToAdd->SetTarget( this ); topLeftCorner.x += rectSize.Width() + 10 + SPACING; /*---------------------------------------------------------------------------- * Adding years menu with option to scroll forward and backward *----------------------------------------------------------------------------*/ // Add the item to scroll list of years down. messageOfItem = new BMessage( kYearDecreased ); if ( !messageOfItem ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd = new DayItem( "‒", messageOfItem ); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetServiceItem(true); itemToAdd->SetFrontColor( fColorForServiceItems ); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); itemToAdd->SetEnabled( true ); rectSize.SetHeight( fixedFontHeightString ); rectSize.SetWidth( 25 ); // rectSize.SetWidth( ( float )fixedFont.StringWidth("‒") + SPACING ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); itemToAdd->SetTarget( this ); topLeftCorner.x += rectSize.Width() + SPACING; // Add year sb.Truncate( 0 ); sb << fRepresentedTime.tm_year; rectSize.SetHeight( plainFontHeightString ); rectSize.SetWidth( ( float )plainFont.StringWidth( sb.String() ) + 10 + SPACING ); BPopUpMenu* listOfYears = CreateYearsMenu(this->fRepresentedTime.tm_year); if ( !listOfYears ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fDateSelector->AddItem( listOfYears, BRect( topLeftCorner, rectSize ) ); topLeftCorner.x += rectSize.Width() + SPACING; // Add item to scroll list of years up. messageOfItem = new BMessage( kYearIncreased ); if ( !messageOfItem ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd = new DayItem( "+", messageOfItem ); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetServiceItem(true); itemToAdd->SetFrontColor( fColorForServiceItems ); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); itemToAdd->SetEnabled(true); rectSize.SetHeight( fixedFontHeightString ); rectSize.SetWidth( 25 ); // rectSize.SetWidth( ( float )fixedFont.StringWidth( "+" ) + SPACING ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); //----------------------------------------------------- // SECOND ROW. WEEKDAY NAMES //----------------------------------------------------- sb.Truncate( 0 ); rectSize.SetHeight( fixedFontHeightString ); sb << ( int )fCalModule->GetLongestMonthLength(); rectSize.SetWidth( fixedFont.StringWidth( sb.String() ) + SPACING ); float rowHeight = rectSize.Height() + SPACING; float itemWidth = rectSize.Width() + 15 + SPACING; rectSize.SetWidth( itemWidth ); rectSize.SetHeight( rowHeight ); topLeftCorner.x = SPACING; topLeftCorner.y += rowHeight + ( SPACING * 2 ); map<uint32, DoubleNames> weekdayNames = fCalModule->GetWeekdayNames(); uint32 limit = ( uint32 )fCalModule->GetDaysInWeek(); uint32 curDay; for (uint32 i = firstDayOfWeek; i < limit+firstDayOfWeek; ++i) { curDay = ( (i - 1) % limit ) + 1; itemToAdd = new DayItem( weekdayNames[ curDay ].shortName.String(), NULL ); if (!itemToAdd) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetServiceItem( true ); // If this is a weekend, we shold display it in another color if ( fWeekends.HasItem( (void*)i ) || fWeekends.HasItem( (void*)( i % daysInWeek ) ) ) { itemToAdd->SetFrontColor( fColorForWeekends ); } else { itemToAdd->SetFrontColor( fColorForServiceItems );; } itemToAdd->SetEnabled(false); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); topLeftCorner.x += itemWidth + SPACING; } topLeftCorner.x = SPACING; topLeftCorner.y += rowHeight + SPACING; //----------------------------------------------------------------------- // THIRD ROW AND DOWN - THE WEEK INDIVIDUAL DAYS. //---------------------------------------------------------------------- uint32 currentWeekday = ( uint32 )firstDayOfMonthInFirstWeek; topLeftCorner.x += ( itemWidth + SPACING ) * firstDayOfMonthInFirstWeek; for (int day = 1; day <= daysInMonth; ++day ) { messageOfItem = new BMessage(kTodayModified); if ( !messageOfItem ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } messageOfItem->AddInt32( "Date", day ); sb.Truncate( 0 ); char padding = ' '; // <-- For proper aligning of the items ( day < 10 ) ? sb << padding << day : sb << day; itemToAdd = new DayItem( sb.String(), messageOfItem ); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } itemToAdd->SetEnabled( true ); itemToAdd->SetServiceItem( false ); messageOfItem->AddPointer( "Item", &itemToAdd ); if ( fWeekends.HasItem( ( void* )( ( fFirstDayOfEveryWeek + currentWeekday ) % daysInWeek ) ) || fWeekends.HasItem( ( void* )( ( fFirstDayOfEveryWeek + currentWeekday ) ) ) ) { itemToAdd->SetFrontColor( weekendDateColor ); } else { itemToAdd->SetFrontColor( ui_color( B_MENU_ITEM_TEXT_COLOR ) ); } // Does this item represent today? if ( fRepresentedTime.tm_mday == day ) { itemToAdd->SetToday( true ); itemToAdd->SetBackColor( fColorForServiceItems ); itemToAdd->SetMarked( true ); } fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); itemToAdd->SetTarget( this ); topLeftCorner.x += itemWidth + SPACING; ++currentWeekday; if ( ( currentWeekday % daysInWeek == 0 ) && ( day < daysInMonth ) ) { topLeftCorner.x = SPACING; topLeftCorner.y += rowHeight+SPACING; currentWeekday = 0; } } //----------------------------------------------------------------------- // LAST ROW - The option to return to current date. //---------------------------------------------------------------------- topLeftCorner.y += rowHeight + SPACING; messageOfItem = new BMessage( kReturnToToday ); if ( !messageOfItem ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } sb.Truncate( 0 ); sb << "Go to today"; // Label itemToAdd = new DayItem( sb.String(), messageOfItem ); if ( !itemToAdd ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } // Setting the color to blue itemToAdd->SetServiceItem(true); itemToAdd->SetFrontColor( fColorForServiceItems ); itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); itemToAdd->SetEnabled( true ); itemToAdd->SetTarget( this ); // The new v-alignment was already set above. Now it's time to set the // x-alignment. I'd like to align this item to the center of Menu's rec- // tangle, which require some additional calculations. float currentWidth = itemWidth * daysInWeek + ( SPACING * 2 ); float desiredWidth = plainFont.StringWidth( sb.String()) ; topLeftCorner.x = SPACING + 0.5 * ( currentWidth - desiredWidth ); rectSize.SetHeight( plainFontHeightString ); rectSize.SetWidth( desiredWidth + 30 ); fDateSelector->AddItem( itemToAdd, BRect( topLeftCorner, rectSize ) ); fDateSelector->SetTargetForItems( this ); UpdateTargets( fDateSelector ); }
ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, BMessage* settings) : BWindow(frame, B_TRANSLATE_SYSTEM_NAME("Expander"), B_TITLED_WINDOW, B_NORMAL_WINDOW_FEEL), fSourcePanel(NULL), fDestPanel(NULL), fSourceChanged(true), fListingThread(NULL), fListingStarted(false), fExpandingThread(NULL), fExpandingStarted(false), fSettings(*settings), fPreferences(NULL) { BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 0); SetLayout(layout); _AddMenuBar(layout); fDestButton = new BButton(B_TRANSLATE("Destination"), new BMessage(MSG_DEST)); fSourceButton = new BButton(B_TRANSLATE("Source"), new BMessage(MSG_SOURCE)); fExpandButton = new BButton(B_TRANSLATE("Expand"), new BMessage(MSG_EXPAND)); BSize size = fDestButton->PreferredSize(); size.width = max_c(size.width, fSourceButton->PreferredSize().width); size.width = max_c(size.width, fExpandButton->PreferredSize().width); fDestButton->SetExplicitMaxSize(size); fSourceButton->SetExplicitMaxSize(size); fExpandButton->SetExplicitMaxSize(size); fListingText = new BTextView("listingText"); fListingText->SetText(""); fListingText->MakeEditable(false); fListingText->SetStylable(false); fListingText->SetWordWrap(false); BFont font = be_fixed_font; fListingText->SetFontAndColor(&font); BScrollView* scrollView = new BScrollView("", fListingText, B_INVALIDATE_AFTER_LAYOUT, true, true); BView* topView = layout->View(); const float spacing = be_control_look->DefaultItemSpacing(); topView->AddChild(BGroupLayoutBuilder(B_VERTICAL, spacing) .AddGroup(B_HORIZONTAL, spacing) .AddGroup(B_VERTICAL, 5.0) .Add(fSourceButton) .Add(fDestButton) .Add(fExpandButton) .End() .AddGroup(B_VERTICAL, spacing) .Add(fSourceText = new BTextControl(NULL, NULL, new BMessage(MSG_SOURCETEXT))) .Add(fDestText = new BTextControl(NULL, NULL, new BMessage(MSG_DESTTEXT))) .AddGroup(B_HORIZONTAL, spacing) .Add(fShowContents = new BCheckBox( B_TRANSLATE("Show contents"), new BMessage(MSG_SHOWCONTENTS))) .Add(fStatusView = new BStringView(NULL, NULL)) .End() .End() .End() .Add(scrollView) .SetInsets(spacing, spacing, spacing, spacing) ); size = topView->PreferredSize(); fSizeLimit = size.Height() - scrollView->PreferredSize().height - spacing; ResizeTo(Bounds().Width(), fSizeLimit); SetSizeLimits(size.Width(), 32767.0f, fSizeLimit, fSizeLimit); SetZoomLimits(Bounds().Width(), fSizeLimit); fPreviousHeight = -1; Show(); }