Commit 44bafd1c authored by Maciej Suminski's avatar Maciej Suminski
Browse files

Improved selection rules. Added some comments to the selection tool.

parent 55744d1e
Loading
Loading
Loading
Loading
+50 −9
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <class_drawpanel_gal.h>
#include <class_board.h>
#include <class_board_item.h>
#include <class_track.h>
#include <class_module.h>

#include <wxPcbStruct.h>
@@ -68,6 +69,10 @@ void SELECTION_TOOL::Reset()
int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
{
    bool dragging = false;
    m_board = static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetEditFrame() )->GetBoard();

    if( !m_board )
        return 0;

    // Main loop: keep receiving events
    while( OPT_TOOL_EVENT evt = Wait() )
@@ -131,10 +136,14 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
        if( !m_additive )
            clearSelection();

        // Prevent selection of invisible items
        if( selectable( aItem ) )
        {
            aItem->SetSelected();
            m_selectedItems.insert( aItem );
        }
    }
}


void SELECTION_TOOL::clearSelection()
@@ -214,11 +223,6 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector
}


void SELECTION_TOOL::handleHighlight( const VECTOR2D& aP )
{
}


void SELECTION_TOOL::selectMultiple()
{
    OPT_TOOL_EVENT evt;
@@ -258,8 +262,8 @@ void SELECTION_TOOL::selectMultiple()
            {
                BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );

                // Add only those items which are fully within a selection box
                if( selectionBox.Contains( item->ViewBBox() ) )
                // Add only those items which are visible and fully within the selection box
                if( selectable( item ) && selectionBox.Contains( item->ViewBBox() ) )
                {
                    item->SetSelected();
                    m_selectedItems.insert( item );
@@ -331,3 +335,40 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )

    return NULL;
}


bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
{
    switch( aItem->Type() )
    {
    case PCB_VIA_T:
    {
        // For vias it is enough if only one of layers is visible
        LAYER_NUM top, bottom;
        static_cast<const SEGVIA*>( aItem )->ReturnLayerPair( &top, &bottom );

        return ( m_board->IsLayerVisible( top ) ||
                 m_board->IsLayerVisible( bottom ) );
    }
    break;

    case PCB_PAD_T:
        // Pads are supposed to be on top, bottom or both at the same time (THT)
        if( aItem->IsOnLayer( LAYER_N_FRONT ) && m_board->IsLayerVisible( LAYER_N_FRONT ) )
            return true;

        if( aItem->IsOnLayer( LAYER_N_BACK ) && m_board->IsLayerVisible( LAYER_N_BACK ) )
            return true;

        return false;
        break;

    case PCB_MODULE_EDGE_T:
        // These are not selectable, otherwise silkscreen drawings would be easily destroyed
        return false;
        break;
    }

    // All other items
    return m_board->IsLayerVisible( aItem->GetLayer() );
}
+74 −4
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ class SELECTION_AREA;
class BOARD_ITEM;
class GENERAL_COLLECTOR;


/**
 * Class SELECTION_TOOL
 *
@@ -43,8 +42,6 @@ class GENERAL_COLLECTOR;
 * - pick single objects (click LMB)
 * - add objects to existing selection (Shift+LMB)
 * - draw selection box (drag LMB)
 *
 * WORK IN PROGRESS. CONSIDER AS A DEMO!
 */

class SELECTION_TOOL : public TOOL_INTERACTIVE
@@ -53,25 +50,98 @@ public:
    SELECTION_TOOL();
    ~SELECTION_TOOL();

    /**
     * Function Reset()
     *
     * Initializes the selection tool.
     */
    void Reset();

    /**
     * Function Main()
     *
     * The main loop.
     */
    int Main( TOOL_EVENT& aEvent );

    /**
     * Function GetSelection()
     *
     * Returns the set of currently selected items.
     */
    const std::set<BOARD_ITEM*>& GetSelection() const
    {
        return m_selectedItems;
    }

private:
    /**
     * Function selectSingle()
     * Selects an item pointed by the parameter aWhere. If there is more than one item at that
     * place, there is a menu displayed that allows to choose the item.
     *
     * @param aWhere is the place where the item should be selected.
     */
    void selectSingle( const VECTOR2I& aWhere );

    /**
     * Function selectMultiple()
     * Handles drawing a selection box that allows to select many items at the same time.
     */
    void selectMultiple();
    void handleHighlight( const VECTOR2D& aP );

    /**
     * Function disambiguationMenu()
     * Handles the menu that allows to select one of many items in case there is more than one
     * item at the selected point (@see selectSingle()).
     *
     * @param aItems contains list of items that are displayed to the user.
     */
    BOARD_ITEM* disambiguationMenu( GENERAL_COLLECTOR* aItems );

    /**
     * Function pickSmallestComponent()
     * Allows to find the smallest (in terms of bounding box area) item from the list.
     *
     * @param aCollector containes the list of items.
     */
    BOARD_ITEM* pickSmallestComponent( GENERAL_COLLECTOR* aCollector );

    /**
     * Function toggleSelection()
     * Changes selection status of a given item.
     *
     * @param aItem is the item to have selection status changed.
     */
    void toggleSelection( BOARD_ITEM* aItem );

    /**
     * Function clearSelection()
     * Clears selections of currently selected items.
     */
    void clearSelection();

    /**
     * Function selectable()
     * Checks conditions for an item to be selected.
     *
     * @return True if the item fulfills conditions to be selected.
     */
    bool selectable( const BOARD_ITEM* aItem ) const;

    /// Currently used PCB
    BOARD* m_board;

    /// Container storing currently selected items
    std::set<BOARD_ITEM*> m_selectedItems;

    /// Visual representation of selection area
    SELECTION_AREA* m_selArea;

    /// Menu shown in case of selection ambiguity
    boost::shared_ptr<CONTEXT_MENU> m_menu;

    /// Flag saying if items should be added to the current selection or rather replace it
    bool m_additive;
};