From aab2f8a775e5ef4e75c26d4bdb6986b5385bf36f Mon Sep 17 00:00:00 2001 From: stambaughw Date: Mon, 22 Feb 2010 16:45:35 +0000 Subject: [PATCH] USE_WX_ZOOM clean up and other minor improvements. * Make USE_WX_ZOOM clipping routine actually clip rather than just test if line needs drawn. * Clean up as many USE_WX_ZOOM #ifdefs as possible. * Minor coordinate rounding improvements. * Minor scrolling and panning improvements. * Remove unused KicadGraphicContext object code. --- common/drawframe.cpp | 63 +++-- common/drawpanel.cpp | 326 ++++++++++++------------- common/gr_basic.cpp | 239 +++++++++++++++--- common/zoom.cpp | 8 +- cvpcb/class_DisplayFootprintsFrame.cpp | 10 +- eeschema/controle.cpp | 39 +-- gerbview/controle.cpp | 11 +- include/kicad_device_context.h | 9 - pcbnew/controle.cpp | 11 +- pcbnew/moduleframe.cpp | 11 +- 10 files changed, 418 insertions(+), 309 deletions(-) diff --git a/common/drawframe.cpp b/common/drawframe.cpp index f392e51b19..9c82ea95d0 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -22,6 +22,12 @@ #include +/* Definitions for enabling and disabling extra debugging output. Please + * remember to set these to 0 before committing changes to SVN. + */ +#define DEBUG_DUMP_SCROLLBAR_SETTINGS 0 // Set to 1 to print scroll bar settings. + + /* Configuration entry names. */ static const wxString CursorShapeEntryKeyword( wxT( "CursorShape" ) ); static const wxString ShowGridEntryKeyword( wxT( "ShowGrid" ) ); @@ -446,6 +452,7 @@ void WinEDA_DrawFrame::AdjustScrollBars() int unitsX, unitsY, posX, posY; wxSize drawingSize, clientSize; BASE_SCREEN* screen = GetBaseScreen(); + bool noRefresh = true; if( screen == NULL || DrawPanel == NULL ) return; @@ -457,30 +464,27 @@ void WinEDA_DrawFrame::AdjustScrollBars() // client area at the current zoom level. clientSize = DrawPanel->GetClientSize(); -#ifdef USE_WX_ZOOM - INSTALL_DC( dc, DrawPanel ); - clientSize.x = dc.DeviceToLogicalXRel( clientSize.x ); - clientSize.y = dc.DeviceToLogicalYRel( clientSize.y ); -#else - screen->Unscale( clientSize ); -#endif + double scalar = screen->GetScalingFactor(); + clientSize.x = wxRound( (double) clientSize.x / scalar ); + clientSize.y = wxRound( (double) clientSize.y / scalar ); /* Adjust drawing size when zooming way out to prevent centering around * cursor problems. */ if( clientSize.x > drawingSize.x || clientSize.y > drawingSize.y ) drawingSize = clientSize; - drawingSize += clientSize / 2; + drawingSize.x += wxRound( (double) clientSize.x / 2.0 ); + drawingSize.y += wxRound( (double) clientSize.y / 2.0 ); if( screen->m_Center ) { - screen->m_DrawOrg.x = -drawingSize.x / 2; - screen->m_DrawOrg.y = -drawingSize.y / 2; + screen->m_DrawOrg.x = -wxRound( (double) drawingSize.x / 2.0 ); + screen->m_DrawOrg.y = -wxRound( (double) drawingSize.y / 2.0 ); } else { - screen->m_DrawOrg.x = -clientSize.x / 2; - screen->m_DrawOrg.y = -clientSize.y / 2; + screen->m_DrawOrg.x = -wxRound( (double) clientSize.x / 2.0 ); + screen->m_DrawOrg.y = -wxRound( (double) clientSize.y / 2.0 ); } /* Always set scrollbar pixels per unit to 1 unless you want the zoom @@ -492,41 +496,32 @@ void WinEDA_DrawFrame::AdjustScrollBars() screen->m_ScrollPixelsPerUnitX = screen->m_ScrollPixelsPerUnitY = 1; // Calculate the number of scroll bar units for the given zoom level. */ -#ifdef USE_WX_ZOOM - unitsX = dc.LogicalToDeviceXRel( drawingSize.x ); - unitsY = dc.LogicalToDeviceYRel( drawingSize.y ); -#else - unitsX = screen->Scale( drawingSize.x ); - unitsY = screen->Scale( drawingSize.y ); -#endif + unitsX = wxRound( (double) drawingSize.x * scalar ); + unitsY = wxRound( (double) drawingSize.y * scalar ); // Calculate the position, place the cursor at the center of screen. posX = screen->m_Curseur.x - screen->m_DrawOrg.x; posY = screen->m_Curseur.y - screen->m_DrawOrg.y; - posX -= clientSize.x / 2; - posY -= clientSize.y / 2; + posX -= wxRound( (double) clientSize.x / 2.0 ); + posY -= wxRound( (double) clientSize.y / 2.0 ); - if( posX <= 0 ) + if( posX < 0 ) posX = 0; - if( posY <= 0 ) + if( posY < 0 ) posY = 0; -#ifdef USE_WX_ZOOM - posX = dc.LogicalToDeviceXRel( posX ); - posY = dc.LogicalToDeviceYRel( posY ); -#else - posX = screen->Scale( posX ); - posY = screen->Scale( posY ); -#endif + posX = wxRound( (double) posX * scalar ); + posY = wxRound( (double) posY * scalar ); screen->m_ScrollbarPos = wxPoint( posX, posY ); screen->m_ScrollbarNumber = wxSize( unitsX, unitsY ); -#if 0 +#if DEBUG_DUMP_SCROLLBAR_SETTINGS wxLogDebug( wxT( "SetScrollbars(%d, %d, %d, %d, %d, %d)" ), - m_ScrollPixelsPerUnitX, m_ScrollPixelsPerUnitY, - unitsX, unitsY, posX, posY ); + screen->m_ScrollPixelsPerUnitX, screen->m_ScrollPixelsPerUnitY, + screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, + screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y ); #endif DrawPanel->SetScrollbars( screen->m_ScrollPixelsPerUnitX, @@ -534,7 +529,7 @@ void WinEDA_DrawFrame::AdjustScrollBars() screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, screen->m_ScrollbarPos.x, - screen->m_ScrollbarPos.y, TRUE ); + screen->m_ScrollbarPos.y, noRefresh ); } diff --git a/common/drawpanel.cpp b/common/drawpanel.cpp index 2fd96dec2a..92957b95e3 100644 --- a/common/drawpanel.cpp +++ b/common/drawpanel.cpp @@ -17,33 +17,16 @@ #define CURSOR_SIZE 12 // Cursor size in pixels - -// Helper class to handle the client Device Context -KicadGraphicContext::KicadGraphicContext( WinEDA_DrawPanel* aDrawPanel ) : - wxClientDC( aDrawPanel ) -{ - GRResetPenAndBrush( this ); - SetBackgroundMode( wxTRANSPARENT ); - -#ifdef USE_WX_ZOOM - if( aDrawPanel->GetScreen() != NULL ) - { - double scale = aDrawPanel->GetScreen()->GetScalingFactor(); - - aDrawPanel->SetScale( scale, scale ); - aDrawPanel->DoPrepareDC( *this ); - wxPoint origin = aDrawPanel->GetScreen()->m_DrawOrg; - SetLogicalOrigin( origin.x, origin.y ); - } -#endif - - aDrawPanel->SetBoundaryBox( this ); -} +#define CLIP_BOX_PADDING 12 -KicadGraphicContext::~KicadGraphicContext() -{ -} +/* Definitions for enabling and disabling debugging features in drawpanel.cpp. + * Please don't forget to turn these off before making any SvN commits. + */ + +#define DEBUG_SHOW_CLIP_RECT 0 // Set to 1 to draw clipping rectangle. +#define DEBUG_DUMP_CLIP_COORDS 0 // Set to 1 to dump clipping rectangle coordinates. +#define DEBUG_DUMP_SCROLL_SETTINGS 0 // Set to 1 to dump scroll settings. /* Used to inhibit a response to a mouse left button release, after a @@ -82,7 +65,6 @@ WinEDA_DrawPanel::WinEDA_DrawPanel( WinEDA_DrawFrame* parent, int id, m_scrollIncrementX = MIN( size.x / 8, 10 ); m_scrollIncrementY = MIN( size.y / 8, 10 ); - SetBackgroundColour( wxColour( ColorRefs[g_DrawBgColor].m_Red, ColorRefs[g_DrawBgColor].m_Green, ColorRefs[g_DrawBgColor].m_Blue ) ); @@ -216,22 +198,20 @@ wxRealPoint WinEDA_DrawPanel::GetGrid() } -/** Calculate the cursor position in internal units. - * @return position (in internal units) - * @param ScreenPos = absolute position in pixels +/** + * Convert a coordinate position in device (screen) units to logical (drawing) units. + * + * @param aPosition = position in device (screen) units. + * @return position in logical (drawing) units. */ wxPoint WinEDA_DrawPanel::CursorRealPosition( const wxPoint& aPosition ) { -#ifdef USE_WX_ZOOM - wxCoord x, y; - INSTALL_DC( DC, this ); - - x = DC.DeviceToLogicalX( aPosition.x ); - y = DC.DeviceToLogicalY( aPosition.y ); - return wxPoint( x, y ); -#else - return GetScreen()->CursorRealPosition( aPosition ); -#endif + double scalar = GetScreen()->GetScalingFactor(); + wxPoint pos; + pos.x = wxRound( (double) aPosition.x / scalar ); + pos.y = wxRound( (double) aPosition.y / scalar ); + pos += GetScreen()->m_DrawOrg; + return pos; } @@ -304,13 +284,9 @@ void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect ) ConvertPcbUnitsToPixelsUnits( &pos ); aRect->SetOrigin( pos ); // rect origin in pixel units -#if USE_WX_ZOOM double scale = GetScreen()->GetScalingFactor(); aRect->m_Size.x = wxRound( (double) aRect->m_Size.x * scale ); aRect->m_Size.y = wxRound( (double) aRect->m_Size.y * scale ); -#else - GetScreen()->Scale( aRect->m_Size ); -#endif } @@ -328,27 +304,14 @@ void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( wxPoint* aPosition ) drwOrig.x *= x_axis_scale; drwOrig.y *= y_axis_scale; -#if USE_WX_ZOOM - INSTALL_DC( dc, this ); - - drwOrig.x = dc.DeviceToLogicalX( drwOrig.x ); - drwOrig.y = dc.DeviceToLogicalY( drwOrig.y ); - *aPosition -= drwOrig; - aPosition->x = dc.LogicalToDeviceX( aPosition->x ); - aPosition->y = dc.LogicalToDeviceY( aPosition->y ); -#else - // Origin in internal units - GetScreen()->Unscale( drwOrig ); - - // Real origin, according to the "plot" origin - drwOrig += GetScreen()->m_DrawOrg; - - // position in internal units, relative to the visible draw area origin - *aPosition -= drwOrig; - - // position in pixels, relative to the visible draw area origin - GetScreen()->Scale( *aPosition ); -#endif + double x, y; + double scalar = GetScreen()->GetScalingFactor(); + x = (double) aPosition->x - ( ( (double) drwOrig.x / scalar ) + + (double) GetScreen()->m_DrawOrg.x ); + y = (double) aPosition->y - ( ( (double) drwOrig.y / scalar ) + + (double) GetScreen()->m_DrawOrg.y ); + aPosition->x = wxRound( x * scalar ); + aPosition->y = wxRound( y * scalar ); } @@ -358,15 +321,10 @@ void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( wxPoint* aPosition ) wxPoint WinEDA_DrawPanel::CursorScreenPosition() { wxPoint pos = GetScreen()->m_Curseur - GetScreen()->m_DrawOrg; + double scalar = GetScreen()->GetScalingFactor(); -#ifdef USE_WX_ZOOM - INSTALL_DC( DC, this ); - - pos.x = DC.LogicalToDeviceXRel( pos.x ); - pos.y = DC.LogicalToDeviceYRel( pos.y ); -#else - GetScreen()->Scale( pos ); -#endif + pos.x = wxRound( (double) pos.x * scalar ); + pos.y = wxRound( (double) pos.y * scalar ); return pos; } @@ -378,23 +336,19 @@ wxPoint WinEDA_DrawPanel::CursorScreenPosition() */ wxPoint WinEDA_DrawPanel::GetScreenCenterRealPosition( void ) { - wxSize size; - wxPoint realpos; + int x, y, ppuX, ppuY; + wxPoint pos; + double scalar = GetScreen()->GetScalingFactor(); - size = GetClientSize() / 2; + GetViewStart( &x, &y ); + GetScrollPixelsPerUnit( &ppuX, &ppuY ); + x *= ppuX; + y *= ppuY; + pos.x = wxRound( ( (double) GetClientSize().x / 2.0 + (double) x ) / scalar ); + pos.y = wxRound( ( (double) GetClientSize().y / 2.0 + (double) y ) / scalar ); + pos += GetScreen()->m_DrawOrg; -#ifdef USE_WX_ZOOM - INSTALL_DC( DC, this ); - - realpos.x = DC.DeviceToLogicalX( size.x ); - realpos.y = DC.DeviceToLogicalY( size.y ); -#else - realpos = CalcUnscrolledPosition( wxPoint( size.x, size.y ) ); - GetScreen()->Unscale( realpos ); - realpos += GetScreen()->m_DrawOrg; -#endif - - return realpos; + return pos; } @@ -417,11 +371,7 @@ void WinEDA_DrawPanel::MouseTo( const wxPoint& Mouse ) wxPoint screenPos, drawingPos; wxRect clientRect( wxPoint( 0, 0 ), GetClientSize() ); -#ifdef USE_WX_ZOOM CalcScrolledPosition( Mouse.x, Mouse.y, &screenPos.x, &screenPos.y ); -#else - screenPos = Mouse - GetScreen()->m_StartVisu; -#endif /* Scroll if the requested mouse position cursor is outside the drawing * area. */ @@ -475,26 +425,59 @@ void WinEDA_DrawPanel::OnActivate( wxActivateEvent& event ) void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event ) { int id = event.GetEventType(); - int dir, value = 0; + int dir; int x, y; + int ppux, ppuy; + int unitsX, unitsY; + int maxX, maxY; GetViewStart( &x, &y ); + GetScrollPixelsPerUnit( &ppux, &ppuy ); + GetVirtualSize( &unitsX, &unitsY ); + maxX = unitsX; + maxY = unitsY; + + unitsX /= ppux; + unitsY /= ppuy; + dir = event.GetOrientation(); // wxHORIZONTAL or wxVERTICAL if( id == wxEVT_SCROLLWIN_LINEUP ) - value = -m_scrollIncrementY; - + { + if( dir == wxHORIZONTAL ) + { + x -= m_scrollIncrementX; + if( x < 0 ) + x = 0; + } + else + { + y -= m_scrollIncrementY; + if( y < 0 ) + y = 0; + } + } else if( id == wxEVT_SCROLLWIN_LINEDOWN ) - value = m_scrollIncrementY; - + { + if( dir == wxHORIZONTAL ) + { + x += m_scrollIncrementX; + if( x > maxX ) + x = maxX; + } + else + { + y += m_scrollIncrementY; + if( y > maxY ) + y = maxY; + } + } else if( id == wxEVT_SCROLLWIN_THUMBTRACK ) { - value = event.GetPosition(); if( dir == wxHORIZONTAL ) - Scroll( value, -1 ); + x = event.GetPosition(); else - Scroll( -1, value ); - return; + y = event.GetPosition(); } else { @@ -502,24 +485,25 @@ void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event ) return; } - if( dir == wxHORIZONTAL ) - { - Scroll( x + value, -1 ); - } - else - { - Scroll( -1, y + value ); - } +#if DEBUG_DUMP_SCROLL_SETTINGS + wxLogDebug( wxT( "Setting scroll bars ppuX=%d, ppuY=%d, unitsX=%d, unitsY=%d," \ + "posX=%d, posY=%d" ), ppux, ppuy, unitsX, unitsY, x, y ); +#endif + SetScrollbars( ppux, ppuy, unitsX, unitsY, x, y, true ); + INSTALL_DC( dc, this ); + ReDraw( &dc, true ); event.Skip(); } void WinEDA_DrawPanel::OnSize( wxSizeEvent& event ) { -#if !defined( USE_WX_GRAPHICS_CONTEXT ) // Crashes Cairo on initial size event. - INSTALL_DC( dc, this ); // Update boundary box. -#endif + if( IsShown() ) + { + INSTALL_DC( dc, this ); // Update boundary box. + } + event.Skip(); } @@ -551,8 +535,9 @@ void WinEDA_DrawPanel::SetBoundaryBox( wxDC* dc ) int scrollX, scrollY; #ifdef USE_WX_ZOOM - scrollX = dc->LogicalToDeviceXRel( wxRound( Screen->GetGridSize().x ) ); - scrollY = dc->LogicalToDeviceYRel( wxRound( Screen->GetGridSize().y ) ); + double scalar = Screen->GetScalingFactor(); + scrollX = wxRound( Screen->GetGridSize().x * scalar ); + scrollY = wxRound( Screen->GetGridSize().y * scalar ); #else scrollX = wxRound( Screen->Scale( Screen->GetGridSize().x ) ); scrollY = wxRound( Screen->Scale( Screen->GetGridSize().y ) ); @@ -564,27 +549,13 @@ void WinEDA_DrawPanel::SetBoundaryBox( wxDC* dc ) #ifdef USE_WX_ZOOM /* Using wxDC scaling requires clipping in drawing (logical) units. */ - - m_ClipBox.m_Pos.x = dc->DeviceToLogicalX( 0 ); - m_ClipBox.m_Pos.y = dc->DeviceToLogicalY( 0 ); - m_ClipBox.m_Size.x = dc->DeviceToLogicalXRel( m_ClipBox.m_Size.x ); - m_ClipBox.m_Size.y = dc->DeviceToLogicalYRel( m_ClipBox.m_Size.y ); - - /* Set to one (1) to draw bounding box validate bounding box calculation. */ -#if 0 - EDA_Rect bBox = m_ClipBox; - m_ClipBox.Inflate( -dc->DeviceToLogicalXRel( 1 ) ); - GRRect( NULL, dc, bBox.GetOrigin().x, bBox.GetOrigin().y, - bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA ); -#endif - - m_ClipBox.Inflate( dc->DeviceToLogicalXRel( 1 ) ); - - /* Always set the clipping region to the screen size. This prevents this bug: - * from occurring on WXMSW if you happen - * to be zoomed way in and your drawing coodinates get too large. - */ - dc->SetClippingRegion( m_ClipBox ); + m_ClipBox.SetOrigin( CalcUnscrolledPosition( wxPoint( 0, 0 ) ) ); + m_ClipBox.Inflate( CLIP_BOX_PADDING ); + m_ClipBox.m_Pos.x = wxRound( (double) m_ClipBox.m_Pos.x / scalar ); + m_ClipBox.m_Pos.y = wxRound( (double) m_ClipBox.m_Pos.y / scalar ); + m_ClipBox.m_Pos += Screen->m_DrawOrg; + m_ClipBox.m_Size.x = wxRound( (double) m_ClipBox.m_Size.x / scalar ); + m_ClipBox.m_Size.y = wxRound( (double) m_ClipBox.m_Size.y / scalar ); #endif Screen->m_ScrollbarPos.x = GetScrollPos( wxHORIZONTAL ); @@ -599,6 +570,14 @@ void WinEDA_DrawPanel::EraseScreen( wxDC* DC ) GRSFilledRect( &m_ClipBox, DC, m_ClipBox.GetX(), m_ClipBox.GetY(), m_ClipBox.GetRight(), m_ClipBox.GetBottom(), 0, g_DrawBgColor, g_DrawBgColor ); + + /* Set to one (1) to draw bounding box validate bounding box calculation. */ +#if DEBUG_SHOW_CLIP_RECT + EDA_Rect bBox = m_ClipBox; + bBox.Inflate( -DC->DeviceToLogicalXRel( 1 ) ); + GRRect( NULL, DC, bBox.GetOrigin().x, bBox.GetOrigin().y, + bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA ); +#endif } @@ -608,11 +587,12 @@ void WinEDA_DrawPanel::DoPrepareDC(wxDC& dc) if( GetScreen() != NULL ) { double scale = GetScreen()->GetScalingFactor(); + dc.SetUserScale( scale, scale ); - SetScale( scale, scale ); - wxScrolledWindow::DoPrepareDC( dc ); - wxPoint origin = GetScreen()->m_DrawOrg; - dc.SetLogicalOrigin( origin.x, origin.y ); + wxPoint pt = CalcUnscrolledPosition( wxPoint( 0, 0 ) ); + dc.SetDeviceOrigin( -pt.x, -pt.y ); + pt = GetScreen()->m_DrawOrg; + dc.SetLogicalOrigin( pt.x, pt.y ); } #endif @@ -646,7 +626,7 @@ void WinEDA_DrawPanel::OnPaint( wxPaintEvent& event ) // Get the union of all rectangles in the update region. wxRect PaintClipBox = GetUpdateRegion().GetBox(); -#if 0 +#if DEBUG_DUMP_CLIP_COORDS wxLogDebug( wxT( "1) PaintClipBox=(%d, %d, %d, %d), m_ClipBox=(%d, %d, %d, %d)" ), PaintClipBox.x, PaintClipBox.y, PaintClipBox.width, PaintClipBox.height, m_ClipBox.m_Pos.x, m_ClipBox.m_Pos.y, m_ClipBox.m_Size.x, m_ClipBox.m_Size.y ); @@ -656,19 +636,15 @@ void WinEDA_DrawPanel::OnPaint( wxPaintEvent& event ) /* When using wxDC scaling the clipping region coordinates are in drawing * (logical) units. */ - m_ClipBox.m_Pos.x = paintDC.DeviceToLogicalX( PaintClipBox.x ); - m_ClipBox.m_Pos.y = paintDC.DeviceToLogicalY( PaintClipBox.y ); - m_ClipBox.m_Size.x = paintDC.DeviceToLogicalXRel( PaintClipBox.width ); - m_ClipBox.m_Size.y = paintDC.DeviceToLogicalYRel( PaintClipBox.height ); - -#if 0 - EDA_Rect bBox = m_ClipBox; - m_ClipBox.Inflate( -paintDC.DeviceToLogicalXRel( 1 ) ); - GRRect( NULL, &paintDC, bBox.GetOrigin().x, bBox.GetOrigin().y, - bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA ); -#endif - - m_ClipBox.Inflate( paintDC.DeviceToLogicalXRel( 1 ) ); + double scalar = GetScreen()->GetScalingFactor(); + m_ClipBox.m_Pos = CalcUnscrolledPosition( PaintClipBox.GetPosition() ); + m_ClipBox.m_Size = PaintClipBox.GetSize(); + m_ClipBox.Inflate( CLIP_BOX_PADDING ); + m_ClipBox.m_Pos.x = wxRound( (double) m_ClipBox.m_Pos.x / scalar ); + m_ClipBox.m_Pos.y = wxRound( (double) m_ClipBox.m_Pos.y / scalar ); + m_ClipBox.m_Pos += GetScreen()->m_DrawOrg; + m_ClipBox.m_Size.x = wxRound( (double) m_ClipBox.m_Size.x / scalar ); + m_ClipBox.m_Size.y = wxRound( (double) m_ClipBox.m_Size.y / scalar ); PaintClipBox = m_ClipBox; #else /* When using Kicad's scaling the clipping region coordinates are in screen @@ -683,7 +659,7 @@ void WinEDA_DrawPanel::OnPaint( wxPaintEvent& event ) m_ClipBox.Inflate( 1 ); // Give it one pixel more in each direction #endif -#if 0 +#if DEBUG_DUMP_CLIP_COORDS wxLogDebug( wxT( "2) PaintClipBox=(%d, %d, %d, %d), m_ClipBox=(%d, %d, %d, %d)" ), PaintClipBox.x, PaintClipBox.y, PaintClipBox.width, PaintClipBox.height, m_ClipBox.m_Pos.x, m_ClipBox.m_Pos.y, m_ClipBox.m_Size.x, m_ClipBox.m_Size.y ); @@ -1019,12 +995,8 @@ void WinEDA_DrawPanel::OnMouseWheel( wxMouseEvent& event ) return; } -#ifdef USE_WX_ZOOM - GetScreen()->m_Curseur = CursorRealPosition( event.GetPosition() ); -#else GetScreen()->m_Curseur = CursorRealPosition( CalcUnscrolledPosition( event.GetPosition() ) ); -#endif wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); @@ -1050,6 +1022,7 @@ void WinEDA_DrawPanel::OnMouseWheel( wxMouseEvent& event ) } GetEventHandler()->ProcessEvent( cmd ); + event.Skip(); } @@ -1123,20 +1096,12 @@ void WinEDA_DrawPanel::OnMouseEvent( wxMouseEvent& event ) localrealbutt |= localbutt; /* compensation default wxGTK */ -#ifdef USE_WX_ZOOM - /* Compute the cursor position in screen (device) units. */ - screen->m_MousePositionInPixels = event.GetPosition(); - - /* Compute the cursor position in drawing (logical) units. */ - screen->m_MousePosition = CursorRealPosition( event.GetPosition() ); -#else /* Compute the cursor position in screen (device) units. */ screen->m_MousePositionInPixels = CalcUnscrolledPosition( event.GetPosition() ); /* Compute the cursor position in drawing (logical) units. */ screen->m_MousePosition = CursorRealPosition( CalcUnscrolledPosition( event.GetPosition() ) ); -#endif INSTALL_DC( DC, this ); @@ -1417,11 +1382,7 @@ void WinEDA_DrawPanel::OnKeyEvent( wxKeyEvent& event ) } /* Some key commands use the current mouse position: refresh it */ -#ifdef USE_WX_ZOOM - pos = wxGetMousePosition() - GetScreenPosition(); -#else pos = CalcUnscrolledPosition( wxGetMousePosition() - GetScreenPosition() ); -#endif /* Compute cursor position in screen units (pixel) including the * current scroll bar position. Also known as device units to wxDC. */ @@ -1442,8 +1403,17 @@ void WinEDA_DrawPanel::OnKeyEvent( wxKeyEvent& event ) void WinEDA_DrawPanel::OnPan( wxCommandEvent& event ) { int x, y; + int ppux, ppuy; + int unitsX, unitsY; + int maxX, maxY; - GetViewStart( &x, &y ); // x and y are in scroll units, not in pixels + GetViewStart( &x, &y ); + GetScrollPixelsPerUnit( &ppux, &ppuy ); + GetVirtualSize( &unitsX, &unitsY ); + maxX = unitsX; + maxY = unitsY; + unitsX /= ppux; + unitsY /= ppuy; switch( event.GetId() ) { @@ -1465,11 +1435,21 @@ void WinEDA_DrawPanel::OnPan( wxCommandEvent& event ) default: wxLogDebug( wxT( "Unknown ID %d in WinEDA_DrawPanel::OnPan()." ), - event.GetId() ); + event.GetId() ); } - Scroll( x, y ); - MouseToCursorSchema(); + if( x < 0 ) + x = 0; + if( y < 0 ) + y = 0; + if( x > maxX ) + x = maxX; + if( y > maxY ) + y = maxY; + + SetScrollbars( ppux, ppuy, unitsX, unitsY, x, y, true ); + INSTALL_DC( dc, this ); + ReDraw( &dc, true ); } diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index d90b25ac7a..27cb5b211f 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -38,6 +38,13 @@ */ +/* Definitions for enabling and disabling debugging features in gr_basic.cpp. + * Please remember to set these back to 0 before making SVN commits. + */ +#define DEBUG_DUMP_CLIP_ERROR_COORDS 0 // Set to 1 to dump clip algorithm errors. +#define DEBUG_DUMP_CLIP_COORDS 0 // Set to 1 to dump clipped coordinates. + + // For draw mode = XOR GR_XOR or GR_NXOR by background color int g_XorMode = GR_NXOR; @@ -72,9 +79,9 @@ static wxDC* lastDC = NULL; /* Local functions: */ static void GRSRect( EDA_Rect* ClipBox, wxDC* DC, int x1, int y1, - int x2, int y2, int Color ); + int x2, int y2, int Color ); static void GRSRect( EDA_Rect* ClipBox, wxDC* DC, int x1, int y1, - int x2, int y2, int width, int Color ); + int x2, int y2, int width, int Color ); /* * Macro clipping the trace of a line: @@ -138,8 +145,6 @@ int GRMapY( int y ) #define WHEN_INSIDE -#if defined( USE_WX_ZOOM ) - /** * Test if any part of a line falls within the bounds of a rectangle. * @@ -153,56 +158,224 @@ int GRMapY( int y ) * * @return - False if any part of the line lies within the rectangle. */ -static bool clipLine( EDA_Rect* aClipBox, int x1, int y1, int x2, int y2 ) +static bool clipLine( EDA_Rect* aClipBox, int& x1, int& y1, int& x2, int& y2 ) { - if( aClipBox->Inside( x1, y1 ) || aClipBox->Inside( x2, y2 ) ) + if( aClipBox->Inside( x1, y1 ) && aClipBox->Inside( x2, y2 ) ) return false; - int ax1, ay1, ax2, ay2; - wxRect rect =*aClipBox; - ax1 = rect.GetBottomLeft().x; - ay1 = rect.GetBottomLeft().y; - ax2 = rect.GetTopLeft().x; - ay2 = rect.GetTopLeft().y; + wxRect rect = *aClipBox; + int minX = rect.GetLeft(); + int maxX = rect.GetRight(); + int minY = rect.GetTop(); + int maxY = rect.GetBottom(); + int clippedX, clippedY; - /* Left clip rectangle line. */ - if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) +#if DEBUG_DUMP_CLIP_COORDS + int tmpX1, tmpY1, tmpX2, tmpY2; + tmpX1 = x1; + tmpY1 = y1; + tmpX2 = x2; + tmpY2 = y2; +#endif + + if( aClipBox->Inside( x1, y1 ) ) + { + if( x1 == x2 ) /* Vertical line, clip Y. */ + { + if( y2 < minY ) + { + y2 = minY; + return false; + } + + if( y2 > maxY ) + { + y2 = maxY; + return false; + } + } + else if( y1 == y2 ) /* Horizontal line, clip X. */ + { + if( x2 < minX ) + { + x2 = minX; + return false; + } + + if( x2 > maxX ) + { + x2 = maxX; + return false; + } + } + + /* If we're here, it's a diagonal line. */ + + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY, + &clippedX, &clippedY ) /* Left */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY, + &clippedX, &clippedY ) /* Top */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY, + &clippedX, &clippedY ) /* Right */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY, + &clippedX, &clippedY ) ) /* Bottom */ + { + if( x2 != clippedX ) + x2 = clippedX; + if( y2 != clippedY ) + y2 = clippedY; + return false; + } + + /* If we're here, something has gone terribly wrong. */ +#if DEBUG_DUMP_CLIP_ERROR_COORDS + wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ), + tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 ); +#endif return false; + } + else if( aClipBox->Inside( x2, y2 ) ) + { + if( x1 == x2 ) /* Vertical line, clip Y. */ + { + if( y2 < minY ) + { + y2 = minY; + return false; + } - ax1 = rect.GetTopRight().x; - ay1 = rect.GetTopRight().y; + if( y2 > maxY ) + { + y2 = maxY; + return false; + } + } + else if( y1 == y2 ) /* Horizontal line, clip X. */ + { + if( x2 < minX ) + { + x2 = minX; + return false; + } + if( x2 > maxX ) + { + x2 = maxX; + return false; + } + } - /* Top clip rectangle line. */ - if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY, + &clippedX, &clippedY ) /* Left */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY, + &clippedX, &clippedY ) /* Top */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY, + &clippedX, &clippedY ) /* Right */ + || TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY, + &clippedX, &clippedY ) ) /* Bottom */ + { + if( x1 != clippedX ) + x1 = clippedX; + if( y1 != clippedY ) + y1 = clippedY; + return false; + } + + /* If we're here, something has gone terribly wrong. */ +#if DEBUG_DUMP_CLIP_ERROR_COORDS + wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ), + tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 ); +#endif return false; + } + else + { + int* intersectX; + int* intersectY; + int intersectX1, intersectY1, intersectX2, intersectY2; + bool haveFirstPoint = false; - ax2 = rect.GetBottomRight().x; - ay2 = rect.GetBottomRight().y; + intersectX = &intersectX1; + intersectY = &intersectY1; - /* Right clip rectangle line. */ - if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) - return false; + /* Left clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY, + intersectX, intersectY ) ) + { + intersectX = &intersectX2; + intersectY = &intersectY2; + haveFirstPoint = true; + } - ax1 = rect.GetBottomLeft().x; - ay1 = rect.GetBottomLeft().y; + /* Top clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY, + intersectX, intersectY ) ) + { + intersectX = &intersectX2; + intersectY = &intersectY2; + if( haveFirstPoint ) + { + x1 = intersectX1; + y1 = intersectY1; + x2 = intersectX2; + y2 = intersectY2; + return false; + } + haveFirstPoint = true; + } - /* Bottom clip rectangle line. */ - if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) - return false; + /* Right clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY, + intersectX, intersectY ) ) + { + intersectX = &intersectX2; + intersectY = &intersectY2; + if( haveFirstPoint ) + { + x1 = intersectX1; + y1 = intersectY1; + x2 = intersectX2; + y2 = intersectY2; + return false; + } + haveFirstPoint = true; + } + + /* Bottom clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY, + intersectX, intersectY ) ) + { + intersectX = &intersectX2; + intersectY = &intersectY2; + if( haveFirstPoint ) + { + x1 = intersectX1; + y1 = intersectY1; + x2 = intersectX2; + y2 = intersectY2; + return false; + } + } + + /* If we're here and only one line of the clip box has been intersected, + * something has gone terribly wrong. */ +#if DEBUG_DUMP_CLIP_ERROR_COORDS + if( haveFirstPoint ) + wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ), + tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 ); +#endif + } /* Set this to one to verify that diagonal lines get clipped properly. */ -#if 0 +#if DEBUG_DUMP_CLIP_COORDS if( !( x1 == x2 || y1 == y2 ) ) wxLogDebug( wxT( "Clipped line (%d,%d):(%d,%d) from rectangle (%d,%d,%d,%d)" ), - x1, y1, x2, y2, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height ); + tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY ); #endif return true; } -#else - /** * Function clip_line * @return bool - true when WHEN_OUTSIDE fires, else false. @@ -306,8 +479,6 @@ static inline bool clip_line( int& x1, int& y1, int& x2, int& y2 ) return false; } -#endif - static void WinClipAndDrawLine( EDA_Rect* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, diff --git a/common/zoom.cpp b/common/zoom.cpp index 79c2ab9a5c..707efd86b6 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -54,11 +54,11 @@ void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord ) if( !GetBaseScreen()->m_UserGridIsON ) { - int tmp = wxRound( coord->x / grid_size.x ); - coord->x = wxRound( tmp * grid_size.x ); + int tmp = wxRound( (double) coord->x / grid_size.x ); + coord->x = wxRound( (double) tmp * grid_size.x ); - tmp = wxRound( coord->y / grid_size.y ); - coord->y = wxRound( tmp * grid_size.y ); + tmp = wxRound( (double) coord->y / grid_size.y ); + coord->y = wxRound( (double) tmp * grid_size.y ); } } diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index b72cc5d0d1..772d15a131 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -211,6 +211,7 @@ void DISPLAY_FOOTPRINTS_FRAME::GeneralControle( wxDC* DC, wxPoint Mouse ) wxRealPoint delta; int flagcurseur = 0; wxPoint curpos, oldpos; + double scalar = GetScreen()->GetScalingFactor(); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); @@ -219,13 +220,8 @@ void DISPLAY_FOOTPRINTS_FRAME::GeneralControle( wxDC* DC, wxPoint Mouse ) delta = GetScreen()->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( wxRound( delta.x ) ); - delta.y = DC->LogicalToDeviceYRel( wxRound( delta.y ) ); - Mouse = DrawPanel->CalcUnscrolledPosition( Mouse ); -#else - GetScreen()->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x <= 0 ) delta.x = 1; diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index ff431bd93a..aa48863f6d 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -216,13 +216,13 @@ SCH_ITEM* WinEDA_SchematicFrame::SchematicGeneralLocateAndDisplay( } -void WinEDA_SchematicFrame::GeneralControle( wxDC* DC, - wxPoint MousePositionInPixels ) +void WinEDA_SchematicFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels ) { wxRealPoint delta; SCH_SCREEN* screen = GetScreen(); wxPoint curpos, oldpos; int hotkey = 0; + double scalar = screen->GetScalingFactor(); ActiveScreen = screen; @@ -231,13 +231,8 @@ void WinEDA_SchematicFrame::GeneralControle( wxDC* DC, delta = screen->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( wxRound( delta.x ) ); - delta.y = DC->LogicalToDeviceYRel( wxRound( delta.y ) ); - MousePositionInPixels = DrawPanel->CalcUnscrolledPosition( MousePositionInPixels ); -#else - screen->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x <= 0 ) delta.x = 1; @@ -317,13 +312,13 @@ void WinEDA_SchematicFrame::GeneralControle( wxDC* DC, } -void WinEDA_LibeditFrame::GeneralControle( wxDC* DC, - wxPoint MousePositionInPixels ) +void WinEDA_LibeditFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels ) { wxRealPoint delta; SCH_SCREEN* screen = GetScreen(); wxPoint curpos, oldpos; int hotkey = 0; + double scalar = screen->GetScalingFactor(); ActiveScreen = screen; @@ -332,13 +327,8 @@ void WinEDA_LibeditFrame::GeneralControle( wxDC* DC, delta = screen->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( wxRound( delta.x ) ); - delta.y = DC->LogicalToDeviceYRel( wxRound( delta.y ) ); - MousePositionInPixels = DrawPanel->CalcUnscrolledPosition( MousePositionInPixels ); -#else - screen->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x <= 0 ) delta.x = 1; @@ -417,13 +407,13 @@ void WinEDA_LibeditFrame::GeneralControle( wxDC* DC, } -void WinEDA_ViewlibFrame::GeneralControle( wxDC* DC, - wxPoint MousePositionInPixels ) +void WinEDA_ViewlibFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels ) { wxRealPoint delta; SCH_SCREEN* screen = GetScreen(); wxPoint curpos, oldpos; int hotkey = 0; + double scalar = screen->GetScalingFactor(); ActiveScreen = screen; @@ -432,13 +422,8 @@ void WinEDA_ViewlibFrame::GeneralControle( wxDC* DC, delta = screen->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( wxRound( delta.x ) ); - delta.y = DC->LogicalToDeviceYRel( wxRound( delta.y ) ); - MousePositionInPixels = DrawPanel->CalcUnscrolledPosition( MousePositionInPixels ); -#else - screen->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x <= 0 ) delta.x = 1; diff --git a/gerbview/controle.cpp b/gerbview/controle.cpp index d6d3a1ce97..d49fc20d7c 100644 --- a/gerbview/controle.cpp +++ b/gerbview/controle.cpp @@ -38,18 +38,15 @@ void WinEDA_GerberFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) return; } + double scalar = GetScreen()->GetScalingFactor(); + curpos = DrawPanel->CursorRealPosition( Mouse ); oldpos = GetScreen()->m_Curseur; delta = GetScreen()->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( delta.x ); - delta.y = DC->LogicalToDeviceYRel( delta.y ); - Mouse = DrawPanel->CalcUnscrolledPosition( Mouse ); -#else - GetScreen()->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x == 0 ) delta.x = 1; diff --git a/include/kicad_device_context.h b/include/kicad_device_context.h index 4ab4899cd9..6a0ba94b02 100644 --- a/include/kicad_device_context.h +++ b/include/kicad_device_context.h @@ -25,15 +25,6 @@ #include #endif -// Helper class to handle the client Device Context -class KicadGraphicContext : public wxClientDC -{ -public: - KicadGraphicContext( WinEDA_DrawPanel * aDrawPanel ); - ~KicadGraphicContext(); -}; - - // Macro used to declare a device context in kicad: #if USE_WX_GRAPHICS_CONTEXT && USE_WX_ZOOM #define INSTALL_DC(name,parent) \ diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp index 75cc3e4fae..0012011bd0 100644 --- a/pcbnew/controle.cpp +++ b/pcbnew/controle.cpp @@ -258,18 +258,15 @@ void WinEDA_PcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) SetTitle( GetScreen()->m_FileName ); } + double scalar = GetScreen()->GetScalingFactor(); + curpos = DrawPanel->CursorRealPosition( Mouse ); oldpos = GetScreen()->m_Curseur; delta = GetScreen()->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( delta.x ); - delta.y = DC->LogicalToDeviceYRel( delta.y ); - Mouse = DrawPanel->CalcUnscrolledPosition( Mouse ); -#else - GetScreen()->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x <= 0 ) delta.x = 1; diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index d5bc9d9f0c..a7052ce562 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -451,18 +451,15 @@ void WinEDA_ModuleEditFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) return; } + double scalar = GetScreen()->GetScalingFactor(); + curpos = DrawPanel->CursorRealPosition( Mouse ); oldpos = GetScreen()->m_Curseur; delta = GetScreen()->GetGridSize(); -#ifdef USE_WX_ZOOM - delta.x = DC->LogicalToDeviceXRel( wxRound( delta.x ) ); - delta.y = DC->LogicalToDeviceYRel( wxRound( delta.y ) ); - Mouse = DrawPanel->CalcUnscrolledPosition( Mouse ); -#else - GetScreen()->Scale( delta ); -#endif + delta.x *= scalar; + delta.y *= scalar; if( delta.x == 0 ) delta.x = 1;