Added wxRIBBON_PANEL_FLEXIBLE flag to allow toolbars to wrap, taking up the optimum amount of space when used in a vertical palette.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70885 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
4f134f0cf8
commit
98742322cd
@ -55,6 +55,9 @@ public:
|
||||
virtual bool Realize();
|
||||
bool Realise() {return Realize();}
|
||||
|
||||
// Finds the best width and height given the parent's width and height
|
||||
virtual wxSize GetBestSizeForParentSize(const wxSize& WXUNUSED(parentSize)) const { return GetBestSize(); }
|
||||
|
||||
protected:
|
||||
wxRibbonArtProvider* m_art;
|
||||
|
||||
|
@ -24,6 +24,7 @@ enum wxRibbonPanelOption
|
||||
wxRIBBON_PANEL_EXT_BUTTON = 1 << 3,
|
||||
wxRIBBON_PANEL_MINIMISE_BUTTON = 1 << 4,
|
||||
wxRIBBON_PANEL_STRETCH = 1 << 5,
|
||||
wxRIBBON_PANEL_FLEXIBLE = 1 << 6,
|
||||
|
||||
wxRIBBON_PANEL_DEFAULT_STYLE = 0
|
||||
};
|
||||
@ -75,6 +76,11 @@ public:
|
||||
wxRibbonPanel* GetExpandedDummy();
|
||||
wxRibbonPanel* GetExpandedPanel();
|
||||
|
||||
// Finds the best width and height given the parent's width and height
|
||||
virtual wxSize GetBestSizeForParentSize(const wxSize& parentSize) const;
|
||||
|
||||
long GetFlags() { return m_flags; }
|
||||
|
||||
protected:
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
virtual wxSize GetPanelSizerBestSize() const;
|
||||
|
@ -155,6 +155,9 @@ public:
|
||||
virtual void EnableTool(int tool_id, bool enable = true);
|
||||
virtual void ToggleTool(int tool_id, bool checked);
|
||||
|
||||
// Finds the best width and height given the parent's width and height
|
||||
virtual wxSize GetBestSizeForParentSize(const wxSize& parentSize) const;
|
||||
|
||||
protected:
|
||||
friend class wxRibbonToolBarEvent;
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
@ -13,7 +13,7 @@
|
||||
ribbon characteristics of having a ribbon art provider, and (optionally)
|
||||
non-continuous resizing. Despite what the name may imply, it is not the
|
||||
top-level control for creating a ribbon interface - that is wxRibbonBar.
|
||||
|
||||
|
||||
Ribbon controls often have a region which is "transparent", and shows the
|
||||
contents of the ribbon page or panel behind it. If implementing a new
|
||||
ribbon control, then it may be useful to realise that this effect is done
|
||||
@ -36,7 +36,7 @@ public:
|
||||
|
||||
/**
|
||||
Constructor.
|
||||
|
||||
|
||||
If @a parent is a wxRibbonControl with a non-NULL art provider, then
|
||||
the art provider of new control is set to that of @a parent.
|
||||
*/
|
||||
@ -50,12 +50,12 @@ public:
|
||||
Set the art provider to be used. In many cases, setting the art provider
|
||||
will also set the art provider on all child windows which extend
|
||||
wxRibbonControl.
|
||||
|
||||
|
||||
In most cases, controls will not take ownership of the given pointer,
|
||||
with the notable exception being wxRibbonBar::SetArtProvider().
|
||||
*/
|
||||
virtual void SetArtProvider(wxRibbonArtProvider* art);
|
||||
|
||||
|
||||
/**
|
||||
Get the art provider to be used. Note that until an art provider has
|
||||
been set in some way, this function may return NULL.
|
||||
@ -65,31 +65,31 @@ public:
|
||||
/**
|
||||
@return @true if this window can take any size (greater than its minimum
|
||||
size), @false if it can only take certain sizes.
|
||||
|
||||
|
||||
@see GetNextSmallerSize()
|
||||
@see GetNextLargerSize()
|
||||
*/
|
||||
virtual bool IsSizingContinuous() const;
|
||||
|
||||
|
||||
/**
|
||||
If sizing is not continuous, then return a suitable size for the control
|
||||
which is smaller than the current size.
|
||||
|
||||
|
||||
@param direction
|
||||
The direction(s) in which the size should reduce.
|
||||
@return
|
||||
The current size if there is no smaller size, otherwise a suitable
|
||||
size which is smaller in the given direction(s), and the same as the
|
||||
current size in the other direction (if any).
|
||||
|
||||
|
||||
@see IsSizingContinuous()
|
||||
*/
|
||||
wxSize GetNextSmallerSize(wxOrientation direction) const;
|
||||
|
||||
|
||||
/**
|
||||
If sizing is not continuous, then return a suitable size for the control
|
||||
which is smaller than the given size.
|
||||
|
||||
|
||||
@param direction
|
||||
The direction(s) in which the size should reduce.
|
||||
@param relative_to
|
||||
@ -98,31 +98,31 @@ public:
|
||||
@a relative_to if there is no smaller size, otherwise a suitable
|
||||
size which is smaller in the given direction(s), and the same as
|
||||
@a relative_to in the other direction (if any).
|
||||
|
||||
|
||||
@see IsSizingContinuous()
|
||||
@see DoGetNextSmallerSize()
|
||||
*/
|
||||
wxSize GetNextSmallerSize(wxOrientation direction, wxSize relative_to) const;
|
||||
|
||||
|
||||
/**
|
||||
If sizing is not continuous, then return a suitable size for the control
|
||||
which is larger than the current size.
|
||||
|
||||
|
||||
@param direction
|
||||
The direction(s) in which the size should increase.
|
||||
@return
|
||||
The current size if there is no larger size, otherwise a suitable
|
||||
size which is larger in the given direction(s), and the same as the
|
||||
current size in the other direction (if any).
|
||||
|
||||
|
||||
@see IsSizingContinuous()
|
||||
*/
|
||||
wxSize GetNextLargerSize(wxOrientation direction) const;
|
||||
|
||||
|
||||
/**
|
||||
If sizing is not continuous, then return a suitable size for the control
|
||||
which is larger than the given size.
|
||||
|
||||
|
||||
@param direction
|
||||
The direction(s) in which the size should increase.
|
||||
@param relative_to
|
||||
@ -131,23 +131,28 @@ public:
|
||||
@a relative_to if there is no larger size, otherwise a suitable
|
||||
size which is larger in the given direction(s), and the same as
|
||||
@a relative_to in the other direction (if any).
|
||||
|
||||
|
||||
@see IsSizingContinuous()
|
||||
@see DoGetNextLargerSize()
|
||||
*/
|
||||
wxSize GetNextLargerSize(wxOrientation direction, wxSize relative_to) const;
|
||||
|
||||
|
||||
/**
|
||||
Perform initial size and layout calculations after children have been
|
||||
added, and/or realize children.
|
||||
*/
|
||||
virtual bool Realize();
|
||||
|
||||
|
||||
/**
|
||||
Alias for Realize().
|
||||
*/
|
||||
bool Realise();
|
||||
|
||||
|
||||
/**
|
||||
Finds the best width and height given the parent's width and height.
|
||||
Used to implement the wxRIBBON_PANEL_FLEXIBLE panel style.
|
||||
*/
|
||||
virtual wxSize GetBestSizeForParentSize(const wxSize& parentSize) const;
|
||||
protected:
|
||||
/**
|
||||
Implementation of GetNextSmallerSize().
|
||||
|
@ -45,6 +45,12 @@
|
||||
minimises.
|
||||
@style{wxRIBBON_PANEL_STRETCH}
|
||||
Stretches a single panel to fit the parent page.
|
||||
@style{wxRIBBON_PANEL_FLEXIBLE}
|
||||
Allows the panel to size in both directions; currently only useful
|
||||
when a single wxRibbonToolBar is the child of the panel, particularly
|
||||
in vertical orientation where the number of rows is dependent on the
|
||||
amount of horizontal space available. Set the minimum and maximum
|
||||
toolbar rows to take full advantage of this wrapping behaviour.
|
||||
@endStyleTable
|
||||
|
||||
@library{wxribbon}
|
||||
|
@ -495,19 +495,30 @@ bool wxRibbonPage::Realize()
|
||||
|
||||
void wxRibbonPage::PopulateSizeCalcArray(wxSize (wxWindow::*get_size)(void) const)
|
||||
{
|
||||
wxSize parentSize = GetSize();
|
||||
parentSize.x -= m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE);
|
||||
parentSize.x -= m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE);
|
||||
parentSize.y -= m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_TOP_SIZE);
|
||||
parentSize.y -= m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE);
|
||||
|
||||
if(m_size_calc_array_size != GetChildren().GetCount())
|
||||
{
|
||||
delete[] m_size_calc_array;
|
||||
m_size_calc_array_size = GetChildren().GetCount();
|
||||
m_size_calc_array = new wxSize[m_size_calc_array_size];
|
||||
}
|
||||
|
||||
wxSize* node_size = m_size_calc_array;
|
||||
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
|
||||
node;
|
||||
node = node->GetNext(), ++node_size )
|
||||
{
|
||||
wxWindow* child = node->GetData();
|
||||
*node_size = (child->*get_size)();
|
||||
wxRibbonPanel* panel = wxDynamicCast(child, wxRibbonPanel);
|
||||
if (panel && panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE)
|
||||
*node_size = panel->GetBestSizeForParentSize(parentSize);
|
||||
else
|
||||
*node_size = (child->*get_size)();
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,7 +787,12 @@ bool wxRibbonPage::ExpandPanels(wxOrientation direction, int maximum_amount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(panel->IsSizingContinuous())
|
||||
if (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE)
|
||||
{
|
||||
// Don't change if it's flexible since we already calculated the
|
||||
// correct size for the panel.
|
||||
}
|
||||
else if(panel->IsSizingContinuous())
|
||||
{
|
||||
int size = GetSizeInOrientation(*panel_size, direction);
|
||||
if(size < smallest_size)
|
||||
|
@ -311,6 +311,24 @@ bool wxRibbonPanel::IsSizingContinuous() const
|
||||
return (m_flags & wxRIBBON_PANEL_STRETCH) != 0;
|
||||
}
|
||||
|
||||
// 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 childSize = control->GetBestSizeForParentSize(parentSize);
|
||||
wxSize overallSize = m_art->GetPanelSize(temp_dc, this, childSize, NULL);
|
||||
return overallSize;
|
||||
}
|
||||
}
|
||||
return GetSize();
|
||||
}
|
||||
|
||||
wxSize wxRibbonPanel::DoGetNextSmallerSize(wxOrientation direction,
|
||||
wxSize relative_to) const
|
||||
{
|
||||
@ -742,6 +760,13 @@ bool wxRibbonPanel::ShowExpanded()
|
||||
}
|
||||
|
||||
wxSize size = GetBestSize();
|
||||
|
||||
// Special case for flexible panel layout, where GetBestSize doesn't work
|
||||
if (GetFlags() & wxRIBBON_PANEL_FLEXIBLE)
|
||||
{
|
||||
size = GetBestSizeForParentSize(wxSize(400, 1000));
|
||||
}
|
||||
|
||||
wxPoint pos = GetExpandedPosition(wxRect(GetScreenPosition(), GetSize()),
|
||||
size, m_preferred_expand_direction).GetTopLeft();
|
||||
|
||||
@ -750,7 +775,7 @@ bool wxRibbonPanel::ShowExpanded()
|
||||
pos, size, wxFRAME_NO_TASKBAR | wxBORDER_NONE);
|
||||
|
||||
m_expanded_panel = new wxRibbonPanel(container, wxID_ANY,
|
||||
GetLabel(), m_minimised_icon, wxPoint(0, 0), size, m_flags);
|
||||
GetLabel(), m_minimised_icon, wxPoint(0, 0), size, (m_flags /* & ~wxRIBBON_PANEL_FLEXIBLE */));
|
||||
|
||||
m_expanded_panel->SetArtProvider(m_art);
|
||||
m_expanded_panel->m_expanded_dummy = this;
|
||||
|
@ -781,7 +781,21 @@ bool wxRibbonToolBar::Realize()
|
||||
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)
|
||||
@ -809,11 +823,28 @@ bool wxRibbonToolBar::Realize()
|
||||
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);
|
||||
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;
|
||||
|
||||
@ -834,6 +865,20 @@ void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
|
||||
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;
|
||||
@ -844,6 +889,7 @@ void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
|
||||
{
|
||||
area = GetSizeInOrientation(m_sizes[i], major_axis);
|
||||
row_count = m_nrows_min + i;
|
||||
bestSize = m_sizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -895,6 +941,41 @@ void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
|
||||
delete[] row_sizes;
|
||||
}
|
||||
|
||||
// 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;
|
||||
int row_count = m_nrows_max;
|
||||
wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
|
||||
wxVERTICAL : wxHORIZONTAL;
|
||||
|
||||
// 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.
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestSize;
|
||||
}
|
||||
|
||||
wxSize wxRibbonToolBar::DoGetBestSize() const
|
||||
{
|
||||
return GetMinSize();
|
||||
|
Loading…
Reference in New Issue
Block a user