Restore selection around undo/redo.

This commit is contained in:
Jeff Young 2019-05-24 11:11:18 +01:00
parent 431eae0492
commit 09424db68f
7 changed files with 175 additions and 49 deletions

View File

@ -89,8 +89,14 @@ void WORKSHEET_DATAITEM::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGFX::VI
if( pensize == 0 ) if( pensize == 0 )
pensize = aCollector ? aCollector->GetDefaultPenSize() : 0; pensize = aCollector ? aCollector->GetDefaultPenSize() : 0;
for( WS_DRAW_ITEM_BASE* item : m_drawItems ) std::map<int, STATUS_FLAGS> itemFlags;
WS_DRAW_ITEM_BASE* item = nullptr;
for( int ii = 0; ii < m_drawItems.size(); ++ii )
{ {
item = m_drawItems[ ii ];
itemFlags[ ii ] = item->GetFlags();
if( aCollector ) if( aCollector )
aCollector->Remove( item ); aCollector->Remove( item );
@ -108,29 +114,18 @@ void WORKSHEET_DATAITEM::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGFX::VI
continue; continue;
if( m_type == WS_SEGMENT ) if( m_type == WS_SEGMENT )
{ item = new WS_DRAW_ITEM_LINE( this, GetStartPosUi( jj ), GetEndPosUi( jj ), pensize );
auto line = new WS_DRAW_ITEM_LINE( this, GetStartPosUi( jj ), GetEndPosUi( jj ),
pensize );
m_drawItems.push_back( line );
if( aCollector )
aCollector->Append( line );
if( aView )
aView->Add( line );
}
else if( m_type == WS_RECT ) else if( m_type == WS_RECT )
{ item = new WS_DRAW_ITEM_RECT( this, GetStartPosUi( jj ), GetEndPosUi( jj ), pensize );
auto rect = new WS_DRAW_ITEM_RECT( this, GetStartPosUi( jj ), GetEndPosUi( jj ),
pensize ); item->SetFlags( itemFlags[ jj ] );
m_drawItems.push_back( rect ); m_drawItems.push_back( item );
if( aCollector ) if( aCollector )
aCollector->Append( rect ); aCollector->Append( item );
if( aView ) if( aView )
aView->Add( rect ); aView->Add( item );
}
} }
} }
@ -406,8 +401,22 @@ WORKSHEET_DATAITEM_POLYPOLYGON::WORKSHEET_DATAITEM_POLYPOLYGON() :
void WORKSHEET_DATAITEM_POLYPOLYGON::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, void WORKSHEET_DATAITEM_POLYPOLYGON::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector,
KIGFX::VIEW* aView ) KIGFX::VIEW* aView )
{ {
for( WS_DRAW_ITEM_BASE* item : m_drawItems ) std::map<int, STATUS_FLAGS> itemFlags;
WS_DRAW_ITEM_BASE* item = nullptr;
for( int ii = 0; ii < m_drawItems.size(); ++ii )
{
item = m_drawItems[ ii ];
itemFlags[ ii ] = item->GetFlags();
if( aCollector )
aCollector->Remove( item );
if( aView )
aView->Remove( item );
delete item; delete item;
}
m_drawItems.clear(); m_drawItems.clear();
@ -421,6 +430,7 @@ void WORKSHEET_DATAITEM_POLYPOLYGON::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollecto
const bool fill = true; const bool fill = true;
int pensize = GetPenSizeUi(); int pensize = GetPenSizeUi();
auto poly = new WS_DRAW_ITEM_POLYGON( this, GetStartPosUi( jj ), fill, pensize ); auto poly = new WS_DRAW_ITEM_POLYGON( this, GetStartPosUi( jj ), fill, pensize );
item->SetFlags( itemFlags[ jj ] );
m_drawItems.push_back( poly ); m_drawItems.push_back( poly );
if( aCollector ) if( aCollector )
@ -552,8 +562,22 @@ void WORKSHEET_DATAITEM_TEXT::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGF
if( m_Bold ) if( m_Bold )
pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) ); pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) );
for( WS_DRAW_ITEM_BASE* item : m_drawItems ) std::map<int, STATUS_FLAGS> itemFlags;
delete item; WS_DRAW_ITEM_TEXT* text = nullptr;
for( int ii = 0; ii < m_drawItems.size(); ++ii )
{
text = (WS_DRAW_ITEM_TEXT*) m_drawItems[ ii ];
itemFlags[ ii ] = text->GetFlags();
if( aCollector )
aCollector->Remove( text );
if( aView )
aView->Remove( text );
delete text;
}
m_drawItems.clear(); m_drawItems.clear();
@ -562,8 +586,9 @@ void WORKSHEET_DATAITEM_TEXT::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGF
if( jj > 0 && !IsInsidePage( jj ) ) if( jj > 0 && !IsInsidePage( jj ) )
continue; continue;
auto text = new WS_DRAW_ITEM_TEXT( this, m_FullText, GetStartPosUi( jj ), textsize, text = new WS_DRAW_ITEM_TEXT( this, m_FullText, GetStartPosUi( jj ), textsize, pensize,
pensize, m_Italic, m_Bold ); m_Italic, m_Bold );
text->SetFlags( itemFlags[ jj ] );
m_drawItems.push_back( text ); m_drawItems.push_back( text );
if( aCollector ) if( aCollector )
@ -682,8 +707,22 @@ void WORKSHEET_DATAITEM_TEXT::SetConstrainedTextSize()
void WORKSHEET_DATAITEM_BITMAP::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGFX::VIEW* aView ) void WORKSHEET_DATAITEM_BITMAP::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGFX::VIEW* aView )
{ {
for( WS_DRAW_ITEM_BASE* item : m_drawItems ) std::map<int, STATUS_FLAGS> itemFlags;
WS_DRAW_ITEM_BASE* item = nullptr;
for( int ii = 0; ii < m_drawItems.size(); ++ii )
{
item = m_drawItems[ ii ];
itemFlags[ ii ] = item->GetFlags();
if( aCollector )
aCollector->Remove( item );
if( aView )
aView->Remove( item );
delete item; delete item;
}
m_drawItems.clear(); m_drawItems.clear();
@ -693,6 +732,7 @@ void WORKSHEET_DATAITEM_BITMAP::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KI
continue; continue;
auto bitmap = new WS_DRAW_ITEM_BITMAP( this, GetStartPosUi( jj ) ); auto bitmap = new WS_DRAW_ITEM_BITMAP( this, GetStartPosUi( jj ) );
item->SetFlags( itemFlags[ jj ] );
m_drawItems.push_back( bitmap ); m_drawItems.push_back( bitmap );
if( aCollector ) if( aCollector )

View File

@ -46,7 +46,7 @@ public:
m_isHover = aOther.m_isHover; m_isHover = aOther.m_isHover;
} }
const SELECTION& operator= ( const SELECTION& aOther ) SELECTION& operator= ( const SELECTION& aOther )
{ {
m_items = aOther.m_items; m_items = aOther.m_items;
m_isHover = aOther.m_isHover; m_isHover = aOther.m_isHover;

View File

@ -30,6 +30,8 @@
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <functional> #include <functional>
#include <tools/pl_selection_tool.h>
using namespace std::placeholders; using namespace std::placeholders;
@ -64,13 +66,17 @@ void PL_DRAW_PANEL_GAL::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector<MSG_PAN
void PL_DRAW_PANEL_GAL::DisplayWorksheet() void PL_DRAW_PANEL_GAL::DisplayWorksheet()
{ {
m_edaFrame->GetToolManager()->RunAction( PL_ACTIONS::clearSelection, true ); PL_SELECTION_TOOL* selTool = m_edaFrame->GetToolManager()->GetTool<PL_SELECTION_TOOL>();
selTool->GetSelection().Clear();
m_view->Clear(); m_view->Clear();
WS_DRAW_ITEM_LIST::SetupDrawEnvironment( m_edaFrame->GetPageSettings() ); WS_DRAW_ITEM_LIST::SetupDrawEnvironment( m_edaFrame->GetPageSettings() );
for( WORKSHEET_DATAITEM* dataItem : WORKSHEET_LAYOUT::GetTheInstance().GetItems() ) for( WORKSHEET_DATAITEM* dataItem : WORKSHEET_LAYOUT::GetTheInstance().GetItems() )
dataItem->SyncDrawItems( nullptr, m_view ); dataItem->SyncDrawItems( nullptr, m_view );
selTool->RebuildSelection();
} }

View File

@ -502,7 +502,18 @@ void PL_EDITOR_FRAME::RedrawActiveWindow( wxDC* aDC, bool aEraseBg )
void PL_EDITOR_FRAME::HardRedraw() void PL_EDITOR_FRAME::HardRedraw()
{ {
static_cast<PL_DRAW_PANEL_GAL*>( GetGalCanvas() )->DisplayWorksheet(); PL_DRAW_PANEL_GAL* drawPanel = static_cast<PL_DRAW_PANEL_GAL*>( GetGalCanvas() );
drawPanel->DisplayWorksheet();
PL_SELECTION_TOOL* selTool = m_toolManager->GetTool<PL_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
WORKSHEET_DATAITEM* item = nullptr;
if( selection.GetSize() == 1 )
item = static_cast<WS_DRAW_ITEM_BASE*>( selection.Front() )->GetPeer();
m_propertiesPagelayout->CopyPrmsFromItemToPanel( item );
m_propertiesPagelayout->CopyPrmsFromGeneralToPanel(); m_propertiesPagelayout->CopyPrmsFromGeneralToPanel();
m_canvas->Refresh(); m_canvas->Refresh();
} }

View File

@ -26,9 +26,12 @@
#include <fctsys.h> #include <fctsys.h>
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <macros.h> #include <macros.h>
#include <worksheet_dataitem.h>
#include <ws_draw_item.h> #include <ws_draw_item.h>
#include <pl_editor_frame.h> #include <pl_editor_frame.h>
#include <tool/tool_manager.h>
#include <tools/pl_selection_tool.h>
/* Note: the Undo/redo commands use a "brute" method: /* Note: the Undo/redo commands use a "brute" method:
* the full page layout is converted to a S expression, and saved as string. * the full page layout is converted to a S expression, and saved as string.
@ -43,11 +46,63 @@
// A helper class used in undo/redo commad: // A helper class used in undo/redo commad:
class PL_ITEM_LAYOUT: public EDA_ITEM class PL_ITEM_LAYOUT: public EDA_ITEM
{ {
public: wxString m_serialization;
wxString m_Layout; int m_selectedDataItem;
int m_selectedDrawItem;
public: public:
PL_ITEM_LAYOUT() : EDA_ITEM( TYPE_PL_EDITOR_LAYOUT ) {} PL_ITEM_LAYOUT() :
EDA_ITEM( TYPE_PL_EDITOR_LAYOUT ),
m_selectedDataItem( INT_MAX ),
m_selectedDrawItem( INT_MAX )
{
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
pglayout.SaveInString( m_serialization );
for( int ii = 0; ii < pglayout.GetItems().size(); ++ii )
{
WORKSHEET_DATAITEM* dataItem = pglayout.GetItem( ii );
for( int jj = 0; jj < dataItem->GetDrawItems().size(); ++jj )
{
WS_DRAW_ITEM_BASE* drawItem = dataItem->GetDrawItems()[ jj ];
if( drawItem->IsSelected() )
{
m_selectedDataItem = ii;
m_selectedDrawItem = jj;
break;
}
}
}
}
void RestoreLayout( PL_EDITOR_FRAME* aFrame )
{
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
PL_SELECTION_TOOL* selTool = aFrame->GetToolManager()->GetTool<PL_SELECTION_TOOL>();
KIGFX::VIEW* view = aFrame->GetGalCanvas()->GetView();
pglayout.SetPageLayout( TO_UTF8( m_serialization ) );
selTool->ClearSelection();
view->Clear();
for( int ii = 0; ii < pglayout.GetItems().size(); ++ii )
{
WORKSHEET_DATAITEM* dataItem = pglayout.GetItem( ii );
dataItem->SyncDrawItems( nullptr, view );
if( ii == m_selectedDataItem && m_selectedDrawItem < dataItem->GetDrawItems().size() )
{
WS_DRAW_ITEM_BASE* drawItem = dataItem->GetDrawItems()[ m_selectedDrawItem ];
drawItem->SetSelected();
}
}
selTool->RebuildSelection();
}
// Required to keep compiler happy on debug builds. // Required to keep compiler happy on debug builds.
#if defined(DEBUG) #if defined(DEBUG)
@ -65,9 +120,7 @@ public:
void PL_EDITOR_FRAME::SaveCopyInUndoList() void PL_EDITOR_FRAME::SaveCopyInUndoList()
{ {
PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; // constructor stores current layout
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
pglayout.SaveInString( copyItem->m_Layout );
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper( copyItem, UR_LIBEDIT ); ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
@ -89,9 +142,7 @@ void PL_EDITOR_FRAME::GetLayoutFromRedoList()
return; return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; // constructor stores current layout
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
pglayout.SaveInString( copyItem->m_Layout );
ITEM_PICKER wrapper( copyItem, UR_LIBEDIT ); ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
@ -102,10 +153,10 @@ void PL_EDITOR_FRAME::GetLayoutFromRedoList()
wrapper = lastcmd->PopItem(); wrapper = lastcmd->PopItem();
copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() ); copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
pglayout.SetPageLayout( TO_UTF8(copyItem->m_Layout) ); copyItem->RestoreLayout( this );
delete copyItem; delete copyItem;
HardRedraw(); GetCanvas()->Refresh();
OnModify(); OnModify();
} }
@ -120,9 +171,7 @@ void PL_EDITOR_FRAME::GetLayoutFromUndoList()
return; return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT; // constructor stores current layout
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
pglayout.SaveInString( copyItem->m_Layout );
ITEM_PICKER wrapper( copyItem, UR_LIBEDIT ); ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
lastcmd->PushItem( wrapper ); lastcmd->PushItem( wrapper );
@ -132,10 +181,10 @@ void PL_EDITOR_FRAME::GetLayoutFromUndoList()
wrapper = lastcmd->PopItem(); wrapper = lastcmd->PopItem();
copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() ); copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
pglayout.SetPageLayout( TO_UTF8(copyItem->m_Layout) ); copyItem->RestoreLayout( this );
delete copyItem; delete copyItem;
HardRedraw(); GetCanvas()->Refresh();
OnModify(); OnModify();
} }
@ -147,13 +196,12 @@ void PL_EDITOR_FRAME::RollbackFromUndo()
if ( GetScreen()->GetUndoCommandCount() <= 0 ) if ( GetScreen()->GetUndoCommandCount() <= 0 )
return; return;
WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
PICKED_ITEMS_LIST* lastcmd = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* lastcmd = GetScreen()->PopCommandFromUndoList();
ITEM_PICKER wrapper = lastcmd->PopItem(); ITEM_PICKER wrapper = lastcmd->PopItem();
PL_ITEM_LAYOUT* copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() ); PL_ITEM_LAYOUT* copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
pglayout.SetPageLayout( TO_UTF8(copyItem->m_Layout) ); copyItem->RestoreLayout( this );
delete copyItem; delete copyItem;
HardRedraw(); GetCanvas()->Refresh();
} }

View File

@ -504,6 +504,21 @@ int PL_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
} }
void PL_SELECTION_TOOL::RebuildSelection()
{
m_selection.Clear();
for( WORKSHEET_DATAITEM* dataItem : WORKSHEET_LAYOUT::GetTheInstance().GetItems() )
{
for( WS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
{
if( item->IsSelected() )
select( item );
}
}
}
int PL_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent ) int PL_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
{ {
COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>(); COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();

View File

@ -110,6 +110,12 @@ public:
void ClearSelection(); void ClearSelection();
/**
* Rebuild the selection from the flags in the view items. Useful after a hard redraw
* or an undo or redo operation.
*/
void RebuildSelection();
/** /**
* Function SelectionMenu() * Function SelectionMenu()
* Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single * Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single