const PixelRect & TabDisplay::GetButtonSize(unsigned i) const { assert(i < GetSize()); if (buttons[i]->rc.left < buttons[i]->rc.right) return buttons[i]->rc; const UPixelScalar margin = 1; /* bool partialTab = false; if ( ((Layout::landscape ^ flip_orientation) && tab_display->GetTabHeight() < get_height()) || ((!Layout::landscape ^ flip_orientation) && tab_display->GetTabWidth() < get_width()) ) partialTab = true; */ const UPixelScalar finalmargin = 1; //partialTab ? tab_line_height - 1 * margin : margin; // Todo make the final margin display on either beginning or end of tab bar // depending on position of tab bar PixelRect rc; if (Layout::landscape ^ flip_orientation) { const UPixelScalar but_height = (GetTabHeight() - finalmargin) / GetSize() - margin; rc.left = 0; rc.right = GetTabWidth() - tab_bar.GetTabLineHeight(); rc.top = finalmargin + (margin + but_height) * i; rc.bottom = rc.top + but_height; } else { const unsigned portraitRows = (GetSize() > 4) ? 2 : 1; const unsigned portraitColumnsRow0 = ((portraitRows == 1) ? GetSize() : GetSize() / 2); const unsigned portraitColumnsRow1 = ((portraitRows == 1) ? 0 : GetSize() - GetSize() / 2); const unsigned row = (i > (portraitColumnsRow0 - 1)) ? 1 : 0; const UPixelScalar rowheight = (GetTabHeight() - tab_bar.GetTabLineHeight()) / portraitRows - margin; const UPixelScalar but_width = (GetTabWidth() - finalmargin) / ((row == 0) ? portraitColumnsRow0 : portraitColumnsRow1) - margin; rc.top = row * (rowheight + margin); rc.bottom = rc.top + rowheight; rc.left = finalmargin + (margin + but_width) * (row ? (i - portraitColumnsRow0) : i); rc.right = rc.left + but_width; } buttons[i]->rc = rc; return buttons[i]->rc; }
void WorkspacesWindow::Zoom(BPoint origin, float width, float height) { BScreen screen; float screenWidth = screen.Frame().Width(); float screenHeight = screen.Frame().Height(); float aspectRatio = screenWidth / screenHeight; uint32 columns, rows; BPrivate::get_workspaces_layout(&columns, &rows); float workspaceWidth = Frame().Width() / columns; float workspaceHeight = workspaceWidth / aspectRatio; width = floor(workspaceWidth * columns); height = floor(workspaceHeight * rows); while (width + 2 * GetScreenBorderOffset() > screenWidth || height + 2 * GetScreenBorderOffset() + GetTabHeight() > screenHeight) { width = floor(0.95 * width); height = floor(0.95 * height); } ResizeTo(width, height); if (fSettings->AutoRaising()) { // The auto-raising mode makes sense only if the window is positionned // exactly in the bottom-right corner. If the setting is enabled, move // the window there. origin = screen.Frame().RightBottom(); origin.x -= GetScreenBorderOffset() + width; origin.y -= GetScreenBorderOffset() + height; MoveTo(origin); } }
const PixelRect& TabMenuControl::GetSubMenuButtonSize(unsigned page) const { assert(page < buttons.size()); if (buttons[page]->rc.left < buttons[page]->rc.right) return buttons[page]->rc; const PageItem &item = this->GetPageItem(page); const MainMenuButton &main_button = GetMainMenuButton(item.main_menu_index); const unsigned sub_index = page - main_button.first_page_index; PixelRect &rc = buttons[page]->rc; const UPixelScalar margin = Layout::Scale(1); const UPixelScalar finalmargin = Layout::Scale(1); const unsigned subMenuItemCount = main_button.NumSubMenus(); const UPixelScalar tabHeight = GetTabHeight(); const UPixelScalar butHeight = GetMenuButtonHeight(); const UPixelScalar itemHeight = butHeight + margin; const UPixelScalar SubMenuHeight = itemHeight * subMenuItemCount + finalmargin; const UPixelScalar topMainMenuItem = item.main_menu_index * itemHeight + finalmargin; const UPixelScalar offset = Layout::Scale(2); const UPixelScalar topMainMenuItemWOffset = topMainMenuItem + offset; const UPixelScalar subMenuTop = (topMainMenuItemWOffset + SubMenuHeight <= tabHeight) ? topMainMenuItemWOffset : tabHeight - SubMenuHeight - offset; rc.top = subMenuTop + sub_index * itemHeight; rc.bottom = rc.top + butHeight; rc.left = GetMenuButtonWidth() + GetTabLineHeight(); rc.right = rc.left + GetMenuButtonWidth(); return buttons[page]->rc; }
// Layout tabs (optional, e.g. if resizing window) void wxTabView::LayoutTabs(void) { // Make a list of the tab controls, deleting the wxTabLayers. wxList controls; wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst(); while (layerNode) { wxTabLayer *layer = (wxTabLayer *)layerNode->GetData(); wxList::compatibility_iterator tabNode = layer->GetFirst(); while (tabNode) { wxTabControl *tab = (wxTabControl *)tabNode->GetData(); controls.Append(tab); wxList::compatibility_iterator next = tabNode->GetNext(); layer->Erase(tabNode); tabNode = next; } wxTabLayerList::compatibility_iterator nextLayerNode = layerNode->GetNext(); delete layer; m_layers.Erase(layerNode); layerNode = nextLayerNode; } wxTabControl *lastTab = NULL; wxTabLayer *currentLayer = new wxTabLayer; m_layers.Append(currentLayer); wxList::compatibility_iterator node = controls.GetFirst(); while (node) { wxTabControl *tabControl = (wxTabControl *)node->GetData(); if (lastTab) { // Start another layer (row). // Tricky choice: can't just check if will be overlapping the edge, because // this happens anyway for 2nd and subsequent rows. // Should check this for 1st row, and then subsequent rows should not exceed 1st // in length. if (((currentLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) > GetViewRect().width)) || ((currentLayer != m_layers.GetFirst()->GetData()) && (currentLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount()))) { currentLayer = new wxTabLayer; m_layers.Append(currentLayer); lastTab = NULL; } } int layer = m_layers.GetCount() - 1; tabControl->SetRowPosition(currentLayer->GetCount()); tabControl->SetColPosition(layer); // Top of new tab int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight()); // Offset from view top-left int horizontalOffset = 0; if (!lastTab) horizontalOffset = layer*GetHorizontalTabOffset(); else horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing(); tabControl->SetPosition(horizontalOffset, verticalOffset); tabControl->SetSize(GetTabWidth(), GetTabHeight()); currentLayer->Append(tabControl); lastTab = tabControl; node = node->GetNext(); } // Move the selected tab to the bottom wxTabControl *control = FindTabControlForId(m_tabSelection); if (control) MoveSelectionTab(control); }
// Automatically positions tabs // TODO: this should just add the tab to a list, and then // a layout function (e.g. Realize) should be called when all tabs have been added. // The view rect could easily change as the view window is resized. wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab) { // First, find which layer we should be adding to. wxTabLayerList::compatibility_iterator node = m_layers.GetLast(); if (!node) { wxTabLayer *newLayer = new wxTabLayer; node = m_layers.Append(newLayer); } // Check if adding another tab control would go off the // right-hand edge of the layer. wxTabLayer *tabLayer = (wxTabLayer *)node->GetData(); wxList::compatibility_iterator lastTabNode = tabLayer->GetLast(); if (lastTabNode) { wxTabControl *lastTab = (wxTabControl *)lastTabNode->GetData(); // Start another layer (row). // Tricky choice: can't just check if will be overlapping the edge, because // this happens anyway for 2nd and subsequent rows. // Should check this for 1st row, and then subsequent rows should not exceed 1st // in length. if (((tabLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) > GetViewRect().width)) || ((tabLayer != m_layers.GetFirst()->GetData()) && (tabLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount()))) { tabLayer = new wxTabLayer; m_layers.Append(tabLayer); lastTabNode = wxList::compatibility_iterator(); } } int layer = m_layers.GetCount() - 1; wxTabControl *tabControl = existingTab; if (!existingTab) tabControl = OnCreateTabControl(); tabControl->SetRowPosition(tabLayer->GetCount()); tabControl->SetColPosition(layer); wxTabControl *lastTab = NULL; if (lastTabNode) lastTab = (wxTabControl *)lastTabNode->GetData(); // Top of new tab int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight()); // Offset from view top-left int horizontalOffset = 0; if (!lastTab) horizontalOffset = layer*GetHorizontalTabOffset(); else horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing(); tabControl->SetPosition(horizontalOffset, verticalOffset); tabControl->SetSize(GetTabWidth(), GetTabHeight()); tabControl->SetId(id); tabControl->SetLabel(label); tabControl->SetFont(* GetTabFont()); tabLayer->Append(tabControl); m_noTabs ++; return tabControl; }
WorkspacesWindow::WorkspacesWindow(WorkspacesSettings *settings) : BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Workspaces"), B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_AVOID_FRONT | B_WILL_ACCEPT_FIRST_CLICK | B_CLOSE_ON_ESCAPE, B_ALL_WORKSPACES), fSettings(settings), fSwitchOnWheel(false) { // Turn window decor on to grab decor widths. BMessage windowSettings; float borderWidth = 0; SetLook(B_TITLED_WINDOW_LOOK); if (GetDecoratorSettings(&windowSettings) == B_OK) { BRect tabFrame = windowSettings.FindRect("tab frame"); borderWidth = windowSettings.FindFloat("border width"); fTabHeight = tabFrame.Height(); fBorderWidth = borderWidth; } if (!fSettings->SettingsLoaded()) { // No settings, compute a reasonable default frame. // We aim for previews at 10% of actual screen size, and matching the // aspect ratio. We then scale that down, until it fits the screen. // Finally, we put the window on the bottom right of the screen so the // auto-raise mode can be used. BScreen screen; float screenWidth = screen.Frame().Width(); float screenHeight = screen.Frame().Height(); float aspectRatio = screenWidth / screenHeight; uint32 columns, rows; BPrivate::get_workspaces_layout(&columns, &rows); // default size of ~1/10 of screen width float workspaceWidth = screenWidth / 10; float workspaceHeight = workspaceWidth / aspectRatio; float width = floor(workspaceWidth * columns); float height = floor(workspaceHeight * rows); // If you have too many workspaces to fit on the screen, shrink until // they fit. while (width + 2 * borderWidth > screenWidth || height + 2 * borderWidth + GetTabHeight() > screenHeight) { width = floor(0.95 * width); height = floor(0.95 * height); } BRect frame = fSettings->ScreenFrame(); frame.OffsetBy(-2.0 * borderWidth, -2.0 * borderWidth); frame.left = frame.right - width; frame.top = frame.bottom - height; ResizeTo(frame.Width(), frame.Height()); // Put it in bottom corner by default. MoveTo(screenWidth - frame.Width() - borderWidth, screenHeight - frame.Height() - borderWidth); fSettings->SetWindowFrame(frame); } if (!fSettings->HasBorder()) SetLook(B_NO_BORDER_WINDOW_LOOK); else if (!fSettings->HasTitle()) SetLook(B_MODAL_WINDOW_LOOK); AddChild(new WorkspacesView(Bounds())); if (fSettings->AlwaysOnTop()) SetFeel(B_FLOATING_ALL_WINDOW_FEEL); else SetAutoRaise(fSettings->AutoRaising()); SetSwitchOnWheel(fSettings->SwitchOnWheel()); }