]> git.saurik.com Git - wxWidgets.git/commitdiff
generic (will comment on list later about was does/doesn't work) drawer
authorRyan Norton <wxprojects@comcast.net>
Mon, 27 Sep 2004 11:32:05 +0000 (11:32 +0000)
committerRyan Norton <wxprojects@comcast.net>
Mon, 27 Sep 2004 11:32:05 +0000 (11:32 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29445 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/drawer.h [new file with mode: 0644]
include/wx/generic/drawerg.h [new file with mode: 0644]
src/generic/drawerg.cpp [new file with mode: 0644]

diff --git a/include/wx/drawer.h b/include/wx/drawer.h
new file mode 100644 (file)
index 0000000..d06d300
--- /dev/null
@@ -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_
+
diff --git a/include/wx/generic/drawerg.h b/include/wx/generic/drawerg.h
new file mode 100644 (file)
index 0000000..4b74614
--- /dev/null
@@ -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_
\ No newline at end of file
diff --git a/src/generic/drawerg.cpp b/src/generic/drawerg.cpp
new file mode 100644 (file)
index 0000000..c3e6b7d
--- /dev/null
@@ -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();
+}
+