mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-03 17:19:43 +02:00
Remove some direct dependencies on TrackPanel
This commit is contained in:
commit
3af2063fa3
@ -132,6 +132,11 @@ void AudacityProject::SetFrame( wxFrame *pFrame )
|
||||
mFrame = pFrame;
|
||||
}
|
||||
|
||||
void AudacityProject::SetPanel( wxWindow *pPanel )
|
||||
{
|
||||
mPanel = pPanel;
|
||||
}
|
||||
|
||||
wxString AudacityProject::GetProjectName() const
|
||||
{
|
||||
wxString name = wxFileNameFromPath(mFileName);
|
||||
@ -159,3 +164,20 @@ AUDACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
AUDACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetPanel();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
AUDACITY_DLL_API const wxWindow &GetProjectPanel(
|
||||
const AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetPanel();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
@ -115,6 +115,10 @@ class AUDACITY_DLL_API AudacityProject final
|
||||
const wxFrame *GetFrame() const { return mFrame; }
|
||||
void SetFrame( wxFrame *pFrame );
|
||||
|
||||
wxWindow *GetPanel() { return mPanel; }
|
||||
const wxWindow *GetPanel() const { return mPanel; }
|
||||
void SetPanel( wxWindow *pPanel );
|
||||
|
||||
wxString GetProjectName() const;
|
||||
|
||||
const FilePath &GetFileName() { return mFileName; }
|
||||
@ -136,6 +140,7 @@ class AUDACITY_DLL_API AudacityProject final
|
||||
|
||||
private:
|
||||
wxWeakRef< wxFrame > mFrame{};
|
||||
wxWeakRef< wxWindow > mPanel{};
|
||||
};
|
||||
|
||||
///\brief Get the top-level window associated with the project (as a wxFrame
|
||||
@ -152,4 +157,10 @@ inline const wxFrame *FindProjectFrame( const AudacityProject *project ) {
|
||||
return project ? &GetProjectFrame( *project ) : nullptr;
|
||||
}
|
||||
|
||||
///\brief Get the main sub-window of the project frame that displays track data
|
||||
// (as a wxWindow only, when you do not need to use the subclass TrackPanel)
|
||||
AUDACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project );
|
||||
AUDACITY_DLL_API const wxWindow &GetProjectPanel(
|
||||
const AudacityProject &project );
|
||||
|
||||
#endif
|
||||
|
@ -49,9 +49,16 @@ Paul Licameli split from AudacityProject.cpp
|
||||
#include "widgets/AudacityMessageBox.h"
|
||||
#include "widgets/FileHistory.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "widgets/WindowAccessible.h"
|
||||
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/dnd.h>
|
||||
#include <wx/scrolbar.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "../images/AudacityLogoAlpha.xpm"
|
||||
#endif
|
||||
|
||||
const int AudacityProjectTimerID = 5200;
|
||||
|
||||
@ -347,6 +354,174 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
void InitProjectWindow( ProjectWindow &window )
|
||||
{
|
||||
auto &project = window.GetProject();
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
SetBackgroundColour(theTheme.Colour( clrMedium ));
|
||||
#endif
|
||||
// Note that the first field of the status bar is a dummy, and its width is set
|
||||
// to zero latter in the code. This field is needed for wxWidgets 2.8.12 because
|
||||
// if you move to the menu bar, the first field of the menu bar is cleared, which
|
||||
// is undesirable behaviour.
|
||||
// In addition, the help strings of menu items are by default sent to the first
|
||||
// field. Currently there are no such help strings, but it they were introduced, then
|
||||
// there would need to be an event handler to send them to the appropriate field.
|
||||
auto statusBar = window.CreateStatusBar(4);
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
// so that name can be set on a standard control
|
||||
statusBar->SetAccessible(safenew WindowAccessible(statusBar));
|
||||
#endif
|
||||
statusBar->SetName(wxT("status_line")); // not localized
|
||||
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
|
||||
// LLL: Read this!!!
|
||||
//
|
||||
// Until the time (and cpu) required to refresh the track panel is
|
||||
// reduced, leave the following window creations in the order specified.
|
||||
// This will place the refresh of the track panel last, allowing all
|
||||
// the others to get done quickly.
|
||||
//
|
||||
// Near as I can tell, this is only a problem under Windows.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Create the ToolDock
|
||||
//
|
||||
ToolManager::Get( project ).LayoutToolBars();
|
||||
|
||||
//
|
||||
// Create the horizontal ruler
|
||||
//
|
||||
auto &ruler = AdornedRulerPanel::Get( project );
|
||||
|
||||
//
|
||||
// Create the TrackPanel and the scrollbars
|
||||
//
|
||||
|
||||
auto topPanel = window.GetTopPanel();
|
||||
|
||||
{
|
||||
auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
ubs->Add( ToolManager::Get( project ).GetTopDock(), 0, wxEXPAND | wxALIGN_TOP );
|
||||
ubs->Add(&ruler, 0, wxEXPAND);
|
||||
topPanel->SetSizer(ubs.release());
|
||||
}
|
||||
|
||||
// Ensure that the topdock comes before the ruler in the tab order,
|
||||
// irrespective of the order in which they were created.
|
||||
ToolManager::Get(project).GetTopDock()->MoveBeforeInTabOrder(&ruler);
|
||||
|
||||
const auto pPage = window.GetMainPage();
|
||||
|
||||
wxBoxSizer *bs;
|
||||
{
|
||||
auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
bs = ubs.get();
|
||||
bs->Add(topPanel, 0, wxEXPAND | wxALIGN_TOP);
|
||||
bs->Add(pPage, 1, wxEXPAND);
|
||||
bs->Add( ToolManager::Get( project ).GetBotDock(), 0, wxEXPAND );
|
||||
window.SetAutoLayout(true);
|
||||
window.SetSizer(ubs.release());
|
||||
}
|
||||
bs->Layout();
|
||||
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
|
||||
// LLL: When Audacity starts or becomes active after returning from
|
||||
// another application, the first window that can accept focus
|
||||
// will be given the focus even if we try to SetFocus(). By
|
||||
// making the TrackPanel that first window, we resolve several
|
||||
// keyboard focus problems.
|
||||
pPage->MoveBeforeInTabOrder(topPanel);
|
||||
|
||||
bs = (wxBoxSizer *)pPage->GetSizer();
|
||||
|
||||
auto vsBar = &window.GetVerticalScrollBar();
|
||||
auto hsBar = &window.GetHorizontalScrollBar();
|
||||
|
||||
{
|
||||
// Top horizontal grouping
|
||||
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||
|
||||
// Track panel
|
||||
hs->Add(&trackPanel, 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
|
||||
|
||||
{
|
||||
// Vertical grouping
|
||||
auto vs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
|
||||
// Vertical scroll bar
|
||||
vs->Add(vsBar, 1, wxEXPAND | wxALIGN_TOP);
|
||||
hs->Add(vs.release(), 0, wxEXPAND | wxALIGN_TOP);
|
||||
}
|
||||
|
||||
bs->Add(hs.release(), 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
|
||||
}
|
||||
|
||||
{
|
||||
// Bottom horizontal grouping
|
||||
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||
|
||||
// Bottom scrollbar
|
||||
hs->Add(viewInfo.GetLeftOffset() - 1, 0);
|
||||
hs->Add(hsBar, 1, wxALIGN_BOTTOM);
|
||||
hs->Add(vsBar->GetSize().GetWidth(), 0);
|
||||
bs->Add(hs.release(), 0, wxEXPAND | wxALIGN_LEFT);
|
||||
}
|
||||
|
||||
// Lay it out
|
||||
pPage->SetAutoLayout(true);
|
||||
pPage->Layout();
|
||||
|
||||
#ifdef EXPERIMENTAL_NOTEBOOK
|
||||
AddPages(this, Factory, pNotebook);
|
||||
#endif
|
||||
|
||||
auto mainPanel = window.GetMainPanel();
|
||||
|
||||
mainPanel->Layout();
|
||||
|
||||
wxASSERT( trackPanel.GetProject() == &project );
|
||||
|
||||
// MM: Give track panel the focus to ensure keyboard commands work
|
||||
trackPanel.SetFocus();
|
||||
|
||||
window.FixScrollbars();
|
||||
ruler.SetLeftOffset(viewInfo.GetLeftOffset()); // bevel on AdornedRuler
|
||||
|
||||
//
|
||||
// Set the Icon
|
||||
//
|
||||
|
||||
// loads either the XPM or the windows resource, depending on the platform
|
||||
#if !defined(__WXMAC__) && !defined(__WXX11__)
|
||||
{
|
||||
#if defined(__WXMSW__)
|
||||
wxIcon ic{ wxICON(AudacityLogo) };
|
||||
#elif defined(__WXGTK__)
|
||||
wxIcon ic{wxICON(AudacityLogoAlpha)};
|
||||
#else
|
||||
wxIcon ic{};
|
||||
ic.CopyFromBitmap(theTheme.Bitmap(bmpAudacityLogo48x48));
|
||||
#endif
|
||||
window.SetIcon(ic);
|
||||
}
|
||||
#endif
|
||||
|
||||
window.UpdateStatusWidths();
|
||||
wxString msg = wxString::Format(_("Welcome to Audacity version %s"),
|
||||
AUDACITY_VERSION_STRING);
|
||||
statusBar->SetStatusText(msg, mainStatusBarField);
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
ClearBackground();// For wxGTK.
|
||||
#endif
|
||||
}
|
||||
|
||||
AudacityProject *ProjectManager::New()
|
||||
{
|
||||
wxRect wndRect;
|
||||
@ -363,7 +538,7 @@ AudacityProject *ProjectManager::New()
|
||||
auto &projectHistory = ProjectHistory::Get( project );
|
||||
auto &projectManager = Get( project );
|
||||
auto &window = ProjectWindow::Get( *p );
|
||||
window.Init();
|
||||
InitProjectWindow( window );
|
||||
|
||||
ProjectFileIO::Get( *p ).SetProjectTitle();
|
||||
|
||||
@ -906,3 +1081,14 @@ int ProjectManager::GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels) {
|
||||
int iRecMins = (int)round(dRecTime / 60.0);
|
||||
return iRecMins;
|
||||
}
|
||||
|
||||
/// This was moved here to eliminate dependency of Scrubbing.cpp on
|
||||
/// TrackPanel, but perhaps a better home should be found for it in future
|
||||
#include "tracks/ui/Scrubbing.h"
|
||||
static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{
|
||||
[]( AudacityProject &parent ){
|
||||
auto result = std::make_shared< ScrubbingOverlay >( &parent );
|
||||
TrackPanel::Get( parent ).AddOverlay( result );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,6 @@ Paul Licameli split from AudacityProject.cpp
|
||||
#include "ProjectAudioIO.h"
|
||||
#include "ProjectStatus.h"
|
||||
#include "RefreshCode.h"
|
||||
#include "TrackPanel.h"
|
||||
#include "TrackPanelMouseEvent.h"
|
||||
#include "UndoManager.h"
|
||||
#include "ViewInfo.h"
|
||||
@ -37,10 +36,6 @@ Paul Licameli split from AudacityProject.cpp
|
||||
#include <wx/scrolbar.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "../images/AudacityLogoAlpha.xpm"
|
||||
#endif
|
||||
|
||||
// Returns the screen containing a rectangle, or -1 if none does.
|
||||
int ScreenContaining( wxRect & r ){
|
||||
unsigned int n = wxDisplay::GetCount();
|
||||
@ -641,92 +636,15 @@ ProjectWindow::ProjectWindow(wxWindow * parent, wxWindowID id,
|
||||
|
||||
mPlaybackScroller = std::make_unique<PlaybackScroller>( &project );
|
||||
|
||||
project.Bind( EVT_UNDO_MODIFIED, &ProjectWindow::OnUndoPushedModified, this );
|
||||
project.Bind( EVT_UNDO_PUSHED, &ProjectWindow::OnUndoPushedModified, this );
|
||||
project.Bind( EVT_UNDO_OR_REDO, &ProjectWindow::OnUndoRedo, this );
|
||||
project.Bind( EVT_UNDO_RESET, &ProjectWindow::OnUndoReset, this );
|
||||
}
|
||||
|
||||
void ProjectWindow::Init()
|
||||
{
|
||||
auto &project = mProject;
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
SetBackgroundColour(theTheme.Colour( clrMedium ));
|
||||
#endif
|
||||
// Note that the first field of the status bar is a dummy, and its width is set
|
||||
// to zero latter in the code. This field is needed for wxWidgets 2.8.12 because
|
||||
// if you move to the menu bar, the first field of the menu bar is cleared, which
|
||||
// is undesirable behaviour.
|
||||
// In addition, the help strings of menu items are by default sent to the first
|
||||
// field. Currently there are no such help strings, but it they were introduced, then
|
||||
// there would need to be an event handler to send them to the appropriate field.
|
||||
auto statusBar = CreateStatusBar(4);
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
// so that name can be set on a standard control
|
||||
statusBar->SetAccessible(safenew WindowAccessible(statusBar));
|
||||
#endif
|
||||
statusBar->SetName(wxT("status_line")); // not localized
|
||||
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
|
||||
// LLL: Read this!!!
|
||||
//
|
||||
// Until the time (and cpu) required to refresh the track panel is
|
||||
// reduced, leave the following window creations in the order specified.
|
||||
// This will place the refresh of the track panel last, allowing all
|
||||
// the others to get done quickly.
|
||||
//
|
||||
// Near as I can tell, this is only a problem under Windows.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Create the ToolDock
|
||||
//
|
||||
ToolManager::Get( project ).LayoutToolBars();
|
||||
|
||||
//
|
||||
// Create the horizontal ruler
|
||||
//
|
||||
auto &ruler = AdornedRulerPanel::Get( project );
|
||||
|
||||
//
|
||||
// Create the TrackPanel and the scrollbars
|
||||
//
|
||||
|
||||
{
|
||||
auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
ubs->Add( ToolManager::Get( project ).GetTopDock(), 0, wxEXPAND | wxALIGN_TOP );
|
||||
ubs->Add(&ruler, 0, wxEXPAND);
|
||||
mTopPanel->SetSizer(ubs.release());
|
||||
}
|
||||
|
||||
// Ensure that the topdock comes before the ruler in the tab order,
|
||||
// irrespective of the order in which they were created.
|
||||
ToolManager::Get(project).GetTopDock()->MoveBeforeInTabOrder(&ruler);
|
||||
|
||||
const auto pPage = GetMainPage();
|
||||
|
||||
wxBoxSizer *bs;
|
||||
{
|
||||
auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
bs = ubs.get();
|
||||
bs->Add(mTopPanel, 0, wxEXPAND | wxALIGN_TOP);
|
||||
bs->Add(pPage, 1, wxEXPAND);
|
||||
bs->Add( ToolManager::Get( project ).GetBotDock(), 0, wxEXPAND );
|
||||
SetAutoLayout(true);
|
||||
SetSizer(ubs.release());
|
||||
}
|
||||
bs->Layout();
|
||||
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
|
||||
// PRL: Old comments below. No longer observing the ordering that it
|
||||
// recommends. ProjectWindow::OnActivate puts the focus directly into
|
||||
// the TrackPanel, which avoids the problems.
|
||||
// LLL: When Audacity starts or becomes active after returning from
|
||||
// another application, the first window that can accept focus
|
||||
// will be given the focus even if we try to SetFocus(). By
|
||||
// creating the scrollbars after the TrackPanel, we resolve
|
||||
// several focus problems.
|
||||
|
||||
mHsbar = safenew ScrollBar(pPage, HSBarID, wxSB_HORIZONTAL);
|
||||
mVsbar = safenew ScrollBar(pPage, VSBarID, wxSB_VERTICAL);
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
@ -737,93 +655,13 @@ void ProjectWindow::Init()
|
||||
mHsbar->SetLayoutDirection(wxLayout_LeftToRight);
|
||||
mHsbar->SetName(_("Horizontal Scrollbar"));
|
||||
mVsbar->SetName(_("Vertical Scrollbar"));
|
||||
// LLL: When Audacity starts or becomes active after returning from
|
||||
// another application, the first window that can accept focus
|
||||
// will be given the focus even if we try to SetFocus(). By
|
||||
// making the TrackPanel that first window, we resolve several
|
||||
// keyboard focus problems.
|
||||
pPage->MoveBeforeInTabOrder(mTopPanel);
|
||||
|
||||
bs = (wxBoxSizer *)pPage->GetSizer();
|
||||
|
||||
{
|
||||
// Top horizontal grouping
|
||||
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||
|
||||
// Track panel
|
||||
hs->Add(&trackPanel, 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
|
||||
|
||||
{
|
||||
// Vertical grouping
|
||||
auto vs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
|
||||
// Vertical scroll bar
|
||||
vs->Add(mVsbar, 1, wxEXPAND | wxALIGN_TOP);
|
||||
hs->Add(vs.release(), 0, wxEXPAND | wxALIGN_TOP);
|
||||
}
|
||||
|
||||
bs->Add(hs.release(), 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
|
||||
}
|
||||
|
||||
{
|
||||
// Bottom horizontal grouping
|
||||
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||
|
||||
// Bottom scrollbar
|
||||
hs->Add(viewInfo.GetLeftOffset() - 1, 0);
|
||||
hs->Add(mHsbar, 1, wxALIGN_BOTTOM);
|
||||
hs->Add(mVsbar->GetSize().GetWidth(), 0);
|
||||
bs->Add(hs.release(), 0, wxEXPAND | wxALIGN_LEFT);
|
||||
}
|
||||
|
||||
// Lay it out
|
||||
pPage->SetAutoLayout(true);
|
||||
pPage->Layout();
|
||||
|
||||
#ifdef EXPERIMENTAL_NOTEBOOK
|
||||
AddPages(this, Factory, pNotebook);
|
||||
#endif
|
||||
|
||||
mMainPanel->Layout();
|
||||
|
||||
wxASSERT( trackPanel.GetProject() == &project );
|
||||
|
||||
// MM: Give track panel the focus to ensure keyboard commands work
|
||||
trackPanel.SetFocus();
|
||||
|
||||
FixScrollbars();
|
||||
ruler.SetLeftOffset(viewInfo.GetLeftOffset()); // bevel on AdornedRuler
|
||||
|
||||
//
|
||||
// Set the Icon
|
||||
//
|
||||
|
||||
// loads either the XPM or the windows resource, depending on the platform
|
||||
#if !defined(__WXMAC__) && !defined(__WXX11__)
|
||||
{
|
||||
#if defined(__WXMSW__)
|
||||
wxIcon ic{ wxICON(AudacityLogo) };
|
||||
#elif defined(__WXGTK__)
|
||||
wxIcon ic{wxICON(AudacityLogoAlpha)};
|
||||
#else
|
||||
wxIcon ic{};
|
||||
ic.CopyFromBitmap(theTheme.Bitmap(bmpAudacityLogo48x48));
|
||||
#endif
|
||||
SetIcon(ic);
|
||||
}
|
||||
#endif
|
||||
mIconized = false;
|
||||
|
||||
UpdateStatusWidths();
|
||||
wxString msg = wxString::Format(_("Welcome to Audacity version %s"),
|
||||
AUDACITY_VERSION_STRING);
|
||||
statusBar->SetStatusText(msg, mainStatusBarField);
|
||||
project.Bind( EVT_UNDO_MODIFIED, &ProjectWindow::OnUndoPushedModified, this );
|
||||
project.Bind( EVT_UNDO_PUSHED, &ProjectWindow::OnUndoPushedModified, this );
|
||||
project.Bind( EVT_UNDO_OR_REDO, &ProjectWindow::OnUndoRedo, this );
|
||||
project.Bind( EVT_UNDO_RESET, &ProjectWindow::OnUndoReset, this );
|
||||
|
||||
wxTheApp->Bind(EVT_THEME_CHANGE, &ProjectWindow::OnThemeChange, this);
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
ClearBackground();// For wxGTK.
|
||||
#endif
|
||||
}
|
||||
|
||||
ProjectWindow::~ProjectWindow()
|
||||
@ -871,7 +709,7 @@ void ProjectWindow::RedrawProject(const bool bForceWaveTracks /*= false*/)
|
||||
|
||||
auto &project = pThis->mProject ;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &trackPanel = GetProjectPanel( project );
|
||||
pThis->FixScrollbars();
|
||||
if (bForceWaveTracks)
|
||||
{
|
||||
@ -935,6 +773,28 @@ const int sbarHjump = 30; //STM: This is how far the thumb jumps when the
|
||||
#include "AllThemeResources.h"
|
||||
#endif
|
||||
|
||||
// Make sure selection edge is in view
|
||||
void ProjectWindow::ScrollIntoView(double pos)
|
||||
{
|
||||
auto &trackPanel = GetProjectPanel( mProject );
|
||||
auto &viewInfo = ViewInfo::Get( mProject );
|
||||
auto w = viewInfo.GetTracksUsableWidth();
|
||||
|
||||
int pixel = viewInfo.TimeToPosition(pos);
|
||||
if (pixel < 0 || pixel >= w)
|
||||
{
|
||||
TP_ScrollWindow
|
||||
(viewInfo.OffsetTimeByPixels(pos, -(w / 2)));
|
||||
trackPanel.Refresh(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectWindow::ScrollIntoView(int x)
|
||||
{
|
||||
auto &viewInfo = ViewInfo::Get( mProject );
|
||||
ScrollIntoView(viewInfo.PositionToTime(x, viewInfo.GetLeftOffset()));
|
||||
}
|
||||
|
||||
///
|
||||
/// This method handles general left-scrolling, either for drag-scrolling
|
||||
/// or when the scrollbar is clicked to the left of the thumb
|
||||
@ -1141,7 +1001,7 @@ void ProjectWindow::FixScrollbars()
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &trackPanel = GetProjectPanel( project );
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
|
||||
bool refresh = false;
|
||||
@ -1296,7 +1156,7 @@ void ProjectWindow::FixScrollbars()
|
||||
void ProjectWindow::UpdateLayout()
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &trackPanel = GetProjectPanel( project );
|
||||
auto &toolManager = ToolManager::Get( project );
|
||||
|
||||
// 1. Layout panel, to get widths of the docks.
|
||||
@ -1503,7 +1363,7 @@ void ProjectWindow::OnScroll(wxScrollEvent & WXUNUSED(event))
|
||||
void ProjectWindow::DoScroll()
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &trackPanel = GetProjectPanel( project );
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
const double lowerBound = ScrollingLowerBoundTime();
|
||||
|
||||
@ -1619,7 +1479,7 @@ void ProjectWindow::OnActivate(wxActivateEvent & event)
|
||||
auto &toolManager = ToolManager::Get( project );
|
||||
SetActiveProject( &project );
|
||||
if ( ! toolManager.RestoreFocus() )
|
||||
TrackPanel::Get( project ).SetFocus();
|
||||
GetProjectPanel( project ).SetFocus();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
MacShowUndockedToolbars(true);
|
||||
@ -1644,7 +1504,7 @@ void ProjectWindow::ZoomAfterImport(Track *pTrack)
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &trackPanel = GetProjectPanel( project );
|
||||
|
||||
DoZoomFit();
|
||||
|
||||
@ -1717,7 +1577,6 @@ void ProjectWindow::SkipEnd(bool shift)
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
double len = tracks.GetEndTime();
|
||||
|
||||
@ -1726,8 +1585,7 @@ void ProjectWindow::SkipEnd(bool shift)
|
||||
viewInfo.selectedRegion.setT0(len);
|
||||
|
||||
// Make sure the end of the track is visible
|
||||
trackPanel.ScrollIntoView(len);
|
||||
trackPanel.Refresh(false);
|
||||
ScrollIntoView(len);
|
||||
}
|
||||
|
||||
void ProjectWindow::TP_DisplaySelection()
|
||||
@ -1796,7 +1654,7 @@ void ProjectWindow::PlaybackScroller::OnTimer(wxCommandEvent &event)
|
||||
// to the application, so scrub speed control is smoother.
|
||||
// (So I see at least with OS 10.10 and wxWidgets 3.0.2.)
|
||||
// Is there another way to ensure that than by refreshing?
|
||||
auto &trackPanel = TrackPanel::Get( *mProject );
|
||||
auto &trackPanel = GetProjectPanel( *mProject );
|
||||
trackPanel.Refresh(false);
|
||||
}
|
||||
else if (mMode != Mode::Off) {
|
||||
@ -1804,7 +1662,7 @@ void ProjectWindow::PlaybackScroller::OnTimer(wxCommandEvent &event)
|
||||
// fraction of the window width.
|
||||
|
||||
auto &viewInfo = ViewInfo::Get( *mProject );
|
||||
auto &trackPanel = TrackPanel::Get( *mProject );
|
||||
auto &trackPanel = GetProjectPanel( *mProject );
|
||||
const int posX = viewInfo.TimeToPosition(viewInfo.mRecentStreamTime);
|
||||
auto width = viewInfo.GetTracksUsableWidth();
|
||||
int deltaX;
|
||||
@ -1832,7 +1690,6 @@ void ProjectWindow::PlaybackScroller::OnTimer(wxCommandEvent &event)
|
||||
void ProjectWindow::ZoomInByFactor( double ZoomFactor )
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
|
||||
auto gAudioIO = AudioIOBase::Get();
|
||||
@ -1842,8 +1699,7 @@ void ProjectWindow::ZoomInByFactor( double ZoomFactor )
|
||||
ProjectAudioIO::Get( project ).GetAudioIOToken()) &&
|
||||
!gAudioIO->IsPaused()){
|
||||
ZoomBy(ZoomFactor);
|
||||
trackPanel.ScrollIntoView(gAudioIO->GetStreamTime());
|
||||
trackPanel.Refresh(false);
|
||||
ScrollIntoView(gAudioIO->GetStreamTime());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,9 @@ class Track;
|
||||
class wxScrollBar;
|
||||
class wxPanel;
|
||||
|
||||
class ProjectWindow;
|
||||
void InitProjectWindow( ProjectWindow &window );
|
||||
|
||||
///\brief A top-level window associated with a project, and handling scrollbars
|
||||
/// and zooming
|
||||
class ProjectWindow final : public wxFrame
|
||||
@ -34,6 +37,7 @@ public:
|
||||
static ProjectWindow *Find( AudacityProject *pProject );
|
||||
static const ProjectWindow *Find( const AudacityProject *pProject );
|
||||
AudacityProject &GetProject() { return mProject; }
|
||||
const AudacityProject &GetProject() const { return mProject; }
|
||||
|
||||
explicit ProjectWindow(
|
||||
wxWindow * parent, wxWindowID id,
|
||||
@ -44,8 +48,6 @@ public:
|
||||
// Next available ID for sub-windows
|
||||
int NextWindowID();
|
||||
|
||||
void Init();
|
||||
|
||||
bool IsActive() override;
|
||||
bool IsIconized() const override;
|
||||
|
||||
@ -53,6 +55,7 @@ public:
|
||||
void SetIsBeingDeleted() { mIsDeleting = true; }
|
||||
|
||||
wxWindow *GetMainPage() { return mMainPage; }
|
||||
wxPanel *GetMainPanel() { return mMainPanel; }
|
||||
wxPanel *GetTopPanel() { return mTopPanel; }
|
||||
|
||||
void UpdateStatusWidths();
|
||||
@ -101,6 +104,10 @@ public:
|
||||
// Scrollbars
|
||||
|
||||
wxScrollBar &GetVerticalScrollBar() { return *mVsbar; }
|
||||
wxScrollBar &GetHorizontalScrollBar() { return *mHsbar; }
|
||||
|
||||
void ScrollIntoView(double pos);
|
||||
void ScrollIntoView(int x);
|
||||
|
||||
void OnScrollLeft();
|
||||
void OnScrollRight();
|
||||
@ -182,7 +189,7 @@ private:
|
||||
|
||||
bool mAutoScrolling{ false };
|
||||
bool mActive{ true };
|
||||
bool mIconized;
|
||||
bool mIconized{ false };
|
||||
bool mShownOnce{ false };
|
||||
|
||||
|
||||
|
@ -205,7 +205,7 @@ AudacityProject::AttachedWindows::RegisteredFactory sKey{
|
||||
wxASSERT( mainPage ); // to justify safenew
|
||||
|
||||
auto &tracks = TrackList::Get( project );
|
||||
return safenew TrackPanel(mainPage,
|
||||
auto result = safenew TrackPanel(mainPage,
|
||||
window.NextWindowID(),
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
@ -213,6 +213,8 @@ AudacityProject::AttachedWindows::RegisteredFactory sKey{
|
||||
&viewInfo,
|
||||
&project,
|
||||
&ruler);
|
||||
project.SetPanel( result );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -971,25 +973,6 @@ void TrackPanel::UpdateVRulerSize()
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
// Make sure selection edge is in view
|
||||
void TrackPanel::ScrollIntoView(double pos)
|
||||
{
|
||||
auto w = mViewInfo->GetTracksUsableWidth();
|
||||
|
||||
int pixel = mViewInfo->TimeToPosition(pos);
|
||||
if (pixel < 0 || pixel >= w)
|
||||
{
|
||||
mListener->TP_ScrollWindow
|
||||
(mViewInfo->OffsetTimeByPixels(pos, -(w / 2)));
|
||||
Refresh(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TrackPanel::ScrollIntoView(int x)
|
||||
{
|
||||
ScrollIntoView(mViewInfo->PositionToTime(x, mViewInfo->GetLeftOffset()));
|
||||
}
|
||||
|
||||
void TrackPanel::OnTrackMenu(Track *t)
|
||||
{
|
||||
CellularPanel::DoContextMenu( t ? &TrackView::Get( *t ) : nullptr );
|
||||
|
@ -117,9 +117,6 @@ class AUDACITY_DLL_API TrackPanel final
|
||||
void HandlePageDownKey();
|
||||
AudacityProject * GetProject() const override;
|
||||
|
||||
void ScrollIntoView(double pos);
|
||||
void ScrollIntoView(int x);
|
||||
|
||||
void OnTrackMenu(Track *t = NULL);
|
||||
|
||||
void VerticalScroll( float fracPosition);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "../ProjectHistory.h"
|
||||
#include "../ProjectSettings.h"
|
||||
#include "../TrackPanel.h"
|
||||
#include "../ProjectWindow.h"
|
||||
#include "../UndoManager.h"
|
||||
#include "../WaveClip.h"
|
||||
#include "../ViewInfo.h"
|
||||
@ -561,6 +562,7 @@ void DoSelectClip(AudacityProject &project, bool next)
|
||||
{
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
std::vector<FoundClip> results;
|
||||
FindClips(project, selectedRegion.t0(),
|
||||
@ -573,7 +575,7 @@ void DoSelectClip(AudacityProject &project, bool next)
|
||||
double t1 = results[0].endTime;
|
||||
selectedRegion.setTimes(t0, t1);
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
|
||||
// create and send message to screen reader
|
||||
wxString message;
|
||||
@ -607,6 +609,7 @@ void DoCursorClipBoundary
|
||||
{
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
std::vector<FoundClipBoundary> results;
|
||||
FindClipBoundaries(project, next ? selectedRegion.t1() :
|
||||
@ -618,7 +621,7 @@ void DoCursorClipBoundary
|
||||
double time = results[0].time;
|
||||
selectedRegion.setTimes(time, time);
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
|
||||
wxString message = ClipBoundaryMessage(results);
|
||||
trackPanel.MessageForScreenReader(message);
|
||||
@ -691,6 +694,7 @@ void DoClipLeftOrRight
|
||||
(AudacityProject &project, bool right, bool keyUp )
|
||||
{
|
||||
auto &undoManager = UndoManager::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
if (keyUp) {
|
||||
undoManager.StopConsolidating();
|
||||
@ -707,7 +711,7 @@ void DoClipLeftOrRight
|
||||
auto amount = DoClipMove( viewInfo, trackPanel.GetFocusedTrack(),
|
||||
tracks, isSyncLocked, right );
|
||||
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
|
||||
if (amount != 0.0) {
|
||||
wxString message = right? _("Time shifted clips to the right") :
|
||||
|
@ -41,7 +41,6 @@ void FinishCopy
|
||||
bool DoPasteText(AudacityProject &project)
|
||||
{
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
@ -61,7 +60,7 @@ bool DoPasteText(AudacityProject &project)
|
||||
// Make sure caret is in view
|
||||
int x;
|
||||
if (view.CalcCursorX( project, &x )) {
|
||||
trackPanel.ScrollIntoView(x);
|
||||
window.ScrollIntoView(x);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -273,7 +273,7 @@ void MoveWhenAudioInactive
|
||||
}
|
||||
|
||||
// Make sure NEW position is in view
|
||||
trackPanel.ScrollIntoView(viewInfo.selectedRegion.t1());
|
||||
window.ScrollIntoView(viewInfo.selectedRegion.t1());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -282,9 +282,9 @@ void SeekWhenAudioInactive
|
||||
SelectionOperation operation)
|
||||
{
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &tracks = TrackList::Get( project );
|
||||
const auto &settings = ProjectSettings::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
if( operation == CURSOR_MOVE )
|
||||
{
|
||||
@ -318,9 +318,8 @@ SelectionOperation operation)
|
||||
else
|
||||
viewInfo.selectedRegion.setT1( newT );
|
||||
|
||||
// Ensure it is visible, and refresh.
|
||||
trackPanel.ScrollIntoView(newT);
|
||||
trackPanel.Refresh(false);
|
||||
// Ensure it is visible
|
||||
window.ScrollIntoView(newT);
|
||||
}
|
||||
|
||||
// Handle small cursor and play head movements
|
||||
@ -381,8 +380,8 @@ void DoCursorMove(
|
||||
void DoBoundaryMove(AudacityProject &project, int step, SeekInfo &info)
|
||||
{
|
||||
auto &viewInfo = ViewInfo::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
// step is negative, then is moving left. step positive, moving right.
|
||||
// Move the left/right selection boundary, to expand the selection
|
||||
@ -434,9 +433,8 @@ void DoBoundaryMove(AudacityProject &project, int step, SeekInfo &info)
|
||||
else
|
||||
viewInfo.selectedRegion.setT1( newT );
|
||||
|
||||
// Ensure it is visible, and refresh.
|
||||
trackPanel.ScrollIntoView(newT);
|
||||
trackPanel.Refresh(false);
|
||||
// Ensure it is visible
|
||||
window.ScrollIntoView(newT);
|
||||
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
}
|
||||
@ -834,31 +832,31 @@ void OnSelContractRight(const CommandContext &context)
|
||||
void OnCursorSelStart(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
selectedRegion.collapseToT0();
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
}
|
||||
|
||||
void OnCursorSelEnd(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
selectedRegion.collapseToT1();
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t1());
|
||||
window.ScrollIntoView(selectedRegion.t1());
|
||||
}
|
||||
|
||||
void OnCursorTrackStart(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
double kWayOverToRight = std::numeric_limits<double>::max();
|
||||
|
||||
@ -876,15 +874,15 @@ void OnCursorTrackStart(const CommandContext &context)
|
||||
|
||||
selectedRegion.setTimes(minOffset, minOffset);
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
}
|
||||
|
||||
void OnCursorTrackEnd(const CommandContext &context)
|
||||
{
|
||||
auto &project = context.project;
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
double kWayOverToLeft = std::numeric_limits<double>::lowest();
|
||||
|
||||
@ -902,7 +900,7 @@ void OnCursorTrackEnd(const CommandContext &context)
|
||||
|
||||
selectedRegion.setTimes(maxEndOffset, maxEndOffset);
|
||||
ProjectHistory::Get( project ).ModifyState(false);
|
||||
trackPanel.ScrollIntoView(selectedRegion.t1());
|
||||
window.ScrollIntoView(selectedRegion.t1());
|
||||
}
|
||||
|
||||
void OnSkipStart(const CommandContext &context)
|
||||
|
@ -173,7 +173,7 @@ void DoMoveToLabel(AudacityProject &project, bool next)
|
||||
}
|
||||
else {
|
||||
selectedRegion = label->selectedRegion;
|
||||
trackPanel.ScrollIntoView(selectedRegion.t0());
|
||||
window.ScrollIntoView(selectedRegion.t0());
|
||||
window.RedrawProject();
|
||||
}
|
||||
|
||||
|
@ -1302,7 +1302,7 @@ unsigned LabelTrackView::KeyDown(
|
||||
// Make sure caret is in view
|
||||
int x;
|
||||
if (CalcCursorX( *project, &x ))
|
||||
TrackPanel::Get( *project ).ScrollIntoView(x);
|
||||
ProjectWindow::Get( *project ).ScrollIntoView(x);
|
||||
|
||||
// If selection modified, refresh
|
||||
// Otherwise, refresh track display if the keystroke was handled
|
||||
|
@ -25,7 +25,6 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../ProjectSettings.h"
|
||||
#include "../../ProjectStatus.h"
|
||||
#include "../../Track.h"
|
||||
#include "../../TrackPanel.h"
|
||||
#include "../../ViewInfo.h"
|
||||
#include "../../WaveTrack.h"
|
||||
#include "../../prefs/PlaybackPrefs.h"
|
||||
@ -597,7 +596,7 @@ void Scrubber::ContinueScrubbingPoll()
|
||||
gAudioIO->UpdateScrub(speed, mOptions);
|
||||
} else {
|
||||
const wxMouseState state(::wxGetMouseState());
|
||||
auto &trackPanel = TrackPanel::Get( *mProject );
|
||||
auto &trackPanel = GetProjectPanel( *mProject );
|
||||
const wxPoint position = trackPanel.ScreenToClient(state.GetPosition());
|
||||
auto &viewInfo = ViewInfo::Get( *mProject );
|
||||
#ifdef DRAG_SCRUB
|
||||
@ -904,14 +903,6 @@ void Scrubber::Forwarder::OnMouse(wxMouseEvent &event)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class ScrubbingOverlay is responsible for drawing the speed numbers
|
||||
|
||||
static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{
|
||||
[]( AudacityProject &parent ){
|
||||
auto result = std::make_shared< ScrubbingOverlay >( &parent );
|
||||
TrackPanel::Get( parent ).AddOverlay( result );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
ScrubbingOverlay::ScrubbingOverlay(AudacityProject *project)
|
||||
: mProject(project)
|
||||
, mLastScrubRect()
|
||||
@ -1003,7 +994,7 @@ void ScrubbingOverlay::OnTimer(wxCommandEvent &event)
|
||||
mNextScrubRect = wxRect();
|
||||
}
|
||||
else {
|
||||
TrackPanel &trackPanel = TrackPanel::Get( *mProject );
|
||||
auto &trackPanel = GetProjectPanel( *mProject );
|
||||
auto &viewInfo = ViewInfo::Get( *mProject );
|
||||
int panelWidth, panelHeight;
|
||||
trackPanel.GetSize(&panelWidth, &panelHeight);
|
||||
@ -1070,7 +1061,7 @@ void Scrubber::DoScrub(bool seek)
|
||||
const bool wasScrubbing = HasMark() || IsScrubbing();
|
||||
const bool scroll = ShouldScrubPinned();
|
||||
if (!wasScrubbing) {
|
||||
auto &tp = TrackPanel::Get( *mProject );
|
||||
auto &tp = GetProjectPanel( *mProject );
|
||||
const auto &viewInfo = ViewInfo::Get( *mProject );
|
||||
wxCoord xx = tp.ScreenToClient(::wxGetMouseState().GetPosition()).x;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user