29#include <wx/toplevel.h>
30#include <wx/dcscreen.h>
31#include <wx/dcmemory.h>
32#include <wx/settings.h>
37#include "../AdornedRulerPanel.h"
38#include "../TrackPanel.h"
39#include "../toolbars/ToolManager.h"
45#include "../widgets/VetoDialogHook.h"
49#include "../CommonCommandFlags.h"
61 {
wxT(
"FullWindow"),
XO(
"Full Window") },
62 {
wxT(
"WindowPlus"),
XO(
"Window Plus") },
66 {
XO(
"Scriptables") },
67 {
XO(
"Preferences") },
71 {
wxT(
"FirstTrack"),
XO(
"First Track") },
72 {
wxT(
"FirstTwoTracks"),
XO(
"First Two Tracks") },
73 {
wxT(
"FirstThreeTracks"),
XO(
"First Three Tracks") },
74 {
wxT(
"FirstFourTracks"),
XO(
"First Four Tracks") },
75 {
wxT(
"SecondTrack"),
XO(
"Second Track") },
76 {
wxT(
"TracksPlus"),
XO(
"Tracks Plus") },
77 {
wxT(
"FirstTrackPlus"),
XO(
"First Track Plus") },
78 {
wxT(
"AllTracks"),
XO(
"All Tracks") },
79 {
wxT(
"AllTracksPlus"),
XO(
"All Tracks Plus") },
101 mSymbols.emplace_back( pBar->GetSection(), pBar->GetLabel() );
116 {
XC(
"White",
"color") },
132 S.Define(
mPath,
wxT(
"Path"), wxString{});
133 S.DefineEnum(
mWhat,
wxT(
"CaptureWhat"),
kwindow, strings.data(), strings.size() );
140 {
return VisitSettings<false>(
S); }
143 {
return VisitSettings<true>(
S); }
150 S.StartMultiColumn(2, wxALIGN_CENTER);
153 S.TieChoice(
XXO(
"Capture What:"),
155 S.TieChoice(
XXO(
"Background:"),
174 wxWindow * pWin =
dynamic_cast<wxWindow*
>(
event.GetEventObject());
191 wxWindow *front = NULL;
194 for (
auto & win : wxTopLevelWindows)
196 win = wxGetTopLevelParent(win);
197 if (win !=
mIgnore && win != proj && win->IsShown()) {
203 if (!front || !front->IsTopLevel()) {
204 return (wxTopLevelWindow *)proj;
207 return (wxTopLevelWindow *)front;
224 using namespace std::chrono;
226 for (cnt = 10; cnt && !wxTheApp->Yield(
true); cnt--)
227 std::this_thread::sleep_for(10ms);
228 std::this_thread::sleep_for(200ms);
229 for (cnt = 10; cnt && !wxTheApp->Yield(
true); cnt--)
230 std::this_thread::sleep_for(10ms);
235 const wxString &filename,
236 wxWindow *window, wxRect r,
240 int height = r.height;
244 wxWindow * win = window;
245 wxTopLevelWindow * top_win=
nullptr;
246 if( !window->IsTopLevel())
247 win = wxGetTopLevelParent(window);
248 top_win =
dynamic_cast<wxTopLevelWindow*
>( win );
256 int screenW, screenH;
257 wxDisplaySize(&screenW, &screenH);
262 wxBitmap full(screenW, screenH, 24);
267#if defined(__WXMAC__) && !wxCHECK_VERSION(3, 0, 0)
268 full = DoGetAsBitmap(NULL);
272 fullDC.SelectObject(full);
273 fullDC.Blit(0, 0, screenW, screenH, &screenDC, 0, 0);
274 fullDC.SelectObject(wxNullBitmap);
281 if (window && window->GetParent() && !window->IsTopLevel()) {
282 r.SetPosition(window->GetParent()->ClientToScreen(r.GetPosition()));
286 r.Intersect(wxRect(0, 0, screenW, screenH));
289 wxBitmap part = full.GetSubBitmap(r);
295 wxBitmap back(width + b.width, height + b.height);
296 fullDC.SelectObject(back);
298 fullDC.SetBackground(wxBrush(
mBackColor, wxBRUSHSTYLE_SOLID));
301 fullDC.DrawBitmap(part, b.x, b.y);
302 fullDC.SelectObject(wxNullBitmap);
308 wxImage image = part.ConvertToImage();
311 if (image.SaveFile(filename)) {
313 context.
Status( wxString::Format(
_(
"Saved %s"), filename ),
true );
317 wxString::Format(
_(
"Error trying to save file: %s"), filename ) );
340 w->ClientToScreen(&x, &y);
341 w->GetParent()->ScreenToClient(&x, &y);
342 w->GetClientSize(&width, &height);
344 bool result =
Capture(context,
name, w, wxRect(x, y, width, height));
356 wxWindow *win,
const wxString &FileName)
361 win->ClientToScreen(&x, &y);
362 win->GetParent()->ScreenToClient(&x, &y);
363 win->GetClientSize(&width, &height);
365 return Capture(context, FileName, win, wxRect(x, y, width, height));
383 using namespace std::chrono;
384 wxDialog * pDlg =
dynamic_cast<wxDialog*
>(pWin);
386 wxLogDebug(
"Event from bogus dlg" );
390 wxPoint Pos = pDlg->GetScreenPosition();
391 wxSize Siz = pDlg->GetSize();
392 wxString Title = pDlg->GetTitle();
396 Title.Replace(
"/",
"" );
397 Title.Replace(
":",
"" );
400 wxLogDebug(
"Taking screenshot of window %s (%i,%i,%i,%i)", Name,
401 Pos.x, Pos.y, Siz.x, Siz.y );
403 std::this_thread::sleep_for(400ms);
406 Capture( context, Name, pDlg, wxRect((
int)Pos.x+7, (
int)Pos.y, (
int)Siz.x-14, (
int)Siz.y-7) );
409 wxCommandEvent Evt( wxEVT_BUTTON, wxID_CANCEL );
410 pDlg->GetEventHandler()->AddPendingEvent( Evt );
417 using namespace std::chrono;
429 const int nPrefsPages = 19;
431 for(
int i=0;i<nPrefsPages;i++){
442 wxLogDebug(
"Command %s not found",
Command.GET() );
446 std::this_thread::sleep_for(200ms);
457#define TRICKY_CAPTURE
458#define CAPTURE_NYQUIST_TOO
470 "Spectral Edit Parametric EQ...",
471 "Spectral Edit Shelves...",
477 "Bass and Treble...",
486 "Filter Curve EQ...",
498 "Sliding Stretch...",
499 "Truncate Silence...",
502#ifdef CAPTURE_NYQUIST_TOO
503 "Adjustable Fade...",
506 "Crossfade Tracks...",
508 "High Pass Filter...",
510 "Low Pass Filter...",
512 "Nyquist Effects Prompt...",
515 "Vocal Reduction and Isolation...",
525#ifdef CAPTURE_NYQUIST_TOO
529 "Sample Data Import...",
533#ifdef CAPTURE_NYQUIST_TOO
536 "Regular Interval Labels...",
537 "Sample Data Export...",
584 using namespace std::chrono;
597 for(
size_t i=0;i<Commands.size();i++){
604 wxLogDebug(
"Command %s not found", Str);
608 std::this_thread::sleep_for(200ms);
615 if( path.EndsWith(
".png" ) )
619 wxFileName prefixPath;
620 prefixPath.AssignDir(path);
621 wxString prefix = prefixPath.GetPath
622 (wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR);
627 filename.Printf(
wxT(
"%s%s%03d.png"),
628 prefix, basename, i);
630 }
while (::wxFileExists(filename));
666 w->ClientToScreen(&x, &y);
667 w->GetClientSize(&width, &height);
668 return wxRect( x,y,width,height);
673 wxRect r = w->GetRect();
674 r.SetPosition(w->GetScreenPosition());
675 r = w->GetScreenRect();
677#if defined(__WXGTK__)
679 r.width += (wxSystemSettings::GetMetric(wxSYS_BORDER_X, w) * 2);
680 r.height += wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, w) +
681 wxSystemSettings::GetMetric(wxSYS_BORDER_Y, w);
687 r.x = (r.x - b.x) >= 0 ? (r.x - b.x): 0;
688 r.y = (r.y - b.y) >= 0 ? (r.y - b.y): 0;
690 r.height += b.height;
698 wxDisplaySize(&width, &height);
700 return wxRect( 0,0,width,height);
710 panel->ClientToScreen(&x, &y);
711 panel->GetParent()->ScreenToClient(&x, &y);
712 panel->GetClientSize(&width, &height);
713 return wxRect(x, y, width, height + h);
720 ruler->ClientToScreen(&x, &y);
721 ruler->GetParent()->ScreenToClient(&x, &y);
722 ruler->GetClientSize(&width, &height);
723 height =
ruler->GetRulerHeight();
724 return wxRect( x, y, width, height);
731 panel->ClientToScreen(&x, &y);
732 panel->GetParent()->ScreenToClient(&x, &y);
733 panel->GetClientSize(&width, &height);
735 return wxRect( x, y, width, height);
745 panel.GetParent()->ScreenToClient(
746 panel.ClientToScreen(
747 rect.GetPosition())));
757 wxRect r = FindRectangle( *panel, *t );
761 return wxRect( 0,0,0,0);
768 (
wxT(
"-") + w->GetTitle() +
wxT(
"-")));
790 w->ClientToScreen(&x1, &y1);
791 panel->ClientToScreen(&x2, &y2);
793 wxPoint p( x2-x1, y2-y1);
829 r.SetTop( r.GetTop() -
ruler->GetRulerHeight() );
830 r.SetHeight( r.GetHeight() +
ruler->GetRulerHeight() );
835 r.SetTop( r.GetTop() -
ruler->GetRulerHeight() );
836 r.SetHeight( r.GetHeight() +
ruler->GetRulerHeight() );
861 r.SetTop( r.GetTop() -
ruler->GetRulerHeight() );
862 r.SetHeight( r.GetHeight() +
ruler->GetRulerHeight() );
889 Command(
wxT(
"Screenshot"),
XXO(
"Screenshot (short format)..."),
891 wxT(
"Optional/Extra/Part2/Scriptables2")
AUDACITY_DLL_API std::weak_ptr< AudacityProject > GetActiveProject()
Handle changing of active project and keep global project pointer.
constexpr CommandFlag AlwaysEnabledFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
const TranslatableString name
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
accessors for certain important windows associated with each project
static const AttachedProjectObjects::RegisteredFactory manager
static AudacityProject * pIdleHandlerProject
static const EnumValueSymbol kBackgroundStrings[ScreenshotCommand::nBackgrounds]
void IdleHandler(wxIdleEvent &event)
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
declares abstract base class Track, TrackList, and iterators over TrackList
This is an Audacity Specific ruler panel which additionally has border, selection markers,...
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
virtual void Error(const wxString &message) const
virtual void Status(const wxString &message, bool bFlush=false) const
AudacityProject & project
CommandManager implements a system for organizing all user-callable commands.
static CommandManager & Get(AudacityProject &project)
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
typename GlobalVariable< VetoDialogHook, const std::function< bool(wxDialog *) >, nullptr, Options... >::Scope Scope
An explicitly nonlocalized string, not meant for the user to see.
Generates classes whose instances register items at construction.
Implements a command for capturing various areas of the screen or project window. It's one big if-els...
bool CaptureToolbar(const CommandContext &Context, ToolManager *man, Identifier type, const wxString &name)
static ScreenshotCommand * mpShooter
static bool MayCapture(wxDialog *pDlg)
wxRect GetBackgroundRect()
wxRect GetTracksRect(TrackPanel *panel)
void CaptureScriptables(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
void CaptureWindowOnIdle(const CommandContext &context, wxWindow *pWin)
static void SetIdleHandler(AudacityProject &project)
static void(* mIdleHandler)(wxIdleEvent &event)
wxRect GetRulerRect(AdornedRulerPanel *ruler)
bool VisitSettings(SettingsVisitorBase< Const > &S)
void PopulateOrExchange(ShuttleGui &S) override
EnumValueSymbols kCaptureWhatStrings()
bool Capture(const CommandContext &Context, const wxString &basename, wxWindow *window, wxRect rect, bool bg=false)
wxString WindowFileName(AudacityProject *proj, wxTopLevelWindow *w)
wxString MakeFileName(const wxString &path, const wxString &basename)
wxTopLevelWindow * GetFrontWindow(AudacityProject *project)
wxRect GetPanelRect(TrackPanel *panel)
wxRect GetTrackRect(AudacityProject *pProj, TrackPanel *panel, int n)
bool CaptureDock(const CommandContext &Context, wxWindow *win, const wxString &fileName)
void CaptureEffects(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
EnumValueSymbols mSymbols
wxRect GetWindowRect(wxTopLevelWindow *w)
void CapturePreferences(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
wxRect GetFullWindowRect(wxTopLevelWindow *w)
bool Apply(const CommandContext &context) override
static const ComponentInterfaceSymbol Symbol
void CaptureCommands(const CommandContext &Context, const wxArrayStringEx &Commands)
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Abstract base class for an object holding data associated with points on a time axis.
static TrackList & Get(AudacityProject &project)
The TrackPanel class coordinates updates and operations on the main part of the screen which contains...
AdornedRulerPanel * GetRuler()
static TrackPanel & Get(AudacityProject &project)
wxRect FindFocusedTrackRect(const Track *target)
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
AUDACITY_DLL_API bool HandleTextualCommand(const CommandID &Str, const CommandContext &context, CommandFlag flags, bool alwaysEnabled)
AUDACITY_DLL_API void OnAudacityCommand(const CommandContext &ctx)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
BuiltinCommandsModule::Registration< ScreenshotCommand > reg
static CommandContext::TargetFactory::SubstituteInUnique< InteractiveOutputTargets > scope
void copy(const T *src, T *dst, int32_t n)