#ifdef __WXMAC__
#include "wx/osx/private.h"
-// for themeing support
-#include <Carbon/Carbon.h>
#endif
#include "wx/arrimpl.cpp"
m_gripper_pen2 = wxPen(darker3_colour);
m_gripper_pen3 = *wxWHITE_PEN;
- static unsigned char button_dropdown_bits[] = { 0xe0, 0xf1, 0xfb };
- static unsigned char overflow_bits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 };
+ static const unsigned char button_dropdown_bits[] = { 0xe0, 0xf1, 0xfb };
+ static const unsigned char overflow_bits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 };
m_button_dropdown_bmp = wxAuiBitmapFromBits(button_dropdown_bits, 5, 3,
*wxBLACK);
+static wxOrientation GetOrientation(long& style)
+{
+ switch (style & wxAUI_ORIENTATION_MASK)
+ {
+ case wxAUI_TB_HORIZONTAL:
+ return wxHORIZONTAL;
+ case wxAUI_TB_VERTICAL:
+ return wxVERTICAL;
+ default:
+ wxFAIL_MSG("toolbar cannot be locked in both horizontal and vertical orientations (maybe no lock was intended?)");
+ // fall through
+ case 0:
+ return wxBOTH;
+ }
+}
+
BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl)
EVT_SIZE(wxAuiToolBar::OnSize)
EVT_IDLE(wxAuiToolBar::OnIdle)
m_gripper_sizer_item = NULL;
m_overflow_sizer_item = NULL;
m_dragging = false;
+ m_orientation = GetOrientation(style);
+ if (m_orientation == wxBOTH)
+ {
+ m_orientation = wxHORIZONTAL;
+ }
m_style = style | wxBORDER_NONE;
m_gripper_visible = (m_style & wxAUI_TB_GRIPPER) ? true : false;
m_overflow_visible = (m_style & wxAUI_TB_OVERFLOW) ? true : false;
m_overflow_state = 0;
SetMargins(5, 5, 2, 2);
SetFont(*wxNORMAL_FONT);
- m_art->SetFlags((unsigned int)m_style);
+ SetArtFlags();
SetExtraStyle(wxWS_EX_PROCESS_IDLE);
if (style & wxAUI_TB_HORZ_LAYOUT)
SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}
void wxAuiToolBar::SetWindowStyleFlag(long style)
{
+ GetOrientation(style); // assert if style is invalid
+ wxCHECK_RET(IsPaneValid(style),
+ "window settings and pane settings are incompatible");
+
wxControl::SetWindowStyleFlag(style);
m_style = style;
if (m_art)
{
- m_art->SetFlags((unsigned int)m_style);
+ SetArtFlags();
}
if (m_style & wxAUI_TB_GRIPPER)
if (m_art)
{
- m_art->SetFlags((unsigned int)m_style);
+ SetArtFlags();
m_art->SetTextOrientation(m_tool_text_orientation);
}
}
}
-void wxAuiToolBar::SetOrientation(int WXUNUSED(orientation))
+void wxAuiToolBar::SetOrientation(int orientation)
{
+ wxCHECK_RET(orientation == wxHORIZONTAL ||
+ orientation == wxVERTICAL,
+ "invalid orientation value");
+ if (orientation != m_orientation)
+ {
+ m_orientation = wxOrientation(orientation);
+ SetArtFlags();
+ }
}
void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom)
m_custom_overflow_append = append;
}
+// get size of hint rectangle for a particular dock location
+wxSize wxAuiToolBar::GetHintSize(int dock_direction) const
+{
+ switch (dock_direction)
+ {
+ case wxAUI_DOCK_TOP:
+ case wxAUI_DOCK_BOTTOM:
+ return m_horzHintSize;
+ case wxAUI_DOCK_RIGHT:
+ case wxAUI_DOCK_LEFT:
+ return m_vertHintSize;
+ default:
+ wxCHECK_MSG(false, wxDefaultSize, "invalid dock location value");
+ }
+}
+
+bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const
+{
+ return IsPaneValid(m_style, pane);
+}
+
+bool wxAuiToolBar::IsPaneValid(long style, const wxAuiPaneInfo& pane)
+{
+ if (style & wxAUI_TB_HORIZONTAL)
+ {
+ if (pane.IsLeftDockable() || pane.IsRightDockable())
+ {
+ return false;
+ }
+ }
+ else if (style & wxAUI_TB_VERTICAL)
+ {
+ if (pane.IsTopDockable() || pane.IsBottomDockable())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool wxAuiToolBar::IsPaneValid(long style) const
+{
+ wxAuiManager* manager = wxAuiManager::GetManager(const_cast<wxAuiToolBar*>(this));
+ if (manager)
+ {
+ return IsPaneValid(style, manager->GetPane(const_cast<wxAuiToolBar*>(this)));
+ }
+ return true;
+}
+
+void wxAuiToolBar::SetArtFlags() const
+{
+ unsigned int artflags = m_style & ~wxAUI_ORIENTATION_MASK;
+ if (m_orientation == wxVERTICAL)
+ {
+ artflags |= wxAUI_TB_VERTICAL;
+ }
+ m_art->SetFlags(artflags);
+}
size_t wxAuiToolBar::GetToolCount() const
{
wxRect rect = m_items[tool_idx].sizer_item->GetRect();
- if (m_style & wxAUI_TB_VERTICAL)
+ if (m_orientation == wxVERTICAL)
{
// take the dropdown size into account
if (m_overflow_visible)
if (!dc.IsOk())
return false;
- bool horizontal = true;
- if (m_style & wxAUI_TB_VERTICAL)
- horizontal = false;
+ // calculate hint sizes for both horizontal and vertical
+ // in the order that leaves toolbar in correct final state
+ bool retval = false;
+ if (m_orientation == wxHORIZONTAL)
+ {
+ if (RealizeHelper(dc, false))
+ {
+ m_vertHintSize = GetSize();
+ if (RealizeHelper(dc, true))
+ {
+ m_horzHintSize = GetSize();
+ retval = true;
+ }
+ }
+ }
+ else
+ {
+ if (RealizeHelper(dc, true))
+ {
+ m_horzHintSize = GetSize();
+ if (RealizeHelper(dc, false))
+ {
+ m_vertHintSize = GetSize();
+ retval = true;
+ }
+ }
+ }
+ Refresh(false);
+ return retval;
+}
+bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal)
+{
// create the new sizer to add toolbar elements to
wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL);
m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y);
}
- Refresh(false);
return true;
}
wxRect overflow_rect = m_overflow_sizer_item->GetRect();
int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
- if (m_style & wxAUI_TB_VERTICAL)
+ if (m_orientation == wxVERTICAL)
{
overflow_rect.y = cli_rect.height - overflow_size;
overflow_rect.x = 0;
int x, y;
GetClientSize(&x, &y);
- if (x > y)
- SetOrientation(wxHORIZONTAL);
- else
- SetOrientation(wxVERTICAL);
-
if (((x >= y) && m_absolute_min_size.x > x) ||
((y > x) && m_absolute_min_size.y > y))
{
Refresh(false);
Update();
+
+ // idle events aren't sent while user is resizing frame (why?),
+ // but resizing toolbar here causes havoc,
+ // so force idle handler to run after size handling complete
+ QueueEvent(new wxIdleEvent);
}
void wxAuiToolBar::OnIdle(wxIdleEvent& evt)
{
+ // if orientation doesn't match dock, fix it
+ wxAuiManager* manager = wxAuiManager::GetManager(this);
+ if (manager)
+ {
+ wxAuiPaneInfo& pane = manager->GetPane(this);
+ // pane state member is public, so it might have been changed
+ // without going through wxPaneInfo::SetFlag() check
+ bool ok = pane.IsOk();
+ wxCHECK2_MSG(!ok || IsPaneValid(m_style, pane), ok = false,
+ "window settings and pane settings are incompatible");
+ if (ok)
+ {
+ wxOrientation newOrientation = m_orientation;
+ if (pane.IsDocked())
+ {
+ switch (pane.dock_direction)
+ {
+ case wxAUI_DOCK_TOP:
+ case wxAUI_DOCK_BOTTOM:
+ newOrientation = wxHORIZONTAL;
+ break;
+ case wxAUI_DOCK_LEFT:
+ case wxAUI_DOCK_RIGHT:
+ newOrientation = wxVERTICAL;
+ break;
+ default:
+ wxFAIL_MSG("invalid dock location value");
+ }
+ }
+ else if (pane.IsResizable() &&
+ GetOrientation(m_style) == wxBOTH)
+ {
+ // changing orientation in OnSize causes havoc
+ int x, y;
+ GetClientSize(&x, &y);
+
+ if (x > y)
+ {
+ newOrientation = wxHORIZONTAL;
+ }
+ else
+ {
+ newOrientation = wxVERTICAL;
+ }
+ }
+ if (newOrientation != m_orientation)
+ {
+ SetOrientation(newOrientation);
+ Realize();
+ if (newOrientation == wxHORIZONTAL)
+ {
+ pane.best_size = GetHintSize(wxAUI_DOCK_TOP);
+ }
+ else
+ {
+ pane.best_size = GetHintSize(wxAUI_DOCK_LEFT);
+ }
+ if (pane.IsDocked())
+ {
+ pane.floating_size = wxDefaultSize;
+ }
+ else
+ {
+ SetSize(GetParent()->GetClientSize());
+ }
+ manager->Update();
+ }
+ }
+ }
+
DoIdleUpdate();
evt.Skip();
}
void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
- wxBufferedPaintDC dc(this);
+ wxAutoBufferedPaintDC dc(this);
wxRect cli_rect(wxPoint(0,0), GetClientSize());
- bool horizontal = true;
- if (m_style & wxAUI_TB_VERTICAL)
- horizontal = false;
+ bool horizontal = m_orientation == wxHORIZONTAL;
m_art->DrawBackground(dc, this, cli_rect);