24#include <wx/aui/auibook.h>
25#include <wx/aui/framemanager.h>
46 for(
size_t i = 0; i <
m_entries.size(); ++i )
49 return static_cast<int>( i );
58 for(
size_t i = 0; i <
m_entries.size(); ++i )
63 return static_cast<int>( i );
97 return static_cast<int>(
m_entries.size() ) - 1;
165 m_tabs =
new wxAuiNotebook(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
166 wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_SCROLL_BUTTONS );
176 m_tabs->SetMinSize( wxSize( -1, FromDIP( 28 ) ) );
178 m_sizer =
new wxBoxSizer( wxVERTICAL );
233 return static_cast<int>( i );
247 wxAuiTabCtrl* tabCtrl =
m_tabs->GetActiveTabCtrl();
267 int height = hasPages ?
m_tabs->GetTabCtrlHeight() : 0;
270 if( hasPages && height <= 0 )
271 height = FromDIP( 28 );
278 m_tabs->SetMinSize( wxSize( -1, hasPages ? height : FromDIP( 28 ) ) );
290 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_model.Entries().size() ) )
304 const int existing =
m_model.FindIndex( aKey );
308 m_model.OpenDocument( aKey, aAsPreview );
315 wxString reusedOldKey;
319 const int previewSlot =
m_model.PreviewIndex();
321 if( previewSlot >= 0 )
322 reusedOldKey =
m_model.Entries()[previewSlot].key;
325 const int reuse =
m_model.OpenDocument( aKey, aAsPreview );
329 m_tabs->SetPageText( reuse, aLabel );
331 if( !reusedOldKey.empty() && reusedOldKey != aKey )
336 wxWindow* key =
new wxWindow(
m_tabs, wxID_ANY );
342 m_tabs->AddPage( key, aLabel,
false );
366 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_pageWindows.size() ) )
371 const wxString activeBeforeKey =
372 ( activeBefore >= 0 && activeBefore < static_cast<int>(
m_model.Entries().size() ) )
373 ?
m_model.Entries()[activeBefore].key
380 const wxString key =
m_model.Entries()[aIdx].key;
385 m_tabs->DeletePage(
static_cast<size_t>( aIdx ) );
394 const int newCount =
static_cast<int>(
m_pageWindows.size() );
408 if( activeBeforeKey.empty() || activeBeforeKey == key )
409 visualIdx = std::min( aIdx, newCount - 1 );
411 visualIdx =
m_model.FindIndex( activeBeforeKey );
413 if( visualIdx >= 0 && visualIdx < newCount )
417 m_tabs->ChangeSelection(
static_cast<size_t>( visualIdx ) );
423 SelectTab( std::min( aIdx, newCount - 1 ) );
432 if( aKeepIdx < 0 || aKeepIdx >=
static_cast<int>(
m_pageWindows.size() ) )
435 const wxString keepKey =
m_model.Entries()[aKeepIdx].key;
438 for(
int i =
static_cast<int>(
m_pageWindows.size() ) - 1; i >= 0; --i )
440 if(
m_model.Entries()[i].key != keepKey )
449 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_pageWindows.size() ) )
452 for(
int i =
static_cast<int>(
m_pageWindows.size() ) - 1; i > aIdx; --i )
459 for(
int i =
static_cast<int>(
m_pageWindows.size() ) - 1; i >= 0; --i )
466 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_model.Entries().size() ) )
477 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_model.Entries().size() ) )
480 if( !
m_model.Entries()[aIdx].preview )
490 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_pageWindows.size() ) )
495 m_tabs->ChangeSelection(
static_cast<size_t>( aIdx ) );
503 if( aIdx < 0 || aIdx >=
static_cast<int>(
m_model.Entries().size() ) )
531 const wxString activeKey =
m_model.Entries()[active].key;
534 for(
size_t i = 0; i <
m_mru.size(); ++i )
536 if(
m_mru[i] == activeKey )
538 pos =
static_cast<int>( i );
546 const int count =
static_cast<int>(
m_mru.size() );
547 const int next = aForward ? ( pos + 1 ) % count : ( pos - 1 + count ) % count;
557 return m_tabs->GetSelection();
563 return m_model.FindIndex( aKey );
569 const int idx =
m_model.FindIndex( aOldKey );
574 m_model.Rename( aOldKey, aNewKey );
578 m_tabs->SetPageText( idx, aNewLabel );
581 for( wxString& key :
m_mru )
612 const int idx = aEvent.GetSelection();
614 if( idx >= 0 && idx <
static_cast<int>(
m_model.Entries().size() ) )
623 const int idx = aEvent.GetSelection();
656 wxAuiTabCtrl* tabCtrl =
m_tabs->GetActiveTabCtrl();
661 wxWindow* page =
nullptr;
663 if( tabCtrl->TabHitTest( aEvent.GetX(), aEvent.GetY(), &page ) )
675 switch( aEvent.GetId() )
int PreviewIndex() const
Index of the current reusable preview tab, or -1 if none.
bool CanCloseWithoutPrompt(const wxString &aKey) const
True when the document has no unsaved edits and can be closed silently.
void Rename(const wxString &aOldKey, const wxString &aNewKey)
Re-key the entry for aOldKey to aNewKey, keeping its position and state.
void Promote(const wxString &aKey)
Clear the preview flag so the tab becomes permanent and is no longer reused.
void MarkModified(const wxString &aKey, bool aModified)
Update the modified flag.
int FindIndex(const wxString &aKey) const
int OpenDocument(const wxString &aKey, bool aAsPreview)
Return the index to display the document at, reusing a preview slot or appending a new tab.
std::vector< ENTRY > m_entries
void CloseDocument(const wxString &aKey)
Drop the document with aKey, freeing the preview slot if it held it.
void closeTabInternal(int aIdx)
Close the tab at aIdx, prompting the host exactly once.
std::function< TAB_VISUAL_STATE(int)> onQueryVisualState
Host reports the visual state (modified/preview) for the tab at the given index.
void bindTabDClick()
(Re)bind the double-click handler to the notebook's current tab-strip control.
TAB_VISUAL_STATE visualStateForIndex(int aIdx) const
~EDITOR_TABS_PANEL() override
int indexOfWindow(wxWindow *aWindow) const
Map a notebook page window pointer to its current tab index, or -1.
void onPageChanged(wxAuiNotebookEvent &aEvent)
void CloseToRight(int aIdx)
void onContextMenu(wxCommandEvent &aEvent)
bool m_suppressActivateOnClose
When set, closeTabInternal selects the fallback page without firing onActivateTab.
void AdvanceTab(bool aForward)
std::vector< wxString > m_mru
Most-recently-used key order for Ctrl+Tab cycling; front is most recent.
void RenameTab(const wxString &aOldKey, const wxString &aNewKey, const wxString &aNewLabel)
Re-key the tab aOldKey to aNewKey and relabel it to aNewLabel.
void touchMru(const wxString &aKey)
Bump aKey to the front of the MRU order.
void onTabDClick(wxMouseEvent &aEvent)
void PromoteTab(int aIdx)
Convert a preview tab into a permanent one, dropping its italic styling.
std::function< void(int)> onActivateTab
Host swaps the active document context to the tab at the given index.
std::function< bool(int)> onCloseTabRequested
Host prompts as needed; return false to veto the close.
void MarkModified(int aIdx, bool aModified)
Mark the tab modified.
void onTabRightDown(wxAuiNotebookEvent &aEvent)
void updateTabStripHeight()
Clamp the notebook to its tab-strip height and re-Layout so its (unused) page area collapses and the ...
int AddTab(const wxString &aKey, const wxString &aLabel, bool aAsPreview)
void forgetMru(const wxString &aKey)
Remove aKey from the MRU order.
EDITOR_TABS_PANEL(wxWindow *aParent, EDA_DRAW_PANEL_GAL *aSharedCanvas)
EDA_DRAW_PANEL_GAL * m_sharedCanvas
void CloseOthers(int aKeepIdx)
void onPageClose(wxAuiNotebookEvent &aEvent)
std::vector< wxWindow * > m_pageWindows
Hidden per-tab key windows; index-aligned with the model entries.
void activateTab(int aIdx)
Activate the tab at aIdx without re-entering the change handler.
EDITOR_TABS_MODEL m_model
void ReleaseSharedCanvas()
Hand the host-owned canvas back to its original parent.
wxWindow * m_originalCanvasParent
The canvas's parent before it was borrowed, reparented back on destruction so it is not freed as a ch...
bool m_activating
Guards activateTab() against re-entrancy from programmatic SetActivePage().
int FindTab(const wxString &aKey) const
A wxAuiTabArt that renders editor tabs with preview/modified decorations.
TAB_VISUAL_STATE ResolveTabVisualState(bool aPreview, bool aModified)
Resolve a tab's decorations from its document state flags.
Visual decorations derived from document state: preview is italic, modified is bold with a leading as...