///////////////////////////////////////////////////////////////////////////// // Name: drawer.cpp // Purpose: Drawer child window classes. // Drawer windows appear under their parent window and // behave like a drawer, opening and closing to reveal // content that does not need to be visible at all times. // Author: Jason Bagley // Modified by: Ryan Norton (To make it work :), plus bug fixes) // Created: 2004-30-01 // RCS-ID: $Id: drawer.cpp 35650 2005-09-23 12:56:45Z MR $ // Copyright: (c) Jason Bagley; Art & Logic, Inc. // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #include "wx/wxprec.h" #include "wx/mac/private.h" #if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 ) #include "wx/mac/carbon/drawer.h" IMPLEMENT_DYNAMIC_CLASS(wxDrawerWindow, wxWindow) // Use constants for now. // These can be made into member variables and set dynamically. const int kLeadingOffset = 20; const int kTrailingOffset = 20; // Converts Mac window edge constants to wxDirections, wxLEFT, wxRIGHT, etc. static wxDirection WindowEdgeToDirection(OptionBits edge); // Convert wxDirections to MAc window edge constants. static OptionBits DirectionToWindowEdge(wxDirection direction); wxDrawerWindow::wxDrawerWindow() { } wxDrawerWindow::~wxDrawerWindow() { m_isBeingDeleted = TRUE; this->Show(FALSE); } bool wxDrawerWindow::Create(wxWindow *parent, wxWindowID id, const wxString& title, wxSize size, wxDirection edge, const wxString& name) { wxASSERT_MSG(NULL != parent, wxT("wxDrawerWindows must be attached to a parent window.")); // Constrain the drawer size to the parent window. const wxSize parentSize(parent->GetClientSize()); if (wxLEFT == edge || wxRIGHT == edge) { if (size.GetHeight() > parentSize.GetHeight()) size.SetHeight(parentSize.GetHeight() - (kLeadingOffset + kTrailingOffset)); } else { if (size.GetWidth() > parentSize.GetWidth()) size.SetWidth(parentSize.GetWidth() - (kLeadingOffset + kTrailingOffset)); } // Create the drawer window. const wxPoint pos(0, 0); const wxSize dummySize(0,0); const long style = wxFRAME_DRAWER; bool success = wxWindow::Create(parent, id, pos, dummySize, style, name); if (success) { this->MacCreateRealWindow(title, pos, size, style, name); success = (m_macWindow != NULL); } if (success) { // Use drawer brush. m_macBackgroundBrush.MacSetTheme(kThemeBrushDrawerBackground); ::SetThemeWindowBackground((WindowRef)m_macWindow, m_macBackgroundBrush.MacGetTheme(), false); // Leading and trailing offset are gaps from parent window edges // to where the drawer starts. ::SetDrawerOffsets((WindowRef)m_macWindow, kLeadingOffset, kTrailingOffset); // Set the drawers parent. // Is there a better way to get the parent's WindowRef? wxTopLevelWindow* tlwParent = wxDynamicCast(parent, wxTopLevelWindow); if (NULL != tlwParent) { OSStatus status = ::SetDrawerParent((WindowRef)m_macWindow, (WindowRef)tlwParent->MacGetWindowRef()); success = (noErr == status); } else success = false; } return success && SetPreferredEdge(edge); } wxDirection wxDrawerWindow::GetCurrentEdge() const { const OptionBits edge = ::GetDrawerCurrentEdge((WindowRef)m_macWindow); return WindowEdgeToDirection(edge); } wxDirection wxDrawerWindow::GetPreferredEdge() const { const OptionBits edge = ::GetDrawerPreferredEdge((WindowRef)m_macWindow); return WindowEdgeToDirection(edge); } bool wxDrawerWindow::IsOpen() const { WindowDrawerState state = ::GetDrawerState((WindowRef)m_macWindow); return (state == kWindowDrawerOpen || state == kWindowDrawerOpening); } bool wxDrawerWindow::Open(bool show) { static const Boolean kAsynchronous = true; OSStatus status = noErr; if (show) { const OptionBits preferredEdge = ::GetDrawerPreferredEdge((WindowRef)m_macWindow); status = ::OpenDrawer((WindowRef)m_macWindow, preferredEdge, kAsynchronous); } else status = ::CloseDrawer((WindowRef)m_macWindow, kAsynchronous); return (noErr == status); } bool wxDrawerWindow::SetPreferredEdge(wxDirection edge) { const OSStatus status = ::SetDrawerPreferredEdge((WindowRef)m_macWindow, DirectionToWindowEdge(edge)); return (noErr == status); } OptionBits DirectionToWindowEdge(wxDirection direction) { OptionBits edge; switch (direction) { case wxTOP: edge = kWindowEdgeTop; break; case wxBOTTOM: edge = kWindowEdgeBottom; break; case wxRIGHT: edge = kWindowEdgeRight; break; case wxLEFT: default: edge = kWindowEdgeLeft; break; } return edge; } wxDirection WindowEdgeToDirection(OptionBits edge) { wxDirection direction; switch (edge) { case kWindowEdgeTop: direction = wxTOP; break; case kWindowEdgeBottom: direction = wxBOTTOM; break; case kWindowEdgeRight: direction = wxRIGHT; break; case kWindowEdgeDefault: // store current preferred and return that here? case kWindowEdgeLeft: default: direction = wxLEFT; break; } return direction; } #endif // defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 )