33#include <wx/display.h>
34#include <wx/scrolbar.h>
36#include <wx/splitter.h>
37#include <wx/wupdlock.h>
43#ifdef HAS_AUDIOCOM_UPLOAD
64 unsigned int n = wxDisplay::GetCount();
65 for(
unsigned int i = 0;i<n;i++){
67 wxRect scr = d.GetClientArea();
68 if( scr.Contains( r ) )
79 if( wxDisplay::GetFromPoint( r.GetTopLeft() ) == wxNOT_FOUND)
return false;
80 if( wxDisplay::GetFromPoint( r.GetBottomRight() ) == wxNOT_FOUND)
return false;
88 wxRect targetTitleRect(requestedRect->GetLeftTop(), requestedRect->GetBottomRight());
91 targetTitleRect.x += 15;
92 targetTitleRect.width -= 100;
93 if (targetTitleRect.width < 165) targetTitleRect.width = 165;
94 targetTitleRect.height = 15;
95 int targetBottom = targetTitleRect.GetBottom();
96 int targetRight = targetTitleRect.GetRight();
99 for (
int i = targetTitleRect.GetLeft(); i < targetRight; i++) {
100 for (
int j = targetTitleRect.GetTop(); j < targetBottom; j++) {
101 int monitor = display.GetFromPoint(wxPoint(i, j));
113 *defRect = wxGetClientDisplayRect();
134 if (width < defRect->width)
136 defRect->x = (defRect->width - width)/2;
137 defRect->width = width;
140 if (height < defRect->height)
142 defRect->y = (defRect->height - height)/2;
147 const int pixelsFormenu = 60;
148 if( defRect->y < pixelsFormenu )
150 defRect->height = height;
182 if (normalRect.width == 0 || normalRect.height == 0) {
183 normalRect = defaultRect;
185 if (windowRect.width == 0 || windowRect.height == 0) {
186 windowRect = defaultRect;
190 wxRect screenRect( wxGetClientDisplayRect());
191#if defined(__WXMAC__)
195 if (normalRect.y < screenRect.y) {
196 normalRect = defaultRect;
198 if (windowRect.y < screenRect.y) {
199 windowRect = defaultRect;
206 if (*pMaximized || *pIconized) {
207 *nextRect = normalRect;
210 *nextRect = windowRect;
214 *nextRect = defaultRect;
217 *nextRect = defaultRect;
235 normalRect = defaultRect;
238 windowRect = defaultRect;
241 bool validWindowSize =
false;
246 auto pProject = *iter;
248 validWindowSize =
true;
253 if (validWindowSize) {
254 *nextRect = validProject->GetRect();
255 *pMaximized = validProject->IsMaximized();
259 *nextRect = defaultRect;
263 *nextRect = normalRect;
280 const int edgeSlop = 10;
284 wxPoint p = nextRect->GetLeftTop();
285 int scr = std::max( 0, wxDisplay::GetFromPoint( p ));
287 screenRect = d.GetClientArea();
291 wxPoint bottomRight = nextRect->GetBottomRight();
292 if (bottomRight.x > (screenRect.GetRight()+edgeSlop)) {
293 int newWidth = screenRect.GetWidth() - nextRect->GetLeft();
294 if (newWidth < defaultRect.GetWidth()) {
295 nextRect->x = windowRect.x;
296 nextRect->y = windowRect.y;
297 nextRect->width = windowRect.width;
300 nextRect->width = newWidth;
305 bottomRight = nextRect->GetBottomRight();
306 if (bottomRight.y > (screenRect.GetBottom()+edgeSlop)) {
308 bottomRight = nextRect->GetBottomRight();
309 if (bottomRight.y > (screenRect.GetBottom()+edgeSlop)) {
310 nextRect->SetBottom(screenRect.GetBottom());
318 *nextRect = defaultRect;
331 : wxScrollBar(parent,
id, wxDefaultPosition, wxDefaultSize,
style)
337 wxWindow *w = e.GetWindow();
343 void SetScrollbar(
int position,
int thumbSize,
344 int range,
int pageSize,
345 bool refresh =
true)
override;
348 DECLARE_EVENT_TABLE()
351void ScrollBar::SetScrollbar(
int position,
int thumbSize,
352 int range,
int pageSize,
361 position != GetThumbPosition() ||
362 thumbSize != GetThumbSize() ||
363 range != GetRange() ||
364 pageSize != GetPageSize();
368 wxScrollBar::SetScrollbar(position, thumbSize, range, pageSize, refresh);
372 EVT_SET_FOCUS(ScrollBar::OnSetFocus)
378 bool bMaximized =
false;
379 bool bIconized =
false;
385 wxSize(wndRect.width, wndRect.height),
389 auto &window = *pWindow;
392 window.SetPosition(wndRect.GetPosition());
395 window.Maximize(
true);
397 else if (bIconized) {
456 {
return IsWindowValid(mwWindow) ? mwWindow->ViewportSize() : std::pair{ 1, 1 }; }
459 {
return IsWindowValid(mwWindow) ? mwWindow->MinimumTrackHeight() : 0; }
461 {
return IsWindowValid(mwWindow) ? mwWindow->IsTrackMinimized(track) :
false; }
463 {
if (
IsWindowValid(mwWindow)) mwWindow->SetMinimized(track, minimized); }
465 {
return IsWindowValid(mwWindow) ? mwWindow->GetTrackHeight(track) : 0; }
467 {
if (
IsWindowValid(mwWindow)) mwWindow->SetChannelHeights(track, height); }
469 {
return IsWindowValid(mwWindow) ? mwWindow->GetTotalHeight(trackList) : 0; }
472 {
return IsWindowValid(mwWindow) ? mwWindow->GetHorizontalThumbPosition() : 0; }
474 {
return IsWindowValid(mwWindow) ? mwWindow->GetHorizontalThumbSize() : 0; }
476 {
return IsWindowValid(mwWindow) ? mwWindow->GetHorizontalRange() : 0; }
479 if (
IsWindowValid(mwWindow)) mwWindow->SetHorizontalThumbPosition(viewStart);
482 int range,
int pageSize,
bool refresh)
override
485 mwWindow->SetHorizontalScrollbar(
486 position, thumbSize, range, pageSize, refresh);
491 mwWindow->ShowHorizontalScrollbar(shown);
495 {
return IsWindowValid(mwWindow) ? mwWindow->GetVerticalThumbPosition() : 0; }
497 {
return IsWindowValid(mwWindow) ? mwWindow->GetVerticalThumbSize() : 0; }
499 {
return IsWindowValid(mwWindow) ? mwWindow->GetVerticalRange() : 0; }
502 if (
IsWindowValid(mwWindow)) mwWindow->SetVerticalThumbPosition(viewStart);
505 int range,
int pageSize,
bool refresh)
override
508 mwWindow->SetVerticalScrollbar(
509 position, thumbSize, range, pageSize, refresh);
514 mwWindow->ShowVerticalScrollbar(shown);
519 mwWindow->SetToDefaultSize();
530 , mViewportSubscription{
538 constexpr auto EffectsPanelMaxWidth { 500 };
539 constexpr auto TrackPanelMinWidth { 250 };
552 this, wxID_ANY, wxDefaultPosition,
553 wxSize{ this->GetSize().GetWidth(), -1 }
556 mTopPanel->SetLayoutDirection(wxLayout_LeftToRight);
559 auto container =
safenew wxSplitterWindow(
this, wxID_ANY,
562 wxNO_BORDER | wxSP_LIVE_UPDATE | wxSP_THIN_SASH);
563 container->Bind(wxEVT_SPLITTER_DOUBLECLICKED, [](wxSplitterEvent& event){
567 container->Bind(wxEVT_SPLITTER_SASH_POS_CHANGING, [=](wxSplitterEvent& event){
568 if(event.GetSashPosition() > EffectsPanelMaxWidth)
570 event.SetSashPosition(-1);
598#if wxUSE_ACCESSIBILITY
603 mHsbar->SetLayoutDirection(wxLayout_LeftToRight);
604 mHsbar->SetName(
_(
"Horizontal Scrollbar"));
605 mVsbar->SetName(
_(
"Vertical Scrollbar"));
661 toolManager.ForEach([](
auto pToolBar){
663 pToolBar->ReCreateButtons();
699 trackPanel.GetSize(&width, &height);
700 return { width, height };
715 for (
auto pChannel : track.
Channels())
731 for (
auto pChannel : track.
Channels())
737 return mHsbar->GetThumbPosition();
742 return mHsbar->GetThumbSize();
747 return mHsbar->GetRange();
752 mHsbar->SetThumbPosition(viewStart);
756 int range,
int pageSize,
bool refresh)
758 mHsbar->SetScrollbar(position, thumbSize, range, pageSize, refresh);
772 return mVsbar->GetThumbPosition();
777 return mVsbar->GetThumbSize();
782 return mVsbar->GetRange();
787 mVsbar->SetThumbPosition(viewStart);
791 int range,
int pageSize,
bool refresh)
793 mVsbar->SetScrollbar(position, thumbSize, range, pageSize, refresh);
818 toolManager.LayoutToolBars();
832 wxSize mainsz = GetSize();
836 wxPoint tppos = ClientToScreen(trackPanel.GetParent()->GetPosition());
840 wxPoint sbpos = ClientToScreen(toolManager.GetBotDock()->GetPosition());
843 SetMinSize( wxSize(250, (mainsz.y - sbpos.y) + tppos.y + 50));
845 SetMinSize( wxSize(250, 250));
846 SetMaxSize( wxSize(20000, 20000));
874 SetSize(defaultRect.width, defaultRect.height);
879 auto statusBar = GetStatusBar();
881 if (statusBar !=
nullptr)
882 statusBar->Destroy();
893 statusBar = CreateStatusBar(
902 if (pProject !=
nullptr)
913 if (
field.IsVisible(*pProject))
914 statusBar->SetStatusText(
915 field.GetText(*pProject).Translation(), index++);
928 const auto fieldsCount =
930 auto statusBar = GetStatusBar();
932 bool statusBarRecreated =
false;
934 if (!statusBar || fieldsCount != statusBar->GetFieldsCount())
937 statusBarRecreated =
true;
944 std::vector<int> widths(fieldsCount, 0);
960 for (
const auto& function : functions)
963 for (
const auto&
string : results.first)
966 statusBar->GetTextExtent(
string.Translation(), &w,
nullptr);
967 width = std::max<int>(width, w + results.second);
972 widths[index++] = width;
975 statusBar->SetStatusWidths(fieldsCount, widths.data());
991 const auto &children = GetChildren();
992 for(
const auto &child : children) {
993 if (
auto frame =
dynamic_cast<ToolFrame*
>(child)) {
997 else if (frame->GetBar() &&
998 frame->GetBar()->IsVisible() ) {
1006 focused->SetFocus();
1019#if defined(__WXMAC__)
1031 auto VisibleProjectCount = std::count_if(
1052 if (!this->IsMaximized() && !this->
IsIconized())
1071 if (!this->IsMaximized() && !this->
IsIconized())
1108 GetEventHandler()->QueueEvent(
safenew wxSizeEvent(GetSize()));
1133 if (
name != GetTitle()) {
1158 if( event.GetId() < 17000){
1168 bool handled = commandManager.HandleMenuID(
1175 event.ResumePropagation( 999 );
1218 if ( ! toolManager.RestoreFocus() )
1235 if (event.ButtonDown())
1247 mRecentStreamTime = gAudioIO->GetStreamTime();
1249 auto cleanup =
finally([&]{
1256 else if (mMode == Mode::Refresh) {
1263 trackPanel.Refresh(
false);
1265 else if (mMode != Mode::Off) {
1271 const int posX = viewInfo.TimeToPosition(mRecentStreamTime);
1272 auto width = viewInfo.GetTracksUsableWidth();
1284 deltaX = posX - width;
break;
1287 viewInfo.OffsetTimeByPixels(viewInfo.hpos, deltaX,
true);
1289 viewInfo.hpos = std::max(0.0, viewInfo.hpos);
1290 trackPanel.Refresh(
false);
1307 auto [rescroll, scrollbarVisibilityChanged, resize] = message;
1310 trackPanel.Refresh(
false);
1316 if (scrollbarVisibilityChanged || resize)
1321[]( wxWindow &window ){
1322 auto pProjectWindow =
dynamic_cast< ProjectWindow*
>( &window );
1323 return pProjectWindow ? pProjectWindow->
GetTopPanel() :
nullptr;
void SetActiveProject(AudacityProject *project)
Handle changing of active project and keep global project pointer.
EVT_MENU(OnSetPlayRegionToSelectionID, AdornedRulerPanel::OnSetPlayRegionToSelection) EVT_COMMAND(OnTogglePinnedStateID
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
ProjectFileIOMessage
Subscribe to ProjectFileIO to receive messages; always in idle time.
@ ProjectTitleChange
A normal occurrence.
IntSetting ProjectWindowY
bool CornersOnScreen(wxRect &r)
IntSetting ProjectWindowX
void GetDefaultWindowRect(wxRect *defRect)
IntSetting ProjectWindowWidth
BoolSetting ProjectWindowIconized
bool IsWindowAccessible(wxRect *requestedRect)
BoolSetting ProjectWindowMaximized
IntSetting ProjectWindowNormalHeight
IntSetting ProjectWindowHeight
IntSetting ProjectWindowNormalX
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized)
static ToolManager::TopPanelHook::Scope scope
int ScreenContaining(wxRect &r)
IntSetting ProjectWindowNormalWidth
IntSetting ProjectWindowNormalY
AUDACITY_DLL_API wxWindow & GetProjectPanel(AudacityProject &project)
Get the main sub-window of the project frame that displays track data.
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
const_reverse_iterator rend() const
const_iterator end() const
Container::value_type value_type
const_iterator begin() const
const_reverse_iterator rbegin() const
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
This specialization of Setting for bool adds a Toggle method to negate the saved value.
IteratorRange< ChannelIterator< ChannelType > > Channels()
Get range of channels with mutative access.
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
static int GetTotalHeight(const TrackList &list)
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
void SetMinimized(bool minimized)
static int GetChannelGroupHeight(const Track *pTrack)
void SetExpandedHeight(int height)
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
static CommandManager & Get(AudacityProject &project)
void UpdateMenus(bool checkActive=true)
CommandFlag GetUpdateFlags(bool quick=false) const
typename GlobalVariable< TopPanelHook, const std::function< wxWindow * >, nullptr, Options... >::Scope Scope
Specialization of Setting for int.
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
CallbackReturn Publish(const ProjectWindowDestroyedMessage &message)
Send a message to connected callbacks.
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
const wxString & GetProjectTitle() const
static ProjectFileIO & Get(AudacityProject &project)
static const StatusWidthFunctions & GetStatusWidthFunctions()
A top-level window associated with a project.
std::shared_ptr< AudacityProject > FindProject()
A top-level window associated with a project, and handling scrollbars and zooming.
void OnToolBarUpdate(wxCommandEvent &event)
wxSplitterWindow * mContainerWindow
int GetVerticalThumbSize() const
static ProjectWindow & Get(AudacityProject &project)
int GetTrackHeight(const Track &track)
void SetMinimized(Track &track, bool minimized)
void ShowHorizontalScrollbar(bool shown)
unsigned MinimumTrackHeight()
void UpdatePrefs() override
void OnActivate(wxActivateEvent &event)
void SetHorizontalThumbPosition(int viewStart)
void OnScrollLeftButton(wxScrollEvent &event)
void OnUpdateUI(wxUpdateUIEvent &event)
bool IsTrackMinimized(const Track &track)
wxPanel * GetTopPanel() noexcept
Top panel contains project-related controls and tools.
int GetVerticalRange() const
void SetVerticalScrollbar(int position, int thumbSize, int range, int pageSize, bool refresh)
int GetVerticalThumbPosition() const
static ProjectWindow * Find(AudacityProject *pProject)
Observer::Subscription mThemeChangeSubscription
wxWindow * GetTrackListWindow() noexcept
Track list window is the parent container for TrackPanel.
void OnMove(wxMoveEvent &event)
wxSplitterWindow * GetContainerWindow() noexcept
Container is a parent window for both effects panel and track list windows.
void SetNormalizedWindowState(wxRect pSizeAndLocation)
void OnViewportMessage(const ViewportMessage &message)
void OnMouseEvent(wxMouseEvent &event)
void SetVerticalThumbPosition(int viewStart)
~ProjectWindow() override
void SetChannelHeights(Track &track, unsigned height)
bool IsBeingDeleted() const
void OnScrollRightButton(wxScrollEvent &event)
Observer::Subscription mTitleChangeSubscription
int GetTotalHeight(const TrackList &trackList)
void OnScroll(wxScrollEvent &event)
std::unique_ptr< PlaybackScroller > mPlaybackScroller
wxStatusBar * CreateProjectStatusBar()
void OnSize(wxSizeEvent &event)
void UpdateStatusWidths()
void OnProjectTitleChange(ProjectFileIOMessage)
void ShowVerticalScrollbar(bool shown)
void SetHorizontalScrollbar(int position, int thumbSize, int range, int pageSize, bool refresh)
void OnThemeChange(struct ThemeChangeMessage)
int GetHorizontalThumbSize() const
void OnMenu(wxCommandEvent &event)
int GetHorizontalRange() const
bool IsIconized() const override
int GetHorizontalThumbPosition() const
void OnShow(wxShowEvent &event)
std::pair< int, int > ViewportSize() const
wxWindow * mTrackListWindow
ProjectWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, AudacityProject &project)
void OnIconize(wxIconizeEvent &event)
void MacShowUndockedToolbars(bool show)
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined */
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
Abstract base class for status bar fields.
wxColour & Colour(int iIndex)
Abstract base class for an object holding data associated with points on a time axis.
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
static TrackPanel & Get(AudacityProject &project)
static double GetPinnedHeadPositionPreference()
static ViewInfo & Get(AudacityProject &project)
A callback facade hiding GUI toolkit details.
void OnScrollLeftButton()
void SetCallbacks(std::unique_ptr< ViewportCallbacks > pCallbacks)
void OnScrollRightButton()
static Viewport & Get(AudacityProject &project)
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
AUDACITY_DLL_API unsigned MinimumTrackHeight()
void OnCloseWindow(wxCloseEvent &e)
constexpr int DEFAULT_WINDOW_HEIGHT
bool IsWindowValid(const ProjectWindow *window)
AttachedWindows::RegisteredFactory sProjectWindowKey
constexpr int DEFAULT_WINDOW_WIDTH
const char * end(const char *str) noexcept
static std::size_t Count(const AudacityProject *project)
Returns the number of fields in the registry. If project is no null, only visible fields are counted.
static void Visit(const StatusBarFieldRegistryVisitor &visitor)
Visits all fields in the registry in order.
static void OnSize(AudacityProject &project)
Handle OnSize event for all fields in the registry.
std::optional< PreferredSystemAppearance > appearance
bool IsTrackMinimized(const Track &track) override
~Adapter() override=default
void ShowHorizontalScrollbar(bool shown) override
void SetVerticalScrollbar(int position, int thumbSize, int range, int pageSize, bool refresh) override
void SetHorizontalScrollbar(int position, int thumbSize, int range, int pageSize, bool refresh) override
int GetHorizontalRange() const override
int GetVerticalThumbSize() const override
wxWeakRef< ProjectWindow > mwWindow
int GetTrackHeight(const Track &track) override
void ShowVerticalScrollbar(bool shown) override
int GetHorizontalThumbPosition() const override
unsigned MinimumTrackHeight() override
int GetTotalHeight(const TrackList &trackList) override
void SetVerticalThumbPosition(int viewStart) override
void SetMinimized(Track &track, bool minimized) override
Adapter(ProjectWindow &window)
int GetVerticalRange() const override
void SetChannelHeights(Track &track, unsigned height) override
void SetToDefaultSize() override
int GetVerticalThumbPosition() const override
void SetHorizontalThumbPosition(int viewStart) override
std::pair< int, int > ViewportSize() const override
Width and height in pixels of proper viewport area (excluding scrollbars)
int GetHorizontalThumbSize() const override