libtree: Update width automatically

When filtering, we update the width of the displayed column to ensure
the full text is visible to the user.  Check is rough, based on line
width (doesn't completely account for differing char widths) but is
sufficient for the approximate difference

Fixes: lp:1815401
* https://bugs.launchpad.net/kicad/+bug/1815401

Fixes: lp:1788495
* https://bugs.launchpad.net/kicad/+bug/1788495
This commit is contained in:
Seth Hillbrand 2019-02-09 16:57:53 -08:00
parent 3524bed75a
commit a74aa3850a
5 changed files with 71 additions and 20 deletions

View File

@ -104,6 +104,7 @@ public:
LIB_ID LibId; ///< LIB_ID determined by the parent library nickname and alias name.
int Unit; ///< Actual unit, or zero
bool IsRoot; ///< Indicates if the symbol is a root symbol instead of an alias.
int VisLen; ///< Length of the string as shown on screen
/**
* Update the score for this part. This is accumulative - it will be

View File

@ -28,8 +28,6 @@
#include <wx/wupdlock.h>
LIB_TREE_MODEL_ADAPTER::WIDTH_CACHE LIB_TREE_MODEL_ADAPTER::m_width_cache;
static const int kDataViewIndent = 20;
@ -99,6 +97,17 @@ void LIB_TREE_MODEL_ADAPTER::ShowUnits( bool aShow )
}
void LIB_TREE_MODEL_ADAPTER::UpdateWidth( int aCol )
{
auto col = m_widget->GetColumn( aCol );
if( col )
{
col->SetWidth( ColWidth( m_tree, aCol, col->GetTitle() ) );
}
}
void LIB_TREE_MODEL_ADAPTER::SetPreselectNode( LIB_ID const& aLibId, int aUnit )
{
m_preselect_lib_id = aLibId;
@ -112,10 +121,15 @@ void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( wxString const& aNodeName, wxString c
{
auto& lib_node = m_tree.AddLib( aNodeName, aDesc );
lib_node.VisLen = wxTheApp->GetTopWindow()->GetTextExtent( lib_node.Name ).x;
for( auto item: aItemList )
{
if( item )
lib_node.AddItem( item );
{
auto& child_node = lib_node.AddItem( item );
child_node.VisLen = wxTheApp->GetTopWindow()->GetTextExtent( child_node.Name ).x;
}
}
lib_node.AssignIntrinsicRanks( presorted );
@ -170,6 +184,8 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch )
m_widget->Select( item );
m_widget->EnsureVisible( item );
}
UpdateWidth( 0 );
}
@ -183,10 +199,8 @@ void LIB_TREE_MODEL_ADAPTER::AttachTo( wxDataViewCtrl* aDataViewCtrl )
wxString part_head = _( "Item" );
wxString desc_head = _( "Description" );
m_col_part = aDataViewCtrl->AppendTextColumn( part_head, 0, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 0, part_head ) );
m_col_desc = aDataViewCtrl->AppendTextColumn( desc_head, 1, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 1, desc_head ) );
m_col_part = aDataViewCtrl->AppendTextColumn( part_head, 0, wxDATAVIEW_CELL_INERT, 360 );
m_col_desc = aDataViewCtrl->AppendTextColumn( desc_head, 1, wxDATAVIEW_CELL_INERT, 2000 );
}
@ -349,10 +363,33 @@ bool LIB_TREE_MODEL_ADAPTER::GetAttr( wxDataViewItem const& aItem,
int LIB_TREE_MODEL_ADAPTER::ColWidth( LIB_TREE_NODE& aTree, int aCol, wxString const& aHeading )
{
// It's too expensive to calculate widths on really big trees, and the user probably
// wants it left where they dragged it anyway.
if( aCol == 0 )
return 360;
{
int padding = m_widget->GetTextExtent( "MM" ).x;
int longest = m_widget->GetTextExtent( aHeading ).x;
for( auto& node : aTree.Children )
{
auto item = ToItem( &*node );
if( !item.IsOk() )
continue;
if( node->Score > 0 )
longest = std::max( longest, node->VisLen + padding );
if( !m_widget->IsExpanded( item ) )
continue;
for( auto& childNode : node->Children )
{
if( childNode->Score > 0 )
longest = std::max( longest, childNode->VisLen + 2 * padding );
}
}
return longest;
}
else
return 2000;
}

View File

@ -28,6 +28,7 @@
#include <wx/hashmap.h>
#include <wx/dataview.h>
#include <wx/headerctrl.h>
#include <vector>
#include <functional>
@ -133,6 +134,13 @@ public:
*/
void ShowUnits( bool aShow );
/**
* Update the column size based on the displayed contents
*
* @param aCol Which column to resize
*/
void UpdateWidth( int aCol );
/**
* Set the component name to be selected if there are no search results.
* May be set at any time; updates at the next UpdateSearchString().
@ -327,10 +335,6 @@ private:
wxDataViewColumn* m_col_desc;
wxDataViewCtrl* m_widget;
WX_DECLARE_STRING_HASH_MAP( std::vector<int>, WIDTH_CACHE );
static WIDTH_CACHE m_width_cache;
/**
* Compute the width required for the given column of a node and its
* children.

View File

@ -41,8 +41,7 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, LIB_TABLE* aLibTable, LIB_TREE_MODEL_ADAP
m_adapter( aAdapter ),
m_query_ctrl( nullptr ),
m_details_ctrl( nullptr ),
m_menuActive( false ),
m_filtering( false )
m_menuActive( false )
{
// create space for context menu pointers, INVALID is the max value
m_menus.resize( LIB_TREE_NODE::TYPE::INVALID + 1 );
@ -114,6 +113,8 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, LIB_TABLE* aLibTable, LIB_TREE_MODEL_ADAP
m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &LIB_TREE::onTreeActivate, this );
m_tree_ctrl->Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &LIB_TREE::onTreeSelect, this );
m_tree_ctrl->Bind( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, &LIB_TREE::onContextMenu, this );
m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_EXPANDED, &LIB_TREE::onExpandCollapse, this );
m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_COLLAPSED, &LIB_TREE::onExpandCollapse, this );
Bind( COMPONENT_PRESELECTED, &LIB_TREE::onPreselect, this );
@ -129,6 +130,7 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, LIB_TABLE* aLibTable, LIB_TREE_MODEL_ADAP
// There may be a part preselected in the model. Make sure it is displayed.
postPreselectEvent();
m_adapter->UpdateWidth( 0 );
Layout();
sizer->Fit( this );
@ -193,7 +195,6 @@ void LIB_TREE::Regenerate( bool aKeepState )
wxString filter = m_query_ctrl->GetValue();
m_adapter->UpdateSearchString( filter );
m_filtering = !filter.IsEmpty();
postPreselectEvent();
// Restore the state
@ -228,6 +229,7 @@ void LIB_TREE::selectIfValid( const wxDataViewItem& aTreeId )
if( aTreeId.IsOk() )
{
m_tree_ctrl->EnsureVisible( aTreeId );
m_adapter->UpdateWidth( 0 );
m_tree_ctrl->Select( aTreeId );
postPreselectEvent();
}
@ -237,7 +239,10 @@ void LIB_TREE::selectIfValid( const wxDataViewItem& aTreeId )
void LIB_TREE::centerIfValid( const wxDataViewItem& aTreeId )
{
if( aTreeId.IsOk() )
{
m_tree_ctrl->EnsureVisible( aTreeId );
m_adapter->UpdateWidth( 0 );
}
}
@ -361,6 +366,12 @@ void LIB_TREE::onTreeSelect( wxDataViewEvent& aEvent )
}
void LIB_TREE::onExpandCollapse( wxDataViewEvent& aEvent )
{
m_adapter->UpdateWidth( 0 );
}
void LIB_TREE::onTreeActivate( wxDataViewEvent& aEvent )
{
if( !GetSelectedLibId().IsValid() )

View File

@ -169,6 +169,7 @@ protected:
void onTreeSelect( wxDataViewEvent& aEvent );
void onTreeActivate( wxDataViewEvent& aEvent );
void onExpandCollapse( wxDataViewEvent& aEvent );
void onUpdateUI( wxUpdateUIEvent& aEvent );
void onDetailsLink( wxHtmlLinkEvent& aEvent );
@ -188,9 +189,6 @@ protected:
///> Flag indicating whether a right-click context menu is active
bool m_menuActive;
///> Flag indicating whether the results are filtered using the search query
bool m_filtering;
///> State of the widget before any filters applied
STATE m_unfilteredState;
};