popupcmn.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 573 行 · 第 1/2 页
CPP
573 行
///////////////////////////////////////////////////////////////////////////////
// Name: common/popupcmn.cpp
// Purpose: implementation of wxPopupTransientWindow
// Author: Vadim Zeitlin
// Modified by:
// Created: 06.01.01
// RCS-ID: $Id: popupcmn.cpp,v 1.59 2005/08/18 00:35:00 MBN Exp $
// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// License: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "popupwinbase.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
#include "wx/app.h" // wxPostEvent
#include "wx/log.h"
#include "wx/app.h"
#endif //WX_PRECOMP
#ifdef __WXUNIVERSAL__
#include "wx/univ/renderer.h"
#endif // __WXUNIVERSAL__
#ifdef __WXGTK__
#include <gtk/gtk.h>
#endif
#ifdef __WXX11__
#include "wx/x11/private.h"
#endif
IMPLEMENT_DYNAMIC_CLASS(wxPopupWindow, wxWindow)
IMPLEMENT_DYNAMIC_CLASS(wxPopupTransientWindow, wxPopupWindow)
#if wxUSE_COMBOBOX && defined(__WXUNIVERSAL__)
IMPLEMENT_DYNAMIC_CLASS(wxPopupComboWindow, wxPopupTransientWindow)
#endif
// ----------------------------------------------------------------------------
// 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()
DECLARE_NO_COPY_CLASS(wxPopupWindowHandler)
};
class wxPopupFocusHandler : public wxEvtHandler
{
public:
wxPopupFocusHandler(wxPopupTransientWindow *popup) : m_popup(popup) {}
protected:
void OnKillFocus(wxFocusEvent& event);
void OnKeyDown(wxKeyEvent& event);
private:
wxPopupTransientWindow *m_popup;
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxPopupFocusHandler)
};
// ----------------------------------------------------------------------------
// 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)
EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxPopupTransientWindow, wxPopupWindow)
#ifdef __WXMSW__
EVT_IDLE(wxPopupTransientWindow::OnIdle)
#endif
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxPopupWindowBase
// ----------------------------------------------------------------------------
wxPopupWindowBase::~wxPopupWindowBase()
{
// this destructor is required for Darwin
}
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;
m_handlerFocus = NULL;
m_handlerPopup = NULL;
}
wxPopupTransientWindow::wxPopupTransientWindow(wxWindow *parent, int style)
{
Init();
(void)Create(parent, style);
}
wxPopupTransientWindow::~wxPopupTransientWindow()
{
if (m_handlerPopup && m_handlerPopup->GetNextHandler())
PopHandlers();
wxASSERT(!m_handlerFocus || !m_handlerFocus->GetNextHandler());
wxASSERT(!m_handlerPopup || !m_handlerPopup->GetNextHandler());
delete m_handlerFocus;
delete m_handlerPopup;
}
void wxPopupTransientWindow::PopHandlers()
{
if ( m_child )
{
if ( !m_child->RemoveEventHandler(m_handlerPopup) )
{
// something is very wrong and someone else probably deleted our
// handler - so don't risk deleting it second time
m_handlerPopup = NULL;
}
if (m_child->HasCapture())
{
m_child->ReleaseMouse();
}
m_child = NULL;
}
if ( m_focus )
{
if ( !m_focus->RemoveEventHandler(m_handlerFocus) )
{
// see above
m_handlerFocus = NULL;
}
}
m_focus = NULL;
}
void wxPopupTransientWindow::Popup(wxWindow *winFocus)
{
const wxWindowList& children = GetChildren();
if ( children.GetCount() )
{
m_child = children.GetFirst()->GetData();
}
else
{
m_child = this;
}
Show();
// There is is a problem if these are still in use
wxASSERT(!m_handlerFocus || !m_handlerFocus->GetNextHandler());
wxASSERT(!m_handlerPopup || !m_handlerPopup->GetNextHandler());
if (!m_handlerPopup)
m_handlerPopup = new wxPopupWindowHandler(this);
m_child->PushEventHandler(m_handlerPopup);
m_focus = winFocus ? winFocus : this;
m_focus->SetFocus();
#ifdef __WXMSW__
// MSW doesn't allow to set focus to the popup window, but we need to
// subclass the window which has the focus, and not winFocus passed in or
// otherwise everything else breaks down
m_focus = FindFocus();
#elif defined(__WXGTK__)
// GTK+ catches the activate events from the popup
// window, not the focus events from the child window
m_focus = this;
#endif
if ( m_focus )
{
if (!m_handlerFocus)
m_handlerFocus = new wxPopupFocusHandler(this);
m_focus->PushEventHandler(m_handlerFocus);
}
}
bool wxPopupTransientWindow::Show( bool show )
{
#ifdef __WXGTK__
if (!show)
{
gdk_pointer_ungrab( (guint32)GDK_CURRENT_TIME );
gtk_grab_remove( m_widget );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?