2 more files added on wxUniv branch I had forgot to commit
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
feb85348c3
commit
c02ee97f96
@ -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
|
||||
|
343
src/common/popupcmn.cpp
Normal file
343
src/common/popupcmn.cpp
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user