]> git.saurik.com Git - wxWidgets.git/commitdiff
2 more files added on wxUniv branch I had forgot to commit
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 29 Jun 2001 17:18:47 +0000 (17:18 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 29 Jun 2001 17:18:47 +0000 (17:18 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

distrib/msw/tmake/filelist.txt
src/common/popupcmn.cpp [new file with mode: 0644]

index 88425e87cce42f76de8f947445125ec7f947c421..64e50ea75b20c61749ae816a9ba39ec0332ea2e8 100644 (file)
@@ -188,6 +188,7 @@ object.cpp  C       B
 objstrm.cpp    C       B
 odbc.cpp       C       R,X,P
 paper.cpp      C
+popupcmn.cpp   C
 prntbase.cpp   C
 process.cpp    C       32,B
 protocol.cpp   C       S,B
diff --git a/src/common/popupcmn.cpp b/src/common/popupcmn.cpp
new file mode 100644 (file)
index 0000000..8f7215b
--- /dev/null
@@ -0,0 +1,343 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        common/popupcmn.cpp
+// Purpose:     implementation of wxPopupTransientWindow
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     06.01.01
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// License:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "popupwin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#if wxUSE_POPUPWIN
+
+#include "wx/popupwin.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/combobox.h"        // wxComboControl
+#endif //WX_PRECOMP
+
+#ifdef __WXUNIVERSAL__
+    #include "wx/univ/renderer.h"
+#endif // __WXUNIVERSAL__
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// event handlers which we use to intercept events which cause the popup to
+// disappear
+class wxPopupWindowHandler : public wxEvtHandler
+{
+public:
+    wxPopupWindowHandler(wxPopupTransientWindow *popup) { m_popup = popup; }
+
+protected:
+    // event handlers
+    void OnLeftDown(wxMouseEvent& event);
+
+private:
+    wxPopupTransientWindow *m_popup;
+
+    DECLARE_EVENT_TABLE()
+};
+
+class wxPopupFocusHandler : public wxEvtHandler
+{
+public:
+    wxPopupFocusHandler(wxPopupTransientWindow *popup) { m_popup = popup; }
+
+protected:
+    // event handlers
+    void OnKillFocus(wxFocusEvent& event);
+
+private:
+    wxPopupTransientWindow *m_popup;
+
+    DECLARE_EVENT_TABLE()
+};
+
+// ----------------------------------------------------------------------------
+// event tables
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxPopupWindowHandler, wxEvtHandler)
+    EVT_LEFT_DOWN(wxPopupWindowHandler::OnLeftDown)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler)
+    EVT_KILL_FOCUS(wxPopupFocusHandler::OnKillFocus)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxPopupWindowBase
+// ----------------------------------------------------------------------------
+
+bool wxPopupWindowBase::Create(wxWindow* WXUNUSED(parent), int WXUNUSED(flags))
+{
+    return TRUE;
+}
+
+void wxPopupWindowBase::Position(const wxPoint& ptOrigin,
+                                 const wxSize& size)
+{
+    wxSize sizeScreen = wxGetDisplaySize(),
+           sizeSelf = GetSize();
+
+    // is there enough space to put the popup below the window (where we put it
+    // by default)?
+    wxCoord y = ptOrigin.y + size.y;
+    if ( y + sizeSelf.y > sizeScreen.y )
+    {
+        // check if there is enough space above
+        if ( ptOrigin.y > sizeSelf.y )
+        {
+            // do position the control above the window
+            y -= size.y + sizeSelf.y;
+        }
+        //else: not enough space below nor above, leave below
+    }
+
+    // now check left/right too
+    wxCoord x = ptOrigin.x + size.x;
+    if ( x + sizeSelf.x > sizeScreen.x )
+    {
+        // check if there is enough space to the left
+        if ( ptOrigin.x > sizeSelf.x )
+        {
+            // do position the control to the left
+            x -= size.x + sizeSelf.x;
+        }
+        //else: not enough space there neither, leave in default position
+    }
+
+    Move(x, y, wxSIZE_NO_ADJUSTMENTS);
+}
+
+// ----------------------------------------------------------------------------
+// wxPopupTransientWindow
+// ----------------------------------------------------------------------------
+
+void wxPopupTransientWindow::Init()
+{
+    m_child =
+    m_focus = (wxWindow *)NULL;
+}
+
+wxPopupTransientWindow::wxPopupTransientWindow(wxWindow *parent)
+{
+    Init();
+
+    (void)Create(parent);
+}
+
+wxPopupTransientWindow::~wxPopupTransientWindow()
+{
+    PopHandlers();
+}
+
+void wxPopupTransientWindow::PopHandlers()
+{
+    if ( m_child )
+    {
+        m_child->PopEventHandler(TRUE /* delete it */);
+        m_child->ReleaseMouse();
+        m_child = NULL;
+    }
+
+    if ( m_focus )
+    {
+        m_focus->PopEventHandler(TRUE /* delete it */);
+        m_focus = NULL;
+    }
+}
+
+void wxPopupTransientWindow::Popup(wxWindow *winFocus)
+{
+    const wxWindowList& children = GetChildren();
+    if ( children.GetCount() )
+    {
+        m_child = children.GetFirst()->GetData();
+    }
+    else
+    {
+        m_child = this;
+    }
+
+    m_child->CaptureMouse();
+    m_child->PushEventHandler(new wxPopupWindowHandler(this));
+
+    Show();
+
+    m_focus = winFocus ? winFocus : this;
+    m_focus->PushEventHandler(new wxPopupFocusHandler(this));
+    m_focus->SetFocus();
+}
+
+void wxPopupTransientWindow::Dismiss()
+{
+    PopHandlers();
+
+    Hide();
+}
+
+void wxPopupTransientWindow::DismissAndNotify()
+{
+    Dismiss();
+
+    OnDismiss();
+}
+
+void wxPopupTransientWindow::OnDismiss()
+{
+    // nothing to do here - but it may be interesting for derived class
+}
+
+bool wxPopupTransientWindow::ProcessLeftDown(wxMouseEvent& WXUNUSED(event))
+{
+    // no special processing here
+    return FALSE;
+}
+
+#if wxUSE_COMBOBOX
+
+// ----------------------------------------------------------------------------
+// wxPopupComboWindow
+// ----------------------------------------------------------------------------
+
+wxPopupComboWindow::wxPopupComboWindow(wxComboControl *parent)
+                  : wxPopupTransientWindow(parent)
+{
+    m_combo = parent;
+}
+
+bool wxPopupComboWindow::Create(wxComboControl *parent)
+{
+    m_combo = parent;
+
+    return wxPopupWindow::Create(parent);
+}
+
+void wxPopupComboWindow::PositionNearCombo()
+{
+    // the origin point must be in screen coords
+    wxPoint ptOrigin = m_combo->ClientToScreen(wxPoint(0, 0));
+
+#ifdef __WXUNIVERSAL__
+    // account for the fact that (0, 0) is not the top left corner of the
+    // window: there is also the border
+    wxRect rectBorders = m_combo->GetRenderer()->
+                            GetBorderDimensions(m_combo->GetBorder());
+    ptOrigin.x -= rectBorders.x;
+    ptOrigin.y -= rectBorders.y;
+#endif // __WXUNIVERSAL__
+
+    // position below or above the combobox: the width is 0 to put it exactly
+    // below us, not to the left or to the right
+    Position(ptOrigin, wxSize(0, m_combo->GetSize().y));
+}
+
+void wxPopupComboWindow::OnDismiss()
+{
+    m_combo->OnDismiss();
+}
+
+#endif // wxUSE_COMBOBOX
+
+// ----------------------------------------------------------------------------
+// wxPopupWindowHandler
+// ----------------------------------------------------------------------------
+
+void wxPopupWindowHandler::OnLeftDown(wxMouseEvent& event)
+{
+    // let the window have it first (we're the first event handler in the chain
+    // of handlers for this window)
+    if ( m_popup->ProcessLeftDown(event) )
+    {
+        return;
+    }
+
+    wxPoint pos = event.GetPosition();
+
+    // scrollbar on which the click occured
+    wxWindow *sbar = NULL;
+
+    wxWindow *win = (wxWindow *)event.GetEventObject();
+    switch ( win->HitTest(pos.x, pos.y) )
+    {
+        case wxHT_WINDOW_OUTSIDE:
+            // clicking outside a popup dismisses it
+            m_popup->DismissAndNotify();
+            break;
+
+        case wxHT_WINDOW_HORZ_SCROLLBAR:
+            sbar = win->GetScrollbar(wxHORIZONTAL);
+            break;
+
+        case wxHT_WINDOW_VERT_SCROLLBAR:
+            sbar = win->GetScrollbar(wxVERTICAL);
+            break;
+
+        default:
+            // forgot to update the switch after adding a new hit test code?
+            wxFAIL_MSG( _T("unexpected HitTest() return value") );
+            // fall through
+
+        case wxHT_WINDOW_CORNER:
+            // don't actually know if this one is good for anything, but let it
+            // pass just in case
+
+        case wxHT_WINDOW_INSIDE:
+            // let the normal processing take place
+            event.Skip();
+            break;
+    }
+
+    if ( sbar )
+    {
+        // translate the event coordinates to the scrollbar ones
+        pos = sbar->ScreenToClient(win->ClientToScreen(pos));
+
+        // and give the event to it
+        wxMouseEvent event2 = event;
+        event2.m_x = pos.x;
+        event2.m_y = pos.y;
+
+        (void)sbar->GetEventHandler()->ProcessEvent(event2);
+    }
+}
+
+// ----------------------------------------------------------------------------
+// wxPopupFocusHandler
+// ----------------------------------------------------------------------------
+
+void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event)
+{
+    // when we lose focus we always disappear
+    m_popup->DismissAndNotify();
+}
+
+#endif // wxUSE_POPUPWIN