generic (will comment on list later about was does/doesn't work) drawer

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29445 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Ryan Norton 2004-09-27 11:32:05 +00:00
parent a4e391f8e8
commit 4a4a811163
3 changed files with 414 additions and 0 deletions

24
include/wx/drawer.h Normal file
View File

@ -0,0 +1,24 @@
///////////////////////////////////////////////////////////////////////////////
// Name: drawer.h
// Purpose: wxDrawerWindow class
// Author: Ryan Norton
// Modified by:
// Created: 9/27/2004
// RCS-ID: $Id$
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_DRAWER_H_BASE_
#define _WX_DRAWER_H_BASE_
#include "wx/defs.h"
#if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 )
# include "wx/mac/carbon/drawer.h"
#else
# include "wx/generic/drawerg.h"
#endif
#endif // _WX_DRAWER_H_BASE_

View File

@ -0,0 +1,80 @@
/////////////////////////////////////////////////////////////////////////////
// Name: drawerg.h
// Purpose: Generic Drawer child window class.
// 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: Ryan Norton
// Modified by:
// Created: 2004-26-09
// RCS-ID: $Id$
// Copyright: (c) Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_DRAWERG_H_
#define _WX_DRAWERG_H_
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "drawerg.h"
#endif
#include "wx/toplevel.h"
class WXDLLEXPORT wxGenericDrawerWindow : public wxTopLevelWindow
{
DECLARE_DYNAMIC_CLASS(wxGenericDrawerWindow)
public:
wxGenericDrawerWindow();
wxGenericDrawerWindow(wxWindow* parent,
wxWindowID id,
const wxString& title,
wxSize size = wxDefaultSize,
wxDirection edge = wxLEFT,
const wxString& name = wxT("drawerwindow"))
{
this->Create(parent, id, title, size, edge, name);
}
~wxGenericDrawerWindow();
// Create a drawer window.
// If parent is NULL, create as a tool window.
// If parent is not NULL, then wxTopLevelWindow::Attach this window to parent.
bool Create(wxWindow *parent,
wxWindowID id,
const wxString& title,
wxSize size = wxDefaultSize,
wxDirection edge = wxLEFT,
const wxString& name = wxFrameNameStr);
bool Open(const bool& show = true); // open or close the drawer, possibility for async param, i.e. animate
bool Close() { return this->Open(false); }
bool IsOpen() const;
// Set the edge of the parent where the drawer attaches.
bool SetPreferredEdge(const wxDirection& edge);
wxDirection GetPreferredEdge() const;
wxDirection GetCurrentEdge() const; // not necessarily the preferred, due to screen constraints
protected:
bool m_bOpen;
wxDirection m_nCurrentEdge;
wxDirection m_nPreferredEdge;
int m_nOpenOffset;
class wxGenericDrawerTimer* m_pTimer;
friend class wxGenericDrawerTimer;
wxSize m_LastParentSize;
void OnDrawerFocus(class wxFocusEvent& evt);
void OnDrawerMove(class wxMoveEvent& evt);
void OnDrawerSize(class wxSizeEvent& evt);
void DoDrawerPosition();
void DoDrawerSize();
};
#endif // _WX_DRAWERG_H_

310
src/generic/drawerg.cpp Normal file
View File

@ -0,0 +1,310 @@
/////////////////////////////////////////////////////////////////////////////
// Name: drawer.cpp
// Purpose: Generic 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: Ryan Norton
// Modified by:
// Created: 2004-30-01
// RCS-ID: $Id$
// Copyright: (c) Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "drawerg.h"
#endif
#include "wx/defs.h"
#include "wx/generic/drawerg.h"
#include "wx/timer.h"
enum wxGenericDrawerConstants
{
wxGENERICDRAWER_INCREMENT = 1,
wxGENERICDRAWER_INTERVAL = 3
};
class wxGenericDrawerTimer : public wxTimer
{
public:
wxGenericDrawerTimer(wxGenericDrawerWindow* pWin, const int& nMult) :
m_pWin(pWin), m_nMult(nMult) {}
void Notify()
{
if ((m_nMult < 0 && !m_pWin->m_nOpenOffset) ||
(
m_nMult >= 0 &&
(( (m_pWin->m_nCurrentEdge == wxLEFT ||
m_pWin->m_nCurrentEdge == wxRIGHT) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetWidth())
||
( (m_pWin->m_nCurrentEdge == wxTOP ||
m_pWin->m_nCurrentEdge == wxBOTTOM) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetHeight())
))
)
{
/*
wxFprintf(stderr, "shutdown - mult:%i off:%i tlr:%i ttb:%i\n", m_nMult, m_pWin->m_nOpenOffset,
(m_pWin->m_nCurrentEdge == wxLEFT ||
m_pWin->m_nCurrentEdge == wxRIGHT) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetWidth(),
(m_pWin->m_nCurrentEdge == wxTOP ||
m_pWin->m_nCurrentEdge == wxBOTTOM) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetHeight()
);
*/
//clean up & shut down
Stop();
m_pWin->m_pTimer = NULL;
//reset current edge to preferred edge
if (m_nMult < 0)
{
m_pWin->m_nCurrentEdge = m_pWin->m_nPreferredEdge;
m_pWin->DoDrawerPosition();
}
//commit seppuku
delete this;
}
else
{
// wxFprintf(stderr, "continue\n");
wxPoint pos = m_pWin->GetPosition();
switch (m_pWin->m_nCurrentEdge)
{
case wxLEFT:
pos.x -= wxGENERICDRAWER_INCREMENT * m_nMult;
break;
case wxRIGHT:
pos.x += wxGENERICDRAWER_INCREMENT * m_nMult;
break;
case wxTOP:
pos.y -= wxGENERICDRAWER_INCREMENT * m_nMult;
break;
case wxBOTTOM:
default:
pos.y += wxGENERICDRAWER_INCREMENT * m_nMult;
break;
}
m_pWin->SetPosition(pos);
//wxFprintf(stderr, "tpos:%i,%i\n", pos.x, pos.y);
m_pWin->m_nOpenOffset += wxGENERICDRAWER_INCREMENT * m_nMult;
}
}
wxGenericDrawerWindow* m_pWin;
int m_nMult;
};
enum wxGenericDrawerOffsets
{
wxGENERICDRAWER_TOPOFFSET = 20,
wxGENERICDRAWER_BOTTOMOFFSET = 20
};
IMPLEMENT_DYNAMIC_CLASS(wxGenericDrawerWindow, wxWindow)
wxGenericDrawerWindow::wxGenericDrawerWindow() :
m_bOpen(false), m_nCurrentEdge(wxLEFT), m_nPreferredEdge(wxLEFT), m_nOpenOffset(0),
m_pTimer(NULL)
{
}
wxGenericDrawerWindow::~wxGenericDrawerWindow()
{
m_isBeingDeleted = true;
this->Show(false);
if (m_pTimer)
{
m_pTimer->Stop();
delete m_pTimer;
}
}
bool wxGenericDrawerWindow::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."));
wxASSERT_MSG(m_pTimer == NULL, wxT("Currently opening!!"));
wxASSERT_MSG(edge == wxLEFT ||
edge == wxRIGHT ||
edge == wxTOP ||
edge == wxBOTTOM, wxT("Invalid edge") );
// Create the drawer window.
const wxPoint pos(0, 0);
const long style = wxNO_BORDER || wxVSCROLL | wxHSCROLL;//wxFRAME_DRAWER;
bool success = wxTopLevelWindow::Create(parent, id, wxT(""), pos, size, style, name);
if (success)
{
// Set the drawers parent.
if (parent->IsTopLevel())
{
wxTopLevelWindow* tlwParent = (wxTopLevelWindow*) parent;
//connect to parent's events
tlwParent->Connect(tlwParent->GetId(), wxEVT_MOVE,
(wxObjectEventFunction) (wxEventFunction) (wxMoveEventFunction) &wxGenericDrawerWindow::OnDrawerMove,
NULL, //user data
this);
tlwParent->Connect(tlwParent->GetId(), wxEVT_SIZE,
(wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxGenericDrawerWindow::OnDrawerSize,
NULL, //user data
this);
tlwParent->Connect(tlwParent->GetId(), wxEVT_KILL_FOCUS,
(wxObjectEventFunction) (wxEventFunction) (wxFocusEventFunction) &wxGenericDrawerWindow::OnDrawerFocus,
NULL, //user data
this);
m_LastParentSize = parent->GetSize();
DoDrawerPosition();
DoDrawerSize();
}
else
success = false;
}
m_nCurrentEdge = m_nPreferredEdge = edge;
Show(success);
if (success && parent->IsShown()) //bring parent on top
{
parent->Show(false);
parent->Show(true);
}
//wxFprintf(stderr,wxT("success==%i\n"), success);
return success;
}
wxDirection wxGenericDrawerWindow::GetCurrentEdge() const
{
return m_nCurrentEdge;
}
wxDirection wxGenericDrawerWindow::GetPreferredEdge() const
{
return m_nPreferredEdge;
}
bool wxGenericDrawerWindow::IsOpen() const
{
return m_bOpen;
}
bool wxGenericDrawerWindow::Open(const bool& show)
{
if(show)
{
if (m_pTimer)
delete m_pTimer;
m_pTimer = new wxGenericDrawerTimer(this, 1);
m_pTimer->Start(wxGENERICDRAWER_INTERVAL);
}
else
{
if (m_pTimer)
delete m_pTimer;
m_pTimer = new wxGenericDrawerTimer(this, -1);
m_pTimer->Start(wxGENERICDRAWER_INTERVAL);
}
return true;
}
bool wxGenericDrawerWindow::SetPreferredEdge(const wxDirection& edge)
{
wxASSERT(edge == wxLEFT ||
edge == wxRIGHT ||
edge == wxTOP ||
edge == wxBOTTOM );
if (!m_nOpenOffset)
{
m_nCurrentEdge = edge;
DoDrawerPosition();
}
m_nPreferredEdge = edge;
return true;
}
void wxGenericDrawerWindow::DoDrawerPosition()
{
const wxPoint parentPosition(GetParent()->GetPosition());
SetPosition(wxPoint(
parentPosition.x +
(m_nCurrentEdge == wxLEFT ?
-m_nOpenOffset : m_nCurrentEdge == wxRIGHT ? GetParent()->GetSize().GetWidth() + m_nOpenOffset - GetSize().GetWidth(): wxGENERICDRAWER_TOPOFFSET),
parentPosition.y +
(m_nCurrentEdge == wxTOP ?
-m_nOpenOffset : m_nCurrentEdge == wxBOTTOM ? GetParent()->GetSize().GetHeight() + m_nOpenOffset - GetSize().GetHeight() : wxGENERICDRAWER_TOPOFFSET)
));
//wxFprintf(stderr,wxT("parentposition:%i,%i\n"), parentPosition.x, parentPosition.y);
//wxFprintf(stderr,wxT("offset:%i\nposition:%i,%i\n"), m_nOpenOffset, GetPosition().x, GetPosition().y);
}
void wxGenericDrawerWindow::DoDrawerSize()
{
// Constrain the drawer size to the parent window.
const wxSize parentSize(GetParent()->GetClientSize());
wxSize size = GetSize();
if (wxLEFT == m_nCurrentEdge || wxRIGHT == m_nCurrentEdge)
{
if (size.GetHeight() > parentSize.GetHeight())
size.SetHeight(parentSize.GetHeight() - (wxGENERICDRAWER_TOPOFFSET + wxGENERICDRAWER_BOTTOMOFFSET));
size.SetHeight(size.GetHeight() + (parentSize.GetHeight() - m_LastParentSize.GetHeight()));
}
else
{
if (size.GetWidth() > parentSize.GetWidth())
size.SetWidth(parentSize.GetWidth() - (wxGENERICDRAWER_TOPOFFSET + wxGENERICDRAWER_BOTTOMOFFSET));
size.SetWidth(size.GetWidth() + (parentSize.GetWidth() - m_LastParentSize.GetWidth()));
}
SetSize(size);
m_LastParentSize = parentSize;
//wxFprintf(stderr,wxT("size:%i,%i\n"), size.GetWidth(), size.GetHeight());
}
void wxGenericDrawerWindow::OnDrawerFocus(wxFocusEvent& evt)
{
// wxFprintf(stderr, wxT("focus\n"));
if (wxWindow::FindFocus() == this)
GetParent()->SetFocus();
}
void wxGenericDrawerWindow::OnDrawerMove(wxMoveEvent& evt)
{
DoDrawerPosition();
}
void wxGenericDrawerWindow::OnDrawerSize(wxSizeEvent& evt)
{
DoDrawerSize();
}