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; }
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; }