void GraphicsWindowWX::grabFocusIfPointerInWindow() { // focus this window, if the pointer is in the window wxPoint pos = wxGetMousePosition(); if( wxFindWindowAtPoint( pos ) == _canvas ) _canvas->SetFocus(); }
wxTopLevelWindow *ScreenshotCommand::GetFrontWindow(AudacityProject *project) { wxWindow *front = NULL; wxWindow *proj = wxGetTopLevelParent(project); // This is kind of an odd hack. There's no method to enumerate all // possible windows, so we search the whole screen for any windows // that are not this one and not the given Audacity project and // if we find anything, we assume that's the dialog the user wants // to capture. int width, height, x, y; wxDisplaySize(&width, &height); for (x = 0; x < width; x += 50) { for (y = 0; y < height; y += 50) { wxWindow *win = wxFindWindowAtPoint(wxPoint(x, y)); if (win) { win = wxGetTopLevelParent(win); if (win != mIgnore && win != proj) { front = win; break; } } } } if (!front || !front->IsTopLevel()) { return (wxTopLevelWindow *)proj; } return (wxTopLevelWindow *)front; }
void wxPopupTransientWindow::OnIdle(wxIdleEvent& event) { event.Skip(); if (IsShown() && m_child) { // Store the last mouse position to minimize the number of calls to // wxFindWindowAtPoint() which are quite expensive. static wxPoint s_posLast; const wxPoint pos = wxGetMousePosition(); if ( pos != s_posLast ) { s_posLast = pos; wxWindow* const winUnderMouse = wxFindWindowAtPoint(pos); // We release the mouse capture while the mouse is inside the popup // itself to allow using it normally with the controls inside it. if ( wxGetTopLevelParent(winUnderMouse) == this ) { if ( m_child->HasCapture() ) { m_child->ReleaseMouse(); } } else // And we reacquire it as soon as the mouse goes outside. { if ( !m_child->HasCapture() ) { m_child->CaptureMouse(); } } } } }
// Try to find the deepest child that contains 'pt'. // We go backwards, to try to allow for controls that are spacially // within other controls, but are still siblings (e.g. buttons within // static boxes). Static boxes are likely to be created _before_ controls // that sit inside them. wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt) { if (!win->IsShown()) return NULL; // Hack for wxNotebook case: at least in wxGTK, all pages // claim to be shown, so we must only deal with the selected one. #if wxUSE_NOTEBOOK if (win->IsKindOf(CLASSINFO(wxNotebook))) { wxNotebook* nb = (wxNotebook*) win; int sel = nb->GetSelection(); if (sel >= 0) { wxWindow* child = nb->GetPage(sel); wxWindow* foundWin = wxFindWindowAtPoint(child, pt); if (foundWin) return foundWin; } } #endif wxWindowList::compatibility_iterator node = win->GetChildren().GetLast(); while (node) { wxWindow* child = node->GetData(); wxWindow* foundWin = wxFindWindowAtPoint(child, pt); if (foundWin) return foundWin; node = node->GetPrevious(); } wxPoint pos = win->GetPosition(); wxSize sz = win->GetSize(); if ( !win->IsTopLevel() && win->GetParent() ) { pos = win->GetParent()->ClientToScreen(pos); } wxRect rect(pos, sz); if (rect.Contains(pt)) return win; return NULL; }
bool ForwardMouseWheelEvent(wxWindow *source, wxMouseEvent &evt) { wxWindow *target = wxFindWindowAtPoint(wxGetMousePosition()); if (!target || target == source) return true; // If the mouse is over a parent of the source window just pretend it's // over the source window, so that the mouse wheel works on borders and such wxWindow *parent = source->GetParent(); while (parent && parent != target) parent = parent->GetParent(); if (parent == target) return true; // Otherwise send it to the new target target->GetEventHandler()->ProcessEvent(evt); evt.Skip(false); return false; }
wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt) { // Go backwards through the list since windows // on top are likely to have been appended most // recently. wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast(); while (node) { wxWindow* win = node->GetData(); wxWindow* found = wxFindWindowAtPoint(win, pt); if (found) return found; node = node->GetPrevious(); } return NULL; }
wxWindow* wxFindWindowAtPoint(const wxPoint& pt) { #if wxOSX_USE_CARBON Point screenPoint = { pt.y , pt.x }; WindowRef windowRef; if ( FindWindow( screenPoint , &windowRef ) ) { wxNonOwnedWindow *nonOwned = wxNonOwnedWindow::GetFromWXWindow( windowRef ); if ( nonOwned ) return wxFindWindowAtPoint( nonOwned , pt ); } return NULL; #else return wxGenericFindWindowAtPoint( pt ); #endif }
// Find the wxWindow at the current mouse position, returning the mouse // position. wxWindow* wxFindWindowAtPointer(wxPoint& pt) { return wxFindWindowAtPoint(pt = wxGetMousePosition()); }
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectCheck.top = rectLabel.top = rect.top; rectCheck.bottom = rectLabel.bottom = rect.bottom; const int checkSize = GetBestSize().y; const int MARGIN = 3; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectCheck.right = rect.right; rectCheck.left = rectCheck.right - checkSize; rectLabel.right = rectCheck.left - MARGIN; rectLabel.left = rect.left; } else // normal, left-aligned checkbox { rectCheck.left = rect.left; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rectCheck.right + MARGIN; rectLabel.right = rect.right; } // show we draw a focus rect? const bool isFocused = m_isPressed || FindFocus() == this; // draw the checkbox itself: note that this should really, really be in // wxRendererNative but unfortunately we can't add a new virtual function // to it without breaking backwards compatibility // classic Win32 version -- this can be useful when we move this into // wxRendererNative #if defined(__WXWINCE__) || !wxUSE_UXTHEME UINT state = DFCS_BUTTONCHECK; if ( !IsEnabled() ) state |= DFCS_INACTIVE; switch ( Get3StateValue() ) { case wxCHK_CHECKED: state |= DFCS_CHECKED; break; case wxCHK_UNDETERMINED: state |= DFCS_PUSHED; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) state |= DFCS_HOT; if ( !::DrawFrameControl(hdc, &rectCheck, DFC_BUTTON, state) ) { wxLogLastError(_T("DrawFrameControl(DFC_BUTTON)")); } #else // XP version wxUxThemeEngine *themeEngine = wxUxThemeEngine::GetIfActive(); if ( !themeEngine ) return false; wxUxThemeHandle theme(this, L"BUTTON"); if ( !theme ) return false; int state; switch ( Get3StateValue() ) { case wxCHK_CHECKED: state = CBS_CHECKEDNORMAL; break; case wxCHK_UNDETERMINED: state = CBS_MIXEDNORMAL; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: state = CBS_UNCHECKEDNORMAL; break; } if ( !IsEnabled() ) state += CBS_DISABLED_OFFSET; else if ( m_isPressed ) state += CBS_PRESSED_OFFSET; else if ( m_isHot ) state += CBS_HOT_OFFSET; HRESULT hr = themeEngine->DrawThemeBackground ( theme, hdc, BP_CHECKBOX, state, &rectCheck, NULL ); if ( FAILED(hr) ) { wxLogApiError(_T("DrawThemeBackground(BP_CHECKBOX)"), hr); } #endif // 0/1 // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { if ( !::DrawText(hdc, label, label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(_T("DrawText(DT_CALCRECT)")); } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label, label.length(), &rectLabel, fmt) ) { wxLogLastError(_T("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(_T("DrawFocusRect()")); } } return true; }
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectLabel.top = rect.top + (rect.bottom - rect.top - GetBestSize().y) / 2; rectLabel.bottom = rectLabel.top + GetBestSize().y; const int MARGIN = 3; const int CXMENUCHECK = ::GetSystemMetrics(SM_CXMENUCHECK); // the space between the checkbox and the label is included in the // check-mark bitmap const int checkSize = wxMin(CXMENUCHECK - MARGIN, GetSize().y); rectCheck.top = rect.top + (rect.bottom - rect.top - checkSize) / 2; rectCheck.bottom = rectCheck.top + checkSize; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectLabel.right = rect.right - CXMENUCHECK; rectLabel.left = rect.left; rectCheck.left = rectLabel.right + ( CXMENUCHECK + MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; } else // normal, left-aligned checkbox { rectCheck.left = rect.left + ( CXMENUCHECK - MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rect.left + CXMENUCHECK; rectLabel.right = rect.right; } // shall we draw a focus rect? const bool isFocused = m_isPressed || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( wxT("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { RECT oldLabelRect = rectLabel; // needed if right aligned if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(wxT("DrawText(DT_CALCRECT)")); } if ( isRightAligned ) { // move the label rect to the right const int labelWidth = rectLabel.right - rectLabel.left; rectLabel.right = oldLabelRect.right; rectLabel.left = rectLabel.right - labelWidth; } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(wxT("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(wxT("DrawFocusRect()")); } } return true; }
wxWindow * bmx_wxfindwindowatpoint(int x, int y) { return wxFindWindowAtPoint(wxPoint(x, y)); }
bool gcCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectCheck.top = rectLabel.top = rect.top; rectCheck.bottom = rectLabel.bottom = rect.bottom; const int checkSize = GetBestSize().y; const int MARGIN = 3; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectCheck.right = rect.right; rectCheck.left = rectCheck.right - checkSize; rectLabel.right = rectCheck.left - MARGIN; rectLabel.left = rect.left; } else // normal, left-aligned checkbox { rectCheck.left = rect.left; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rectCheck.right + MARGIN; rectLabel.right = rect.right; } // show we draw a focus rect? const bool isFocused = IsChecked() || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(_T("DrawText(DT_CALCRECT)")); } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(_T("DrawText()")); } //// finally draw the focus if ( isFocused ) { COLORREF colBg = wxColourToRGB(wxColor(GetGCThemeManager()->getColor("checkbox", "focus-fg"))); HBRUSH hbrush = ::CreateSolidBrush(colBg); rectLabel.left--; rectLabel.right++; ::FrameRect(hdc, &rectLabel, hbrush); ::DeleteObject(hbrush); } return true; }
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(); // in non-Univ ports the system manages scrollbars for us #if defined(__WXUNIVERSAL__) && wxUSE_SCROLLBAR // scrollbar on which the click occurred wxWindow *sbar = NULL; #endif // __WXUNIVERSAL__ && wxUSE_SCROLLBAR wxWindow *win = (wxWindow *)event.GetEventObject(); switch ( win->HitTest(pos.x, pos.y) ) { case wxHT_WINDOW_OUTSIDE: { // do the coords translation now as after DismissAndNotify() // m_popup may be destroyed wxMouseEvent event2(event); m_popup->ClientToScreen(&event2.m_x, &event2.m_y); // clicking outside a popup dismisses it m_popup->DismissAndNotify(); // dismissing a tooltip shouldn't waste a click, i.e. you // should be able to dismiss it and press the button with the // same click, so repost this event to the window beneath us wxWindow *winUnder = wxFindWindowAtPoint(event2.GetPosition()); if ( winUnder ) { // translate the event coords to the ones of the window // which is going to get the event winUnder->ScreenToClient(&event2.m_x, &event2.m_y); event2.SetEventObject(winUnder); wxPostEvent(winUnder->GetEventHandler(), event2); } } break; #if defined(__WXUNIVERSAL__) && wxUSE_SCROLLBAR case wxHT_WINDOW_HORZ_SCROLLBAR: sbar = win->GetScrollbar(wxHORIZONTAL); break; case wxHT_WINDOW_VERT_SCROLLBAR: sbar = win->GetScrollbar(wxVERTICAL); break; #endif // __WXUNIVERSAL__ && wxUSE_SCROLLBAR default: // forgot to update the switch after adding a new hit test code? wxFAIL_MSG( wxT("unexpected HitTest() return value") ); wxFALLTHROUGH; 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 defined(__WXUNIVERSAL__) && wxUSE_SCROLLBAR 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); } #endif // __WXUNIVERSAL__ && wxUSE_SCROLLBAR }
bool wxMSWOwnerDrawnButtonBase::MSWDrawButton(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !MSWIsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return false; // shall we draw a focus rect? const bool isFocused = m_isPressed || m_win->HasFocus(); int flags = MSWGetButtonCheckedFlag(); if ( dis->itemState & ODS_SELECTED ) flags |= wxCONTROL_SELECTED | wxCONTROL_PRESSED; if ( !m_win->IsEnabled() ) flags |= wxCONTROL_DISABLED; if ( m_isPressed ) flags |= wxCONTROL_PRESSED; if ( wxFindWindowAtPoint(wxGetMousePosition()) == m_win ) flags |= wxCONTROL_CURRENT; // calculate the rectangles for the button itself and the label HDC hdc = dis->hDC; const RECT& rect = dis->rcItem; // calculate the rectangles for the button itself and the label const wxSize bestSize = m_win->GetBestSize(); RECT rectButton, rectLabel; rectLabel.top = rect.top + (rect.bottom - rect.top - bestSize.y) / 2; rectLabel.bottom = rectLabel.top + bestSize.y; // choose the values consistent with those used for native, non // owner-drawn, buttons static const int MARGIN = 3; int CXMENUCHECK = ::GetSystemMetrics(SM_CXMENUCHECK) + 1; // the buttons were even bigger under Windows XP if ( wxGetWinVersion() < wxWinVersion_6 ) CXMENUCHECK += 2; // The space between the button and the label // is included in the button bitmap. const int buttonSize = wxMin(CXMENUCHECK - MARGIN, m_win->GetSize().y); rectButton.top = rect.top + (rect.bottom - rect.top - buttonSize) / 2; rectButton.bottom = rectButton.top + buttonSize; const bool isRightAligned = m_win->HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectLabel.right = rect.right - CXMENUCHECK; rectLabel.left = rect.left; rectButton.left = rectLabel.right + ( CXMENUCHECK + MARGIN - buttonSize ) / 2; rectButton.right = rectButton.left + buttonSize; } else // normal, left-aligned button { rectButton.left = rect.left + ( CXMENUCHECK - MARGIN - buttonSize ) / 2; rectButton.right = rectButton.left + buttonSize; rectLabel.left = rect.left + CXMENUCHECK; rectLabel.right = rect.right; } // Erase the background. ::FillRect(hdc, &rect, m_win->MSWGetBgBrush(hdc)); // draw the button itself wxDCTemp dc(hdc); MSWDrawButtonBitmap(dc, wxRectFromRECT(rectButton), flags); // draw the text const wxString& label = m_win->GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { RECT oldLabelRect = rectLabel; // needed if right aligned if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(wxT("DrawText(DT_CALCRECT)")); } if ( isRightAligned ) { // move the label rect to the right const int labelWidth = rectLabel.right - rectLabel.left; rectLabel.right = oldLabelRect.right; rectLabel.left = rectLabel.right - labelWidth; } } if ( flags & wxCONTROL_DISABLED ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(wxT("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(wxT("DrawFocusRect()")); } } return true; }