void wxRibbonBar::ScrollTabBar(int amount) { bool show_left = true; bool show_right = true; if(m_tab_scroll_amount + amount <= 0) { amount = -m_tab_scroll_amount; show_left = false; } else if(m_tab_scroll_amount + amount + (GetClientSize().GetWidth() - m_tab_margin_left - m_tab_margin_right) >= m_tabs_total_width_minimum) { amount = m_tabs_total_width_minimum - m_tab_scroll_amount - (GetClientSize().GetWidth() - m_tab_margin_left - m_tab_margin_right); show_right = false; } if(amount == 0) { return; } m_tab_scroll_amount += amount; size_t numtabs = m_pages.GetCount(); size_t i; for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); info.rect.SetX(info.rect.GetX() - amount); } if(show_right != (m_tab_scroll_right_button_rect.GetWidth() != 0) || show_left != (m_tab_scroll_left_button_rect.GetWidth() != 0)) { wxClientDC temp_dc(this); if(show_left) { m_tab_scroll_left_button_rect.SetWidth(m_art->GetScrollButtonMinimumSize(temp_dc, this, wxRIBBON_SCROLL_BTN_LEFT | wxRIBBON_SCROLL_BTN_NORMAL | wxRIBBON_SCROLL_BTN_FOR_TABS).GetWidth()); } else { m_tab_scroll_left_button_rect.SetWidth(0); } if(show_right) { if(m_tab_scroll_right_button_rect.GetWidth() == 0) { m_tab_scroll_right_button_rect.SetWidth(m_art->GetScrollButtonMinimumSize(temp_dc, this, wxRIBBON_SCROLL_BTN_RIGHT | wxRIBBON_SCROLL_BTN_NORMAL | wxRIBBON_SCROLL_BTN_FOR_TABS).GetWidth()); m_tab_scroll_right_button_rect.SetX(m_tab_scroll_right_button_rect.GetX() - m_tab_scroll_right_button_rect.GetWidth()); } } else { if(m_tab_scroll_right_button_rect.GetWidth() != 0) { m_tab_scroll_right_button_rect.SetX(m_tab_scroll_right_button_rect.GetX() + m_tab_scroll_right_button_rect.GetWidth()); m_tab_scroll_right_button_rect.SetWidth(0); } } } RefreshTabBar(); }
// Finds the best width and height given the parent's width and height wxSize wxRibbonPanel::GetBestSizeForParentSize(const wxSize& parentSize) const { if (GetChildren().GetCount() == 1) { wxWindow* win = GetChildren().GetFirst()->GetData(); wxRibbonControl* control = wxDynamicCast(win, wxRibbonControl); if (control) { wxClientDC temp_dc((wxRibbonPanel*) this); wxSize clientParentSize = m_art->GetPanelClientSize(temp_dc, this, parentSize, NULL); wxSize childSize = control->GetBestSizeForParentSize(clientParentSize); wxSize overallSize = m_art->GetPanelSize(temp_dc, this, childSize, NULL); return overallSize; } } return GetSize(); }
void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art) { if(art == m_art) { return; } wxRibbonControl::SetArtProvider(art); wxClientDC temp_dc(this); size_t btn_count = m_buttons.Count(); size_t btn_i; for(btn_i = 0; btn_i < btn_count; ++btn_i) { wxRibbonButtonBarButtonBase* base = m_buttons.Item(btn_i); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); } m_layouts_valid = false; Realize(); }
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( size_t pos, int button_id, const wxString& label, const wxBitmap& bitmap, const wxBitmap& bitmap_small, const wxBitmap& bitmap_disabled, const wxBitmap& bitmap_small_disabled, wxRibbonButtonKind kind, const wxString& help_string) { wxASSERT(bitmap.IsOk() || bitmap_small.IsOk()); if(m_buttons.IsEmpty()) { if(bitmap.IsOk()) { m_bitmap_size_large = bitmap.GetSize(); if(!bitmap_small.IsOk()) { m_bitmap_size_small = m_bitmap_size_large; m_bitmap_size_small *= 0.5; } } if(bitmap_small.IsOk()) { m_bitmap_size_small = bitmap_small.GetSize(); if(!bitmap.IsOk()) { m_bitmap_size_large = m_bitmap_size_small; m_bitmap_size_large *= 2.0; } } } wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; base->id = button_id; base->label = label; base->bitmap_large = bitmap; if(!base->bitmap_large.IsOk()) { base->bitmap_large = MakeResizedBitmap(base->bitmap_small, m_bitmap_size_large); } else if(base->bitmap_large.GetSize() != m_bitmap_size_large) { base->bitmap_large = MakeResizedBitmap(base->bitmap_large, m_bitmap_size_large); } base->bitmap_small = bitmap_small; if(!base->bitmap_small.IsOk()) { base->bitmap_small = MakeResizedBitmap(base->bitmap_large, m_bitmap_size_small); } else if(base->bitmap_small.GetSize() != m_bitmap_size_small) { base->bitmap_small = MakeResizedBitmap(base->bitmap_small, m_bitmap_size_small); } base->bitmap_large_disabled = bitmap_disabled; if(!base->bitmap_large_disabled.IsOk()) { base->bitmap_large_disabled = MakeDisabledBitmap(base->bitmap_large); } base->bitmap_small_disabled = bitmap_small_disabled; if(!base->bitmap_small_disabled.IsOk()) { base->bitmap_small_disabled = MakeDisabledBitmap(base->bitmap_small); } base->kind = kind; base->help_string = help_string; base->state = 0; wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); m_buttons.Insert(base, pos); m_layouts_valid = false; return base; }
void wxRibbonBar::RecalculateTabSizes() { size_t numtabs = m_pages.GetCount(); if(numtabs == 0) return; int width = GetSize().GetWidth() - m_tab_margin_left - m_tab_margin_right; int tabsep = m_art->GetMetric(wxRIBBON_ART_TAB_SEPARATION_SIZE); int x = m_tab_margin_left; const int y = 0; if(width >= m_tabs_total_width_ideal) { // Simple case: everything at ideal width size_t i; for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); info.rect.x = x; info.rect.y = y; info.rect.width = info.ideal_width; info.rect.height = m_tab_height; x += info.rect.width + tabsep; } m_tab_scroll_buttons_shown = false; m_tab_scroll_left_button_rect.SetWidth(0); m_tab_scroll_right_button_rect.SetWidth(0); } else if(width < m_tabs_total_width_minimum) { // Simple case: everything minimum with scrollbar size_t i; for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); info.rect.x = x; info.rect.y = y; info.rect.width = info.minimum_width; info.rect.height = m_tab_height; x += info.rect.width + tabsep; } if(!m_tab_scroll_buttons_shown) { m_tab_scroll_left_button_state = wxRIBBON_SCROLL_BTN_NORMAL; m_tab_scroll_right_button_state = wxRIBBON_SCROLL_BTN_NORMAL; m_tab_scroll_buttons_shown = true; } { wxClientDC temp_dc(this); m_tab_scroll_left_button_rect.SetWidth(m_art->GetScrollButtonMinimumSize(temp_dc, this, wxRIBBON_SCROLL_BTN_LEFT | wxRIBBON_SCROLL_BTN_NORMAL | wxRIBBON_SCROLL_BTN_FOR_TABS).GetWidth()); m_tab_scroll_left_button_rect.SetHeight(m_tab_height); m_tab_scroll_left_button_rect.SetX(m_tab_margin_left); m_tab_scroll_left_button_rect.SetY(0); m_tab_scroll_right_button_rect.SetWidth(m_art->GetScrollButtonMinimumSize(temp_dc, this, wxRIBBON_SCROLL_BTN_RIGHT | wxRIBBON_SCROLL_BTN_NORMAL | wxRIBBON_SCROLL_BTN_FOR_TABS).GetWidth()); m_tab_scroll_right_button_rect.SetHeight(m_tab_height); m_tab_scroll_right_button_rect.SetX(GetClientSize().GetWidth() - m_tab_margin_right - m_tab_scroll_right_button_rect.GetWidth()); m_tab_scroll_right_button_rect.SetY(0); } if(m_tab_scroll_amount == 0) { m_tab_scroll_left_button_rect.SetWidth(0); } else if(m_tab_scroll_amount + width >= m_tabs_total_width_minimum) { m_tab_scroll_amount = m_tabs_total_width_minimum - width; m_tab_scroll_right_button_rect.SetX(m_tab_scroll_right_button_rect.GetX() + m_tab_scroll_right_button_rect.GetWidth()); m_tab_scroll_right_button_rect.SetWidth(0); } for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); info.rect.x -= m_tab_scroll_amount; } } else { m_tab_scroll_buttons_shown = false; m_tab_scroll_left_button_rect.SetWidth(0); m_tab_scroll_right_button_rect.SetWidth(0); // Complex case: everything sized such that: minimum <= width < ideal /* Strategy: 1) Uniformly reduce all tab widths from ideal to small_must_have_separator_width 2) Reduce the largest tab by 1 pixel, repeating until all tabs are same width (or at minimum) 3) Uniformly reduce all tabs down to their minimum width */ int smallest_tab_width = INT_MAX; int total_small_width = tabsep * (numtabs - 1); size_t i; for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); if(info.small_must_have_separator_width < smallest_tab_width) { smallest_tab_width = info.small_must_have_separator_width; } total_small_width += info.small_must_have_separator_width; } if(width >= total_small_width) { // Do (1) int total_delta = m_tabs_total_width_ideal - total_small_width; total_small_width -= tabsep * (numtabs - 1); width -= tabsep * (numtabs - 1); for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); int delta = info.ideal_width - info.small_must_have_separator_width; info.rect.x = x; info.rect.y = y; info.rect.width = info.small_must_have_separator_width + delta * (width - total_small_width) / total_delta; info.rect.height = m_tab_height; x += info.rect.width + tabsep; total_delta -= delta; total_small_width -= info.small_must_have_separator_width; width -= info.rect.width; } } else { total_small_width = tabsep * (numtabs - 1); for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); if(info.minimum_width < smallest_tab_width) { total_small_width += smallest_tab_width; } else { total_small_width += info.minimum_width; } } if(width >= total_small_width) { // Do (2) wxRibbonPageTabInfoArray sorted_pages; for(i = 0; i < numtabs; ++i) { // Sneaky obj array trickery to not copy the tab descriptors sorted_pages.Add(&m_pages.Item(i)); } sorted_pages.Sort(OrderPageTabInfoBySmallWidthAsc); width -= tabsep * (numtabs - 1); for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = sorted_pages.Item(i); if(info.small_must_have_separator_width * (int)(numtabs - i) <= width) { info.rect.width = info.small_must_have_separator_width;; } else { info.rect.width = width / (numtabs - i); } width -= info.rect.width; } for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); info.rect.x = x; info.rect.y = y; info.rect.height = m_tab_height; x += info.rect.width + tabsep; sorted_pages.Detach(numtabs - (i + 1)); } } else { // Do (3) total_small_width = (smallest_tab_width + tabsep) * numtabs - tabsep; int total_delta = total_small_width - m_tabs_total_width_minimum; total_small_width = m_tabs_total_width_minimum - tabsep * (numtabs - 1); width -= tabsep * (numtabs - 1); for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); int delta = smallest_tab_width - info.minimum_width; info.rect.x = x; info.rect.y = y; info.rect.width = info.minimum_width + delta * (width - total_small_width) / total_delta; info.rect.height = m_tab_height; x += info.rect.width + tabsep; total_delta -= delta; total_small_width -= info.minimum_width; width -= info.rect.width; } } } } }
bool wxRibbonPanel::Realize() { bool status = true; #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) { wxRibbonControl* child = wxDynamicCast(node->GetData(), wxRibbonControl); if(child == NULL) { continue; } if(!child->Realize()) { status = false; } } wxSize minimum_children_size(0, 0); // Ask sizer if there is one present if(GetSizer()) { minimum_children_size = GetPanelSizerMinSize(); } else if(GetChildren().GetCount() == 1) { minimum_children_size = GetChildren().GetFirst()->GetData()->GetMinSize(); } if(m_art != NULL) { wxClientDC temp_dc(this); m_smallest_unminimised_size = m_art->GetPanelSize(temp_dc, this, minimum_children_size, NULL); wxSize bitmap_size; wxSize panel_min_size = GetMinNotMinimisedSize(); m_minimised_size = m_art->GetMinimisedPanelMinimumSize(temp_dc, this, &bitmap_size, &m_preferred_expand_direction); if(m_minimised_icon.IsOk() && m_minimised_icon.GetSize() != bitmap_size) { wxImage img(m_minimised_icon.ConvertToImage()); img.Rescale(bitmap_size.GetWidth(), bitmap_size.GetHeight(), wxIMAGE_QUALITY_HIGH); m_minimised_icon_resized = wxBitmap(img); } else { m_minimised_icon_resized = m_minimised_icon; } if(m_minimised_size.x > panel_min_size.x && m_minimised_size.y > panel_min_size.y) { // No point in having a minimised size which is larger than the // minimum size which the children can go to. m_minimised_size = wxSize(-1, -1); } else { if(m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL) { m_minimised_size.x = panel_min_size.x; } else { m_minimised_size.y = panel_min_size.y; } } } else { m_minimised_size = wxSize(-1, -1); } return Layout() && status; }