Commit aeb6dd8c authored by Wayne Stambaugh's avatar Wayne Stambaugh

Minor schematic object improvements and code cleaning.

parent 35843238
...@@ -4,6 +4,20 @@ KiCad ChangeLog 2010 ...@@ -4,6 +4,20 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-nov-3 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
================================================================================
++common
* Initial ground work for using Boost container for storing draw items
instead of internal linked list.
++EESchema
* Move tests for dangling end code back into schematic objects.
* Add clear draw object state helper to SCH_SCREEN object.
* Add support for schematic objects to keep temporary list of connection
objects for dangling end and other connection related tests.
* Rearrange schematic label object code.
* Remove duplicate error message boxes when loading schematic items.
2010-oct-28, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-oct-28, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
PolyLine.cpp: PolyLine.cpp:
......
...@@ -542,6 +542,22 @@ PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromRedoList( ) ...@@ -542,6 +542,22 @@ PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromRedoList( )
} }
void BASE_SCREEN::AddItem( EDA_BaseStruct* aItem )
{
wxCHECK_RET( aItem != NULL, wxT( "Attempt to add NULL item pointer to " ) + GetClass() +
wxT( "item list" ) );
m_items.push_back( aItem );
}
void BASE_SCREEN::InsertItem( EDA_ITEMS::iterator aIter, EDA_BaseStruct* aItem )
{
wxCHECK_RET( aItem != NULL, wxT( "Attempt to insert NULL item pointer to " ) + GetClass() +
wxT( "item list" ) );
m_items.insert( aIter, aItem );
}
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function Show * Function Show
......
...@@ -19,16 +19,11 @@ ...@@ -19,16 +19,11 @@
// Imported functions: // Imported functions:
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
const wxPoint aMoveVector ); void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
wxPoint& Center ); void MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, void DeleteItemsInList( WinEDA_DrawPanel* panel, 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, void DuplicateItemsInList( SCH_SCREEN* screen,
PICKED_ITEMS_LIST& aItemsList, PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector ); const wxPoint aMoveVector );
...@@ -38,9 +33,7 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint aPosition ); ...@@ -38,9 +33,7 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint aPosition );
static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem, static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
wxPoint& aPosition, wxPoint& aPosition,
bool aSearchFirst ); bool aSearchFirst );
static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
wxDC* DC,
bool erase );
static void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList ); static void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList );
...@@ -114,8 +107,7 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC ) ...@@ -114,8 +107,7 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC )
{ {
wxString msg; wxString msg;
err = TRUE; err = TRUE;
msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd \ msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd %d, state %d)" ),
%d, state %d)" ),
block->m_Command, block->m_State ); block->m_Command, block->m_State );
DisplayError( this, msg ); DisplayError( this, msg );
} }
...@@ -136,10 +128,7 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC ) ...@@ -136,10 +128,7 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC )
if( DrawPanel->ManageCurseur ) if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
SaveCopyInUndoList( block->m_ItemsSelection, SaveCopyInUndoList( block->m_ItemsSelection, UR_MOVED, block->m_MoveVector );
UR_MOVED,
block->m_MoveVector );
MoveItemsInList( block->m_ItemsSelection, block->m_MoveVector ); MoveItemsInList( block->m_ItemsSelection, block->m_MoveVector );
block->ClearItemsList(); block->ClearItemsList();
break; break;
...@@ -149,13 +138,10 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC ) ...@@ -149,13 +138,10 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC )
if( DrawPanel->ManageCurseur ) if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
DuplicateItemsInList( DuplicateItemsInList( GetScreen(), block->m_ItemsSelection, block->m_MoveVector );
GetScreen(), block->m_ItemsSelection, block->m_MoveVector );
SaveCopyInUndoList( SaveCopyInUndoList( block->m_ItemsSelection,
block->m_ItemsSelection, ( block->m_Command == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW );
(block->m_Command ==
BLOCK_PRESELECT_MOVE) ? UR_CHANGED : UR_NEW );
block->ClearItemsList(); block->ClearItemsList();
break; break;
...@@ -178,12 +164,8 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC ) ...@@ -178,12 +164,8 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC )
OnModify(); OnModify();
/* clear struct.m_Flags */ // clear struct.m_Flags.
SCH_ITEM* Struct; GetScreen()->ClearDrawingState();
for( Struct = GetScreen()->EEDrawList;
Struct != NULL;
Struct = Struct->Next() )
Struct->m_Flags = 0;
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
...@@ -196,13 +178,11 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC ) ...@@ -196,13 +178,11 @@ void WinEDA_SchematicFrame::HandleBlockPlace( wxDC* DC )
if( block->GetCount() ) if( block->GetCount() )
{ {
DisplayError( this, DisplayError( this, wxT( "HandleBlockPLace() error: some items left in buffer" ) );
wxT( "HandleBlockPLace() error: some items left in buffer" ) );
block->ClearItemsList(); block->ClearItemsList();
} }
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
wxEmptyString );
DrawPanel->Refresh(); DrawPanel->Refresh();
} }
...@@ -288,11 +268,9 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC ) ...@@ -288,11 +268,9 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC )
DrawAndSizingBlockOutlines( DrawPanel, DC, FALSE ); DrawAndSizingBlockOutlines( DrawPanel, DC, FALSE );
if( block->GetCount() ) if( block->GetCount() )
{ {
wxPoint move_vector = wxPoint move_vector = -GetScreen()->m_BlockLocate.m_BlockLastCursorPosition;
-GetScreen()->m_BlockLocate.m_BlockLastCursorPosition;
SaveStructListForPaste( block->m_ItemsSelection ); SaveStructListForPaste( block->m_ItemsSelection );
MoveItemsInList( g_BlockSaveDataList.m_ItemsSelection, MoveItemsInList( g_BlockSaveDataList.m_ItemsSelection, move_vector );
move_vector );
ii = -1; ii = -1;
} }
block->ClearItemsList(); block->ClearItemsList();
...@@ -317,12 +295,7 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC ) ...@@ -317,12 +295,7 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC )
if( block->m_Command == BLOCK_ABORT ) if( block->m_Command == BLOCK_ABORT )
{ {
/* clear struct.m_Flags */ GetScreen()->ClearDrawingState();
EDA_BaseStruct* Struct;
for( Struct = GetScreen()->EEDrawList;
Struct != NULL;
Struct = Struct->Next() )
Struct->m_Flags = 0;
} }
if( ii <= 0 ) if( ii <= 0 )
...@@ -333,9 +306,7 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC ) ...@@ -333,9 +306,7 @@ int WinEDA_SchematicFrame::HandleBlockEnd( wxDC* DC )
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->SetCurItem( NULL ); GetScreen()->SetCurItem( NULL );
SetToolID( m_ID_current_state, SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
DrawPanel->m_PanelDefaultCursor,
wxEmptyString );
} }
if( zoom_command ) if( zoom_command )
...@@ -415,8 +386,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -415,8 +386,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
if( block->GetCount() ) if( block->GetCount() )
{ {
wxPoint move_vector = wxPoint move_vector = -GetScreen()->m_BlockLocate.m_BlockLastCursorPosition;
-GetScreen()->m_BlockLocate.m_BlockLastCursorPosition;
SaveStructListForPaste( block->m_ItemsSelection ); SaveStructListForPaste( block->m_ItemsSelection );
MoveItemsInList( g_BlockSaveDataList.m_ItemsSelection, move_vector ); MoveItemsInList( g_BlockSaveDataList.m_ItemsSelection, move_vector );
} }
...@@ -424,8 +394,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -424,8 +394,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
case BLOCK_ZOOM: /* Window Zoom */ case BLOCK_ZOOM: /* Window Zoom */
DrawPanel->ForceCloseManageCurseur( DrawPanel, DC ); DrawPanel->ForceCloseManageCurseur( DrawPanel, DC );
DrawPanel->SetCursor( DrawPanel->SetCursor( DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor );
DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor );
Window_Zoom( GetScreen()->m_BlockLocate ); Window_Zoom( GetScreen()->m_BlockLocate );
break; break;
...@@ -439,9 +408,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -439,9 +408,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
/* Compute the rotation center and put it on grid */ /* Compute the rotation center and put it on grid */
wxPoint rotationPoint = block->Centre(); wxPoint rotationPoint = block->Centre();
PutOnGrid( &rotationPoint ); PutOnGrid( &rotationPoint );
SaveCopyInUndoList( block->m_ItemsSelection, SaveCopyInUndoList( block->m_ItemsSelection, UR_ROTATED, rotationPoint );
UR_ROTATED,
rotationPoint );
RotateListOfItems( block->m_ItemsSelection, rotationPoint ); RotateListOfItems( block->m_ItemsSelection, rotationPoint );
OnModify(); OnModify();
} }
...@@ -460,9 +427,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -460,9 +427,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
/* Compute the mirror center and put it on grid */ /* Compute the mirror center and put it on grid */
wxPoint mirrorPoint = block->Centre(); wxPoint mirrorPoint = block->Centre();
PutOnGrid( &mirrorPoint ); PutOnGrid( &mirrorPoint );
SaveCopyInUndoList( block->m_ItemsSelection, SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_X, mirrorPoint );
UR_MIRRORED_X,
mirrorPoint );
Mirror_X_ListOfItems( block->m_ItemsSelection, mirrorPoint ); Mirror_X_ListOfItems( block->m_ItemsSelection, mirrorPoint );
OnModify(); OnModify();
// block->m_State = STATE_BLOCK_MOVE; // block->m_State = STATE_BLOCK_MOVE;
...@@ -481,9 +446,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -481,9 +446,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
/* Compute the mirror center and put it on grid */ /* Compute the mirror center and put it on grid */
wxPoint mirrorPoint = block->Centre(); wxPoint mirrorPoint = block->Centre();
PutOnGrid( &mirrorPoint ); PutOnGrid( &mirrorPoint );
SaveCopyInUndoList( block->m_ItemsSelection, SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_Y, mirrorPoint );
UR_MIRRORED_Y,
mirrorPoint );
MirrorListOfItems( block->m_ItemsSelection, mirrorPoint ); MirrorListOfItems( block->m_ItemsSelection, mirrorPoint );
OnModify(); OnModify();
// block->m_State = STATE_BLOCK_MOVE; // block->m_State = STATE_BLOCK_MOVE;
...@@ -506,9 +469,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -506,9 +469,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->SetCurItem( NULL ); GetScreen()->SetCurItem( NULL );
SetToolID( m_ID_current_state, SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
DrawPanel->m_PanelDefaultCursor,
wxEmptyString );
} }
} }
...@@ -516,8 +477,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC ) ...@@ -516,8 +477,7 @@ void WinEDA_SchematicFrame::HandleBlockEndByPopUp( int Command, wxDC* DC )
/* Traces the outline of the search block structures /* Traces the outline of the search block structures
* The entire block follows the cursor * The entire block follows the cursor
*/ */
static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
bool erase )
{ {
BLOCK_SELECTOR* block = &panel->GetScreen()->m_BlockLocate;; BLOCK_SELECTOR* block = &panel->GetScreen()->m_BlockLocate;;
...@@ -555,9 +515,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -555,9 +515,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC,
*/ */
void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList ) void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList )
{ {
g_BlockSaveDataList.ClearListAndDeleteItems(); // delete previous g_BlockSaveDataList.ClearListAndDeleteItems(); // delete previous saved list, if exists
// saved list, if
// exists
/* save the new list: */ /* save the new list: */
ITEM_PICKER item; ITEM_PICKER item;
...@@ -569,8 +527,7 @@ void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList ) ...@@ -569,8 +527,7 @@ void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList )
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{ {
/* Make a copy of the original picked item. */ /* Make a copy of the original picked item. */
SCH_ITEM* DrawStructCopy = DuplicateStruct( SCH_ITEM* DrawStructCopy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
(SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
DrawStructCopy->SetParent( NULL ); DrawStructCopy->SetParent( NULL );
item.m_PickedItem = DrawStructCopy; item.m_PickedItem = DrawStructCopy;
g_BlockSaveDataList.PushItem( item ); g_BlockSaveDataList.PushItem( item );
...@@ -599,8 +556,7 @@ void WinEDA_SchematicFrame::PasteListOfItems( wxDC* DC ) ...@@ -599,8 +556,7 @@ void WinEDA_SchematicFrame::PasteListOfItems( wxDC* DC )
for( unsigned ii = 0; ii < g_BlockSaveDataList.GetCount(); ii++ ) for( unsigned ii = 0; ii < g_BlockSaveDataList.GetCount(); ii++ )
{ {
Struct = DuplicateStruct( Struct = DuplicateStruct(
(SCH_ITEM*) g_BlockSaveDataList.m_ItemsSelection.GetPickedItem( (SCH_ITEM*) g_BlockSaveDataList.m_ItemsSelection.GetPickedItem( ii ) );
ii ) );
picker.m_PickedItem = Struct; picker.m_PickedItem = Struct;
picklist.PushItem( picker ); picklist.PushItem( picker );
...@@ -621,10 +577,7 @@ void WinEDA_SchematicFrame::PasteListOfItems( wxDC* DC ) ...@@ -621,10 +577,7 @@ void WinEDA_SchematicFrame::PasteListOfItems( wxDC* DC )
MoveItemsInList( picklist, GetScreen()->m_BlockLocate.m_MoveVector ); MoveItemsInList( picklist, GetScreen()->m_BlockLocate.m_MoveVector );
/* clear .m_Flags member for all items */ /* clear .m_Flags member for all items */
for( Struct = GetScreen()->EEDrawList; GetScreen()->ClearDrawingState();
Struct != NULL;
Struct = Struct->Next() )
Struct->m_Flags = 0;
OnModify(); OnModify();
...@@ -646,11 +599,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen ) ...@@ -646,11 +599,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
if( pickedlist->GetCount() == 0 ) if( pickedlist->GetCount() == 0 )
return; return;
/* .m_Flags member is used to handle how a wire is exactly selected screen->ClearDrawingState();
* (fully selected, or partially selected by an end point )
*/
for( Struct = screen->EEDrawList; Struct != NULL; Struct = Struct->Next() )
Struct->m_Flags = 0;
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ ) for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{ {
...@@ -724,7 +673,8 @@ static void CollectStructsToDrag( SCH_SCREEN* screen ) ...@@ -724,7 +673,8 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
SCH_SHEET* sheet = (SCH_SHEET*) Struct; SCH_SHEET* sheet = (SCH_SHEET*) Struct;
// Add all pins sheets of a selected hierarchical sheet to the list // Add all pins sheets of a selected hierarchical sheet to the list
BOOST_FOREACH( SCH_SHEET_PIN label, sheet->GetSheetPins() ) { BOOST_FOREACH( SCH_SHEET_PIN label, sheet->GetSheetPins() )
{
AddPickedItem( screen, label.m_Pos ); AddPickedItem( screen, label.m_Pos );
} }
} }
......
...@@ -898,6 +898,70 @@ void SCH_SHEET::renumberLabels() ...@@ -898,6 +898,70 @@ void SCH_SHEET::renumberLabels()
} }
void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
// Using BOOST_FOREACH here creates problems (bad pointer value to pinsheet).
// I do not know why.
for( unsigned ii = 0; ii < GetSheetPins().size(); ii++ )
{
SCH_SHEET_PIN &pinsheet = GetSheetPins()[ii];
wxCHECK2_MSG( pinsheet.Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE, continue,
wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
pinsheet.GetEndPoints( aItemList );
}
}
bool SCH_SHEET::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
{
bool currentState = IsDangling();
BOOST_FOREACH( SCH_SHEET_PIN& pinsheet, GetSheetPins() )
{
pinsheet.IsDanglingStateChanged( aItemList );
}
return currentState != IsDangling();
}
bool SCH_SHEET::IsDangling() const
{
// If any hierarchical label in the sheet is dangling, then the sheet is dangling.
for( size_t i = 0; i < GetSheetPins().size(); i++ )
{
if( GetSheetPins()[i].IsDangling() )
return true;
}
return false;
}
bool SCH_SHEET::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
EDA_Rect boundingBox = GetBoundingBox();
if( aRect.Intersects( boundingBox ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
void SCH_SHEET::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
for( size_t i = 0; i < GetSheetPins().size(); i++ )
aPoints.push_back( GetSheetPins()[i].m_Pos );
}
#if defined(DEBUG) #if defined(DEBUG)
void SCH_SHEET::Show( int nestLevel, std::ostream& os ) void SCH_SHEET::Show( int nestLevel, std::ostream& os )
......
...@@ -23,7 +23,6 @@ extern SCH_SHEET* g_RootSheet; ...@@ -23,7 +23,6 @@ extern SCH_SHEET* g_RootSheet;
* the sheet, it corresponds to a hierarchical label. * the sheet, it corresponds to a hierarchical label.
*/ */
//class SCH_SHEET_PIN : public SCH_ITEM, public EDA_TextStruct
class SCH_SHEET_PIN : public SCH_HIERLABEL class SCH_SHEET_PIN : public SCH_HIERLABEL
{ {
private: private:
...@@ -168,8 +167,9 @@ public: ...@@ -168,8 +167,9 @@ public:
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return True if this item matches the search criteria. * @return True if this item matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
void* aAuxData, wxPoint * aFindLocation );
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
}; };
...@@ -251,6 +251,11 @@ public: ...@@ -251,6 +251,11 @@ public:
SCH_SHEET_PIN_LIST& GetSheetPins() { return m_labels; } SCH_SHEET_PIN_LIST& GetSheetPins() { return m_labels; }
SCH_SHEET_PIN_LIST& GetSheetPins() const
{
return const_cast< SCH_SHEET_PIN_LIST& >( m_labels );
}
/** /**
* Remove a sheet label from this sheet. * Remove a sheet label from this sheet.
* *
...@@ -412,7 +417,9 @@ public: ...@@ -412,7 +417,9 @@ public:
virtual void Move( const wxPoint& aMoveVector ) virtual void Move( const wxPoint& aMoveVector )
{ {
m_Pos += aMoveVector; m_Pos += aMoveVector;
BOOST_FOREACH( SCH_SHEET_PIN & label, m_labels ) {
BOOST_FOREACH( SCH_SHEET_PIN & label, m_labels )
{
label.Move( aMoveVector ); label.Move( aMoveVector );
} }
} }
...@@ -437,8 +444,7 @@ public: ...@@ -437,8 +444,7 @@ public:
* *
* @return True if this item matches the search criteria. * @return True if this item matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
void* aAuxData, wxPoint * aFindLocation );
/** /**
* Resize this sheet to aSize and adjust all of the labels accordingly. * Resize this sheet to aSize and adjust all of the labels accordingly.
...@@ -457,6 +463,16 @@ public: ...@@ -457,6 +463,16 @@ public:
*/ */
wxPoint GetFileNamePosition (); wxPoint GetFileNamePosition ();
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsDangling() const;
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
#if defined(DEBUG) #if defined(DEBUG)
// comment inherited by Doxygen from Base_Struct // comment inherited by Doxygen from Base_Struct
......
...@@ -340,6 +340,46 @@ void SCH_SHEET_PIN::Rotate( wxPoint rotationPoint ) ...@@ -340,6 +340,46 @@ void SCH_SHEET_PIN::Rotate( wxPoint rotationPoint )
} }
/** Virtual Function SCH_SHEET_PIN::CreateGraphicShape
* calculates the graphic shape (a polygon) associated to the text
* @param aCorner_list = a buffer to fill with polygon corners coordinates
* @param aPos = Position of the shape
*/
void SCH_SHEET_PIN::CreateGraphicShape( std::vector <wxPoint>& aCorner_list,
const wxPoint& aPos )
{
/* This is the same icon shapes as SCH_HIERLABEL
* but the graphic icon is slightly different in 2 cases:
* for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL
* for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL
*/
int tmp = m_Shape;
switch( m_Shape )
{
case NET_INPUT:
m_Shape = NET_OUTPUT;
break;
case NET_OUTPUT:
m_Shape = NET_INPUT;
break;
default:
break;
}
SCH_HIERLABEL::CreateGraphicShape( aCorner_list, aPos );
m_Shape = tmp;
}
void SCH_SHEET_PIN::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
DANGLING_END_ITEM item( SHEET_LABEL_END, this );
item.m_Pos = m_Pos;
aItemList.push_back( item );
}
#if defined(DEBUG) #if defined(DEBUG)
void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os ) void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os )
{ {
......
...@@ -180,3 +180,16 @@ void SCH_MARKER::Mirror_Y( int aYaxis_position ) ...@@ -180,3 +180,16 @@ void SCH_MARKER::Mirror_Y( int aYaxis_position )
m_Pos.x = -m_Pos.x; m_Pos.x = -m_Pos.x;
m_Pos.x += aYaxis_position; m_Pos.x += aYaxis_position;
} }
bool SCH_MARKER::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
if( aRect.Contains( m_Pos ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
...@@ -116,6 +116,8 @@ public: ...@@ -116,6 +116,8 @@ public:
*/ */
void DisplayInfo( WinEDA_DrawFrame* aFrame ); void DisplayInfo( WinEDA_DrawFrame* aFrame );
virtual bool IsSelectStateChanged( const wxRect& aRect );
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
......
...@@ -973,9 +973,9 @@ bool SCH_COMPONENT::Save( FILE* f ) const ...@@ -973,9 +973,9 @@ bool SCH_COMPONENT::Save( FILE* f ) const
if( GetField( REFERENCE )->m_Text.IsEmpty() ) if( GetField( REFERENCE )->m_Text.IsEmpty() )
strncpy( Name1, CONV_TO_UTF8( m_PrefixString ), sizeof( Name1 ) ); strncpy( Name1, CONV_TO_UTF8( m_PrefixString ), sizeof( Name1 ) );
else else
strncpy( Name1, CONV_TO_UTF8( GetField( REFERENCE )->m_Text ), strncpy( Name1, CONV_TO_UTF8( GetField( REFERENCE )->m_Text ), sizeof( Name1 ) );
sizeof( Name1 ) );
} }
for( ii = 0; ii < (int) strlen( Name1 ); ii++ ) for( ii = 0; ii < (int) strlen( Name1 ); ii++ )
{ {
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
...@@ -1284,3 +1284,77 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxP ...@@ -1284,3 +1284,77 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxP
return false; return false;
} }
void SCH_COMPONENT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName );
if( Entry == NULL )
return;
for( LIB_PIN* Pin = Entry->GetNextPin(); Pin != NULL; Pin = Entry->GetNextPin( Pin ) )
{
wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE );
if( Pin->GetUnit() && m_Multi && ( m_Multi != Pin->GetUnit() ) )
continue;
if( Pin->GetConvert() && m_Convert && ( m_Convert != Pin->GetConvert() ) )
continue;
DANGLING_END_ITEM item( PIN_END, Pin );
item.m_Pos = GetPinPhysicalPosition( Pin );
aItemList.push_back( item );
}
}
wxPoint SCH_COMPONENT::GetPinPhysicalPosition( LIB_PIN* Pin )
{
wxCHECK_MSG( Pin != NULL && Pin->Type() == COMPONENT_PIN_DRAW_TYPE, wxPoint( 0, 0 ),
wxT( "Cannot get physical position of pin." ) );
return m_Transform.TransformCoordinate( Pin->m_Pos ) + m_Pos;
}
bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
EDA_Rect boundingBox = GetBoundingBox();
if( aRect.Intersects( boundingBox ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
void SCH_COMPONENT::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
LIB_PIN* pin;
LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( m_ChipName );
wxCHECK_RET( component != NULL,
wxT( "Cannot add connection points to list. Cannot find component <" ) +
m_ChipName + wxT( "> in any of the loaded libraries." ) );
for( pin = component->GetNextPin( pin ); pin != NULL; pin = component->GetNextPin( pin ) )
{
wxCHECK_RET( pin->Type() == COMPONENT_PIN_DRAW_TYPE,
wxT( "GetNextPin() did not return a pin object. Bad programmer!" ) );
// Skip items not used for this part.
if( m_Multi && pin->GetUnit() && ( pin->GetUnit() != m_Multi ) )
continue;
if( m_Convert && pin->GetConvert() && ( pin->GetConvert() != m_Convert ) )
continue;
// Calculate the pin position relative to the component position and orientation.
aPoints.push_back( m_Transform.TransformCoordinate( pin->m_Pos ) + m_Pos );
}
}
/*****************************************************/ /******************************************************/
/* Definitions for the Component classes for EESchema */ /* Definitions for the Component classes for EESchema */
/*****************************************************/ /******************************************************/
#ifndef COMPONENT_CLASS_H #ifndef COMPONENT_CLASS_H
#define COMPONENT_CLASS_H #define COMPONENT_CLASS_H
...@@ -85,8 +85,7 @@ private: ...@@ -85,8 +85,7 @@ private:
void Init( const wxPoint& pos = wxPoint( 0, 0 ) ); void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
public: public:
SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL );
SCH_ITEM* aParent = NULL );
/** /**
* Create schematic component from library component object. * Create schematic component from library component object.
...@@ -122,6 +121,7 @@ public: ...@@ -122,6 +121,7 @@ public:
return wxT( "SCH_COMPONENT" ); return wxT( "SCH_COMPONENT" );
} }
TRANSFORM& GetTransform() const { return const_cast< TRANSFORM& >( m_Transform ); }
/** /**
* Function Save * Function Save
...@@ -312,8 +312,7 @@ public: ...@@ -312,8 +312,7 @@ public:
int GetUnitSelection( SCH_SHEET_PATH* aSheet ); int GetUnitSelection( SCH_SHEET_PATH* aSheet );
// Set the unit selection, for the given sheet path. // Set the unit selection, for the given sheet path.
void SetUnitSelection( SCH_SHEET_PATH* aSheet, void SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection );
int aUnitSelection );
/** Function GetPenSize /** Function GetPenSize
* @return the size of the "pen" that be used to draw or plot this item * @return the size of the "pen" that be used to draw or plot this item
...@@ -355,8 +354,15 @@ public: ...@@ -355,8 +354,15 @@ public:
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return True if this component reference or value field matches the search criteria. * @return True if this component reference or value field matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
void* aAuxData, wxPoint * aFindLocation );
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
wxPoint GetPinPhysicalPosition( LIB_PIN* Pin );
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
#if defined(DEBUG) #if defined(DEBUG)
......
...@@ -353,6 +353,13 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ...@@ -353,6 +353,13 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
} }
void SCH_SCREEN::ClearDrawingState()
{
for( SCH_ITEM* item = EEDrawList; item != NULL; item = item->Next() )
item->m_Flags = 0;
}
/******************************************************************/ /******************************************************************/
/* Class SCH_SCREENS to handle the list of screens in a hierarchy */ /* Class SCH_SCREENS to handle the list of screens in a hierarchy */
/******************************************************************/ /******************************************************************/
......
...@@ -167,12 +167,45 @@ void SCH_BUS_ENTRY::Rotate( wxPoint rotationPoint ) ...@@ -167,12 +167,45 @@ void SCH_BUS_ENTRY::Rotate( wxPoint rotationPoint )
} }
void SCH_BUS_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
{
DANGLING_END_ITEM item( ENTRY_END, this );
item.m_Pos = m_Pos;
DANGLING_END_ITEM item1( ENTRY_END, this );
item1.m_Pos = m_End();
aItemList.push_back( item );
aItemList.push_back( item1 );
}
bool SCH_BUS_ENTRY::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
// If either end of the bus entry is inside the selection rectangle, the entire
// bus entry is selected. Bus entries have a fixed length and angle.
if( aRect.Contains( m_Pos ) || aRect.Contains( m_End() ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
void SCH_BUS_ENTRY::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
aPoints.push_back( m_Pos );
aPoints.push_back( m_End() );
}
/**********************/ /**********************/
/* class SCH_JUNCTION */ /* class SCH_JUNCTION */
/**********************/ /**********************/
SCH_JUNCTION::SCH_JUNCTION( const wxPoint& pos ) : SCH_JUNCTION::SCH_JUNCTION( const wxPoint& pos ) : SCH_ITEM( NULL, DRAW_JUNCTION_STRUCT_TYPE )
SCH_ITEM( NULL, DRAW_JUNCTION_STRUCT_TYPE )
{ {
#define DRAWJUNCTION_DIAMETER 32 /* Diameter of junction symbol between wires */ #define DRAWJUNCTION_DIAMETER 32 /* Diameter of junction symbol between wires */
m_Pos = pos; m_Pos = pos;
...@@ -289,6 +322,33 @@ void SCH_JUNCTION::Rotate( wxPoint rotationPoint ) ...@@ -289,6 +322,33 @@ void SCH_JUNCTION::Rotate( wxPoint rotationPoint )
} }
void SCH_JUNCTION::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
DANGLING_END_ITEM item( JUNCTION_END, this );
item.m_Pos = m_Pos;
aItemList.push_back( item );
}
bool SCH_JUNCTION::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
if( aRect.Contains( m_Pos ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
void SCH_JUNCTION::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
aPoints.push_back( m_Pos );
}
#if defined(DEBUG) #if defined(DEBUG)
void SCH_JUNCTION::Show( int nestLevel, std::ostream& os ) void SCH_JUNCTION::Show( int nestLevel, std::ostream& os )
{ {
...@@ -306,8 +366,7 @@ void SCH_JUNCTION::Show( int nestLevel, std::ostream& os ) ...@@ -306,8 +366,7 @@ void SCH_JUNCTION::Show( int nestLevel, std::ostream& os )
/* class SCH_NO_CONNECT */ /* class SCH_NO_CONNECT */
/************************/ /************************/
SCH_NO_CONNECT::SCH_NO_CONNECT( const wxPoint& pos ) : SCH_NO_CONNECT::SCH_NO_CONNECT( const wxPoint& pos ) : SCH_ITEM( NULL, DRAW_NOCONNECT_STRUCT_TYPE )
SCH_ITEM( NULL, DRAW_NOCONNECT_STRUCT_TYPE )
{ {
#define DRAWNOCONNECT_SIZE 48 /* No symbol connection range. */ #define DRAWNOCONNECT_SIZE 48 /* No symbol connection range. */
m_Pos = pos; m_Pos = pos;
...@@ -430,6 +489,25 @@ void SCH_NO_CONNECT::Rotate( wxPoint rotationPoint ) ...@@ -430,6 +489,25 @@ void SCH_NO_CONNECT::Rotate( wxPoint rotationPoint )
} }
bool SCH_NO_CONNECT::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
if( aRect.Contains( m_Pos ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
return previousState != IsSelected();
}
void SCH_NO_CONNECT::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
aPoints.push_back( m_Pos );
}
/******************/ /******************/
/* Class SCH_LINE */ /* Class SCH_LINE */
/******************/ /******************/
...@@ -634,9 +712,7 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine ) ...@@ -634,9 +712,7 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
wxCHECK_MSG( aLine != NULL && aLine->Type() == DRAW_SEGMENT_STRUCT_TYPE, false, wxCHECK_MSG( aLine != NULL && aLine->Type() == DRAW_SEGMENT_STRUCT_TYPE, false,
wxT( "Cannot test line segment for overlap." ) ); wxT( "Cannot test line segment for overlap." ) );
if( this == aLine ) if( this == aLine || GetLayer() != aLine->GetLayer() )
return false;
if( GetLayer() != aLine->GetLayer() )
return false; return false;
// Search for a common end, and modify coordinates to ensure RefSegm->m_End // Search for a common end, and modify coordinates to ensure RefSegm->m_End
...@@ -658,8 +734,10 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine ) ...@@ -658,8 +734,10 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
EXCHG( aLine->m_Start, aLine->m_End ); EXCHG( aLine->m_Start, aLine->m_End );
} }
else if( m_End != aLine->m_Start ) else if( m_End != aLine->m_Start )
{
// No common end point, segments cannot be merged. // No common end point, segments cannot be merged.
return false; return false;
}
/* Test alignment: */ /* Test alignment: */
if( m_Start.y == m_End.y ) // Horizontal segment if( m_Start.y == m_End.y ) // Horizontal segment
...@@ -693,12 +771,86 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine ) ...@@ -693,12 +771,86 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
} }
/***********************/ void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
if( GetLayer() == LAYER_NOTES )
return;
if( ( GetLayer() == LAYER_BUS ) || ( GetLayer() == LAYER_WIRE ) )
{
DANGLING_END_ITEM item( (GetLayer() == LAYER_BUS) ? BUS_START_END : WIRE_START_END, this );
item.m_Pos = m_Start;
DANGLING_END_ITEM item1( (GetLayer() == LAYER_BUS) ? BUS_END_END : WIRE_END_END, this );
item1.m_Pos = m_End;
aItemList.push_back( item );
aItemList.push_back( item1 );
}
}
bool SCH_LINE::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
{
bool previousStartState = m_StartIsDangling;
bool previousEndState = m_EndIsDangling;
if( GetLayer() == LAYER_WIRE )
{
BOOST_FOREACH( DANGLING_END_ITEM item, aItemList )
{
if( item.m_Item == this )
continue;
if( m_Start == item.m_Pos )
m_StartIsDangling = false;
if( m_End == item.m_Pos )
m_EndIsDangling = false;
if( (m_StartIsDangling == false) && (m_EndIsDangling == false) )
break;
}
}
else if( GetLayer() == LAYER_BUS || GetLayer() == LAYER_NOTES )
{
// Lines on the notes layer and the bus layer cannot be tested for dangling ends.
previousStartState = previousEndState = m_StartIsDangling = m_EndIsDangling = false;
}
return ( previousStartState != m_StartIsDangling ) || ( previousEndState != m_EndIsDangling );
}
bool SCH_LINE::IsSelectStateChanged( const wxRect& aRect )
{
bool previousState = IsSelected();
if( aRect.Contains( m_Start ) )
m_Flags |= STARTPOINT | SELECTED;
else
m_Flags &= ~( STARTPOINT | SELECTED );
if( aRect.Contains( m_End ) )
m_Flags |= ENDPOINT | SELECTED;
else
m_Flags &= ~( ENDPOINT | SELECTED );
return previousState != IsSelected();
}
void SCH_LINE::GetConnectionPoints( vector< wxPoint >& aPoints ) const
{
aPoints.push_back( m_Start );
aPoints.push_back( m_End );
}
/**********************/
/* Class SCH_POLYLINE */ /* Class SCH_POLYLINE */
/***********************/ /**********************/
SCH_POLYLINE::SCH_POLYLINE( int layer ) : SCH_POLYLINE::SCH_POLYLINE( int layer ) : SCH_ITEM( NULL, DRAW_POLYLINE_STRUCT_TYPE )
SCH_ITEM( NULL, DRAW_POLYLINE_STRUCT_TYPE )
{ {
m_Width = 0; m_Width = 0;
......
...@@ -108,6 +108,16 @@ public: ...@@ -108,6 +108,16 @@ public:
*/ */
bool MergeOverlap( SCH_LINE* aLine ); bool MergeOverlap( SCH_LINE* aLine );
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsDangling() const { return m_StartIsDangling || m_EndIsDangling; }
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
...@@ -185,6 +195,10 @@ public: ...@@ -185,6 +195,10 @@ public:
virtual void Mirror_Y( int aYaxis_position ); virtual void Mirror_Y( int aYaxis_position );
virtual void Mirror_X( int aXaxis_position ); virtual void Mirror_X( int aXaxis_position );
virtual void Rotate( wxPoint rotationPoint ); virtual void Rotate( wxPoint rotationPoint );
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
}; };
...@@ -259,6 +273,12 @@ public: ...@@ -259,6 +273,12 @@ public:
virtual void Mirror_Y( int aYaxis_position ); virtual void Mirror_Y( int aYaxis_position );
virtual void Mirror_X( int aXaxis_position ); virtual void Mirror_X( int aXaxis_position );
virtual void Rotate( wxPoint rotationPoint ); virtual void Rotate( wxPoint rotationPoint );
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
}; };
class SCH_POLYLINE : public SCH_ITEM class SCH_POLYLINE : public SCH_ITEM
...@@ -405,6 +425,12 @@ public: ...@@ -405,6 +425,12 @@ public:
virtual void Mirror_X( int aXaxis_position ); virtual void Mirror_X( int aXaxis_position );
virtual void Rotate( wxPoint rotationPoint ); virtual void Rotate( wxPoint rotationPoint );
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
......
...@@ -65,29 +65,21 @@ static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 }; ...@@ -65,29 +65,21 @@ static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
static int* TemplateShape[5][4] = static int* TemplateShape[5][4] =
{ {
{ TemplateIN_HN, TemplateIN_UP, TemplateIN_HI, { TemplateIN_HN, TemplateIN_UP, TemplateIN_HI, TemplateIN_BOTTOM },
TemplateIN_BOTTOM }, { TemplateOUT_HN, TemplateOUT_UP, TemplateOUT_HI, TemplateOUT_BOTTOM },
{ TemplateOUT_HN, TemplateOUT_UP, TemplateOUT_HI, { TemplateBIDI_HN, TemplateBIDI_UP, TemplateBIDI_HI, TemplateBIDI_BOTTOM },
TemplateOUT_BOTTOM }, { Template3STATE_HN, Template3STATE_UP, Template3STATE_HI, Template3STATE_BOTTOM },
{ TemplateBIDI_HN, TemplateBIDI_UP, TemplateBIDI_HI, { TemplateUNSPC_HN, TemplateUNSPC_UP, TemplateUNSPC_HI, TemplateUNSPC_BOTTOM }
TemplateBIDI_BOTTOM },
{ Template3STATE_HN, Template3STATE_UP, Template3STATE_HI,
Template3STATE_BOTTOM },
{ TemplateUNSPC_HN, TemplateUNSPC_UP, TemplateUNSPC_HI,
TemplateUNSPC_BOTTOM }
}; };
/**************************************************************************/ SCH_TEXT::SCH_TEXT( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
SCH_TEXT::SCH_TEXT( const wxPoint& pos, const wxString& text,
KICAD_T aType ) :
SCH_ITEM( NULL, aType ), EDA_TextStruct( text ) SCH_ITEM( NULL, aType ), EDA_TextStruct( text )
{ {
/**************************************************************************/
m_Layer = LAYER_NOTES; m_Layer = LAYER_NOTES;
m_Pos = pos; m_Pos = pos;
m_Shape = 0; m_Shape = 0;
m_IsDangling = FALSE; m_IsDangling = false;
m_MultilineAllowed = true; m_MultilineAllowed = true;
m_SchematicOrientation = 0; m_SchematicOrientation = 0;
} }
...@@ -103,10 +95,8 @@ bool SCH_TEXT::HitTest( const wxPoint& aPosRef ) ...@@ -103,10 +95,8 @@ bool SCH_TEXT::HitTest( const wxPoint& aPosRef )
} }
/*********************************************/
SCH_TEXT* SCH_TEXT::GenCopy() SCH_TEXT* SCH_TEXT::GenCopy()
{ {
/*********************************************/
SCH_TEXT* newitem; SCH_TEXT* newitem;
switch( Type() ) switch( Type() )
...@@ -195,18 +185,6 @@ bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint ...@@ -195,18 +185,6 @@ bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint
} }
/** function GetSchematicTextOffset (virtual)
* @return the offset between the SCH_TEXT position and the text itself
* position
* This offset depend on orientation, and the type of text
* (room to draw an associated graphic symbol, or put the text above a wire)
*/
wxPoint SCH_LABEL::GetSchematicTextOffset()
{
return SCH_TEXT::GetSchematicTextOffset();
}
/** virtual function Mirror_Y /** virtual function Mirror_Y
* mirror item relative to an Y axis * mirror item relative to an Y axis
* @param aYaxis_position = the y axis position * @param aYaxis_position = the y axis position
...@@ -330,505 +308,297 @@ void SCH_TEXT::Rotate( wxPoint rotationPoint ) ...@@ -330,505 +308,297 @@ void SCH_TEXT::Rotate( wxPoint rotationPoint )
} }
/** function GetSchematicTextOffset (virtual) /** function SetTextOrientAndJustifyParmeters (virtual)
* @return the offset between the SCH_TEXT position and the text itself * Set m_SchematicOrientation, and initialize
* position * m_orient,m_HJustified and m_VJustified, according to the value of
* This offset depend on orientation, and the type of text * m_SchematicOrientation
* (room to draw an associated graphic symbol, or put the text above a wire) * must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/ */
wxPoint SCH_HIERLABEL::GetSchematicTextOffset() void SCH_TEXT::SetSchematicTextOrientation( int aSchematicOrientation )
{ {
wxPoint text_offset; m_SchematicOrientation = aSchematicOrientation;
int width = MAX( m_Width, g_DrawDefaultLineThickness );
int ii = m_Size.x + TXTMARGE + width;
switch( m_SchematicOrientation ) switch( m_SchematicOrientation )
{ {
case 0: /* Orientation horiz normale */ default:
text_offset.x = -ii; case 0: /* Horiz Normal Orientation (left justified) */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break; break;
case 1: /* Orientation vert UP */ case 1: /* Vert Orientation UP */
text_offset.y = -ii; m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break; break;
case 2: /* Orientation horiz inverse */ case 2: /* Horiz Orientation - Right justified */
text_offset.x = ii; m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break; break;
case 3: /* Orientation vert BOTTOM */ case 3: /* Vert Orientation BOTTOM */
text_offset.y = ii; m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break; break;
} }
return text_offset;
} }
/** virtual function Mirror_Y void SCH_TEXT::SwapData( SCH_TEXT* copyitem )
* mirror item relative to an Y axis
* @param aYaxis_position = the y axis position
*/
void SCH_HIERLABEL::Mirror_Y( int aYaxis_position )
{ {
/* The hierarchical label is NOT really mirrored. EXCHG( m_Text, copyitem->m_Text );
* for an horizontal label, the schematic orientation is changed. EXCHG( m_Pos, copyitem->m_Pos );
* for a vericalal label, the schematic orientation is not changed. EXCHG( m_Size, copyitem->m_Size );
* and the label is moved to a suitable position EXCHG( m_Width, copyitem->m_Width );
*/ EXCHG( m_Shape, copyitem->m_Shape );
EXCHG( m_Orient, copyitem->m_Orient );
switch( GetSchematicTextOrientation() ) EXCHG( m_Layer, copyitem->m_Layer );
EXCHG( m_HJustify, copyitem->m_HJustify );
EXCHG( m_VJustify, copyitem->m_VJustify );
EXCHG( m_IsDangling, copyitem->m_IsDangling );
EXCHG( m_SchematicOrientation, copyitem->m_SchematicOrientation );
}
void SCH_TEXT::Place( WinEDA_SchematicFrame* frame, wxDC* DC )
{
/* save old text in undo list */
if( g_ItemToUndoCopy && ( (m_Flags & IS_NEW) == 0 ) )
{ {
case 0: /* horizontal text */ /* restore old values and save new ones */
SetSchematicTextOrientation( 2 ); SwapData( (SCH_TEXT*) g_ItemToUndoCopy );
break;
case 2: /* invert horizontal text*/ /* save in undo list */
SetSchematicTextOrientation( 0 ); frame->SaveCopyInUndoList( this, UR_CHANGED );
break;
/* restore new values */
SwapData( (SCH_TEXT*) g_ItemToUndoCopy );
SAFE_DELETE( g_ItemToUndoCopy );
} }
m_Pos.x -= aYaxis_position; SCH_ITEM::Place( frame, DC );
NEGATE( m_Pos.x );
m_Pos.x += aYaxis_position;
} }
void SCH_HIERLABEL::Mirror_X( int aXaxis_position ) /** Function GetPenSize
* @return the size of the "pen" that be used to draw or plot this item
*/
int SCH_TEXT::GetPenSize()
{ {
switch( GetSchematicTextOrientation() ) int pensize = m_Width;
{
case 1: /* vertical text */
SetSchematicTextOrientation( 3 );
break;
case 3: /* invert vertical text*/ if( pensize == 0 ) // Use default values for pen size
SetSchematicTextOrientation( 1 ); {
break; if( m_Bold )
pensize = GetPenSizeForBold( m_Size.x );
else
pensize = g_DrawDefaultLineThickness;
} }
m_Pos.y -= aXaxis_position; // Clip pen size for small texts:
NEGATE( m_Pos.y ); pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
m_Pos.y += aXaxis_position; return pensize;
} }
void SCH_HIERLABEL::Rotate( wxPoint rotationPoint ) /* Text type Comment (text on layer "NOTE") have 4 directions, and the Text
* origin is the first letter
*/
void SCH_TEXT::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& aOffset,
int DrawMode, int Color )
{ {
RotatePoint( &m_Pos, rotationPoint, 900 ); EDA_Colors color;
SetSchematicTextOrientation( (GetSchematicTextOrientation() + 3) % 4 ); int linewidth = ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
if( Color >= 0 )
color = (EDA_Colors) Color;
else
color = ReturnLayerColor( m_Layer );
GRSetDrawMode( DC, DrawMode );
wxPoint text_offset = aOffset + GetSchematicTextOffset();
EXCHG( linewidth, m_Width ); // Set the minimum width
EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
EXCHG( linewidth, m_Width ); // set initial value
if( m_IsDangling )
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
// Enable these line to draw the bounding box (debug tests purposes only)
#if 0
{
EDA_Rect BoundaryBox;
BoundaryBox = GetBoundingBox();
int x1 = BoundaryBox.GetX();
int y1 = BoundaryBox.GetY();
int x2 = BoundaryBox.GetRight();
int y2 = BoundaryBox.GetBottom();
GRRect( &panel->m_ClipBox, DC, x1, y1, x2, y2, BROWN );
}
#endif
} }
/** virtual function Mirror_Y /**
* mirror item relative to an Y axis * Function Save
* @param aYaxis_position = the y axis position * writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/ */
void SCH_GLOBALLABEL::Mirror_Y( int aYaxis_position ) bool SCH_TEXT::Save( FILE* aFile ) const
{ {
/* The global label is NOT really mirrored. bool success = true;
* for an horizontal label, the schematic orientation is changed. const char* shape = "~";
* for a vericalal label, the schematic orientation is not changed.
* and the label is moved to a suitable position if( m_Italic )
*/ shape = "Italic";
switch( GetSchematicTextOrientation() )
wxString text = m_Text;
for( ; ; )
{ {
case 0: /* horizontal text */ int i = text.find( '\n' );
SetSchematicTextOrientation( 2 ); if( i == wxNOT_FOUND )
break; break;
case 2: /* invert horizontal text*/ text.erase( i, 1 );
SetSchematicTextOrientation( 0 ); text.insert( i, wxT( "\\n" ) );
break;
} }
m_Pos.x -= aYaxis_position; if( fprintf( aFile, "Text Notes %-4d %-4d %-4d %-4d %s %d\n%s\n",
NEGATE( m_Pos.x ); m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x,
m_Pos.x += aYaxis_position; shape, m_Width, CONV_TO_UTF8( text ) ) == EOF )
{
success = false;
}
return success;
} }
void SCH_GLOBALLABEL::Mirror_X( int aXaxis_position ) void SCH_TEXT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{ {
switch( GetSchematicTextOrientation() ) // Normal text labels cannot be tested for dangling ends.
if( Type() == TYPE_SCH_TEXT )
return;
DANGLING_END_ITEM item( LABEL_END, this );
item.m_Pos = m_Pos;
aItemList.push_back( item );
}
bool SCH_TEXT::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
{
// Normal text labels cannot be tested for dangling ends.
if( Type() == TYPE_SCH_TEXT )
return false;
bool previousState = m_IsDangling;
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
{ {
case 1: /* vertical text */ DANGLING_END_ITEM& item = aItemList[ii];
SetSchematicTextOrientation( 3 );
if( item.m_Item == this )
continue;
switch( item.m_Type )
{
case PIN_END:
case LABEL_END:
case SHEET_LABEL_END:
if( m_Pos == item.m_Pos )
m_IsDangling = false;
break; break;
case 3: /* invert vertical text*/ case WIRE_START_END:
SetSchematicTextOrientation( 1 ); case BUS_START_END:
{
// These schematic items have created 2 DANGLING_END_ITEM one per end. But being
// a paranoid programmer, I'll check just in case.
ii++;
wxCHECK_MSG( ii < aItemList.size(), previousState != m_IsDangling,
wxT( "Dangling end type list overflow. Bad programmer!" ) );
DANGLING_END_ITEM & nextItem = aItemList[ii];
m_IsDangling = !SegmentIntersect( item.m_Pos, nextItem.m_Pos, m_Pos );
}
break;
default:
break; break;
} }
m_Pos.y -= aXaxis_position; if( m_IsDangling == false )
NEGATE( m_Pos.y ); break;
m_Pos.y += aXaxis_position; }
return previousState != m_IsDangling;
} }
void SCH_GLOBALLABEL::Rotate( wxPoint rotationPoint ) bool SCH_TEXT::IsSelectStateChanged( const wxRect& aRect )
{ {
RotatePoint( &m_Pos, rotationPoint, 900 ); bool previousState = IsSelected();
SetSchematicTextOrientation( (GetSchematicTextOrientation() + 3) % 4 );
}
if( aRect.Contains( m_Pos ) )
m_Flags |= SELECTED;
else
m_Flags &= ~SELECTED;
/** function GetSchematicTextOffset (virtual) return previousState != IsSelected();
* @return the offset between the SCH_TEXT position and the text itself
* position
* This offset depend on orientation, and the type of text
* (room to draw an associated graphic symbol, or put the text above a wire)
*/
wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset()
{
wxPoint text_offset;
int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
width = Clamp_Text_PenSize( width, m_Size, m_Bold );
int HalfSize = m_Size.x / 2;
int offset = width;
switch( m_Shape )
{
case NET_INPUT:
case NET_BIDI:
case NET_TRISTATE:
offset += HalfSize;
break;
case NET_OUTPUT:
case NET_UNSPECIFIED:
offset += TXTMARGE;
break;
default:
break;
}
switch( m_SchematicOrientation )
{
case 0: /* Orientation horiz normal */
text_offset.x -= offset;
break;
case 1: /* Orientation vert UP */
text_offset.y -= offset;
break;
case 2: /* Orientation horiz inverse */
text_offset.x += offset;
break;
case 3: /* Orientation vert BOTTOM */
text_offset.y += offset;
break;
}
return text_offset;
}
/** function SetTextOrientAndJustifyParmeters (virtual)
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_TEXT::SetSchematicTextOrientation( int aSchematicOrientation )
{
m_SchematicOrientation = aSchematicOrientation;
switch( m_SchematicOrientation )
{
default:
case 0: /* Horiz Normal Orientation (left justified) */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break;
case 1: /* Vert Orientation UP */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break;
case 2: /* Horiz Orientation - Right justified */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break;
case 3: /* Vert Orientation BOTTOM */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
break;
}
} }
/** function SetTextOrientAndJustifyParmeters void SCH_TEXT::GetConnectionPoints( vector< wxPoint >& aPoints ) const
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation (for a label)
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_LABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{ {
SCH_TEXT::SetSchematicTextOrientation( aSchematicOrientation ); // Normal text labels do not have connection points. All others do.
} if( Type() == TYPE_SCH_TEXT )
return;
/** function SetTextOrientAndJustifyParmeters
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_GLOBALLABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{
m_SchematicOrientation = aSchematicOrientation;
switch( m_SchematicOrientation )
{
default:
case 0: /* Horiz Normal Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 1: /* Vert Orientation UP */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 2: /* Horiz Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 3: /* Vert Orientation BOTTOM */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
}
}
/** function SetTextOrientAndJustifyParmeters
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_HIERLABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{
m_SchematicOrientation = aSchematicOrientation;
switch( m_SchematicOrientation )
{
default:
case 0: /* Horiz Normal Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 1: /* Vert Orientation UP */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 2: /* Horiz Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 3: /* Vert Orientation BOTTOM */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
}
}
/********************************************************/
void SCH_TEXT::SwapData( SCH_TEXT* copyitem )
{
/********************************************************/
EXCHG( m_Text, copyitem->m_Text );
EXCHG( m_Pos, copyitem->m_Pos );
EXCHG( m_Size, copyitem->m_Size );
EXCHG( m_Width, copyitem->m_Width );
EXCHG( m_Shape, copyitem->m_Shape );
EXCHG( m_Orient, copyitem->m_Orient );
EXCHG( m_Layer, copyitem->m_Layer );
EXCHG( m_HJustify, copyitem->m_HJustify );
EXCHG( m_VJustify, copyitem->m_VJustify );
EXCHG( m_IsDangling, copyitem->m_IsDangling );
EXCHG( m_SchematicOrientation, copyitem->m_SchematicOrientation );
}
/***************************************************************/
void SCH_TEXT::Place( WinEDA_SchematicFrame* frame, wxDC* DC )
{
/***************************************************************/
/* save old text in undo list */
if( g_ItemToUndoCopy && ( (m_Flags & IS_NEW) == 0 ) )
{
/* restore old values and save new ones */
SwapData( (SCH_TEXT*) g_ItemToUndoCopy );
/* save in undo list */
frame->SaveCopyInUndoList( this, UR_CHANGED );
/* restore new values */
SwapData( (SCH_TEXT*) g_ItemToUndoCopy );
SAFE_DELETE( g_ItemToUndoCopy );
}
SCH_ITEM::Place( frame, DC );
}
/** Function GetPenSize
* @return the size of the "pen" that be used to draw or plot this item
*/
int SCH_TEXT::GetPenSize()
{
int pensize = m_Width;
if( pensize == 0 ) // Use default values for pen size
{
if( m_Bold )
pensize = GetPenSizeForBold( m_Size.x );
else
pensize = g_DrawDefaultLineThickness;
}
// Clip pen size for small texts:
pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
return pensize;
}
/****************************************************************************/
void SCH_TEXT::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& aOffset,
int DrawMode, int Color )
{
/****************************************************************************/
/* Text type Comment (text on layer "NOTE") have 4 directions, and the Text
* origin is the first letter
*/
EDA_Colors color;
int linewidth =
(m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
if( Color >= 0 )
color = (EDA_Colors) Color;
else
color = ReturnLayerColor( m_Layer );
GRSetDrawMode( DC, DrawMode );
wxPoint text_offset = aOffset + GetSchematicTextOffset();
EXCHG( linewidth, m_Width ); // Set the minimum width
EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED,
UNSPECIFIED_COLOR );
EXCHG( linewidth, m_Width ); // set initial value
if( m_IsDangling )
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
// Enable these line to draw the bounding box (debug tests purposes only)
#if 0
{
EDA_Rect BoundaryBox;
BoundaryBox = GetBoundingBox();
int x1 = BoundaryBox.GetX();
int y1 = BoundaryBox.GetY();
int x2 = BoundaryBox.GetRight();
int y2 = BoundaryBox.GetBottom();
GRRect( &panel->m_ClipBox, DC, x1, y1, x2, y2, BROWN );
}
#endif
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool SCH_TEXT::Save( FILE* aFile ) const
{
bool success = true;
const char* shape = "~";
if( m_Italic ) aPoints.push_back( m_Pos );
shape = "Italic"; }
wxString text = m_Text;
for( ; ; ) EDA_Rect SCH_TEXT::GetBoundingBox()
{ {
int i = text.find( '\n' ); // We must pass the effective text thickness to GetTextBox
if( i==wxNOT_FOUND ) // when calculating the bounding box
break; int linewidth = ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
text.erase( i, 1 ); linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
text.insert( i, wxT( "\\n" ) ); EXCHG( linewidth, m_Width ); // Set the real width
} EDA_Rect rect = GetTextBox( -1 );
EXCHG( linewidth, m_Width ); // set initial value
if( fprintf( aFile, "Text Notes %-4d %-4d %-4d %-4d %s %d\n%s\n", if( m_Orient ) // Rotate rect
m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x,
shape, m_Width, CONV_TO_UTF8( text ) ) == EOF )
{ {
success = false; wxPoint pos = rect.GetOrigin();
wxPoint end = rect.GetEnd();
RotatePoint( &pos, m_Pos, m_Orient );
RotatePoint( &end, m_Pos, m_Orient );
rect.SetOrigin( pos );
rect.SetEnd( end );
} }
return success; rect.Normalize();
return rect;
} }
...@@ -851,11 +621,40 @@ void SCH_TEXT::Show( int nestLevel, std::ostream& os ) ...@@ -851,11 +621,40 @@ void SCH_TEXT::Show( int nestLevel, std::ostream& os )
#endif #endif
/****************************************************************************/
/** function GetSchematicTextOffset (virtual)
* @return the offset between the SCH_TEXT position and the text itself
* position
* This offset depend on orientation, and the type of text
* (room to draw an associated graphic symbol, or put the text above a wire)
*/
wxPoint SCH_LABEL::GetSchematicTextOffset()
{
return SCH_TEXT::GetSchematicTextOffset();
}
/** function SetTextOrientAndJustifyParmeters
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation (for a label)
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_LABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{
SCH_TEXT::SetSchematicTextOrientation( aSchematicOrientation );
}
SCH_LABEL::SCH_LABEL( const wxPoint& pos, const wxString& text ) : SCH_LABEL::SCH_LABEL( const wxPoint& pos, const wxString& text ) :
SCH_TEXT( pos, text, TYPE_SCH_LABEL ) SCH_TEXT( pos, text, TYPE_SCH_LABEL )
{ {
/****************************************************************************/
m_Layer = LAYER_LOCLABEL; m_Layer = LAYER_LOCLABEL;
m_Shape = NET_INPUT; m_Shape = NET_INPUT;
m_IsDangling = TRUE; m_IsDangling = TRUE;
...@@ -914,11 +713,67 @@ bool SCH_LABEL::Save( FILE* aFile ) const ...@@ -914,11 +713,67 @@ bool SCH_LABEL::Save( FILE* aFile ) const
} }
/*****************************************************************************/ /** Function SCH_LABEL::Draw
* a label is drawn like a text. So just call SCH_TEXT::Draw
*/
void SCH_LABEL::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset,
int DrawMode, int Color )
{
SCH_TEXT::Draw( panel, DC, offset, DrawMode, Color );
}
EDA_Rect SCH_LABEL::GetBoundingBox()
{
int x, y, dx, dy, length, height;
x = m_Pos.x;
y = m_Pos.y;
int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
length = LenSize( m_Text );
height = m_Size.y + width;
dx = dy = 0;
switch( m_SchematicOrientation )
{
case 0: /* Horiz Normal Orientation (left justified) */
dx = 2 * DANGLING_SYMBOL_SIZE + length;
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
x -= DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break;
case 1: /* Vert Orientation UP */
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
dy = -2 * DANGLING_SYMBOL_SIZE - length;
x += DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break;
case 2: /* Horiz Orientation - Right justified */
dx = -2 * DANGLING_SYMBOL_SIZE - length;
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
x += DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break;
case 3: /* Vert Orientation BOTTOM */
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
dy = 2 * DANGLING_SYMBOL_SIZE + length;
x += DANGLING_SYMBOL_SIZE;
y -= DANGLING_SYMBOL_SIZE;
break;
}
EDA_Rect box( wxPoint( x, y ), wxSize( dx, dy ) );
box.Normalize();
return box;
}
SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) : SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) :
SCH_TEXT( pos, text, TYPE_SCH_GLOBALLABEL ) SCH_TEXT( pos, text, TYPE_SCH_GLOBALLABEL )
{ {
/*****************************************************************************/
m_Layer = LAYER_GLOBLABEL; m_Layer = LAYER_GLOBLABEL;
m_Shape = NET_BIDI; m_Shape = NET_BIDI;
m_IsDangling = TRUE; m_IsDangling = TRUE;
...@@ -941,8 +796,7 @@ bool SCH_GLOBALLABEL::Save( FILE* aFile ) const ...@@ -941,8 +796,7 @@ bool SCH_GLOBALLABEL::Save( FILE* aFile ) const
shape = "Italic"; shape = "Italic";
if( fprintf( aFile, "Text GLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n", if( fprintf( aFile, "Text GLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x, m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x,
SheetLabelType[m_Shape], shape, m_Width, SheetLabelType[m_Shape], shape, m_Width, CONV_TO_UTF8( m_Text ) ) == EOF )
CONV_TO_UTF8( m_Text ) ) == EOF )
{ {
success = false; success = false;
} }
...@@ -951,101 +805,185 @@ bool SCH_GLOBALLABEL::Save( FILE* aFile ) const ...@@ -951,101 +805,185 @@ bool SCH_GLOBALLABEL::Save( FILE* aFile ) const
} }
/************************************************/
bool SCH_GLOBALLABEL::HitTest( const wxPoint& aPosRef )
{
/************************************************/
/** Function HitTest /** Function HitTest
* @return true if the point aPosRef is within item area * @return true if the point aPosRef is within item area
* @param aPosRef = a wxPoint to test * @param aPosRef = a wxPoint to test
*/ */
bool SCH_GLOBALLABEL::HitTest( const wxPoint& aPosRef )
{
EDA_Rect rect = GetBoundingBox(); EDA_Rect rect = GetBoundingBox();
return rect.Inside( aPosRef ); return rect.Inside( aPosRef );
} }
/*****************************************************************************/ /** virtual function Mirror_Y
SCH_HIERLABEL::SCH_HIERLABEL( const wxPoint& pos, const wxString& text, KICAD_T aType ) : * mirror item relative to an Y axis
SCH_TEXT( pos, text, aType ) * @param aYaxis_position = the y axis position
*/
void SCH_GLOBALLABEL::Mirror_Y( int aYaxis_position )
{ {
/*****************************************************************************/ /* The global label is NOT really mirrored.
m_Layer = LAYER_HIERLABEL; * for an horizontal label, the schematic orientation is changed.
m_Shape = NET_INPUT; * for a vericalal label, the schematic orientation is not changed.
m_IsDangling = TRUE; * and the label is moved to a suitable position
m_MultilineAllowed = false; */
switch( GetSchematicTextOrientation() )
{
case 0: /* horizontal text */
SetSchematicTextOrientation( 2 );
break;
case 2: /* invert horizontal text*/
SetSchematicTextOrientation( 0 );
break;
}
m_Pos.x -= aYaxis_position;
NEGATE( m_Pos.x );
m_Pos.x += aYaxis_position;
} }
/** void SCH_GLOBALLABEL::Mirror_X( int aXaxis_position )
* Function Save {
* writes the data structures for this object out to a FILE in "*.brd" format. switch( GetSchematicTextOrientation() )
* @param aFile The FILE to write to. {
* @return bool - true if success writing else false. case 1: /* vertical text */
SetSchematicTextOrientation( 3 );
break;
case 3: /* invert vertical text*/
SetSchematicTextOrientation( 1 );
break;
}
m_Pos.y -= aXaxis_position;
NEGATE( m_Pos.y );
m_Pos.y += aXaxis_position;
}
void SCH_GLOBALLABEL::Rotate( wxPoint rotationPoint )
{
RotatePoint( &m_Pos, rotationPoint, 900 );
SetSchematicTextOrientation( (GetSchematicTextOrientation() + 3) % 4 );
}
/** function GetSchematicTextOffset (virtual)
* @return the offset between the SCH_TEXT position and the text itself
* position
* This offset depend on orientation, and the type of text
* (room to draw an associated graphic symbol, or put the text above a wire)
*/ */
bool SCH_HIERLABEL::Save( FILE* aFile ) const wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset()
{ {
bool success = true; wxPoint text_offset;
const char* shape = "~"; int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
if( m_Italic ) width = Clamp_Text_PenSize( width, m_Size, m_Bold );
shape = "Italic"; int HalfSize = m_Size.x / 2;
if( fprintf( aFile, "Text HLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n", int offset = width;
m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x,
SheetLabelType[m_Shape], shape, m_Width, switch( m_Shape )
CONV_TO_UTF8( m_Text ) ) == EOF )
{ {
success = false; case NET_INPUT:
case NET_BIDI:
case NET_TRISTATE:
offset += HalfSize;
break;
case NET_OUTPUT:
case NET_UNSPECIFIED:
offset += TXTMARGE;
break;
default:
break;
} }
return success; switch( m_SchematicOrientation )
{
case 0: /* Orientation horiz normal */
text_offset.x -= offset;
break;
case 1: /* Orientation vert UP */
text_offset.y -= offset;
break;
case 2: /* Orientation horiz inverse */
text_offset.x += offset;
break;
case 3: /* Orientation vert BOTTOM */
text_offset.y += offset;
break;
}
return text_offset;
} }
/************************************************/ /** function SetTextOrientAndJustifyParmeters
bool SCH_HIERLABEL::HitTest( const wxPoint& aPosRef ) * Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_GLOBALLABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{ {
/************************************************/ m_SchematicOrientation = aSchematicOrientation;
/** Function HitTest switch( m_SchematicOrientation )
* @return true if the point aPosRef is within item area {
* @param aPosRef = a wxPoint to test default:
*/ case 0: /* Horiz Normal Orientation */
EDA_Rect rect = GetBoundingBox(); m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
return rect.Inside( aPosRef ); case 1: /* Vert Orientation UP */
} m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 2: /* Horiz Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
/** Function SCH_LABEL::Draw case 3: /* Vert Orientation BOTTOM */
* a label is drawn like a text. So just call SCH_TEXT::Draw m_Orient = TEXT_ORIENT_VERT;
*/ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
void SCH_LABEL::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
int DrawMode, int Color ) break;
{ }
SCH_TEXT::Draw( panel, DC, offset, DrawMode, Color );
} }
/*****************************************************************************/ /* Texts type Global Label have 4 directions, and the Text origin is the graphic icon
void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel, */
void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel,
wxDC* DC, wxDC* DC,
const wxPoint& offset, const wxPoint& aOffset,
int DrawMode, int DrawMode,
int Color ) int Color )
{ {
/*****************************************************************************/
/* Hierarchical Label have a text and a graphic icon.
* Texts type have 4 directions, and the text origin is the graphic icon
*/
static std::vector <wxPoint> Poly; static std::vector <wxPoint> Poly;
EDA_Colors color; EDA_Colors color;
int linewidth = wxPoint text_offset = aOffset + GetSchematicTextOffset();
( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
if( Color >= 0 ) if( Color >= 0 )
color = (EDA_Colors) Color; color = (EDA_Colors) Color;
...@@ -1054,18 +992,17 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel, ...@@ -1054,18 +992,17 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel,
GRSetDrawMode( DC, DrawMode ); GRSetDrawMode( DC, DrawMode );
int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
EXCHG( linewidth, m_Width ); // Set the minimum width EXCHG( linewidth, m_Width ); // Set the minimum width
wxPoint text_offset = offset + GetSchematicTextOffset(); EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED,
UNSPECIFIED_COLOR );
EXCHG( linewidth, m_Width ); // set initial value EXCHG( linewidth, m_Width ); // set initial value
CreateGraphicShape( Poly, m_Pos + offset ); CreateGraphicShape( Poly, m_Pos + aOffset );
GRPoly( &panel->m_ClipBox, DC, Poly.size(), &Poly[0], 0, linewidth, GRPoly( &panel->m_ClipBox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
color, color );
if( m_IsDangling ) if( m_IsDangling )
DrawDanglingSymbol( panel, DC, m_Pos + offset, color ); DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
// Enable these line to draw the bounding box (debug tests purposes only) // Enable these line to draw the bounding box (debug tests purposes only)
#if 0 #if 0
...@@ -1082,68 +1019,97 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel, ...@@ -1082,68 +1019,97 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel,
} }
/** Function CreateGraphicShape /** function CreateGraphicShape
* calculates the graphic shape (a polygon) associated to the text * Calculates the graphic shape (a polygon) associated to the text
* @param aCorner_list = a buffer to fill with polygon corners coordinates * @param aCorner_list = a buffer to fill with polygon corners coordinates
* @param Pos = Postion of the shape * @param Pos = Position of the shape
*/ */
void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aCorner_list, void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aCorner_list,
const wxPoint& Pos ) const wxPoint& Pos )
{ {
int* Template = TemplateShape[m_Shape][m_SchematicOrientation]; int HalfSize = m_Size.y / 2;
int HalfSize = m_Size.x / 2; int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
int imax = *Template; Template++; linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
aCorner_list.clear(); aCorner_list.clear();
for( int ii = 0; ii < imax; ii++ )
{
wxPoint corner;
corner.x = ( HalfSize * (*Template) ) + Pos.x;
Template++;
corner.y = ( HalfSize * (*Template) ) + Pos.y; int symb_len = LenSize( m_Text ) + ( TXTMARGE * 2 );
Template++;
aCorner_list.push_back( corner ); // Create outline shape : 6 points
} int x = symb_len + linewidth + 3;
}
// 50% more for negation bar
int y = wxRound( (double) HalfSize * 1.5 + (double) linewidth + 3.0 );
// Starting point(anchor)
aCorner_list.push_back( wxPoint( 0, 0 ) );
aCorner_list.push_back( wxPoint( 0, -y ) ); // Up
aCorner_list.push_back( wxPoint( -x, -y ) ); // left
aCorner_list.push_back( wxPoint( -x, 0 ) ); // Up left
aCorner_list.push_back( wxPoint( -x, y ) ); // left down
aCorner_list.push_back( wxPoint( 0, y ) ); // down
int x_offset = 0;
/** Virtual Function SCH_SHEET_PIN::CreateGraphicShape
* calculates the graphic shape (a polygon) associated to the text
* @param aCorner_list = a buffer to fill with polygon corners coordinates
* @param aPos = Position of the shape
*/
void SCH_SHEET_PIN::CreateGraphicShape( std::vector <wxPoint>& aCorner_list,
const wxPoint& aPos )
{
/* This is the same icon shapes as SCH_HIERLABEL
* but the graphic icon is slightly different in 2 cases:
* for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL
* for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL
*/
int tmp = m_Shape;
switch( m_Shape ) switch( m_Shape )
{ {
case NET_INPUT: case NET_INPUT:
m_Shape = NET_OUTPUT; x_offset = -HalfSize;
aCorner_list[0].x += HalfSize;
break; break;
case NET_OUTPUT: case NET_OUTPUT:
m_Shape = NET_INPUT; aCorner_list[3].x -= HalfSize;
break;
case NET_BIDI:
case NET_TRISTATE:
x_offset = -HalfSize;
aCorner_list[0].x += HalfSize;
aCorner_list[3].x -= HalfSize;
break; break;
case NET_UNSPECIFIED:
default: default:
break; break;
} }
SCH_HIERLABEL::CreateGraphicShape( aCorner_list, aPos );
m_Shape = tmp; int angle = 0;
switch( m_SchematicOrientation )
{
case 0: /* Orientation horiz normal */
break;
case 1: /* Orientation vert UP */
angle = -900;
break;
case 2: /* Orientation horiz inverse */
angle = 1800;
break;
case 3: /* Orientation vert BOTTOM */
angle = 900;
break;
}
// Rotate outlines and move corners in real position
for( unsigned ii = 0; ii < aCorner_list.size(); ii++ )
{
aCorner_list[ii].x += x_offset;
if( angle )
RotatePoint( &aCorner_list[ii], angle );
aCorner_list[ii] += Pos;
}
aCorner_list.push_back( aCorner_list[0] ); // closing
} }
/****************************************/
EDA_Rect SCH_HIERLABEL::GetBoundingBox() EDA_Rect SCH_GLOBALLABEL::GetBoundingBox()
{ {
/****************************************/
int x, y, dx, dy, length, height; int x, y, dx, dy, length, height;
x = m_Pos.x; x = m_Pos.x;
...@@ -1151,15 +1117,14 @@ EDA_Rect SCH_HIERLABEL::GetBoundingBox() ...@@ -1151,15 +1117,14 @@ EDA_Rect SCH_HIERLABEL::GetBoundingBox()
dx = dy = 0; dx = dy = 0;
int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width; int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
height = m_Size.y + width + 2 * TXTMARGE; height = ( (m_Size.y * 15) / 10 ) + width + 2 * TXTMARGE;
length = LenSize( m_Text )
+ height // add height for triangular shapes // text X size add height for triangular shapes(bidirectional)
+ 2 * DANGLING_SYMBOL_SIZE; length = LenSize( m_Text ) + height + DANGLING_SYMBOL_SIZE;
switch( m_SchematicOrientation ) // respect orientation switch( m_SchematicOrientation ) // respect orientation
{ {
case 0: /* Horiz Normal Orientation (left case 0: /* Horiz Normal Orientation (left justified) */
*justified) */
dx = -length; dx = -length;
dy = height; dy = height;
x += DANGLING_SYMBOL_SIZE; x += DANGLING_SYMBOL_SIZE;
...@@ -1173,43 +1138,134 @@ EDA_Rect SCH_HIERLABEL::GetBoundingBox() ...@@ -1173,43 +1138,134 @@ EDA_Rect SCH_HIERLABEL::GetBoundingBox()
y += DANGLING_SYMBOL_SIZE; y += DANGLING_SYMBOL_SIZE;
break; break;
case 2: /* Horiz Orientation - Right justified */ case 2: /* Horiz Orientation - Right justified */
dx = length; dx = length;
dy = height; dy = height;
x -= DANGLING_SYMBOL_SIZE; x -= DANGLING_SYMBOL_SIZE;
y -= height / 2; y -= height / 2;
break;
case 3: /* Vert Orientation BOTTOM */
dx = height;
dy = length;
x -= height / 2;
y -= DANGLING_SYMBOL_SIZE;
break;
}
EDA_Rect box( wxPoint( x, y ), wxSize( dx, dy ) );
box.Normalize();
return box;
}
SCH_HIERLABEL::SCH_HIERLABEL( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
SCH_TEXT( pos, text, aType )
{
m_Layer = LAYER_HIERLABEL;
m_Shape = NET_INPUT;
m_IsDangling = TRUE;
m_MultilineAllowed = false;
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool SCH_HIERLABEL::Save( FILE* aFile ) const
{
bool success = true;
const char* shape = "~";
if( m_Italic )
shape = "Italic";
if( fprintf( aFile, "Text HLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
m_Pos.x, m_Pos.y, m_SchematicOrientation, m_Size.x,
SheetLabelType[m_Shape], shape, m_Width, CONV_TO_UTF8( m_Text ) ) == EOF )
{
success = false;
}
return success;
}
/** Function HitTest
* @return true if the point aPosRef is within item area
* @param aPosRef = a wxPoint to test
*/
bool SCH_HIERLABEL::HitTest( const wxPoint& aPosRef )
{
EDA_Rect rect = GetBoundingBox();
return rect.Inside( aPosRef );
}
/** function SetTextOrientAndJustifyParmeters
* Set m_SchematicOrientation, and initialize
* m_orient,m_HJustified and m_VJustified, according to the value of
* m_SchematicOrientation
* must be called after changing m_SchematicOrientation
* @param aSchematicOrientation =
* 0 = normal (horizontal, left justified).
* 1 = up (vertical)
* 2 = (horizontal, right justified). This can be seen as the mirrored
* position of 0
* 3 = bottom . This can be seen as the mirrored position of up
*/
void SCH_HIERLABEL::SetSchematicTextOrientation( int aSchematicOrientation )
{
m_SchematicOrientation = aSchematicOrientation;
switch( m_SchematicOrientation )
{
default:
case 0: /* Horiz Normal Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 1: /* Vert Orientation UP */
m_Orient = TEXT_ORIENT_VERT;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case 2: /* Horiz Orientation */
m_Orient = TEXT_ORIENT_HORIZ;
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
break; break;
case 3: /* Vert Orientation BOTTOM */ case 3: /* Vert Orientation BOTTOM */
dx = height; m_Orient = TEXT_ORIENT_VERT;
dy = length; m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
x -= height / 2; m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
y -= DANGLING_SYMBOL_SIZE;
break; break;
} }
EDA_Rect box( wxPoint( x, y ), wxSize( dx, dy ) );
box.Normalize();
return box;
} }
/*****************************************************************************/ /* Hierarchical Label have a text and a graphic icon.
void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel, * Texts type have 4 directions, and the text origin is the graphic icon
*/
void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel,
wxDC* DC, wxDC* DC,
const wxPoint& aOffset, const wxPoint& offset,
int DrawMode, int DrawMode,
int Color ) int Color )
{ {
/*****************************************************************************/
/* Texts type Global Label have 4 directions, and the Text origin is the
* graphic icon
*/
static std::vector <wxPoint> Poly; static std::vector <wxPoint> Poly;
EDA_Colors color; EDA_Colors color;
wxPoint text_offset = aOffset + GetSchematicTextOffset(); int linewidth = ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
if( Color >= 0 ) if( Color >= 0 )
color = (EDA_Colors) Color; color = (EDA_Colors) Color;
...@@ -1218,19 +1274,16 @@ void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel, ...@@ -1218,19 +1274,16 @@ void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel,
GRSetDrawMode( DC, DrawMode ); GRSetDrawMode( DC, DrawMode );
int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
EXCHG( linewidth, m_Width ); // Set the minimum width EXCHG( linewidth, m_Width ); // Set the minimum width
EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED, wxPoint text_offset = offset + GetSchematicTextOffset();
UNSPECIFIED_COLOR ); EDA_TextStruct::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
EXCHG( linewidth, m_Width ); // set initial value EXCHG( linewidth, m_Width ); // set initial value
CreateGraphicShape( Poly, m_Pos + aOffset ); CreateGraphicShape( Poly, m_Pos + offset );
GRPoly( &panel->m_ClipBox, DC, Poly.size(), &Poly[0], 0, linewidth, GRPoly( &panel->m_ClipBox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
color, color );
if( m_IsDangling ) if( m_IsDangling )
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color ); DrawDanglingSymbol( panel, DC, m_Pos + offset, color );
// Enable these line to draw the bounding box (debug tests purposes only) // Enable these line to draw the bounding box (debug tests purposes only)
#if 0 #if 0
...@@ -1247,99 +1300,35 @@ void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel, ...@@ -1247,99 +1300,35 @@ void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel,
} }
/** function CreateGraphicShape /** Function CreateGraphicShape
* Calculates the graphic shape (a polygon) associated to the text * calculates the graphic shape (a polygon) associated to the text
* @param aCorner_list = a buffer to fill with polygon corners coordinates * @param aCorner_list = a buffer to fill with polygon corners coordinates
* @param Pos = Position of the shape * @param Pos = Postion of the shape
*/ */
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aCorner_list, void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aCorner_list,
const wxPoint& Pos ) const wxPoint& Pos )
{ {
int HalfSize = m_Size.y / 2; int* Template = TemplateShape[m_Shape][m_SchematicOrientation];
int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width; int HalfSize = m_Size.x / 2;
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); int imax = *Template; Template++;
aCorner_list.clear(); aCorner_list.clear();
for( int ii = 0; ii < imax; ii++ )
int symb_len = LenSize( m_Text ) + ( TXTMARGE * 2 );
// Create outline shape : 6 points
int x = symb_len + linewidth + 3;
// 50% more for negation bar
int y = wxRound( (double) HalfSize * 1.5 + (double) linewidth + 3.0 );
// Starting point(anchor)
aCorner_list.push_back( wxPoint( 0, 0 ) );
aCorner_list.push_back( wxPoint( 0, -y ) ); // Up
aCorner_list.push_back( wxPoint( -x, -y ) ); // left
aCorner_list.push_back( wxPoint( -x, 0 ) ); // Up left
aCorner_list.push_back( wxPoint( -x, y ) ); // left down
aCorner_list.push_back( wxPoint( 0, y ) ); // down
int x_offset = 0;
switch( m_Shape )
{
case NET_INPUT:
x_offset = -HalfSize;
aCorner_list[0].x += HalfSize;
break;
case NET_OUTPUT:
aCorner_list[3].x -= HalfSize;
break;
case NET_BIDI:
case NET_TRISTATE:
x_offset = -HalfSize;
aCorner_list[0].x += HalfSize;
aCorner_list[3].x -= HalfSize;
break;
case NET_UNSPECIFIED:
default:
break;
}
int angle = 0;
switch( m_SchematicOrientation )
{ {
case 0: /* Orientation horiz normal */ wxPoint corner;
break; corner.x = ( HalfSize * (*Template) ) + Pos.x;
Template++;
case 1: /* Orientation vert UP */
angle = -900;
break;
case 2: /* Orientation horiz inverse */
angle = 1800;
break;
case 3: /* Orientation vert BOTTOM */ corner.y = ( HalfSize * (*Template) ) + Pos.y;
angle = 900; Template++;
break;
}
// Rotate outlines and move corners in real position aCorner_list.push_back( corner );
for( unsigned ii = 0; ii < aCorner_list.size(); ii++ )
{
aCorner_list[ii].x += x_offset;
if( angle )
RotatePoint( &aCorner_list[ii], angle );
aCorner_list[ii] += Pos;
} }
aCorner_list.push_back( aCorner_list[0] ); // closing
} }
EDA_Rect SCH_HIERLABEL::GetBoundingBox()
/******************************************/
EDA_Rect SCH_GLOBALLABEL::GetBoundingBox()
{ {
/******************************************/
int x, y, dx, dy, length, height; int x, y, dx, dy, length, height;
x = m_Pos.x; x = m_Pos.x;
...@@ -1347,14 +1336,15 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox() ...@@ -1347,14 +1336,15 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox()
dx = dy = 0; dx = dy = 0;
int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width; int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
height = ( (m_Size.y * 15) / 10 ) + width + 2 * TXTMARGE; height = m_Size.y + width + 2 * TXTMARGE;
length = LenSize( m_Text )
// text X size add height for triangular shapes(bidirectional) + height // add height for triangular shapes
length = LenSize( m_Text ) + height + DANGLING_SYMBOL_SIZE; + 2 * DANGLING_SYMBOL_SIZE;
switch( m_SchematicOrientation ) // respect orientation switch( m_SchematicOrientation ) // respect orientation
{ {
case 0: /* Horiz Normal Orientation (left justified) */ case 0: /* Horiz Normal Orientation (left
*justified) */
dx = -length; dx = -length;
dy = height; dy = height;
x += DANGLING_SYMBOL_SIZE; x += DANGLING_SYMBOL_SIZE;
...@@ -1389,80 +1379,93 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox() ...@@ -1389,80 +1379,93 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox()
} }
/***********************************/ /** function GetSchematicTextOffset (virtual)
EDA_Rect SCH_LABEL::GetBoundingBox() * @return the offset between the SCH_TEXT position and the text itself
/***********************************/ * position
* This offset depend on orientation, and the type of text
* (room to draw an associated graphic symbol, or put the text above a wire)
*/
wxPoint SCH_HIERLABEL::GetSchematicTextOffset()
{ {
int x, y, dx, dy, length, height; wxPoint text_offset;
x = m_Pos.x; int width = MAX( m_Width, g_DrawDefaultLineThickness );
y = m_Pos.y;
int width = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width; int ii = m_Size.x + TXTMARGE + width;
length = LenSize( m_Text );
height = m_Size.y + width;
dx = dy = 0;
switch( m_SchematicOrientation ) switch( m_SchematicOrientation )
{ {
case 0: /* Horiz Normal Orientation (left justified) */ case 0: /* Orientation horiz normale */
dx = 2 * DANGLING_SYMBOL_SIZE + length; text_offset.x = -ii;
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
x -= DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break; break;
case 1: /* Vert Orientation UP */ case 1: /* Orientation vert UP */
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE; text_offset.y = -ii;
dy = -2 * DANGLING_SYMBOL_SIZE - length;
x += DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break; break;
case 2: /* Horiz Orientation - Right justified */ case 2: /* Orientation horiz inverse */
dx = -2 * DANGLING_SYMBOL_SIZE - length; text_offset.x = ii;
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
x += DANGLING_SYMBOL_SIZE;
y += DANGLING_SYMBOL_SIZE;
break; break;
case 3: /* Vert Orientation BOTTOM */ case 3: /* Orientation vert BOTTOM */
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE; text_offset.y = ii;
dy = 2 * DANGLING_SYMBOL_SIZE + length;
x += DANGLING_SYMBOL_SIZE;
y -= DANGLING_SYMBOL_SIZE;
break; break;
} }
EDA_Rect box( wxPoint( x, y ), wxSize( dx, dy ) ); return text_offset;
box.Normalize();
return box;
} }
/***********************************/ /** virtual function Mirror_Y
EDA_Rect SCH_TEXT::GetBoundingBox() * mirror item relative to an Y axis
/***********************************/ * @param aYaxis_position = the y axis position
*/
void SCH_HIERLABEL::Mirror_Y( int aYaxis_position )
{ {
// We must pass the effective text thickness to GetTextBox /* The hierarchical label is NOT really mirrored.
// when calculating the bounding box * for an horizontal label, the schematic orientation is changed.
int linewidth = * for a vericalal label, the schematic orientation is not changed.
(m_Width == 0) ? g_DrawDefaultLineThickness : m_Width; * and the label is moved to a suitable position
*/
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); switch( GetSchematicTextOrientation() )
EXCHG( linewidth, m_Width ); // Set the real width {
EDA_Rect rect = GetTextBox( -1 ); case 0: /* horizontal text */
EXCHG( linewidth, m_Width ); // set initial value SetSchematicTextOrientation( 2 );
break;
if( m_Orient ) // Rotate rect case 2: /* invert horizontal text*/
SetSchematicTextOrientation( 0 );
break;
}
m_Pos.x -= aYaxis_position;
NEGATE( m_Pos.x );
m_Pos.x += aYaxis_position;
}
void SCH_HIERLABEL::Mirror_X( int aXaxis_position )
{
switch( GetSchematicTextOrientation() )
{ {
wxPoint pos = rect.GetOrigin(); case 1: /* vertical text */
wxPoint end = rect.GetEnd(); SetSchematicTextOrientation( 3 );
RotatePoint( &pos, m_Pos, m_Orient ); break;
RotatePoint( &end, m_Pos, m_Orient );
rect.SetOrigin( pos ); case 3: /* invert vertical text*/
rect.SetEnd( end ); SetSchematicTextOrientation( 1 );
break;
} }
rect.Normalize(); m_Pos.y -= aXaxis_position;
return rect; NEGATE( m_Pos.y );
m_Pos.y += aXaxis_position;
}
void SCH_HIERLABEL::Rotate( wxPoint rotationPoint )
{
RotatePoint( &m_Pos, rotationPoint, 900 );
SetSchematicTextOrientation( (GetSchematicTextOrientation() + 3) % 4 );
} }
...@@ -167,8 +167,17 @@ public: ...@@ -167,8 +167,17 @@ public:
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return True if this schematic text item matches the search criteria. * @return True if this schematic text item matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
void* aAuxData, wxPoint * aFindLocation );
virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsDangling() const { return m_IsDangling; }
virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
......
...@@ -4,55 +4,14 @@ ...@@ -4,55 +4,14 @@
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "gr_basic.h"
#include "common.h"
#include "program.h" #include "program.h"
#include "general.h" #include "general.h"
#include "netlist.h"
#include "protos.h" #include "protos.h"
#include "class_library.h" #include "class_libentry.h"
#include "lib_pin.h" #include "lib_pin.h"
enum End_Type {
UNKNOWN = 0,
WIRE_START_END,
WIRE_END_END,
BUS_START_END,
BUS_END_END,
JUNCTION_END,
PIN_END,
LABEL_END,
ENTRY_END,
SHEET_LABEL_END
};
// A helper class to store a list of items that can be connected to something:
class DANGLING_END_ITEM
{
public:
const void* m_Item; // a pointer to the parent
wxPoint m_Pos; // the position of the connecting point
int m_Type; // type of parent
DANGLING_END_ITEM( int type, const void* aItem )
{
m_Item = aItem;
m_Type = type;
}
};
static void TestWireForDangling( std::vector <DANGLING_END_ITEM>& aItemList,
SCH_LINE* DrawRef,
WinEDA_SchematicFrame* frame,
wxDC* aDC );
void TestLabelForDangling( std::vector <DANGLING_END_ITEM>& aItemList,
SCH_TEXT* aLabel,
WinEDA_SchematicFrame* aFrame,
wxDC* aDC );
void RebuildEndPointsList( std::vector <DANGLING_END_ITEM>& aItemList, SCH_ITEM* aDrawList );
/* Returns true if the point P is on the segment S. */ /* Returns true if the point P is on the segment S. */
bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint ) bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint )
{ {
...@@ -71,53 +30,20 @@ bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint ) ...@@ -71,53 +30,20 @@ bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint )
} }
void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC ) void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* aDrawList, wxDC* aDC )
{ {
// this list is static to avoid many useles memory allocation. SCH_ITEM* item;
std::vector <DANGLING_END_ITEM> itemList; std::vector< DANGLING_END_ITEM > endPoints;
RebuildEndPointsList( itemList, DrawList );
for( SCH_ITEM* item = DrawList; item; item = item->Next() ) for( item = aDrawList; item != NULL; item = item->Next() )
{ item->GetEndPoints( endPoints );
switch( item->Type() )
{
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
case TYPE_SCH_LABEL:
TestLabelForDangling( itemList, (SCH_LABEL*) item, this, DC );
break;
case DRAW_SHEET_STRUCT_TYPE: for( item = aDrawList; item; item = item->Next() )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) item; if( item->IsDanglingStateChanged( endPoints ) && aDC != NULL )
// Read the hierarchical pins list and teast for dangling pins:
BOOST_FOREACH( SCH_SHEET_PIN & pinsheet, sheet->GetSheetPins() )
{ {
TestLabelForDangling( itemList, &pinsheet, this, DC ); RedrawOneStruct( DrawPanel, aDC, item, g_XorMode );
} RedrawOneStruct( DrawPanel, aDC, item, GR_DEFAULT_DRAWMODE );
}
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (SCH_LINE*) item )
if( STRUCT->GetLayer() == LAYER_WIRE )
{
TestWireForDangling( itemList, STRUCT, this, DC );
break;
}
if( STRUCT->GetLayer() == LAYER_NOTES )
break;
if( STRUCT->GetLayer() == LAYER_BUS )
{
STRUCT->m_StartIsDangling = STRUCT->m_EndIsDangling = false;
break;
}
break;
default:
break;
} }
} }
} }
...@@ -129,8 +55,7 @@ void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC ) ...@@ -129,8 +55,7 @@ void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC )
* @param DrawList = List of SCH_ITEMs to check. * @param DrawList = List of SCH_ITEMs to check.
* @return a LIB_PIN pointer to the located pin or NULL if no pin was found. * @return a LIB_PIN pointer to the located pin or NULL if no pin was found.
*/ */
LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList, LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList, const wxPoint& pos )
const wxPoint& pos )
{ {
SCH_COMPONENT* DrawLibItem; SCH_COMPONENT* DrawLibItem;
LIB_PIN* Pin; LIB_PIN* Pin;
...@@ -153,234 +78,3 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList, ...@@ -153,234 +78,3 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList,
return Pin; return Pin;
return NULL; return NULL;
} }
void TestWireForDangling( std::vector <DANGLING_END_ITEM>& aItemList,
SCH_LINE* DrawRef,
WinEDA_SchematicFrame* frame,
wxDC* DC )
{
bool Sdangstate = true, Edangstate = true;
BOOST_FOREACH( DANGLING_END_ITEM terminal_item, aItemList )
{
if( terminal_item.m_Item == DrawRef )
continue;
if( DrawRef->m_Start == terminal_item.m_Pos )
Sdangstate = false;
if( DrawRef->m_End == terminal_item.m_Pos )
Edangstate = false;
if( (Sdangstate == false) && (Edangstate == false) )
break;
}
if( (Sdangstate != DrawRef->m_StartIsDangling)
|| (Edangstate != DrawRef->m_EndIsDangling) )
{
if( DC )
RedrawOneStruct( frame->DrawPanel, DC, DrawRef, g_XorMode );
DrawRef->m_StartIsDangling = Sdangstate;
DrawRef->m_EndIsDangling = Edangstate;
if( DC )
RedrawOneStruct( frame->DrawPanel, DC, DrawRef,
GR_DEFAULT_DRAWMODE );
}
}
void TestLabelForDangling( std::vector <DANGLING_END_ITEM>& aItemList,
SCH_TEXT* aLabel,
WinEDA_SchematicFrame* aFrame,
wxDC* aDC )
{
bool dangstate = true;
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
{
DANGLING_END_ITEM & terminal_item = aItemList[ii];
if( terminal_item.m_Item == aLabel )
continue;
switch( terminal_item.m_Type )
{
case PIN_END:
case LABEL_END:
case SHEET_LABEL_END:
if( aLabel->m_Pos == terminal_item.m_Pos )
dangstate = false;
break;
case WIRE_START_END:
case BUS_START_END:
{
// these schematic items have created 2 DANGLING_END_ITEM
// one per end.
ii++;
DANGLING_END_ITEM & next_terminal = aItemList[ii];
dangstate = !SegmentIntersect( terminal_item.m_Pos,
next_terminal.m_Pos,
aLabel->m_Pos );
}
break;
case UNKNOWN:
case JUNCTION_END:
case ENTRY_END:
case WIRE_END_END:
case BUS_END_END:
break;
}
if( dangstate == false )
break;
}
if( dangstate != aLabel->m_IsDangling )
{
if( aDC )
RedrawOneStruct( aFrame->DrawPanel, aDC, aLabel, g_XorMode );
aLabel->m_IsDangling = dangstate;
if( aDC )
RedrawOneStruct( aFrame->DrawPanel, aDC, aLabel, GR_DEFAULT_DRAWMODE );
}
}
/* Returns the physical position of the pin relative to the component
* orientation. */
wxPoint ReturnPinPhysicalPosition( LIB_PIN* Pin, SCH_COMPONENT* DrawLibItem )
{
wxPoint PinPos = Pin->m_Pos;
if( DrawLibItem == NULL )
NEGATE( PinPos.y );
else
PinPos = DrawLibItem->m_Transform.TransformCoordinate( Pin->m_Pos ) + DrawLibItem->m_Pos;
return PinPos;
}
void RebuildEndPointsList( std::vector <DANGLING_END_ITEM>& aItemList, SCH_ITEM* aDrawList )
{
SCH_ITEM* schItem;
aItemList.clear();
for( schItem = aDrawList; schItem != NULL; schItem = schItem->Next() )
{
switch( schItem->Type() )
{
case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
{
#undef STRUCT
#define STRUCT ( (SCH_LABEL*) schItem )
DANGLING_END_ITEM item( LABEL_END, schItem );
item.m_Pos = STRUCT->m_Pos;
aItemList.push_back( item );
}
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (SCH_LINE*) schItem )
if( STRUCT->GetLayer() == LAYER_NOTES )
break;
if( ( STRUCT->GetLayer() == LAYER_BUS )
|| (STRUCT->GetLayer() == LAYER_WIRE ) )
{
DANGLING_END_ITEM item( (STRUCT->GetLayer() == LAYER_BUS) ?
BUS_START_END : WIRE_START_END, schItem );
item.m_Pos = STRUCT->m_Start;
DANGLING_END_ITEM item1( (STRUCT->GetLayer() == LAYER_BUS) ?
BUS_END_END : WIRE_END_END, schItem );
item1.m_Pos = STRUCT->m_End;
aItemList.push_back( item );
aItemList.push_back( item1 );
}
break;
case DRAW_JUNCTION_STRUCT_TYPE:
{
#undef STRUCT
#define STRUCT ( (SCH_JUNCTION*) schItem )
DANGLING_END_ITEM item( JUNCTION_END, schItem );
item.m_Pos = STRUCT->m_Pos;
aItemList.push_back( item );
}
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
{
#undef STRUCT
#define STRUCT ( (SCH_BUS_ENTRY*) schItem )
DANGLING_END_ITEM item( ENTRY_END, schItem );
item.m_Pos = STRUCT->m_Pos;
DANGLING_END_ITEM item1( ENTRY_END, schItem );
item1.m_Pos = STRUCT->m_End();
aItemList.push_back( item );
aItemList.push_back( item1 );
}
break;
case TYPE_SCH_COMPONENT:
{
#undef STRUCT
#define STRUCT ( (SCH_COMPONENT*) schItem )
LIB_COMPONENT* Entry;
Entry = CMP_LIBRARY::FindLibraryComponent( STRUCT->m_ChipName );
if( Entry == NULL )
break;
for( LIB_PIN* Pin = Entry->GetNextPin(); Pin != NULL;
Pin = Entry->GetNextPin( Pin ) )
{
wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE );
if( Pin->GetUnit() && STRUCT->m_Multi && ( STRUCT->m_Multi != Pin->GetUnit() ) )
continue;
if( Pin->GetConvert() && STRUCT->m_Convert
&& ( STRUCT->m_Convert != Pin->GetConvert() ) )
continue;
DANGLING_END_ITEM item( PIN_END, Pin );
item.m_Pos = ReturnPinPhysicalPosition( Pin, STRUCT );
aItemList.push_back( item );
}
break;
}
case DRAW_SHEET_STRUCT_TYPE:
{
SCH_SHEET* sheet = (SCH_SHEET*) schItem;
// Using BOOST_FOREACH here creates problems (bad pointer value to pinsheet).
// I do not know why.
for( unsigned ii = 0; ii < sheet->GetSheetPins().size(); ii++ )
{
SCH_SHEET_PIN &pinsheet = sheet->GetSheetPins()[ii];
wxASSERT( pinsheet.Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE );
DANGLING_END_ITEM item( SHEET_LABEL_END, &pinsheet );
item.m_Pos = pinsheet.m_Pos;
aItemList.push_back( item );
}
}
break;
default:
;
}
}
}
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
/* in read_from_file_schematic_items_description.cpp */ /* in read_from_file_schematic_items_description.cpp */
SCH_ITEM* ReadTextDescr( LINE_READER* aLine, wxString& aMsgDiag, int aSchematicFileVersion ); SCH_ITEM* ReadTextDescr( LINE_READER* aLine, wxString& aMsgDiag, int aSchematicFileVersion );
int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ); int ReadSheetDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window );
bool ReadSchemaDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ); bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window );
int ReadPartDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ); int ReadPartDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window );
static void LoadLayers( LINE_READER* aLine ); static void LoadLayers( LINE_READER* aLine );
...@@ -29,8 +29,7 @@ static void LoadLayers( LINE_READER* aLine ); ...@@ -29,8 +29,7 @@ static void LoadLayers( LINE_READER* aLine );
* Routine to load an EESchema file. * Routine to load an EESchema file.
* Returns true if file has been loaded (at least partially.) * Returns true if file has been loaded (at least partially.)
*/ */
bool WinEDA_SchematicFrame::LoadOneEEFile( SCH_SCREEN* screen, bool WinEDA_SchematicFrame::LoadOneEEFile( SCH_SCREEN* screen, const wxString& FullFileName )
const wxString& FullFileName )
{ {
char Name1[256], char Name1[256],
Name2[256]; Name2[256];
...@@ -122,13 +121,13 @@ again." ); ...@@ -122,13 +121,13 @@ again." );
{ {
case '$': // identification block case '$': // identification block
if( line[1] == 'C' ) if( line[1] == 'C' )
Failed = ReadPartDescr( this, &reader, MsgDiag, screen ); Failed = ReadPartDescr( &reader, MsgDiag, screen );
else if( line[1] == 'S' ) else if( line[1] == 'S' )
Failed = ReadSheetDescr( this, &reader, MsgDiag, screen ); Failed = ReadSheetDescr( &reader, MsgDiag, screen );
else if( line[1] == 'D' ) else if( line[1] == 'D' )
Failed = ReadSchemaDescr( this, &reader, MsgDiag, screen ); Failed = ReadSchemaDescr( &reader, MsgDiag, screen );
else if( line[1] == 'T' ) // text part else if( line[1] == 'T' ) // text part
{ {
...@@ -148,7 +147,7 @@ again." ); ...@@ -148,7 +147,7 @@ again." );
break; break;
case 'L': // Its a library item. case 'L': // Its a library item.
Failed = ReadPartDescr( this, &reader, MsgDiag, screen ); Failed = ReadPartDescr( &reader, MsgDiag, screen );
break; break;
case 'W': // Its a Segment (WIRE or BUS) item. case 'W': // Its a Segment (WIRE or BUS) item.
......
...@@ -175,7 +175,7 @@ SCH_ITEM* ReadTextDescr( LINE_READER* aLine, wxString& aMsgDiag, int aSchematicF ...@@ -175,7 +175,7 @@ SCH_ITEM* ReadTextDescr( LINE_READER* aLine, wxString& aMsgDiag, int aSchematicF
/* Function used by LoadEEFile(). /* Function used by LoadEEFile().
* Get the lines for a description of a piece of hierarchy. * Get the lines for a description of a piece of hierarchy.
*/ */
int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ) int ReadSheetDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window )
{ {
int ii, fieldNdx, size; int ii, fieldNdx, size;
char Name1[256], Char1[256], Char2[256]; char Name1[256], Char1[256], Char2[256];
...@@ -286,7 +286,6 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS ...@@ -286,7 +286,6 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS
aLine->LineNumber() ); aLine->LineNumber() );
aMsgDiag << CONV_FROM_UTF8( line ); aMsgDiag << CONV_FROM_UTF8( line );
DisplayError( frame, aMsgDiag );
} }
if( size == 0 ) if( size == 0 )
size = DEFAULT_SIZE_TEXT; size = DEFAULT_SIZE_TEXT;
...@@ -316,7 +315,6 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS ...@@ -316,7 +315,6 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS
aMsgDiag.Printf( wxT( "EESchema file sheet label error at line %d, ignoring.\n" ), aMsgDiag.Printf( wxT( "EESchema file sheet label error at line %d, ignoring.\n" ),
aLine->LineNumber() ); aLine->LineNumber() );
aMsgDiag << CONV_FROM_UTF8( line ); aMsgDiag << CONV_FROM_UTF8( line );
DisplayError( frame, aMsgDiag );
continue; continue;
} }
...@@ -391,7 +389,7 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS ...@@ -391,7 +389,7 @@ int ReadSheetDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BAS
/* Read the schematic header. */ /* Read the schematic header. */
bool ReadSchemaDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ) bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window )
{ {
char Text[256], buf[1024]; char Text[256], buf[1024];
int ii; int ii;
...@@ -427,7 +425,6 @@ bool ReadSchemaDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, B ...@@ -427,7 +425,6 @@ bool ReadSchemaDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, B
line %d, \aAbort reading file.\n" ), line %d, \aAbort reading file.\n" ),
aLine->LineNumber() ); aLine->LineNumber() );
aMsgDiag << CONV_FROM_UTF8( line ); aMsgDiag << CONV_FROM_UTF8( line );
DisplayError( frame, aMsgDiag );
} }
Window->m_CurrentSheetDesc = wsheet; Window->m_CurrentSheetDesc = wsheet;
...@@ -509,7 +506,7 @@ line %d, \aAbort reading file.\n" ), ...@@ -509,7 +506,7 @@ line %d, \aAbort reading file.\n" ),
* Get the lines for a description of a schematic component. * Get the lines for a description of a schematic component.
*/ */
int ReadPartDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ) int ReadPartDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window )
{ {
int ii; int ii;
char Name1[256], Name2[256], char Name1[256], Name2[256],
...@@ -754,7 +751,6 @@ int ReadPartDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE ...@@ -754,7 +751,6 @@ int ReadPartDescr( wxWindow* frame, LINE_READER* aLine, wxString& aMsgDiag, BASE
aMsgDiag.Printf( aMsgDiag.Printf(
wxT( "Component Field error line %d, aborted" ), wxT( "Component Field error line %d, aborted" ),
aLine->LineNumber() ); aLine->LineNumber() );
DisplayError( frame, aMsgDiag );
continue; continue;
} }
......
...@@ -348,6 +348,7 @@ public: ...@@ -348,6 +348,7 @@ public:
inline bool IsModified() const { return m_Flags & IS_CHANGED; } inline bool IsModified() const { return m_Flags & IS_CHANGED; }
inline bool IsMoving() const { return m_Flags & IS_MOVED; } inline bool IsMoving() const { return m_Flags & IS_MOVED; }
inline bool IsDragging() const { return m_Flags & IS_DRAGGED; } inline bool IsDragging() const { return m_Flags & IS_DRAGGED; }
inline bool IsSelected() const { return m_Flags & SELECTED; }
int GetState( int type ) const int GetState( int type ) const
{ {
......
...@@ -14,12 +14,23 @@ ...@@ -14,12 +14,23 @@
#include "block_commande.h" #include "block_commande.h"
#include "common.h" #include "common.h"
#include <boost/ptr_container/ptr_vector.hpp>
// Forward declarations: // Forward declarations:
class SCH_ITEM; class SCH_ITEM;
class Ki_PageDescr; class Ki_PageDescr;
/**
* Define list of drawing items for screens.
*
* The Boost containter was choosen over the statand C++ contain because you can detach
* the pointer from a list with the release method.
*/
typedef boost::ptr_vector< EDA_BaseStruct > EDA_ITEMS;
/* Simple class for handling grid arrays. */ /* Simple class for handling grid arrays. */
class GRID_TYPE class GRID_TYPE
{ {
...@@ -56,13 +67,12 @@ WX_DECLARE_OBJARRAY( GRID_TYPE, GridArray ); ...@@ -56,13 +67,12 @@ WX_DECLARE_OBJARRAY( GRID_TYPE, GridArray );
/*******************************************************************/ /*******************************************************************/
class BASE_SCREEN : public EDA_BaseStruct class BASE_SCREEN : public EDA_BaseStruct
{ {
EDA_ITEMS m_items; ///< The drawing items associated with this screen.
public: public:
wxPoint m_DrawOrg; /* offsets for drawing the circuit on the wxPoint m_DrawOrg; /* offsets for drawing the circuit on the screen */
* screen */ wxPoint m_Curseur; /* Screen cursor coordinate (on grid) in user units. */
wxPoint m_Curseur; /* Screen cursor coordinate (on grid) in user wxPoint m_MousePosition; /* Mouse cursor coordinate (off grid) in user units. */
* units. */
wxPoint m_MousePosition; /* Mouse cursor coordinate (off grid) in user
* units. */
wxPoint m_MousePositionInPixels; wxPoint m_MousePositionInPixels;
wxPoint m_O_Curseur; /* Relative Screen cursor coordinate (on grid) wxPoint m_O_Curseur; /* Relative Screen cursor coordinate (on grid)
* in user units. * in user units.
...@@ -280,8 +290,7 @@ public: ...@@ -280,8 +290,7 @@ public:
/** /**
* Function SetZoomList * Function SetZoomList
* sets the list of zoom factors. * sets the list of zoom factors.
* @param aZoomList An array of zoom factors in ascending order, zero * @param aZoomList An array of zoom factors in ascending order, zero terminated
* terminated
*/ */
void SetZoomList( const wxArrayInt& zoomlist ); void SetZoomList( const wxArrayInt& zoomlist );
...@@ -300,8 +309,7 @@ public: ...@@ -300,8 +309,7 @@ public:
bool SetFirstZoom(); bool SetFirstZoom();
bool SetLastZoom(); bool SetLastZoom();
//----<grid //----<grid stuff>----------------------------------------------------------
// stuff>----------------------------------------------------------
/** /**
* Return the command ID of the currently selected grid. * Return the command ID of the currently selected grid.
...@@ -359,6 +367,13 @@ public: ...@@ -359,6 +367,13 @@ public:
return wxT( "BASE_SCREEN" ); return wxT( "BASE_SCREEN" );
} }
/**
* Helpers for accessing the draw item list.
*/
EDA_ITEMS::iterator Begin() { return m_items.begin(); }
EDA_ITEMS::iterator End() { return m_items.end(); }
virtual void AddItem( EDA_BaseStruct* aItem );
virtual void InsertItem( EDA_ITEMS::iterator aIter, EDA_BaseStruct* aItem );
#if defined(DEBUG) #if defined(DEBUG)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define CLASS_SCREEN_H #define CLASS_SCREEN_H
#include "macros.h" #include "macros.h"
#include "base_struct.h" #include "sch_item_struct.h"
#include "class_base_screen.h" #include "class_base_screen.h"
...@@ -17,8 +17,9 @@ ...@@ -17,8 +17,9 @@
class SCH_SCREEN : public BASE_SCREEN class SCH_SCREEN : public BASE_SCREEN
{ {
public: public:
int m_RefCount; /*how many sheets reference this screen? int m_RefCount; ///< Number of sheets referencing this screen.
* delete when it goes to zero. */ ///< Delete when it goes to zero.
SCH_SCREEN( KICAD_T aType = SCREEN_STRUCT_TYPE ); SCH_SCREEN( KICAD_T aType = SCREEN_STRUCT_TYPE );
~SCH_SCREEN(); ~SCH_SCREEN();
...@@ -90,6 +91,17 @@ public: ...@@ -90,6 +91,17 @@ public:
* @return bool - true if success writing else false. * @return bool - true if success writing else false.
*/ */
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
/**
* Clear the state flags of all the items in the screen.
*/
void ClearDrawingState();
virtual void AddItem( SCH_ITEM* aItem ) { BASE_SCREEN::AddItem( (EDA_BaseStruct*) aItem ); }
virtual void InsertItem( EDA_ITEMS::iterator aIter, SCH_ITEM* aItem )
{
BASE_SCREEN::InsertItem( aIter, (EDA_BaseStruct*) aItem );
}
}; };
......
...@@ -5,11 +5,46 @@ ...@@ -5,11 +5,46 @@
#ifndef SCH_ITEM_STRUCT_H #ifndef SCH_ITEM_STRUCT_H
#define SCH_ITEM_STRUCT_H #define SCH_ITEM_STRUCT_H
#include <vector>
#include <class_base_screen.h>
using namespace std;
class SCH_ITEM;
class WinEDA_SchematicFrame; class WinEDA_SchematicFrame;
class wxFindReplaceData; class wxFindReplaceData;
enum DANGLING_END_T {
UNKNOWN = 0,
WIRE_START_END,
WIRE_END_END,
BUS_START_END,
BUS_END_END,
JUNCTION_END,
PIN_END,
LABEL_END,
ENTRY_END,
SHEET_LABEL_END
};
// A helper class to store a list of items that can be connected to something:
class DANGLING_END_ITEM
{
public:
const void* m_Item; // a pointer to the parent
wxPoint m_Pos; // the position of the connecting point
DANGLING_END_T m_Type; // type of parent
DANGLING_END_ITEM( DANGLING_END_T type, const void* aItem )
{
m_Item = aItem;
m_Type = type;
}
};
/** /**
* Class SCH_ITEM * Class SCH_ITEM
* is a base class for any item which can be embedded within the SCHEMATIC * is a base class for any item which can be embedded within the SCHEMATIC
...@@ -21,7 +56,7 @@ class SCH_ITEM : public EDA_BaseStruct ...@@ -21,7 +56,7 @@ class SCH_ITEM : public EDA_BaseStruct
{ {
protected: protected:
int m_Layer; int m_Layer;
EDA_ITEMS m_connections; ///< List of items connected to this item.
public: public:
SCH_ITEM( EDA_BaseStruct* aParent, KICAD_T aType ); SCH_ITEM( EDA_BaseStruct* aParent, KICAD_T aType );
...@@ -72,15 +107,15 @@ public: ...@@ -72,15 +107,15 @@ public:
* move item to a new position. * move item to a new position.
* @param aMoveVector = the deplacement vector * @param aMoveVector = the deplacement vector
*/ */
virtual void Move(const wxPoint& aMoveVector) = 0; virtual void Move( const wxPoint& aMoveVector ) = 0;
/** virtual function Mirror_Y /** virtual function Mirror_Y
* mirror item relative to an Y axis * mirror item relative to an Y axis
* @param aYaxis_position = the y axis position * @param aYaxis_position = the y axis position
*/ */
virtual void Mirror_Y(int aYaxis_position) = 0; virtual void Mirror_Y( int aYaxis_position ) = 0;
virtual void Mirror_X(int aXaxis_position) = 0; virtual void Mirror_X( int aXaxis_position ) = 0;
virtual void Rotate(wxPoint rotationPoint) = 0; virtual void Rotate( wxPoint rotationPoint ) = 0;
/** /**
...@@ -109,8 +144,7 @@ public: ...@@ -109,8 +144,7 @@ public:
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return True if this schematic text item matches the search criteria. * @return True if this schematic text item matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
void * aAuxData, wxPoint * aFindLocation )
{ return false; } { return false; }
/** /**
...@@ -121,6 +155,62 @@ public: ...@@ -121,6 +155,62 @@ public:
* @return True if this item matches the search criteria. * @return True if this item matches the search criteria.
*/ */
bool Matches( const wxString& aText, wxFindReplaceData& aSearchData ); bool Matches( const wxString& aText, wxFindReplaceData& aSearchData );
/**
* Add schematic item end points to \a aItemList if the item has endpoints.
*
* The default version doesn't do anything since many of the schematic object cannot
* be tested for dangling ends. If you add a new schematic item that can have a
* dangling end ( no connect ), override this method to provide the correct end
* points.
*
* @param aItemList - List of DANGLING_END_ITEMS to add to.
*/
virtual void GetEndPoints( vector< DANGLING_END_ITEM >& aItemList ) {}
/**
* Test the schematic item to \a aItemList to check if it's dangling state has changed.
*
* Note that the return value only true when the state of the test has changed. Use
* the IsDangling() method to get the current dangling state of the item. Some of
* the schematic objects cannot be tested for a dangling state, the default method
* always returns false. Only override the method if the item can be tested for a
* dangling state.
*
* @param aItemList - List of items to test item against.
* @return True if the dangling state has changed from it's current setting.
*/
virtual bool IsDanglingStateChanged( vector< DANGLING_END_ITEM >& aItemList ) { return false; }
virtual bool IsDangling() const { return false; }
/**
* Check if the selection state of an item inside \a aRect has changed.
*
* The is used by the block selection code to verify if an item is selected or not.
* True is be return anytime the select state changes. If you need to know the
* the current selection state, use the IsSelected() method.
*
* @param aRect - Rectange to test against.
*/
virtual bool IsSelectStateChanged( const wxRect& aRect ) { return false; }
/**
* Get a list of connection points for this item.
*
* Not all schematic items have connection points so the default method does nothing.
*
* @param aPoints - List of connection points to add to.
*/
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const { }
/**
* Clear all of the connection items from the list.
*
* The vector release method is used to prevent the item pointers from being deleted.
* Do not use the vector erase method on the connection list.
*/
void ClearConnections() { m_connections.release(); }
}; };
#endif /* SCH_ITEM_STRUCT_H */ #endif /* SCH_ITEM_STRUCT_H */
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