// Finds the best width and height given the parents' width and height wxSize wxRibbonToolBar::GetBestSizeForParentSize(const wxSize& parentSize) const { if (!m_sizes) return GetMinSize(); // Choose row count with largest possible area wxSize size = parentSize; // A toolbar should maximize its width whether vertical or horizontal, so // force the major axis to be horizontal. Without this, there will be // redundant horizontal space. wxOrientation major_axis = wxHORIZONTAL; wxSize bestSize = m_sizes[0]; if(m_nrows_max != m_nrows_min) { int area = 0; for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i) { if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y && GetSizeInOrientation(m_sizes[i], major_axis) > area) { area = GetSizeInOrientation(m_sizes[i], major_axis); bestSize = m_sizes[i]; } } } return bestSize; }
wxSize wxRibbonToolBar::DoGetNextLargerSize(wxOrientation direction, wxSize relative_to) const { // Pick the smallest of our sizes which are larger than the given size wxSize result(relative_to); int area = INT_MAX; int nrows; for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows) { wxSize size(m_sizes[nrows - m_nrows_min]); wxSize original(size); switch(direction) { case wxHORIZONTAL: if(size.GetWidth() > relative_to.GetWidth() && size.GetHeight() <= relative_to.GetHeight()) { size.SetHeight(relative_to.GetHeight()); break; } continue; case wxVERTICAL: if(size.GetWidth() <= relative_to.GetWidth() && size.GetHeight() > relative_to.GetHeight()) { size.SetWidth(relative_to.GetWidth()); break; } continue; case wxBOTH: if(size.GetWidth() > relative_to.GetWidth() && size.GetHeight() > relative_to.GetHeight()) { break; } continue; } if(GetSizeInOrientation(original, direction) < area) { result = size; area = GetSizeInOrientation(original, direction); } } return result; }
void wxRibbonToolBar::OnSize(wxSizeEvent& evt) { if(m_art == NULL) return; // Choose row count with largest possible area wxSize size = evt.GetSize(); int row_count = m_nrows_max; wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ? wxVERTICAL : wxHORIZONTAL; if(m_nrows_max != m_nrows_min) { int area = 0; for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i) { if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y && GetSizeInOrientation(m_sizes[i], major_axis) > area) { area = GetSizeInOrientation(m_sizes[i], major_axis); row_count = m_nrows_min + i; } } } // Assign groups to rows and calculate row widths wxSize* row_sizes = new wxSize[row_count]; int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE); int r; for(r = 0; r < row_count; ++r) row_sizes[r] = wxSize(0, 0); size_t g; size_t group_count = m_groups.GetCount(); for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); int shortest_row = 0; for(r = 1; r < row_count; ++r) { if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth()) shortest_row = r; } group->position = wxPoint(row_sizes[shortest_row].x, shortest_row); row_sizes[shortest_row].x += group->size.x + sep; if(group->size.y > row_sizes[shortest_row].y) row_sizes[shortest_row].y = group->size.y; } // Calculate row positions int total_height = 0; for(r = 0; r < row_count; ++r) total_height += row_sizes[r].GetHeight(); int rowsep = (size.GetHeight() - total_height) / (row_count + 1); int* rowypos = new int[row_count]; rowypos[0] = rowsep; for(r = 1; r < row_count; ++r) { rowypos[r] = rowypos[r - 1] + row_sizes[r - 1].GetHeight() + rowsep; } // Set group y positions for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); group->position.y = rowypos[group->position.y]; } delete[] rowypos; delete[] row_sizes; }
bool wxRibbonToolBar::Realize() { if(m_art == NULL) return false; // Calculate the size of each group and the position/size of each tool wxMemoryDC temp_dc; size_t group_count = m_groups.GetCount(); size_t g, t; for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolBase* prev = NULL; wxRibbonToolBarToolGroup* group = m_groups.Item(g); size_t tool_count = group->tools.GetCount(); int tallest = 0; for(t = 0; t < tool_count; ++t) { wxRibbonToolBarToolBase* tool = group->tools.Item(t); tool->size = m_art->GetToolSize(temp_dc, this, tool->bitmap.GetSize(), tool->kind, t == 0, t == (tool_count - 1), &tool->dropdown); if(t == 0) tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST; if(t == tool_count - 1) tool->state |= wxRIBBON_TOOLBAR_TOOL_LAST; if(tool->size.GetHeight() > tallest) tallest = tool->size.GetHeight(); if(prev) { tool->position = prev->position; tool->position.x += prev->size.x; } else { tool->position = wxPoint(0, 0); } prev = tool; } if(tool_count == 0) group->size = wxSize(0, 0); else { group->size = wxSize(prev->position.x + prev->size.x, tallest); for(t = 0; t < tool_count; ++t) group->tools.Item(t)->size.SetHeight(tallest); } } // Calculate the minimum size for each possible number of rows int nrows, r; int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE); int smallest_area = INT_MAX; wxSize* row_sizes = new wxSize[m_nrows_max]; wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ? wxVERTICAL : wxHORIZONTAL; SetMinSize(wxSize(0, 0)); for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows) { for(r = 0; r < nrows; ++r) row_sizes[r] = wxSize(0, 0); for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); int shortest_row = 0; for(r = 1; r < nrows; ++r) { if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth()) shortest_row = r; } row_sizes[shortest_row].x += group->size.x + sep; if(group->size.y > row_sizes[shortest_row].y) row_sizes[shortest_row].y = group->size.y; } wxSize size(0, 0); for(r = 0; r < nrows; ++r) { if(row_sizes[r].GetWidth() != 0) row_sizes[r].DecBy(sep, 0); if(row_sizes[r].GetWidth() > size.GetWidth()) size.SetWidth(row_sizes[r].GetWidth()); size.IncBy(0, row_sizes[r].y); } m_sizes[nrows - m_nrows_min] = size; if(GetSizeInOrientation(size, major_axis) < smallest_area) { SetMinSize(size); smallest_area = GetSizeInOrientation(size, major_axis); } } delete[] row_sizes; // Position the groups wxSizeEvent dummy_event(GetSize()); OnSize(dummy_event); return true; }
void wxRibbonToolBar::OnSize(wxSizeEvent& evt) { if(m_art == NULL) return; // Choose row count with largest possible area wxSize size = evt.GetSize(); int row_count = m_nrows_max; wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ? wxVERTICAL : wxHORIZONTAL; // See if we're sizing flexibly, and set min size differently bool sizingFlexibly = false; wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel); if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE)) sizingFlexibly = true; // Without this, there will be redundant horizontal space because SetMinSize will // use the smallest possible height (and therefore largest width). if (sizingFlexibly) major_axis = wxHORIZONTAL; wxSize bestSize = m_sizes[0]; if(m_nrows_max != m_nrows_min) { int area = 0; for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i) { if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y && GetSizeInOrientation(m_sizes[i], major_axis) > area) { area = GetSizeInOrientation(m_sizes[i], major_axis); row_count = m_nrows_min + i; bestSize = m_sizes[i]; } } } // Assign groups to rows and calculate row widths wxSize* row_sizes = new wxSize[row_count]; int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE); int r; for(r = 0; r < row_count; ++r) row_sizes[r] = wxSize(0, 0); size_t g; size_t group_count = m_groups.GetCount(); for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); int shortest_row = 0; for(r = 1; r < row_count; ++r) { if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth()) shortest_row = r; } group->position = wxPoint(row_sizes[shortest_row].x, shortest_row); row_sizes[shortest_row].x += group->size.x + sep; if(group->size.y > row_sizes[shortest_row].y) row_sizes[shortest_row].y = group->size.y; } // Calculate row positions int total_height = 0; for(r = 0; r < row_count; ++r) total_height += row_sizes[r].GetHeight(); int rowsep = (size.GetHeight() - total_height) / (row_count + 1); int* rowypos = new int[row_count]; rowypos[0] = rowsep; for(r = 1; r < row_count; ++r) { rowypos[r] = rowypos[r - 1] + row_sizes[r - 1].GetHeight() + rowsep; } // Set group y positions for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); group->position.y = rowypos[group->position.y]; } delete[] rowypos; delete[] row_sizes; }
bool wxRibbonToolBar::Realize() { if(m_art == NULL) return false; // Calculate the size of each group and the position/size of each tool wxMemoryDC temp_dc; size_t group_count = m_groups.GetCount(); size_t g, t; for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolBase* prev = NULL; wxRibbonToolBarToolGroup* group = m_groups.Item(g); size_t tool_count = group->tools.GetCount(); int tallest = 0; for(t = 0; t < tool_count; ++t) { wxRibbonToolBarToolBase* tool = group->tools.Item(t); tool->size = m_art->GetToolSize(temp_dc, this, tool->bitmap.GetSize(), tool->kind, t == 0, t == (tool_count - 1), &tool->dropdown); if(t == 0) tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST; if(t == tool_count - 1) tool->state |= wxRIBBON_TOOLBAR_TOOL_LAST; if(tool->size.GetHeight() > tallest) tallest = tool->size.GetHeight(); if(prev) { tool->position = prev->position; tool->position.x += prev->size.x; } else { tool->position = wxPoint(0, 0); } prev = tool; } if(tool_count == 0) group->size = wxSize(0, 0); else { group->size = wxSize(prev->position.x + prev->size.x, tallest); for(t = 0; t < tool_count; ++t) group->tools.Item(t)->size.SetHeight(tallest); } } // Calculate the minimum size for each possible number of rows int nrows, r; int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE); int smallest_area = INT_MAX; wxSize* row_sizes = new wxSize[m_nrows_max]; wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ? wxVERTICAL : wxHORIZONTAL; SetMinSize(wxSize(0, 0)); wxSize minSize(INT_MAX, INT_MAX); // See if we're sizing flexibly (i.e. wrapping), and set min size differently bool sizingFlexibly = false; wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel); if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE)) sizingFlexibly = true; // Without this, there will be redundant horizontal space because SetMinSize will // use the smallest possible height (and therefore largest width). if (sizingFlexibly) major_axis = wxHORIZONTAL; for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows) { for(r = 0; r < nrows; ++r) row_sizes[r] = wxSize(0, 0); for(g = 0; g < group_count; ++g) { wxRibbonToolBarToolGroup* group = m_groups.Item(g); int shortest_row = 0; for(r = 1; r < nrows; ++r) { if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth()) shortest_row = r; } row_sizes[shortest_row].x += group->size.x + sep; if(group->size.y > row_sizes[shortest_row].y) row_sizes[shortest_row].y = group->size.y; } wxSize size(0, 0); for(r = 0; r < nrows; ++r) { if(row_sizes[r].GetWidth() != 0) row_sizes[r].DecBy(sep, 0); if(row_sizes[r].GetWidth() > size.GetWidth()) size.SetWidth(row_sizes[r].GetWidth()); size.IncBy(0, row_sizes[r].y); } m_sizes[nrows - m_nrows_min] = size; if(GetSizeInOrientation(size, major_axis) < smallest_area) { smallest_area = GetSizeInOrientation(size, major_axis); SetMinSize(size); } if (sizingFlexibly) { if (size.x < minSize.x) minSize.x = size.x; if (size.y < minSize.y) minSize.y = size.y; } } if (sizingFlexibly) { // Give it the min size in either direction regardless of row, // so that we're able to vary the size of the panel according to // the space the toolbar takes up. SetMinSize(minSize); } delete[] row_sizes; // Position the groups wxSizeEvent dummy_event(GetSize()); OnSize(dummy_event); return true; }