← Back to team overview

kicad-developers team mailing list archive

[PATCH] Eeschema wire/bus selection logic

 

​Attached is a patch to correct the wire/bus connection logic.  Currently,
Eeschema will register wires and busses as being connected if their
endpoints touch.  They will drag together and their endpoints will not show
the "unconnected" symbols.

The attached patch implements the following logic.  The logic is largely
based on how I like to work with entries, so please shout if you feel this
is backwards somehow.
​
Dragging:
    - busses and bus-bus entries drag each other when connected at endpoints
    - wires and wire-bus entries drag each other when connected at endpoints
    - entries do not drag wires or busses when connected to wire middles
    - wire-bus entries do not drag busses

Connections:
    - bus-bus entries connect busses to busses but not wires
    - wire-bus entries connect wires to busses but not wire to wires or
busses to busses
​
​Best-
Seth​
From 20195cc80c3769a8360ded667d5ff3261f3c65bf Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 30 Nov 2017 17:21:23 -0800
Subject: [PATCH] Eeschema: Correct wire/bus/entry connections

Fixes the connection display and dragging behavior of wires,
busses and their entries.

The implemented drag logic is:
-busses and bus-bus entries drag each other when connected at endpoints
-wires and wire-bus entries drag each other when connected at endpoints
-entries do not drag wires or busses when connected to wire middles
-wire-bus entries do not drag busses

The implemented connection logic is:
-bus-bus entries connect busses to busses but not wires
-wire-bus entries connect wires to busses but not wire to wires or
busses to busses
---
 eeschema/class_sch_screen.h |  3 ++-
 eeschema/sch_bus_entry.cpp  | 36 ++++++++++++++++++++++++++----------
 eeschema/sch_bus_entry.h    | 11 +++++++++--
 eeschema/sch_item_struct.h  |  5 ++++-
 eeschema/sch_line.cpp       |  5 ++++-
 eeschema/sch_screen.cpp     | 12 +++++++++---
 6 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h
index a90763f35..d3aa93d9b 100644
--- a/eeschema/class_sch_screen.h
+++ b/eeschema/class_sch_screen.h
@@ -92,9 +92,10 @@ private:
      * \a aPosition and adds them to the block selection pick list.  This is used when a block
      * drag is being performed to ensure connections to items in the block are not lost.
      *</p>
+     * @param aItem = The item we are connecting from
      * @param aPosition = The connection point to test.
      */
-    void addConnectedItemsToBlock( const wxPoint& aPosition );
+    void addConnectedItemsToBlock( const SCH_ITEM* aItem, const wxPoint& aPosition );
 
 public:
 
diff --git a/eeschema/sch_bus_entry.cpp b/eeschema/sch_bus_entry.cpp
index 9291b3963..504b25ac0 100644
--- a/eeschema/sch_bus_entry.cpp
+++ b/eeschema/sch_bus_entry.cpp
@@ -78,6 +78,12 @@ EDA_ITEM* SCH_BUS_BUS_ENTRY::Clone() const
 }
 
 
+bool SCH_BUS_ENTRY_BASE::doIsConnected( const wxPoint& aPosition ) const
+{
+    return ( m_pos == aPosition || m_End() == aPosition );
+}
+
+
 wxPoint SCH_BUS_ENTRY_BASE::m_End() const
 {
     return wxPoint( m_pos.x + m_size.x, m_pos.y + m_size.y );
@@ -120,6 +126,26 @@ int SCH_BUS_BUS_ENTRY::GetPenSize() const
 }
 
 
+void SCH_BUS_WIRE_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+    DANGLING_END_ITEM item( WIRE_ENTRY_END, this, m_pos );
+    aItemList.push_back( item );
+
+    DANGLING_END_ITEM item1( WIRE_ENTRY_END, this, m_End() );
+    aItemList.push_back( item1 );
+}
+
+
+void SCH_BUS_BUS_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+    DANGLING_END_ITEM item( BUS_ENTRY_END, this, m_pos );
+    aItemList.push_back( item );
+
+    DANGLING_END_ITEM item1( BUS_ENTRY_END, this, m_End() );
+    aItemList.push_back( item1 );
+}
+
+
 void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
                           GR_DRAWMODE aDrawMode, COLOR4D aColor )
 {
@@ -175,16 +201,6 @@ void SCH_BUS_ENTRY_BASE::Rotate( wxPoint aPosition )
 }
 
 
-void SCH_BUS_ENTRY_BASE::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
-{
-    DANGLING_END_ITEM item( ENTRY_END, this, m_pos );
-    aItemList.push_back( item );
-
-    DANGLING_END_ITEM item1( ENTRY_END, this, m_End() );
-    aItemList.push_back( item1 );
-}
-
-
 bool SCH_BUS_ENTRY_BASE::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
 {
     bool previousStateStart = m_isDanglingStart;
diff --git a/eeschema/sch_bus_entry.h b/eeschema/sch_bus_entry.h
index d96dc9741..81369f168 100644
--- a/eeschema/sch_bus_entry.h
+++ b/eeschema/sch_bus_entry.h
@@ -97,12 +97,12 @@ public:
 
     void Rotate( wxPoint aPosition ) override;
 
-    void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) override;
-
     bool IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList ) override;
 
     bool IsDangling() const override;
 
+    bool IsUnconnected() const override { return m_isDanglingEnd && m_isDanglingStart; }
+
     bool IsSelectStateChanged( const wxRect& aRect ) override;
 
     bool IsConnectable() const override { return true; }
@@ -124,6 +124,9 @@ public:
 #if defined(DEBUG)
     void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
 #endif
+
+private:
+    bool doIsConnected( const wxPoint& aPosition ) const override;
 };
 
 /**
@@ -143,6 +146,8 @@ public:
 
     int GetPenSize() const override;
 
+    void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
+
     wxString GetSelectMenuText() const override;
 
     EDA_ITEM* Clone() const override;
@@ -165,6 +170,8 @@ public:
 
     int GetPenSize() const override;
 
+    void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
+
     wxString GetSelectMenuText() const override;
 
     EDA_ITEM* Clone() const override;
diff --git a/eeschema/sch_item_struct.h b/eeschema/sch_item_struct.h
index 9d696e7bb..44a50960d 100644
--- a/eeschema/sch_item_struct.h
+++ b/eeschema/sch_item_struct.h
@@ -72,7 +72,8 @@ enum DANGLING_END_T {
     JUNCTION_END,
     PIN_END,
     LABEL_END,
-    ENTRY_END,
+    BUS_ENTRY_END,
+    WIRE_ENTRY_END,
     SHEET_LABEL_END,
     NO_CONNECT_END,
 };
@@ -262,6 +263,8 @@ public:
 
     virtual bool IsDangling() const { return false; }
 
+    virtual bool IsUnconnected() const { return false; }
+
     /**
      * Function IsSelectStateChanged
      * checks if the selection state of an item inside \a aRect has changed.
diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp
index ce4ba4cb0..bd1deef88 100644
--- a/eeschema/sch_line.cpp
+++ b/eeschema/sch_line.cpp
@@ -509,7 +509,10 @@ bool SCH_LINE::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemLi
             if( item.GetItem() == this )
                 continue;
 
-            if( item.GetType() == NO_CONNECT_END )
+            if(     item.GetType() == NO_CONNECT_END ||
+                    item.GetType() == BUS_START_END ||
+                    item.GetType() == BUS_END_END  ||
+                    item.GetType() == BUS_ENTRY_END )
                 continue;
 
             if( m_start == item.GetPosition() )
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
index f3f26b07d..dc52d8d2f 100644
--- a/eeschema/sch_screen.cpp
+++ b/eeschema/sch_screen.cpp
@@ -717,7 +717,7 @@ void SCH_SCREEN::SelectBlockItems()
         std::vector< wxPoint > connections;
         item->GetConnectionPoints( connections );
         for( auto conn : connections )
-            addConnectedItemsToBlock( conn );
+            addConnectedItemsToBlock( item, conn );
     };
 
     PICKED_ITEMS_LIST* pickedlist = &m_BlockLocate.GetItems();
@@ -785,23 +785,29 @@ void SCH_SCREEN::SelectBlockItems()
 }
 
 
-void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position )
+void SCH_SCREEN::addConnectedItemsToBlock( const SCH_ITEM* aItem, const wxPoint& position )
 {
     SCH_ITEM* item;
     ITEM_PICKER picker;
 
+    if( aItem->IsUnconnected() )
+        return;
+
     for( item = m_drawList.begin(); item; item = item->Next() )
     {
         bool addinlist = true;
         picker.SetItem( item );
 
         if( !item->IsConnectable() || !item->IsConnected( position )
-            || (item->GetFlags() & SKIP_STRUCT) )
+            || (item->GetFlags() & SKIP_STRUCT) || item->IsUnconnected() )
             continue;
 
         if( item->IsSelected() && item->Type() != SCH_LINE_T )
             continue;
 
+        if( item->GetLayer() != aItem->GetLayer() )
+            continue;
+
         // A line having 2 ends, it can be tested twice: one time per end
         if( item->Type() == SCH_LINE_T )
         {
-- 
2.11.0


Follow ups