// Author: Peter Cawley
// Modified by:
// Created: 2009-05-25
-// RCS-ID: $Id$
// Copyright: (C) Peter Cawley
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#pragma hdrstop
#endif
-#include "wx/ribbon/page.h"
-
#if wxUSE_RIBBON
+#include "wx/ribbon/page.h"
#include "wx/ribbon/art.h"
#include "wx/ribbon/bar.h"
#include "wx/dcbuffer.h"
{
case wxRIBBON_SCROLL_BTN_DOWN:
case wxRIBBON_SCROLL_BTN_RIGHT:
- m_sibling->ScrollLines(1);
+ m_sibling->ScrollSections(1);
break;
case wxRIBBON_SCROLL_BTN_UP:
case wxRIBBON_SCROLL_BTN_LEFT:
- m_sibling->ScrollLines(-1);
+ m_sibling->ScrollSections(-1);
break;
default:
break;
return true;
}
+bool wxRibbonPage::ScrollSections(int sections)
+{
+ // Currently the only valid values are -1 and 1 for scrolling left and
+ // right, respectively.
+ const bool scrollForward = sections >= 1;
+
+ // Determine by how many pixels to scroll. If something on the page
+ // is partially visible, scroll to make it fully visible. Otherwise
+ // find the next item that will become visible and scroll to make it
+ // fully visible. The ScrollPixel call will correct if we scroll too
+ // much if the available width is smaller than the items.
+
+ // Scroll at minimum the same amount as ScrollLines(1):
+ int minscroll = sections * 8;
+ // How many pixels to scroll:
+ int pixels = 0;
+
+ // Determine the scroll position, that is, the page border where items
+ // are appearing.
+ int scrollpos = 0;
+
+ wxOrientation major_axis = GetMajorAxis();
+ int gap = 0;
+
+ int width = 0;
+ int height = 0;
+ int x = 0;
+ int y = 0;
+ GetSize(&width, &height);
+ GetPosition(&x, &y);
+ if(major_axis == wxHORIZONTAL)
+ {
+ gap = m_art->GetMetric(wxRIBBON_ART_PANEL_X_SEPARATION_SIZE);
+ if (scrollForward)
+ {
+ scrollpos = width - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE);
+ }
+ else
+ {
+ scrollpos = m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE);
+ }
+ }
+ else
+ {
+ gap = m_art->GetMetric(wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE);
+ if (scrollForward)
+ {
+ scrollpos = width - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE);
+ }
+ else
+ {
+ scrollpos = m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_TOP_SIZE);
+ }
+ }
+
+ // Find the child that is partially shown or just beyond the scroll position
+ for(wxWindowList::compatibility_iterator
+ node = scrollForward ? GetChildren().GetFirst()
+ : GetChildren().GetLast();
+ node;
+ node = scrollForward ? node->GetNext()
+ : node->GetPrevious())
+ {
+ wxWindow* child = node->GetData();
+ child->GetSize(&width, &height);
+ child->GetPosition(&x, &y);
+ int pos0 = 0;
+ int pos1 = 0;
+ if (major_axis == wxHORIZONTAL)
+ {
+ pos0 = x;
+ pos1 = x + width + gap;
+ }
+ else
+ {
+ pos0 = y;
+ pos1 = y + height + gap;
+ }
+ if (scrollpos >= pos0 && scrollpos <= pos1)
+ {
+ // This section is partially visible, scroll to make it fully visible.
+ if (scrollForward)
+ {
+ pixels += pos1 - scrollpos;
+ }
+ else
+ {
+ pixels += pos0 - scrollpos;
+ }
+ if (abs(pixels) >= abs(minscroll))
+ break;
+ }
+ if (scrollpos <= pos0 && scrollForward)
+ {
+ // This section is next, scroll the entire section width
+ pixels += (pos1 - pos0);
+ break;
+ }
+ if (scrollpos >= pos1 && !scrollForward)
+ {
+ // This section is next, scroll the entire section width
+ pixels += (pos0 - pos1);
+ break;
+ }
+ }
+ // Do a final safety sanity check, should not be necessary, but will not hurt either.
+ if (pixels == 0)
+ {
+ pixels = minscroll;
+ }
+ if (pixels * minscroll < 0)
+ {
+ pixels = -pixels;
+ }
+
+ return ScrollPixels(pixels);
+}
+
void wxRibbonPage::SetSizeWithScrollButtonAdjustment(int x, int y, int width, int height)
{
if(m_scroll_buttons_visible)
}
}
}
+ if (width < 0) width = 0;
+ if (height < 0) height = 0;
SetSize(x, y, width, height);
}
// When a resize triggers the scroll buttons to become visible, the page is resized.
// This resize from within a resize event can cause (MSW) wxWidgets some confusion,
// and report the 1st size to the 2nd size event. Hence the most recent size is
- // remembered internally and used in Layout() where appropiate.
+ // remembered internally and used in Layout() where appropriate.
if(GetMajorAxis() == wxHORIZONTAL)
{
{
wxSize new_size = evt.GetSize();
- wxMemoryDC temp_dc;
- wxRect invalid_rect = m_art->GetPageBackgroundRedrawArea(temp_dc, this, m_old_size, new_size);
- Refresh(true, &invalid_rect);
+ if (m_art)
+ {
+ wxMemoryDC temp_dc;
+ wxRect invalid_rect = m_art->GetPageBackgroundRedrawArea(temp_dc, this, m_old_size, new_size);
+ Refresh(true, &invalid_rect);
+ }
m_old_size = new_size;
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)();
}
}
ShowScrollButtons();
else if(todo_hide_scroll_buttons)
HideScrollButtons();
+ else if(m_scroll_buttons_visible)
+ ShowScrollButtons();
Refresh();
return true;
if(show_left)
{
- if(m_scroll_left_btn == NULL)
+ wxMemoryDC temp_dc;
+ wxSize size;
+ long direction;
+ if(GetMajorAxis() == wxHORIZONTAL)
{
- wxMemoryDC temp_dc;
- wxSize size;
- long direction;
- if(GetMajorAxis() == wxHORIZONTAL)
- {
- direction = wxRIBBON_SCROLL_BTN_LEFT;
- size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
- size.SetHeight(GetSize().GetHeight());
- }
- else
- {
- direction = wxRIBBON_SCROLL_BTN_UP;
- size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
- size.SetWidth(GetSize().GetWidth());
- }
- m_scroll_left_btn = new wxRibbonPageScrollButton(this, wxID_ANY, GetPosition(), size, direction);
- if(!IsShown())
- {
- m_scroll_left_btn->Hide();
- }
- reposition = true;
+ direction = wxRIBBON_SCROLL_BTN_LEFT;
+ size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
+ size.SetHeight(GetSize().GetHeight());
+ }
+ else
+ {
+ direction = wxRIBBON_SCROLL_BTN_UP;
+ size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
+ size.SetWidth(GetSize().GetWidth());
+ }
+ if (m_scroll_left_btn)
+ {
+ m_scroll_left_btn->SetSize(size);
+ }
+ else
+ {
+ m_scroll_left_btn = new wxRibbonPageScrollButton(this, wxID_ANY, GetPosition(), size, direction);
+ reposition = true;
+ }
+ if(!IsShown())
+ {
+ m_scroll_left_btn->Hide();
}
}
else
if(show_right)
{
- if(m_scroll_right_btn == NULL)
+ wxMemoryDC temp_dc;
+ wxSize size;
+ long direction;
+ if(GetMajorAxis() == wxHORIZONTAL)
{
- wxMemoryDC temp_dc;
- wxSize size;
- long direction;
- if(GetMajorAxis() == wxHORIZONTAL)
- {
- direction = wxRIBBON_SCROLL_BTN_RIGHT;
- size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
- size.SetHeight(GetSize().GetHeight());
- }
- else
- {
- direction = wxRIBBON_SCROLL_BTN_DOWN;
- size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
- size.SetWidth(GetSize().GetWidth());
- }
- wxPoint initial_pos = GetPosition() + GetSize() - size;
- m_scroll_right_btn = new wxRibbonPageScrollButton(this, wxID_ANY, initial_pos, size, direction);
- if(!IsShown())
- {
- m_scroll_right_btn->Hide();
- }
- reposition = true;
+ direction = wxRIBBON_SCROLL_BTN_RIGHT;
+ size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
+ size.SetHeight(GetSize().GetHeight());
+ }
+ else
+ {
+ direction = wxRIBBON_SCROLL_BTN_DOWN;
+ size = m_art->GetScrollButtonMinimumSize(temp_dc, GetParent(), direction);
+ size.SetWidth(GetSize().GetWidth());
+ }
+ wxPoint initial_pos = GetPosition() + GetSize() - size;
+ if (m_scroll_right_btn)
+ {
+ m_scroll_right_btn->SetSize(size);
+ }
+ else
+ {
+ m_scroll_right_btn = new wxRibbonPageScrollButton(this, wxID_ANY, initial_pos, size, direction);
+ reposition = true;
+ }
+ if(!IsShown())
+ {
+ m_scroll_right_btn->Hide();
}
}
else
{
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)
return best;
}
+void wxRibbonPage::HideIfExpanded()
+{
+ wxStaticCast(m_parent, wxRibbonBar)->HideIfExpanded();
+}
+
#endif // wxUSE_RIBBON