delete track uses dirty rect

This commit is contained in:
dickelbeck 2008-03-10 15:00:22 +00:00
parent 920ea81061
commit 3bb1764dff
8 changed files with 229 additions and 221 deletions

View File

@ -8,7 +8,7 @@ email address.
2008-Mar-10 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Mar-10 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
+pcbnew +pcbnew
* Improved some comments on new functions. * Improved some comments on new functions dirty area functions
* Changed * Changed
void ConvertPcbUnitsToPixelsUnits( EDA_Rect& aRect ); to void ConvertPcbUnitsToPixelsUnits( EDA_Rect& aRect ); to
void ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect ); void ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect );
@ -21,6 +21,9 @@ email address.
* Changed from "new wxDCClip()" to use an automatic wxDCClip() variable in * Changed from "new wxDCClip()" to use an automatic wxDCClip() variable in
drawpanel.cpp drawpanel.cpp
* Removed a printf() from "release" build of drawpanel.cpp * Removed a printf() from "release" build of drawpanel.cpp
* Added WinEDA_DrawPanel::PostDirtyRect()
* Renamed Supprime_Une_Piste() to Remove_One_Track() and it now uses
PostDirtyRect().
2008-Mar-10 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2008-Mar-10 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>

View File

@ -96,6 +96,18 @@ public:
wxPoint CursorRealPosition( const wxPoint& ScreenPos ); wxPoint CursorRealPosition( const wxPoint& ScreenPos );
wxPoint CursorScreenPosition(); wxPoint CursorScreenPosition();
/**
* Function PostDirtyRect
* appends the given rectangle in pcb units to the DrawPanel's invalid
* region list so that very soon (but not immediately), this rectangle
* along with any other recently posted rectangles is redrawn. Conversion
* to pixels is done in here.
* @param aRect The rectangle to append, it must be orthogonal
* (vertical and horizontal edges only), and it must be [,) in nature, i.e.
* [pos, dim) == [inclusive, exclusive)
*/
void PostDirtyRect( EDA_Rect aRect );
/** /**
* Function ConvertPcbUnitsToPixelsUnits * Function ConvertPcbUnitsToPixelsUnits
* converts pos and size of the given EDA_Rect to pos and size in pixels, * converts pos and size of the given EDA_Rect to pos and size in pixels,

View File

@ -476,7 +476,7 @@ public:
TRACK* Delete_Segment( wxDC* DC, TRACK* Track ); TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
void Delete_Track( wxDC* DC, TRACK* Track ); void Delete_Track( wxDC* DC, TRACK* Track );
void Delete_net( wxDC* DC, TRACK* Track ); void Delete_net( wxDC* DC, TRACK* Track );
void Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm ); void Remove_One_Track( wxDC* DC, TRACK* pt_segm );
bool Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via ); bool Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via );
void Edit_Net_Width( wxDC* DC, int Netcode ); void Edit_Net_Width( wxDC* DC, int Netcode );
void Edit_Track_Width( wxDC* DC, TRACK* Track ); void Edit_Track_Width( wxDC* DC, TRACK* Track );

View File

@ -210,11 +210,37 @@ EDA_Rect TRACK::GetBoundingBox() const
// end of track is round, this is its radius, rounded up // end of track is round, this is its radius, rounded up
int radius = ( m_Width+1 )/2; int radius = ( m_Width+1 )/2;
int ymax = MAX( m_Start.y, m_End.y ); int ymax;
int xmax = MAX( m_Start.x, m_End.x ); int xmax;
int ymin = MIN( m_Start.y, m_End.y ); int ymin;
int xmin = MIN( m_Start.x, m_End.x ); int xmin;
if( Type() == TYPEVIA )
{
// because vias are sometimes drawn larger than their m_Width would
// provide, erasing them using a dirty rect must also compensate for
// possibility (that the via is larger than its m_Width would provide).
// because it is cheap to return a larger BoundingBox, do it so that
// the via gets erased properly. Do not divide width by 2 for this reason.
radius = m_Width;
ymax = m_Start.y;
xmax = m_Start.x;
ymin = m_Start.y;
xmin = m_Start.x;
}
else
{
radius = ( m_Width+1 )/2;
ymax = MAX( m_Start.y, m_End.y );
xmax = MAX( m_Start.x, m_End.x );
ymin = MIN( m_Start.y, m_End.y );
xmin = MIN( m_Start.x, m_End.x );
}
ymax += radius; ymax += radius;
xmax += radius; xmax += radius;
@ -890,39 +916,6 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame )
*/ */
bool TRACK::HitTest( const wxPoint& ref_pos ) bool TRACK::HitTest( const wxPoint& ref_pos )
{ {
#if 0
int l_piste; /* demi-largeur de la piste */
int dx, dy, spot_cX, spot_cY;
int ux0, uy0;
/* calcul des coordonnees du segment teste */
l_piste = m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = m_Start.x;
uy0 = m_Start.y; /* coord de depart */
dx = m_End.x;
dy = m_End.y; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0;
dy -= uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( Type() == TYPEVIA ) /* VIA rencontree */
{
return (double) spot_cX * spot_cX + (double) spot_cY * spot_cY <=
(double) l_piste * l_piste;
}
else
{
if( DistanceTest( l_piste, dx, dy, spot_cX, spot_cY ) )
return true;
}
#else
int radius = m_Width >> 1; int radius = m_Width >> 1;
// (dx, dy) is a vector from m_Start to m_End (an origin of m_Start) // (dx, dy) is a vector from m_Start to m_End (an origin of m_Start)
@ -944,8 +937,6 @@ bool TRACK::HitTest( const wxPoint& ref_pos )
return true; return true;
} }
#endif
return false; return false;
} }

View File

@ -792,7 +792,7 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche )
oldpercent = -1; oldpercent = -1;
frame->m_Pcb->m_Status_Pcb = 0; frame->m_Pcb->m_Status_Pcb = 0;
frame->Supprime_Une_Piste( DC, segment ); frame->Remove_One_Track( DC, segment );
next = frame->m_Pcb->m_Track; /* NextS a peut etre ete efface */ next = frame->m_Pcb->m_Track; /* NextS a peut etre ete efface */
if( affiche ) if( affiche )

View File

@ -119,29 +119,8 @@ TRACK* WinEDA_PcbFrame::Delete_Segment( wxDC* DC, TRACK* Track )
current_net_code = Track->GetNet(); current_net_code = Track->GetNet();
#if 0
Track->Draw( DrawPanel, DC, GR_XOR );
#else
// redraw the area where the track was // redraw the area where the track was
// this rectangle is correct DrawPanel->PostDirtyRect( Track->GetBoundingBox() );
EDA_Rect dirty = Track->GetBoundingBox();
// Convert the rect coordinates and size in pixels (make a draw clip box):
DrawPanel->ConvertPcbUnitsToPixelsUnits( &dirty );
/* now that TRACK::GetBoundingBox() returns a [,) type of rectangle, and
rounds up the track radius, let's see if this is really needed.
// Ensure the last line and column are in the dirty rectangle after truncatures
dirty.m_Size.x += 1; dirty.m_Size.y += 1;
*/
// pass wxRect() via EDA_Rect::operator wxRect() overload
DrawPanel->RefreshRect( dirty, TRUE );
#endif
SaveItemEfface( Track, 1 ); SaveItemEfface( Track, 1 );
GetScreen()->SetModify(); GetScreen()->SetModify();
@ -159,7 +138,7 @@ void WinEDA_PcbFrame::Delete_Track( wxDC* DC, TRACK* Track )
if( Track != NULL ) if( Track != NULL )
{ {
int current_net_code = Track->GetNet(); int current_net_code = Track->GetNet();
Supprime_Une_Piste( DC, Track ); Remove_One_Track( DC, Track );
GetScreen()->SetModify(); GetScreen()->SetModify();
test_1_net_connexion( DC, current_net_code ); test_1_net_connexion( DC, current_net_code );
} }
@ -205,7 +184,7 @@ void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* Track )
/********************************************************************/ /********************************************************************/
void WinEDA_PcbFrame::Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm ) void WinEDA_PcbFrame::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
/********************************************************************/ /********************************************************************/
/* Routine de suppression de 1 piste: /* Routine de suppression de 1 piste:
@ -213,26 +192,25 @@ void WinEDA_PcbFrame::Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm )
* jusqu'a un pad ou un point de jonction de plus de 2 segments * jusqu'a un pad ou un point de jonction de plus de 2 segments
*/ */
{ {
TRACK* pt_track, * Struct; TRACK* trackList;
int ii, nb_segm; int nb_segm;
if( pt_segm == NULL ) if( pt_segm == NULL )
return; return;
pt_track = Marque_Une_Piste( this, DC, pt_segm, trackList = Marque_Une_Piste( this, DC, pt_segm, &nb_segm, 0 );
&nb_segm, GR_OR | GR_SURBRILL );
if( nb_segm ) /* Il y a nb_segm segments de piste a effacer */ if( nb_segm ) /* Il y a nb_segm segments de piste a effacer */
{ {
Trace_Une_Piste( DrawPanel, DC, pt_track, nb_segm, GR_XOR | GR_SURBRILL ); TRACK* t;
int ii;
/* Effacement flag BUSY */ for( t = trackList, ii=0; ii<nb_segm; ii++, t = t->Next() )
Struct = pt_track;;
for( ii = 0; ii<nb_segm; ii++, Struct = (TRACK*) Struct->Pnext )
{ {
Struct->SetState( BUSY, OFF ); t->SetState( BUSY, OFF );
DrawPanel->PostDirtyRect( t->GetBoundingBox() );
} }
SaveItemEfface( pt_track, nb_segm ); SaveItemEfface( trackList, nb_segm );
} }
} }

View File

@ -110,17 +110,23 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC,
int layer; int layer;
if( Segm->RefTrack->Type() != TYPEVIA ) if( Segm->RefTrack->Type() != TYPEVIA )
continue; continue;
if( Segm->RefTrack == pt_segm ) if( Segm->RefTrack == pt_segm )
continue; continue;
Segm->RefTrack->SetState( BUSY, ON ); Segm->RefTrack->SetState( BUSY, ON );
masque_layer = Segm->RefTrack->ReturnMaskLayer(); masque_layer = Segm->RefTrack->ReturnMaskLayer();
Track = Fast_Locate_Piste( frame->m_Pcb->m_Track, NULL, Track = Fast_Locate_Piste( frame->m_Pcb->m_Track, NULL,
Segm->RefTrack->m_Start, Segm->RefTrack->m_Start,
masque_layer ); masque_layer );
if( Track == NULL ) if( Track == NULL )
continue; continue;
/* Test des connexions: si via utile: suppression marquage */ /* Test des connexions: si via utile: suppression marquage */
layer = Track->GetLayer(); layer = Track->GetLayer();
while( ( Track = Fast_Locate_Piste( (TRACK*) Track->Pnext, NULL, while( ( Track = Fast_Locate_Piste( (TRACK*) Track->Pnext, NULL,
Segm->RefTrack->m_Start, Segm->RefTrack->m_Start,
masque_layer ) ) != NULL ) masque_layer ) ) != NULL )
@ -136,7 +142,8 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC,
/* liberation memoire */ /* liberation memoire */
for( Segm = ListSegm; Segm != NULL; Segm = NextSegm ) for( Segm = ListSegm; Segm != NULL; Segm = NextSegm )
{ {
NextSegm = Segm->Pnext; delete Segm; NextSegm = Segm->Pnext;
delete Segm;
} }
ListSegm = NULL; ListSegm = NULL;
@ -144,10 +151,12 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC,
/* Reclassement des segments marques en une chaine */ /* Reclassement des segments marques en une chaine */
FirstTrack = frame->m_Pcb->m_Track; NbSegmBusy = 0; FirstTrack = frame->m_Pcb->m_Track; NbSegmBusy = 0;
for( ; FirstTrack != NULL; FirstTrack = (TRACK*) FirstTrack->Pnext ) for( ; FirstTrack != NULL; FirstTrack = (TRACK*) FirstTrack->Pnext )
{ /* recherche du debut de la liste des segments marques a BUSY */ {
/* recherche du debut de la liste des segments marques a BUSY */
if( FirstTrack->GetState( BUSY ) ) if( FirstTrack->GetState( BUSY ) )
{ {
NbSegmBusy = 1; break; NbSegmBusy = 1;
break;
} }
} }

View File

@ -266,6 +266,21 @@ bool WinEDA_DrawPanel::IsPointOnDisplay( wxPoint ref_pos )
} }
void WinEDA_DrawPanel::PostDirtyRect( EDA_Rect aRect )
{
// Convert the rect coordinates and size to pixels (make a draw clip box):
ConvertPcbUnitsToPixelsUnits( &aRect );
// Ensure the last line and column are in the dirty rectangle after truncations.
// The pcb units have finer granularity than the pixels, so this can happen.
aRect.m_Size.x += 1;
aRect.m_Size.y += 1;
// pass wxRect() via EDA_Rect::operator wxRect() overload
RefreshRect( aRect, TRUE );
}
/************************************************************************/ /************************************************************************/
void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect ) void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect )
/************************************************************************/ /************************************************************************/