diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index ff7cf9da65..8c96d1b787 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -2414,6 +2414,17 @@ # endif #endif /* wxUSE_PROPGRID */ +#if wxUSE_TIPWINDOW +# if !wxUSE_POPUPWIN +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxTipWindow requires wxUSE_POPUPWIN" +# else +# undef wxUSE_POPUPWIN +# define wxUSE_POPUPWIN 1 +# endif +# endif +#endif /* wxUSE_TIPWINDOW */ + #endif /* wxUSE_GUI */ #endif /* _WX_CHKCONF_H_ */ diff --git a/include/wx/tipwin.h b/include/wx/tipwin.h index 08c0957e5b..2f16cbb03a 100644 --- a/include/wx/tipwin.h +++ b/include/wx/tipwin.h @@ -14,16 +14,7 @@ #if wxUSE_TIPWINDOW -#if wxUSE_POPUPWIN - #include "wx/popupwin.h" - - #define wxTipWindowBase wxPopupTransientWindow -#else - #include "wx/frame.h" - - #define wxTipWindowBase wxFrame -#endif -#include "wx/arrstr.h" +#include "wx/popupwin.h" class WXDLLIMPEXP_FWD_CORE wxTipWindowView; @@ -31,7 +22,7 @@ class WXDLLIMPEXP_FWD_CORE wxTipWindowView; // wxTipWindow // ---------------------------------------------------------------------------- -class WXDLLIMPEXP_CORE wxTipWindow : public wxTipWindowBase +class WXDLLIMPEXP_CORE wxTipWindow : public wxPopupTransientWindow { public: // the mandatory ctor parameters are: the parent window and the text to @@ -69,17 +60,9 @@ protected: // event handlers void OnMouseClick(wxMouseEvent& event); -#if !wxUSE_POPUPWIN - void OnActivate(wxActivateEvent& event); - void OnKillFocus(wxFocusEvent& event); -#else // wxUSE_POPUPWIN virtual void OnDismiss() wxOVERRIDE; -#endif // wxUSE_POPUPWIN/!wxUSE_POPUPWIN private: - wxArrayString m_textLines; - wxCoord m_heightLine; - wxTipWindowView *m_view; wxTipWindow** m_windowPtr; diff --git a/src/generic/tipwin.cpp b/src/generic/tipwin.cpp index b3f56f51d6..2ecb4b206b 100644 --- a/src/generic/tipwin.cpp +++ b/src/generic/tipwin.cpp @@ -33,6 +33,9 @@ #include "wx/settings.h" #endif // WX_PRECOMP +#include "wx/display.h" +#include "wx/vector.h" + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -55,19 +58,15 @@ public: void OnMouseClick(wxMouseEvent& event); void OnMouseMove(wxMouseEvent& event); -#if !wxUSE_POPUPWIN - void OnKillFocus(wxFocusEvent& event); -#endif // wxUSE_POPUPWIN - // calculate the client rect we need to display the text void Adjust(const wxString& text, wxCoord maxLength); private: wxTipWindow* m_parent; -#if !wxUSE_POPUPWIN - long m_creationTime; -#endif // !wxUSE_POPUPWIN + wxVector m_textLines; + wxCoord m_heightLine; + wxDECLARE_EVENT_TABLE(); wxDECLARE_NO_COPY_CLASS(wxTipWindowView); @@ -81,15 +80,10 @@ private: // event tables // ---------------------------------------------------------------------------- -wxBEGIN_EVENT_TABLE(wxTipWindow, wxTipWindowBase) +wxBEGIN_EVENT_TABLE(wxTipWindow, wxPopupTransientWindow) EVT_LEFT_DOWN(wxTipWindow::OnMouseClick) EVT_RIGHT_DOWN(wxTipWindow::OnMouseClick) EVT_MIDDLE_DOWN(wxTipWindow::OnMouseClick) - -#if !wxUSE_POPUPWIN - EVT_KILL_FOCUS(wxTipWindow::OnKillFocus) - EVT_ACTIVATE(wxTipWindow::OnActivate) -#endif // !wxUSE_POPUPWIN wxEND_EVENT_TABLE() wxBEGIN_EVENT_TABLE(wxTipWindowView, wxWindow) @@ -100,10 +94,6 @@ wxBEGIN_EVENT_TABLE(wxTipWindowView, wxWindow) EVT_MIDDLE_DOWN(wxTipWindowView::OnMouseClick) EVT_MOTION(wxTipWindowView::OnMouseMove) - -#if !wxUSE_POPUPWIN - EVT_KILL_FOCUS(wxTipWindowView::OnKillFocus) -#endif // !wxUSE_POPUPWIN wxEND_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -115,13 +105,7 @@ wxTipWindow::wxTipWindow(wxWindow *parent, wxCoord maxLength, wxTipWindow** windowPtr, wxRect *rectBounds) -#if wxUSE_POPUPWIN : wxPopupTransientWindow(parent) -#else - : wxFrame(parent, wxID_ANY, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxNO_BORDER | wxFRAME_NO_TASKBAR ) -#endif { SetTipWindowPtr(windowPtr); if ( rectBounds ) @@ -133,33 +117,51 @@ wxTipWindow::wxTipWindow(wxWindow *parent, SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); - // set size, position and show it - m_view = new wxTipWindowView(this); - m_view->Adjust(text, maxLength); -#if !wxUSE_POPUPWIN - m_view->SetFocus(); -#endif - int x, y; wxGetMousePosition(&x, &y); - // we want to show the tip below the mouse, not over it + // move to the center of the target display so wxTipWindowView will use the + // correct DPI + wxPoint posScreen; + wxSize sizeScreen; + + const int displayNum = wxDisplay::GetFromPoint(wxPoint(x, y)); + if ( displayNum != wxNOT_FOUND ) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + wxPoint center(posScreen.x + sizeScreen.GetWidth() / 2, + posScreen.y + sizeScreen.GetHeight() / 2); + Move(center, wxSIZE_NO_ADJUSTMENTS); + + // set size, position and show it + m_view = new wxTipWindowView(this); + m_view->Adjust(text, FromDIP(parent->ToDIP(maxLength)) ); + + // we want to show the tip below the mouse, not over it, make sure to not + // overflow into the next display // // NB: the reason we use "/ 2" here is that we don't know where the current // cursors hot spot is... it would be nice if we could find this out // though - y += wxSystemSettings::GetMetric(wxSYS_CURSOR_Y, this) / 2; + int cursorOffset = wxSystemSettings::GetMetric(wxSYS_CURSOR_Y, this) / 2; + if (y + cursorOffset >= posScreen.y + sizeScreen.GetHeight()) + cursorOffset = posScreen.y + sizeScreen.GetHeight() - y - 1; + y += cursorOffset; -#if wxUSE_POPUPWIN Position(wxPoint(x, y), wxSize(0,0)); Popup(m_view); #ifdef __WXGTK__ m_view->CaptureMouse(); #endif -#else - Move(x, y); - Show(true); -#endif } wxTipWindow::~wxTipWindow() @@ -168,11 +170,9 @@ wxTipWindow::~wxTipWindow() { *m_windowPtr = NULL; } - #if wxUSE_POPUPWIN - #ifdef __WXGTK__ - if ( m_view->HasCapture() ) - m_view->ReleaseMouse(); - #endif + #ifdef __WXGTK__ + if ( m_view->HasCapture() ) + m_view->ReleaseMouse(); #endif } @@ -181,33 +181,11 @@ void wxTipWindow::OnMouseClick(wxMouseEvent& WXUNUSED(event)) Close(); } -#if wxUSE_POPUPWIN - void wxTipWindow::OnDismiss() { Close(); } -#else // !wxUSE_POPUPWIN - -void wxTipWindow::OnActivate(wxActivateEvent& event) -{ - if (!event.GetActive()) - Close(); -} - -void wxTipWindow::OnKillFocus(wxFocusEvent& WXUNUSED(event)) -{ - // Under Windows at least, we will get this immediately - // because when the view window is focussed, the - // tip window goes out of focus. -#ifdef __WXGTK__ - Close(); -#endif -} - -#endif // wxUSE_POPUPWIN // !wxUSE_POPUPWIN - void wxTipWindow::SetBoundingRect(const wxRect& rectBound) { m_rectBound = rectBound; @@ -221,7 +199,6 @@ void wxTipWindow::Close() m_windowPtr = NULL; } -#if wxUSE_POPUPWIN Show(false); #ifdef __WXGTK__ if ( m_view->HasCapture() ) @@ -232,9 +209,6 @@ void wxTipWindow::Close() #ifndef __WXOSX__ Destroy(); #endif -#else - wxFrame::Close(); -#endif } // ---------------------------------------------------------------------------- @@ -250,11 +224,9 @@ wxTipWindowView::wxTipWindowView(wxWindow *parent) SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); -#if !wxUSE_POPUPWIN - m_creationTime = wxGetLocalTime(); -#endif // !wxUSE_POPUPWIN - m_parent = (wxTipWindow*)parent; + + m_heightLine = 0; } void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength) @@ -267,7 +239,6 @@ void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength) wxString current; wxCoord height, width, widthMax = 0; - m_parent->m_heightLine = 0; bool breakLine = false; for ( const wxChar *p = text.c_str(); ; p++ ) @@ -278,10 +249,10 @@ void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength) if ( width > widthMax ) widthMax = width; - if ( height > m_parent->m_heightLine ) - m_parent->m_heightLine = height; + if ( height > m_heightLine ) + m_heightLine = height; - m_parent->m_textLines.Add(current); + m_textLines.push_back(current); if ( !*p ) { @@ -295,7 +266,7 @@ void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength) else if ( breakLine && (*p == wxT(' ') || *p == wxT('\t')) ) { // word boundary - break the line here - m_parent->m_textLines.Add(current); + m_textLines.push_back(current); current.clear(); breakLine = false; } @@ -309,14 +280,14 @@ void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength) if ( width > widthMax ) widthMax = width; - if ( height > m_parent->m_heightLine ) - m_parent->m_heightLine = height; + if ( height > m_heightLine ) + m_heightLine = height; } } // take into account the border size and the margins width = 2*(TEXT_MARGIN_X + 1) + widthMax; - height = 2*(TEXT_MARGIN_Y + 1) + wx_truncate_cast(wxCoord, m_parent->m_textLines.GetCount())*m_parent->m_heightLine; + height = 2*(TEXT_MARGIN_Y + 1) + wx_truncate_cast(wxCoord, m_textLines.size())*m_heightLine; m_parent->SetClientSize(width, height); SetSize(0, 0, width, height); } @@ -343,12 +314,12 @@ void wxTipWindowView::OnPaint(wxPaintEvent& WXUNUSED(event)) wxPoint pt; pt.x = TEXT_MARGIN_X; pt.y = TEXT_MARGIN_Y; - size_t count = m_parent->m_textLines.GetCount(); + const size_t count = m_textLines.size(); for ( size_t n = 0; n < count; n++ ) { - dc.DrawText(m_parent->m_textLines[n], pt); + dc.DrawText(m_textLines[n], pt); - pt.y += m_parent->m_heightLine; + pt.y += m_heightLine; } } @@ -373,13 +344,4 @@ void wxTipWindowView::OnMouseMove(wxMouseEvent& event) } } -#if !wxUSE_POPUPWIN -void wxTipWindowView::OnKillFocus(wxFocusEvent& WXUNUSED(event)) -{ - // Workaround the kill focus event happening just after creation in wxGTK - if (wxGetLocalTime() > m_creationTime + 1) - m_parent->Close(); -} -#endif // !wxUSE_POPUPWIN - #endif // wxUSE_TIPWINDOW