void SplitterWindow2::sizeWindows() { initSashPosition(); if (m_splitMode != SplitMode_Unset) { const wxWindowUpdateLocker lockUpdates(this); if (m_maximizedWindow != NULL) { m_maximizedWindow->SetSize(wxRect(GetClientAreaOrigin(), GetClientSize())); m_sash->SetSize(wxRect(wxPoint(0, 0),wxPoint(0, 0))); } else { const int origH = h(GetClientAreaOrigin()); const int origV = h(GetClientAreaOrigin()); const int sizeH = h(GetClientSize()); const int sizeV = v(GetClientSize()); wxPoint pos[2]; wxSize size[2]; setHV(pos[0], origH, origV); setHV(pos[1], origH + currentSashPosition() + sashSize(), origV); setHV(size[0], currentSashPosition(), sizeV); setHV(size[1], sizeH - currentSashPosition() - sashSize(), sizeV); for (size_t i = 0; i < NumWindows; ++i) m_windows[i]->SetSize(wxRect(pos[i], size[i])); wxPoint sashPos; wxSize sashSize; setHV(sashPos, origH + currentSashPosition(), origV); setHV(sashSize, SplitterWindow2::sashSize(), sizeV); m_sash->SetSize(wxRect(sashPos, sashSize)); } } }
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. void wxFrame::DoGetClientSize(int *x, int *y) const { wxSize size = GetSize(); wxPoint pos = GetClientAreaOrigin(); *x = size.x - pos.x - 1; *y = size.y - pos.y - 1; }
void wxFrame::DoSetClientSize(int width, int height) { // leave enough space for the status bar if we have (and show) it #if wxUSE_STATUSBAR wxStatusBar *statbar = GetStatusBar(); if ( statbar && statbar->IsShown() ) { height += statbar->GetSize().y; } #endif // wxUSE_STATUSBAR // call GetClientAreaOrigin() to take the toolbar into account wxPoint pt = GetClientAreaOrigin(); width += pt.x; height += pt.y; #if wxUSE_TOOLBAR wxToolBar * const toolbar = GetToolBar(); if ( toolbar ) { if ( toolbar->HasFlag(wxTB_RIGHT | wxTB_BOTTOM) ) { const wxSize sizeTB = toolbar->GetSize(); if ( toolbar->HasFlag(wxTB_RIGHT) ) width -= sizeTB.x; else // wxTB_BOTTOM height -= sizeTB.y; } //else: toolbar already taken into account by GetClientAreaOrigin() } #endif // wxUSE_TOOLBAR wxTopLevelWindow::DoSetClientSize(width, height); }
int wxNotebook::HitTest(const wxPoint& pt, long * flags) const { int resultV = wxNOT_FOUND; #if TARGET_API_MAC_OSX const int countPages = GetPageCount(); // we have to convert from Client to Window relative coordinates wxPoint adjustedPt = pt + GetClientAreaOrigin(); // and now to HIView native ones adjustedPt.x -= MacGetLeftBorderSize() ; adjustedPt.y -= MacGetTopBorderSize() ; HIPoint hipoint= { adjustedPt.x , adjustedPt.y } ; HIViewPartCode outPart = 0 ; OSStatus err = HIViewGetPartHit( m_peer->GetControlRef(), &hipoint, &outPart ); int max = m_peer->GetMaximum() ; if ( outPart == 0 && max > 0 ) { // this is a hack, as unfortunately a hit on an already selected tab returns 0, // so we have to go some extra miles to make sure we select something different // and try again .. int val = m_peer->GetValue() ; int maxval = max ; if ( max == 1 ) { m_peer->SetMaximum( 2 ) ; maxval = 2 ; } if ( val == 1 ) m_peer->SetValue( maxval ) ; else m_peer->SetValue( 1 ) ; err = HIViewGetPartHit( m_peer->GetControlRef(), &hipoint, &outPart ); m_peer->SetValue( val ) ; if ( max == 1 ) m_peer->SetMaximum( 1 ) ; } if ( outPart >= 1 && outPart <= countPages ) resultV = outPart - 1 ; #endif // TARGET_API_MAC_OSX if (flags != NULL) { *flags = 0; // we cannot differentiate better if (resultV >= 0) *flags |= wxBK_HITTEST_ONLABEL; else *flags |= wxBK_HITTEST_NOWHERE; } return resultV; }
void wxTopLevelWindowBase::DoScreenToClient(int *x, int *y) const { wxWindow::DoScreenToClient(x, y); // translate the wxWindow client coords to our client coords wxPoint pt(GetClientAreaOrigin()); if ( x ) *x -= pt.x; if ( y ) *y -= pt.y; }
void wxTopLevelWindowBase::DoClientToScreen(int *x, int *y) const { // our client area origin (0, 0) may be really something like (0, 30) for // wxWindow if we have a toolbar, account for it before translating wxPoint pt(GetClientAreaOrigin()); if ( x ) *x += pt.x; if ( y ) *y += pt.y; wxWindow::DoClientToScreen(x, y); }
void wxStaticBox::DoGetClientSize(int *width, int *height) const { // See: http://msdn.microsoft.com/en-us/library/aa511279.aspx wxPoint lr = ConvertDialogToPixels(wxPoint(6,7)); wxPoint ul = GetClientAreaOrigin(); wxSize sz = GetSize(); if (width) *width = sz.x - ul.x - lr.x; if (height) *height = sz.y - ul.y - lr.x; }
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. void wxFrame::DoGetClientSize(int *x, int *y) const { wxTopLevelWindow::DoGetClientSize(x, y); // account for the possible toolbar wxPoint pt = GetClientAreaOrigin(); if ( x ) *x -= pt.x; if ( y ) *y -= pt.y; #if wxUSE_TOOLBAR wxToolBar * const toolbar = GetToolBar(); if ( toolbar ) { if ( toolbar->HasFlag(wxTB_RIGHT | wxTB_BOTTOM) ) { const wxSize sizeTB = toolbar->GetSize(); if ( toolbar->HasFlag(wxTB_RIGHT) ) { if ( x ) *x -= sizeTB.x; } else // wxTB_BOTTOM { if ( y ) *y -= sizeTB.y; } } //else: toolbar already taken into account by GetClientAreaOrigin() } #endif // wxUSE_TOOLBAR #if wxUSE_STATUSBAR // adjust client area height to take the status bar into account if ( y ) { wxStatusBar *statbar = GetStatusBar(); if ( statbar && statbar->IsShown() ) { *y -= statbar->GetSize().y; } } #endif // wxUSE_STATUSBAR }
//////////////////////////////////////////////////////////////////////////////// // This handler will display a popup menu for the currently selected item //////////////////////////////////////////////////////////////////////////////// void frmMain::OnContextMenu(wxCommandEvent &event) { wxPoint point; if (FindFocus() == browser) { wxRect rect; wxTreeItemId item = browser->GetSelection(); browser->GetBoundingRect(item, rect); point = rect.GetPosition(); wxPoint origin = GetClientAreaOrigin(); // Because this Tree is inside a vertical splitter, we // must compensate for the size of the other elements point.x += origin.x; point.y += origin.y; doPopup(this, point, browser->GetObject(item)); } }
bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region) { // Windows takes ownership of the region, so // we'll have to make a copy of the region to give to it. DWORD noBytes = ::GetRegionData(GetHrgnOf(region), 0, NULL); RGNDATA *rgnData = (RGNDATA*) new char[noBytes]; ::GetRegionData(GetHrgnOf(region), noBytes, rgnData); HRGN hrgn = ::ExtCreateRegion(NULL, noBytes, rgnData); delete[] (char*) rgnData; // SetWindowRgn expects the region to be in coordinates // relative to the window, not the client area. const wxPoint clientOrigin = GetClientAreaOrigin(); ::OffsetRgn(hrgn, -clientOrigin.x, -clientOrigin.y); // Now call the shape API with the new region. if (::SetWindowRgn(GetHwnd(), hrgn, TRUE) == 0) { wxLogLastError(wxT("SetWindowRgn")); return false; } return true; }
void wxWindowDFB::PaintWindow(const wxRect& rect) { wxCHECK_RET( !IsFrozen() && IsShown(), "shouldn't be called" ); wxLogTrace(TRACE_PAINT, "%p ('%s'): painting region [%i,%i,%i,%i]", this, GetName().c_str(), rect.x, rect.y, rect.GetRight(), rect.GetBottom()); m_updateRegion = rect; // FIXME_DFB: don't waste time rendering the area if it's fully covered // by some children, go directly to rendering the children // (unless some child has HasTransparentBackground()=true!) // NB: unconditionally send wxEraseEvent, because our implementation of // wxWindow::Refresh() ignores the eraseBack argument wxWindowDC dc((wxWindow*)this); wxEraseEvent eventEr(m_windowId, &dc); eventEr.SetEventObject(this); HandleWindowEvent(eventEr); wxRect clientRect(GetClientRect()); // only send wxNcPaintEvent if drawing at least part of nonclient area: if ( !clientRect.Contains(rect) ) { wxNcPaintEvent eventNc(GetId()); eventNc.SetEventObject(this); HandleWindowEvent(eventNc); } else { wxLogTrace(TRACE_PAINT, "%p ('%s'): not sending wxNcPaintEvent", this, GetName().c_str()); } // only send wxPaintEvent if drawing at least part of client area: if ( rect.Intersects(clientRect) ) { wxPaintEvent eventPt(GetId()); eventPt.SetEventObject(this); HandleWindowEvent(eventPt); } else { wxLogTrace(TRACE_PAINT, "%p ('%s'): not sending wxPaintEvent", this, GetName().c_str()); } // draw window's overlays on top of the painted window, if we have any: PaintOverlays(rect); m_updateRegion.Clear(); // client area portion of 'rect': wxRect rectClientOnly(rect); rectClientOnly.Intersect(clientRect); // paint the children: wxPoint origin = GetClientAreaOrigin(); wxWindowList& children = GetChildren(); for ( wxWindowList::iterator i = children.begin(); i != children.end(); ++i ) { wxWindow *child = *i; if ( child->IsFrozen() || !child->IsShown() ) continue; // don't paint anything if the window is frozen or hidden // compute child's area to repaint wxRect childrect(child->GetRect()); childrect.Offset(origin); if ( child->CanBeOutsideClientArea() ) childrect.Intersect(rect); else childrect.Intersect(rectClientOnly); if ( childrect.IsEmpty() ) continue; // and repaint it: childrect.Offset(-child->GetPosition()); childrect.Offset(-origin); child->PaintWindow(childrect); } }
void wxWindow::Refresh(bool eraseBackground, const wxRect *rect) { wxRect rectClient; // the same rectangle in client coordinates wxPoint origin = GetClientAreaOrigin(); wxSize size = GetClientSize(); if ( rect ) { // the rectangle passed as argument is in client coordinates rectClient = *rect; // don't refresh anything beyond the client area (scrollbars for // example) if ( rectClient.GetRight() > size.x ) rectClient.SetRight(size.x); if ( rectClient.GetBottom() > size.y ) rectClient.SetBottom(size.y); } else // refresh the entire client area { // x,y is already set to 0 by default rectClient.SetSize(size); } // convert refresh rectangle to window coordinates: wxRect rectWin(rectClient); rectWin.Offset(origin); // debugging helper #ifdef WXDEBUG_REFRESH static bool s_refreshDebug = false; if ( s_refreshDebug ) { wxWindowDC dc(this); dc.SetBrush(*wxCYAN_BRUSH); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rectWin); // under Unix we use "--sync" X option for this #if defined(__WXMSW__) && !defined(__WXMICROWIN__) ::GdiFlush(); ::Sleep(200); #endif // __WXMSW__ } #endif // WXDEBUG_REFRESH wxWindowNative::Refresh(eraseBackground, &rectWin); // Refresh all sub controls if any. wxWindowList& children = GetChildren(); for ( wxWindowList::iterator i = children.begin(); i != children.end(); ++i ) { wxWindow *child = *i; // only refresh subcontrols if they are visible: if ( child->IsTopLevel() || !child->IsShown() || child->IsFrozen() ) continue; // ...and when the subcontrols are in the update region: wxRect childrect(child->GetRect()); childrect.Intersect(rectClient); if ( childrect.IsEmpty() ) continue; // refresh the subcontrol now: childrect.Offset(-child->GetPosition()); // NB: We must call wxWindowNative version because we need to refresh // the entire control, not just its client area, and this is why we // don't account for child client area origin here neither. Also // note that we don't pass eraseBackground to the child, but use // true instead: this is because we can't be sure that // eraseBackground=false is safe for children as well and not only // for the parent. child->wxWindowNative::Refresh(eraseBackground, &childrect); } }
wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) { wxASSERT_MSG( !dx || !dy, wxT("can't be used for diag scrolling") ); // the rect to refresh (which we will calculate) wxRect rect; if ( !dx && !dy ) { // nothing to do return rect; } // calculate the part of the window which we can just redraw in the new // location wxSize sizeTotal = rectTotal ? rectTotal->GetSize() : GetClientSize(); wxLogTrace(wxT("scroll"), wxT("rect is %dx%d, scroll by %d, %d"), sizeTotal.x, sizeTotal.y, dx, dy); // the initial and end point of the region we move in client coords wxPoint ptSource, ptDest; if ( rectTotal ) { ptSource = rectTotal->GetPosition(); ptDest = rectTotal->GetPosition(); } // the size of this region wxSize size; size.x = sizeTotal.x - abs(dx); size.y = sizeTotal.y - abs(dy); if ( size.x <= 0 || size.y <= 0 ) { // just redraw everything as nothing of the displayed image will stay wxLogTrace(wxT("scroll"), wxT("refreshing everything")); rect = rectTotal ? *rectTotal : wxRect(0, 0, sizeTotal.x, sizeTotal.y); } else // move the part which doesn't change to the new location { // note that when we scroll the canvas in some direction we move the // block which doesn't need to be refreshed in the opposite direction if ( dx < 0 ) { // scroll to the right, move to the left ptSource.x -= dx; } else { // scroll to the left, move to the right ptDest.x += dx; } if ( dy < 0 ) { // scroll down, move up ptSource.y -= dy; } else { // scroll up, move down ptDest.y += dy; } #if wxUSE_CARET // we need to hide the caret before moving or it will erase itself at // the wrong (old) location wxCaret *caret = GetCaret(); if ( caret ) caret->Hide(); #endif // wxUSE_CARET // do move wxClientDC dc(this); wxBitmap bmp(size.x, size.y); wxMemoryDC dcMem; dcMem.SelectObject(bmp); dcMem.Blit(wxPoint(0,0), size, &dc, ptSource #if defined(__WXGTK__) && !defined(wxHAS_WORKING_GTK_DC_BLIT) + GetClientAreaOrigin() #endif // broken wxGTK wxDC::Blit ); dc.Blit(ptDest, size, &dcMem, wxPoint(0,0)); wxLogTrace(wxT("scroll"), wxT("Blit: (%d, %d) of size %dx%d -> (%d, %d)"), ptSource.x, ptSource.y, size.x, size.y, ptDest.x, ptDest.y); // and now repaint the uncovered area // FIXME: We repaint the intersection of these rectangles twice - is // it bad? I don't think so as it is rare to scroll the window // diagonally anyhow and so adding extra logic to compute // rectangle intersection is probably not worth the effort rect.x = ptSource.x; rect.y = ptSource.y; if ( dx ) { if ( dx < 0 ) { // refresh the area along the right border rect.x += size.x + dx; rect.width = -dx; } else { // refresh the area along the left border rect.width = dx; } rect.height = sizeTotal.y; wxLogTrace(wxT("scroll"), wxT("refreshing (%d, %d)-(%d, %d)"), rect.x, rect.y, rect.GetRight() + 1, rect.GetBottom() + 1); } if ( dy ) { if ( dy < 0 ) { // refresh the area along the bottom border rect.y += size.y + dy; rect.height = -dy; } else { // refresh the area along the top border rect.height = dy; } rect.width = sizeTotal.x; wxLogTrace(wxT("scroll"), wxT("refreshing (%d, %d)-(%d, %d)"), rect.x, rect.y, rect.GetRight() + 1, rect.GetBottom() + 1); } #if wxUSE_CARET if ( caret ) caret->Show(); #endif // wxUSE_CARET } return rect; }
// Does a physical scroll void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect) { // No scrolling requested. if ((dx == 0) && (dy == 0)) return; if (!m_updateRegion.IsEmpty()) { m_updateRegion.Offset( dx, dy ); int cw = 0; int ch = 0; GetSize( &cw, &ch ); // GetClientSize() ?? m_updateRegion.Intersect( 0, 0, cw, ch ); } if (!m_clearRegion.IsEmpty()) { m_clearRegion.Offset( dx, dy ); int cw = 0; int ch = 0; GetSize( &cw, &ch ); // GetClientSize() ?? m_clearRegion.Intersect( 0, 0, cw, ch ); } Window xwindow = (Window) GetClientAreaWindow(); wxCHECK_RET( xwindow, wxT("invalid window") ); Display *xdisplay = wxGlobalDisplay(); GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL ); XSetGraphicsExposures( xdisplay, xgc, True ); int s_x = 0; int s_y = 0; int cw; int ch; if (rect) { s_x = rect->x; s_y = rect->y; cw = rect->width; ch = rect->height; } else { s_x = 0; s_y = 0; GetClientSize( &cw, &ch ); } #if wxUSE_TWO_WINDOWS wxPoint offset( 0,0 ); #else wxPoint offset = GetClientAreaOrigin(); s_x += offset.x; s_y += offset.y; #endif int w = cw - abs(dx); int h = ch - abs(dy); if ((h < 0) || (w < 0)) { Refresh(); } else { wxRect rect; if (dx < 0) rect.x = cw+dx + offset.x; else rect.x = s_x; if (dy < 0) rect.y = ch+dy + offset.y; else rect.y = s_y; if (dy != 0) rect.width = cw; else rect.width = abs(dx); if (dx != 0) rect.height = ch; else rect.height = abs(dy); int d_x = s_x; int d_y = s_y; if (dx < 0) s_x += -dx; if (dy < 0) s_y += -dy; if (dx > 0) d_x = dx + offset.x; if (dy > 0) d_y = dy + offset.y; XCopyArea( xdisplay, xwindow, xwindow, xgc, s_x, s_y, w, h, d_x, d_y ); // wxLogDebug( "Copy: s_x %d s_y %d w %d h %d d_x %d d_y %d", s_x, s_y, w, h, d_x, d_y ); // wxLogDebug( "Update: %d %d %d %d", rect.x, rect.y, rect.width, rect.height ); m_updateRegion.Union( rect ); m_clearRegion.Union( rect ); } XFreeGC( xdisplay, xgc ); // Move Clients, but not the scrollbars // FIXME: There may be a better method to move a lot of Windows within X11 wxScrollBar *sbH = ((wxWindow *) this)->GetScrollbar( wxHORIZONTAL ); wxScrollBar *sbV = ((wxWindow *) this)->GetScrollbar( wxVERTICAL ); wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); while ( node ) { // Only propagate to non-top-level windows wxWindow *win = node->GetData(); if ( win->GetParent() && win != sbH && win != sbV ) { wxPoint pos = win->GetPosition(); // Add the delta to the old Position pos.x += dx; pos.y += dy; win->SetPosition(pos); } node = node->GetNext(); } }