From 54b561236f0da0dce4389513085829901d622b33 Mon Sep 17 00:00:00 2001 From: charras Date: Tue, 12 Jan 2010 13:15:13 +0000 Subject: [PATCH] Uses a buffered DC in OnPaint event. Seems solve slow grid redraw on some PC. --- CHANGELOG.txt | 8 ++++ CMakeLists.txt | 3 +- common/drawpanel.cpp | 6 --- common/zoom.cpp | 42 +++++++++---------- include/class_drawpanel.h | 1 - include/kicad_device_context.h | 27 ++++++++---- pcbnew/class_zone.cpp | 6 +-- pcbnew/class_zone.h | 3 +- pcbnew/class_zone_setting.cpp | 5 ++- pcbnew/dialog_copper_zones.cpp | 10 +++-- pcbnew/pcbnew.h | 4 ++ .../zones_convert_brd_items_to_polygons.cpp | 13 +++--- 12 files changed, 73 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 68c4eabe86..b4b0b4da7b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,14 @@ KiCad ChangeLog 2009 Please add newer entries at the top, list the date and your name with email address. +2010-Jan-12 UPDATE Jean-Pierre Charras +================================================================================ +++All + Use wxAutoBufferedPaintDC in OnPaint event + Seems solves slow grid redraw on some PC (tested under Window 7) + and is faster than use wxPaintDC, not buffered + (note MACOSX has natively a double buffer, so no change for MACOSX) + 2010-Jan-08 UPDATE Jean-Pierre Charras ================================================================================ ++Gerbview diff --git a/CMakeLists.txt b/CMakeLists.txt index 94989bf076..90aed790d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,8 @@ check_find_package_result(OPENGL_FOUND "OpenGL") # http://www.wxwidgets.org/manuals/2.8/wx_librarieslist.html if( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) - find_package(wxWidgets COMPONENTS gl html adv core net base aui QUIET) +# find_package(wxWidgets COMPONENTS gl html adv core net base aui QUIET) + find_package(wxWidgets COMPONENTS gl html adv core net base QUIET) else( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) find_package(wxWidgets COMPONENTS gl html adv core net base QUIET) endif( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) diff --git a/common/drawpanel.cpp b/common/drawpanel.cpp index 187d621a0c..ffd203d85f 100644 --- a/common/drawpanel.cpp +++ b/common/drawpanel.cpp @@ -421,12 +421,6 @@ void WinEDA_DrawPanel::OnActivate( wxActivateEvent& event ) } -void WinEDA_DrawPanel::OnEraseBackground( wxEraseEvent& event ) -{ - event.Skip(); -} - - void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event ) { int id = event.GetEventType(); diff --git a/common/zoom.cpp b/common/zoom.cpp index d5f878cced..a6836463b5 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -15,8 +15,6 @@ #include "class_base_screen.h" #include "wxstruct.h" -#include "kicad_device_context.h" - /** Compute draw offset (scroll bars and draw parameters) * in order to have the current graphic cursor position at the screen center * @param ToMouse if TRUE, the mouse cursor is moved @@ -28,8 +26,8 @@ void WinEDA_DrawFrame::Recadre_Trace( bool ToMouse ) { PutOnGrid( &(GetBaseScreen()->m_Curseur) ); AdjustScrollBars(); - INSTALL_DC( dc, DrawPanel ) ; - DrawPanel->ReDraw( &dc ); + DrawPanel->Refresh(); // send OnPaint event + wxSafeYield(); // needed to allow OnPaint event execution here /* Move the mouse cursor to the on grid graphic cursor position */ if( ToMouse == TRUE ) @@ -40,8 +38,8 @@ void WinEDA_DrawFrame::Recadre_Trace( bool ToMouse ) /** Adjust the coordinate to the nearest grid value -* @param coord = coordinate to adjust -*/ + * @param coord = coordinate to adjust + */ void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord ) { wxRealPoint grid_size = GetBaseScreen()->GetGridSize(); @@ -52,7 +50,7 @@ void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord ) coord->x = wxRound( tmp * grid_size.x ); tmp = wxRound( coord->y / grid_size.y ); - coord->y = wxRound ( tmp * grid_size.y ); + coord->y = wxRound( tmp * grid_size.y ); } } @@ -73,15 +71,16 @@ void WinEDA_DrawFrame::Zoom_Automatique( bool move_mouse_cursor ) */ void WinEDA_DrawFrame::Window_Zoom( EDA_Rect& Rect ) { - double scalex, bestscale; + double scalex, bestscale; wxSize size; /* Compute the best zoom */ Rect.Normalize(); - size = DrawPanel->GetClientSize(); + size = DrawPanel->GetClientSize(); + // Use ceil to at least show the full rect - scalex = (double) Rect.GetSize().x / size.x; - bestscale = (double)Rect.GetSize().y / size.y; + scalex = (double) Rect.GetSize().x / size.x; + bestscale = (double) Rect.GetSize().y / size.y; bestscale = MAX( bestscale, scalex ); GetBaseScreen()->SetScalingFactor( bestscale ); @@ -96,7 +95,7 @@ void WinEDA_DrawFrame::Window_Zoom( EDA_Rect& Rect ) void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event ) { if( DrawPanel == NULL ) - return; + return; int i; int id = event.GetId(); @@ -107,7 +106,8 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event ) { case ID_POPUP_ZOOM_IN: zoom_at_cursor = true; - // fall thru + + // fall thru case ID_ZOOM_IN: if( id == ID_ZOOM_IN ) @@ -118,7 +118,8 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event ) case ID_POPUP_ZOOM_OUT: zoom_at_cursor = true; - // fall thru + + // fall thru case ID_ZOOM_OUT: if( id == ID_ZOOM_OUT ) @@ -128,12 +129,7 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event ) break; case ID_ZOOM_REDRAW: - // DrawPanel->Refresh(); usually good, - // but does not work under linux, when called from here (wxGTK bug ?) - { - INSTALL_DC( dc, DrawPanel ); - DrawPanel->ReDraw( &dc ); - } + DrawPanel->Refresh(); break; case ID_POPUP_ZOOM_CENTER: @@ -199,12 +195,12 @@ void WinEDA_DrawPanel::AddMenuZoom( wxMenu* MasterMenu ) zoom = GetScreen()->GetZoom(); maxZoomIds = ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START; maxZoomIds = ( (size_t) maxZoomIds < GetScreen()->m_ZoomList.GetCount() ) ? - maxZoomIds : GetScreen()->m_ZoomList.GetCount(); + maxZoomIds : GetScreen()->m_ZoomList.GetCount(); /* Populate zoom submenu. */ for( i = 0; i < (size_t) maxZoomIds; i++ ) { - if ( ( GetScreen()->m_ZoomList[i] % GetScreen()->m_ZoomScalar ) == 0 ) + if( ( GetScreen()->m_ZoomList[i] % GetScreen()->m_ZoomScalar ) == 0 ) msg.Printf( wxT( "%u" ), GetScreen()->m_ZoomList[i] / GetScreen()->m_ZoomScalar ); else @@ -240,7 +236,7 @@ void WinEDA_DrawPanel::AddMenuZoom( wxMenu* MasterMenu ) } else { - if ( g_UnitMetric == 0 ) // inches + if( g_UnitMetric == 0 ) // inches msg.Printf( wxT( "%.1f mils" ), gridValue * 1000 ); else msg.Printf( wxT( "%.3f mm" ), gridValue ); diff --git a/include/class_drawpanel.h b/include/class_drawpanel.h index 7553256935..2ddd535ec4 100644 --- a/include/class_drawpanel.h +++ b/include/class_drawpanel.h @@ -99,7 +99,6 @@ public: void* aData ); void DrawBackGround( wxDC* DC ); void DrawAuxiliaryAxis( wxDC* DC, int drawmode ); - void OnEraseBackground( wxEraseEvent& event ); void OnActivate( wxActivateEvent& event ); /* Mouse and keys events */ diff --git a/include/kicad_device_context.h b/include/kicad_device_context.h index d1610e8ee2..18365388af 100644 --- a/include/kicad_device_context.h +++ b/include/kicad_device_context.h @@ -10,8 +10,15 @@ // and uncomment to use buffered DC // #define KICAD_USE_BUFFERED_DC // Currently under test -#ifdef KICAD_USE_BUFFERED_DC -#include +// Comment this line to use the standard wxPaintDC +// and uncomment to use buffered PaintDC +#define KICAD_USE_BUFFERED_PAINTDC // Currently under test + +#if defined KICAD_USE_BUFFERED_DC || defined KICAD_USE_BUFFERED_PAINTDC + #ifndef KICAD_USE_BUFFERED_PAINTDC + #define KICAD_USE_BUFFERED_PAINTDC + #endif + #include #endif // Helper class to handle the client Device Context @@ -27,14 +34,16 @@ public: #ifdef KICAD_USE_BUFFERED_DC #define INSTALL_DC(name,parent) \ -KicadGraphicContext _cDC( parent );\ -wxBufferedDC name(&_cDC, _cDC.GetSize() ); - -#define INSTALL_PAINTDC(name,parent) wxBufferedPaintDC name(parent ) - + KicadGraphicContext _cDC( parent );\ + wxBufferedDC name(&_cDC, _cDC.GetSize() ); #else -#define INSTALL_DC(name,parent) KicadGraphicContext name( parent ) -#define INSTALL_PAINTDC(name,parent) wxPaintDC name( parent ) + #define INSTALL_DC(name,parent) KicadGraphicContext name( parent ) +#endif + +#ifdef KICAD_USE_BUFFERED_PAINTDC + #define INSTALL_PAINTDC(name,parent) wxAutoBufferedPaintDC name(parent ) +#else + #define INSTALL_PAINTDC(name,parent) wxPaintDC name( parent ) #endif #endif // __KICAD_DEVICE_CONTEXT_H__ diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 4099f627fb..2b6947a273 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -318,7 +318,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) else if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found { int fillmode = 1; - int arcsegmentcount = 16; + int arcsegmentcount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; char fillstate = 'F'; text = Line + 8; ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &fillstate, @@ -329,8 +329,8 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) else m_FillMode = fillmode ? 1 : 0; - if( arcsegmentcount >= 32 ) - m_ArcToSegmentsCount = 32; + if( arcsegmentcount >= ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ) + m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF; m_IsFilled = fillstate == 'F' ? true : false; } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 702df763f8..ee2d771052 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -42,7 +42,8 @@ public: int m_ZoneClearance; // clearance value int m_ZoneMinThickness; // Min thickness value in filled areas int m_FillMode; // How to fillingareas: 0 = use polygonal areas , != 0 fill with segments - int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon (uses 16 or 32) + int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon + // (uses ARC_APPROX_SEGMENTS_COUNT_LOW_DEF or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF) int m_PadOption; // int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs diff --git a/pcbnew/class_zone_setting.cpp b/pcbnew/class_zone_setting.cpp index 433672f9f4..5973233e07 100644 --- a/pcbnew/class_zone_setting.cpp +++ b/pcbnew/class_zone_setting.cpp @@ -30,8 +30,9 @@ ZONE_SETTING::ZONE_SETTING( void ) m_NetcodeSelection = 0; // Net code selection for the current zone m_CurrentZone_Layer = 0; // Layer used to create the current zone m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches - m_ArcToSegmentsCount = 16; /* Option to select number of segments to approximate a circle - * 16 or 32 segments */ + m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; /* Option to select number of segments to approximate a circle + * ARC_APPROX_SEGMENTS_COUNT_LOW_DEF + * or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments */ m_ThermalReliefGapValue = 200; // tickness of the gap in thermal reliefs m_ThermalReliefCopperBridgeValue = 200; // tickness of the copper bridge in thermal reliefs diff --git a/pcbnew/dialog_copper_zones.cpp b/pcbnew/dialog_copper_zones.cpp index 80bc6c24b0..0708babb91 100644 --- a/pcbnew/dialog_copper_zones.cpp +++ b/pcbnew/dialog_copper_zones.cpp @@ -33,7 +33,7 @@ dialog_copper_zone::dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* z m_Config = wxGetApp().m_EDA_Config; m_Zone_Setting = zone_setting; m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort, and filtering net names - m_OnExitCode = ZONE_ABORT; + m_OnExitCode = ZONE_ABORT; if( m_Config ) { @@ -124,7 +124,8 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) break; } - m_ArcApproximationOpt->SetSelection( m_Zone_Setting->m_ArcToSegmentsCount == 32 ? 1 : 0 ); + m_ArcApproximationOpt->SetSelection( + m_Zone_Setting->m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 ); /* build copper layers list */ int layer_cnt = board->GetCopperLayerCount(); @@ -253,7 +254,9 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab break; } - m_Zone_Setting->m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? 32 : 16; + m_Zone_Setting->m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? + ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF : + ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; if( m_Config ) { @@ -437,6 +440,7 @@ void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event ) m_Zone_Setting->ExportSetting( *zone, false ); // false = partiel export m_Parent->GetScreen()->SetModify(); } + m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones } diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h index 6f4e42f54e..7dfdcf28d1 100644 --- a/pcbnew/pcbnew.h +++ b/pcbnew/pcbnew.h @@ -10,6 +10,10 @@ #define U_PCB (PCB_INTERNAL_UNIT / EESCHEMA_INTERNAL_UNIT) +// Arcs are appromed by segments: define the number of segments per 360 deg (kicad use 0.1 deg approx: +#define ARC_APPROX_SEGMENTS_COUNT_LOW_DEF 16 // be aware 3600/ARC_APPROX_SEGMENTS_COUNT_LOW_DEF is an integer +#define ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF 32 + /* Flag used in locate functions * the locate ref point is the on grid cursor or the off grid mouse cursor */ #define CURSEUR_ON_GRILLE (0 << 0) diff --git a/pcbnew/zones_convert_brd_items_to_polygons.cpp b/pcbnew/zones_convert_brd_items_to_polygons.cpp index 5644b41cb7..2eb3540816 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons.cpp @@ -75,9 +75,10 @@ void AddRoundedEndsSegmentPolygon( Bool_Engine* aBooleng, // Local Variables: /* how many segments are used to create a polygon from a circle: */ -static int s_CircleToSegmentsCount = 16; /* default value. the real value will be changed to 32 - * if g_Zone_Arc_Approximation == 1 - */ +static int s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; /* default value. the real value will be changed to + * ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF + * if m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF + */ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (and vias) * because the segment approximation for arcs and circles * create a smaller gap than a true circle @@ -129,10 +130,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) bool have_poly_to_substract = false; // Set the number of segments in arc approximations - if( m_ArcToSegmentsCount == 32 ) - s_CircleToSegmentsCount = 32; + if( m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ) + s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF; else - s_CircleToSegmentsCount = 16; + s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; /* calculates the coeff to compensate radius reduction of holes clearance * due to the segment approx.