Commit fbeb4116 authored by jean-pierre charras's avatar jean-pierre charras

Eeschema: Fix incorrect behavior of block drag and wire drag commands.

Other minor fixes
parent ed8c021f
......@@ -28,12 +28,13 @@
// Imported functions:
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
void MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
void DeleteItemsInList( WinEDA_DrawPanel* panel, PICKED_ITEMS_LIST& aItemsList );
void DuplicateItemsInList( SCH_SCREEN* screen,
extern void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen );
extern void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
extern void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
extern void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
extern void MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
extern void DeleteItemsInList( WinEDA_DrawPanel* panel, PICKED_ITEMS_LIST& aItemsList );
extern void DuplicateItemsInList( SCH_SCREEN* screen,
PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector );
......@@ -581,7 +582,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
( (SCH_COMPONENT*) Struct )->m_TimeStamp = GetTimeStamp();
( (SCH_COMPONENT*) Struct )->ClearAnnotation( NULL );
}
SetaParent( Struct, GetScreen() );
SetSchItemParent( Struct, GetScreen() );
Struct->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
Struct->SetNext( GetScreen()->GetDrawItems() );
GetScreen()->SetDrawItems( Struct );
......
......@@ -89,14 +89,12 @@ void BreakSegment( SCH_SCREEN* aScreen, wxPoint aBreakpoint )
if( !TestSegmentHit( aBreakpoint, segment->m_Start, segment->m_End, 0 ) )
continue;
/* ???
* Segment connecte: doit etre coupe en 2 si px,py
* n'est
* pas une extremite */
/* A segment is found
* It will be cut if aBreakpoint is not a segment end */
if( ( segment->m_Start == aBreakpoint ) || ( segment->m_End == aBreakpoint ) )
continue;
/* Here we must cut the segment into 2. */
/* Here we must cut the segment and create a new segment. */
NewSegment = new SCH_LINE( *segment );
NewSegment->m_Start = aBreakpoint;
segment->m_End = NewSegment->m_Start;
......
......@@ -23,6 +23,34 @@
#include "sch_junction.h"
void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
{
switch( Struct->Type() )
{
case SCH_POLYLINE_T:
case SCH_JUNCTION_T:
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
case SCH_COMPONENT_T:
case SCH_LINE_T:
case SCH_BUS_ENTRY_T:
case SCH_SHEET_T:
case SCH_MARKER_T:
case SCH_NO_CONNECT_T:
Struct->SetParent( Screen );
break;
case SCH_SHEET_LABEL_T:
break;
default:
break;
}
}
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& rotationPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
......@@ -198,7 +226,7 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
break;
}
SetaParent( newitem, screen );
SetSchItemParent( newitem, screen );
newitem->SetNext( screen->GetDrawItems() );
screen->SetDrawItems( newitem );
}
......
......@@ -232,12 +232,6 @@ void BreakSegmentOnJunction( SCH_SCREEN* Screen );
*/
void BreakSegment(SCH_SCREEN * aScreen, wxPoint aBreakpoint );
/**************/
/* EECLASS.CPP */
/**************/
void SetaParent( SCH_ITEM* Struct, SCH_SCREEN* Screen );
/***************/
/* OPTIONS.CPP */
/***************/
......
......@@ -212,13 +212,13 @@ void SCH_LINE::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset,
if( m_Layer == LAYER_NOTES )
GRDashedLine( &panel->m_ClipBox, DC, start.x, start.y, end.x, end.y, width, color );
else
GRLine( &panel->m_ClipBox, DC, start.x, start.y, end.x, end.y, width, color );
GRLine( &panel->m_ClipBox, DC, start, end, width, color );
if( m_StartIsDangling )
DrawDanglingSymbol( panel, DC, m_Start + offset, color );
DrawDanglingSymbol( panel, DC, start, color );
if( m_EndIsDangling )
DrawDanglingSymbol( panel, DC, m_End + offset, color );
DrawDanglingSymbol( panel, DC, end, color );
}
......@@ -374,6 +374,7 @@ bool SCH_LINE::IsSelectStateChanged( const wxRect& aRect )
if( aRect.Contains( m_Start ) && aRect.Contains( m_End ) )
{
m_Flags |= SELECTED;
m_Flags &= ~(STARTPOINT | ENDPOINT);
}
else if( aRect.Contains( m_Start ) )
{
......
......@@ -152,6 +152,10 @@ void SCH_NO_CONNECT::GetConnectionPoints( vector< wxPoint >& aPoints ) const
aPoints.push_back( m_Pos );
}
bool SCH_NO_CONNECT::doIsConnected( const wxPoint& aPosition ) const
{
return m_Pos == aPosition;
}
bool SCH_NO_CONNECT::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const
{
......
......@@ -95,6 +95,7 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
private:
virtual bool doIsConnected( const wxPoint& aPosition ) const;
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const;
virtual bool doHitTest( const EDA_Rect& aRect, bool aContained, int aAccuracy ) const;
virtual EDA_ITEM* doClone() const;
......
......@@ -25,34 +25,6 @@
#include <boost/foreach.hpp>
void SetaParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
{
switch( Struct->Type() )
{
case SCH_POLYLINE_T:
case SCH_JUNCTION_T:
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
case SCH_COMPONENT_T:
case SCH_LINE_T:
case SCH_BUS_ENTRY_T:
case SCH_SHEET_T:
case SCH_MARKER_T:
case SCH_NO_CONNECT_T:
Struct->SetParent( Screen );
break;
case SCH_SHEET_LABEL_T:
break;
default:
break;
}
}
/* Default EESchema zoom values. Limited to 17 values to keep a decent size
* to menus
*/
......@@ -573,13 +545,29 @@ void SCH_SCREEN::SelectBlockItems()
return;
// Select all the items in the screen connected to the items in the block.
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
// be sure end lines that are on the block limits are seen inside this block
m_BlockLocate.Inflate(1);
unsigned last_select_id = pickedlist->GetCount();
unsigned ii = 0;
for( ; ii < last_select_id; ii++ )
{
item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
if( item->Type() == SCH_LINE_T )
{
item->IsSelectStateChanged( m_BlockLocate );
if( ( item->m_Flags & SELECTED ) == 0 )
{ // This is a special case:
// this selected wire has no ends in block.
// But it was selected (because it intersects the selecting area),
// so we must keep it selected and select items connected to it
// Note: an other option could be: remove it from drag list
item->m_Flags |= SELECTED | SKIP_STRUCT;
std::vector< wxPoint > connections;
item->GetConnectionPoints( connections );
for( size_t i = 0; i < connections.size(); i++ )
addConnectedItemsToBlock( connections[i] );
}
pickedlist->SetPickerFlags( item->m_Flags, ii );
}
else if( item->IsConnectable() )
......@@ -592,6 +580,8 @@ void SCH_SCREEN::SelectBlockItems()
addConnectedItemsToBlock( connections[i] );
}
}
m_BlockLocate.Inflate(-1);
}
......@@ -599,29 +589,42 @@ void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position )
{
SCH_ITEM* item;
ITEM_PICKER picker;
bool addinlist = true;
for( item = GetDrawItems(); item != NULL; item = item->Next() )
{
picker.m_PickedItem = item;
picker.m_PickedItemType = item->Type();
if( item->IsSelected() || !item->IsConnectable() || !item->IsConnected( position ) )
if( !item->IsConnectable() || !item->IsConnected( position ) || (item->m_Flags & SKIP_STRUCT) )
continue;
item->m_Flags = SELECTED;
if( item->IsSelected() && item->Type() != SCH_LINE_T )
continue;
// A line having 2 ends, it can be tested twice: one time per end
if( item->Type() == SCH_LINE_T )
{
if( ! item->IsSelected() ) // First time this line is tested
item->m_Flags = SELECTED | STARTPOINT | ENDPOINT;
else // second time (or more) this line is tested
addinlist = false;
SCH_LINE* line = (SCH_LINE*) item;
if( line->m_Start == position )
item->m_Flags |= ENDPOINT;
item->m_Flags &= ~STARTPOINT;
else if( line->m_End == position )
item->m_Flags |= STARTPOINT;
item->m_Flags &= ~ENDPOINT;
}
else
item->m_Flags = SELECTED;
picker.m_PickerFlags = item->m_Flags;
m_BlockLocate.m_ItemsSelection.PushItem( picker );
if( addinlist )
{
picker.m_PickerFlags = item->m_Flags;
m_BlockLocate.m_ItemsSelection.PushItem( picker );
}
}
}
......
......@@ -464,21 +464,11 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
// Ensure the block selection contains the segment, or one end of
// the segment. The initial rect is only one point (w = h = 0)
// The rect must contains one or 2 ends.
// If only one end is selected, this is a drag Node
// if no ends selected, we adjust the rect area to contain the
// whole segment. This works fine only for H and V segments and
// only if they do not cross a component
// TODO: a better way to drag only wires
SCH_LINE* segm = (SCH_LINE*) screen->GetCurItem();
if( !screen->m_BlockLocate.Contains( segm->m_Start )
&& !screen->m_BlockLocate.Contains( segm->m_End ) )
{
screen->m_BlockLocate.SetOrigin( segm->m_Start );
screen->m_BlockLocate.SetEnd( segm->m_End );
}
// the segment. The initial rect is only one point (w = h = 2)
// The rect contains one or 0 ends.
// If one end is selected, this is a drag Node
// if no ends selected the current segment is dragged
screen->m_BlockLocate.Inflate( 1 );
HandleBlockEnd( &dc );
}
break;
......
......@@ -189,7 +189,11 @@ bool WinEDA_PcbFrame::ReadPcbNetlist( const wxString& aNetlistFullFilename,
GetScreen()->ClearUndoRedoList();
OnModify();
// Clear flags and pointeurs to avoid inconsistencies
GetBoard()->m_Status_Pcb = 0;
SetCurItem( NULL );
State = 0;
Comment = 0;
s_NbNewModules = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment