]>
git.saurik.com Git - wxWidgets.git/blob - utils/screenshotgen/src/autocapture.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: autocapture.cpp
3 // Purpose: Implement wxCtrlMaskOut class
4 // Author: Utensil Candel (UtensilCandel@@gmail.com)
6 // Licence: wxWindows license
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx/wx.h".
10 #include "wx/wxprec.h"
16 // for all others, include the necessary headers wxWidgets headers)
22 #include <wx/notebook.h>
24 #include "autocapture.h"
31 // ----------------------------------------------------------------------------
32 // AutoCaptureMechanism
33 // ----------------------------------------------------------------------------
36 wxString
AutoCaptureMechanism :: default_dir
= _T ( "screenshots" );
39 wxString
AutoCaptureMechanism :: GetDefaultDirectoryAbsPath ()
41 wxFileName output
= wxFileName :: DirName ( GetDefaultDirectory ());
42 output
. MakeAbsolute ();
43 return output
. GetFullPath ();
47 void AutoCaptureMechanism :: Delay ( int seconds
)
49 // TODO: Switch this to use wxTimer.
52 clock_t start
= clock ();
53 while ( clock () - start
< CLOCKS_PER_SEC
* seconds
)
58 wxBitmap
AutoCaptureMechanism :: Capture ( int x
, int y
, int width
, int height
, int delay
)
60 // Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
63 // wxExecute(_T("screencapture -x ") + tempfile, wxEXEC_SYNC);
65 char captureCommand
[ 80 ] = "" ; // a reasonable max size is 80
67 sprintf ( captureCommand
, "sleep %d ; %s " , delay
, "screencapture -x /tmp/wx_screen_capture.png" );
69 system ( captureCommand
);
73 if ( delay
) Delay ( delay
);
77 fullscreen
= wxBitmap ( _T ( "/tmp/wx_screen_capture.png" ), wxBITMAP_TYPE_PNG
);
79 while (! fullscreen
. IsOk ());
81 wxBitmap screenshot
= fullscreen
. GetSubBitmap ( wxRect ( x
, y
, width
, height
));
83 // to prevent loading the old screenshot next time
84 system ( "rm /tmp/wx_screen_capture.png" );
86 #else // Under other paltforms, take a real screenshot
88 if ( delay
) Delay ( delay
);
90 // Create a DC for the whole screen area
93 // Create a Bitmap that will later on hold the screenshot image
94 // Note that the Bitmap must have a size big enough to hold the screenshot
95 // -1 means using the current default colour depth
96 wxBitmap
screenshot ( width
, height
, - 1 );
98 // Create a memory DC that will be used for actually taking the screenshot
101 // Tell the memory DC to use our Bitmap
102 // all drawing action on the memory DC will go to the Bitmap now
103 memDC
. SelectObject ( screenshot
);
105 // Blit (in this case copy) the actual screen on the memory DC
106 // and thus the Bitmap
107 memDC
. Blit ( 0 , // Copy to this X coordinate
108 0 , // Copy to this Y coordinate
109 width
, // Copy this width
110 height
, // Copy this height
111 & dcScreen
, // From where do we copy?
112 x
, // What's the X offset in the original DC?
113 y
// What's the Y offset in the original DC?
116 // Select the Bitmap out of the memory DC by selecting a new
117 // uninitialized Bitmap
118 memDC
. SelectObject ( wxNullBitmap
);
119 #endif // #ifdef __WXMAC__
125 wxBitmap
AutoCaptureMechanism :: Capture ( wxRect rect
, int delay
)
127 wxPoint origin
= rect
. GetPosition ();
128 return Capture ( origin
. x
, origin
. y
, rect
. GetWidth (), rect
. GetHeight (), delay
);
132 void AutoCaptureMechanism :: Save ( wxBitmap screenshot
, wxString fileName
)
134 // make sure default_dir exists
135 if (! wxDirExists ( default_dir
))
136 wxMkdir ( default_dir
);
138 wxFileName
fullFileName ( default_dir
, fileName
+ ".png" );
140 // do not overwrite already existing files with this name
141 while ( fullFileName
. FileExists ())
142 fullFileName
. SetName ( fullFileName
. GetName () + "_" );
144 // save the screenshot as a PNG
145 screenshot
. SaveFile ( fullFileName
. GetFullPath (), wxBITMAP_TYPE_PNG
);
148 void AutoCaptureMechanism :: CaptureAll ()
150 // start from the first page
151 m_notebook
-> SetSelection ( 0 );
154 for ( ControlList :: iterator it
= m_controlList
. begin ();
155 it
!= m_controlList
. end ();
160 if ( ctrl
. flag
== AJ_TurnPage
) // Turn to next page
162 m_notebook
-> SetSelection ( m_notebook
-> GetSelection () + 1 );
167 // create the screenshot
168 wxBitmap screenshot
= Capture ( ctrl
);
170 if ( ctrl
. flag
& AJ_Union
)
172 // union screenshots until AJ_UnionEnd
176 it
-> name
= ctrl
. name
; //preserving the name
177 screenshot
= Union ( screenshot
, Capture (* it
));
179 while (!( it
-> flag
& AJ_UnionEnd
));
183 Save ( screenshot
, ctrl
. name
);
187 wxBitmap
AutoCaptureMechanism :: Capture ( Control
& ctrl
)
189 // no manual specification for the control name
190 // or name adjustment is disabled globally
191 if ( ctrl
. name
== _T ( "" ) || m_flag
& AJ_DisableNameAdjust
)
193 // Get its name from wxRTTI
194 ctrl
. name
= ctrl
. ctrl
-> GetClassInfo ()-> GetClassName ();
199 wxRect rect
= GetRect ( ctrl
. ctrl
, ctrl
. flag
);
201 if ( ctrl
. flag
& AJ_Dropdown
&& !( m_flag
& AJ_DisableDropdown
))
203 // for drop-down controls we need the help of the user
204 wxString caption
= _ ( "Drop-down screenshot..." );
206 wxString :: Format ( _ ( "Do you wish to capture the drop-down list of ' %s ' ? \n\n If YES, please drop down the list of ' %s ' in 5 seconds after closing this message box. \n If NO, the screenshot for this control won't contain its drop-down list." ),
207 ctrl
. name
, ctrl
. name
);
209 choice
= wxMessageBox ( msg
, caption
, wxYES_NO
, m_notebook
);
214 ctrl
. ctrl
-> SetCursor ( wxCursor ( wxCURSOR_HAND
));
216 // Do some rect adjust so it can include the dropdown list
217 // This adjust isn't pretty, but it works fine on all three paltforms.
218 // Looking forward to a better solution
219 int h
= rect
. GetHeight ();
220 rect
. SetHeight ( h
* 4 );
224 // cut off "wx" and change the name into lowercase.
225 // e.g. wxButton will have a name of "button" at the end
226 ctrl
. name
. StartsWith ( _T ( "wx" ), &( ctrl
. name
));
227 ctrl
. name
. MakeLower ();
229 // take the screenshot
230 wxBitmap screenshot
= Capture ( rect
, ( choice
== wxYES
)? 5 : 0 );
232 if ( choice
== wxYES
) ctrl
. ctrl
-> SetCursor ( wxNullCursor
);
234 if ( ctrl
. flag
& AJ_RegionAdjust
)
240 wxBitmap
AutoCaptureMechanism :: Union ( wxBitmap pic1
, wxBitmap pic2
)
242 int w1
, w2
, h1
, h2
, w
, h
;
243 w1
= pic1
. GetWidth ();
244 w2
= pic2
. GetWidth ();
245 h1
= pic1
. GetHeight ();
246 h2
= pic2
. GetHeight ();
248 const int gap_between
= 20 ;
250 w
= ( w1
>= w2
) ? w1
: w2
;
251 h
= h1
+ h2
+ gap_between
;
253 wxBitmap
result ( w
, h
, - 1 );
256 dstDC
. SelectObject ( result
);
258 dstDC
. SetPen (* wxTRANSPARENT_PEN
);
259 dstDC
. SetBrush (* wxWHITE_BRUSH
);
260 dstDC
. DrawRectangle (- 1 , - 1 , w
+ 1 , h
+ 1 );
261 dstDC
. DrawBitmap ( pic1
, 0 , 0 , false );
262 dstDC
. DrawBitmap ( pic2
, 0 , h1
+ gap_between
, false );
264 dstDC
. SelectObject ( wxNullBitmap
);
269 wxRect
AutoCaptureMechanism :: GetRect ( wxWindow
* ctrl
, int flag
)
271 if ( !( m_flag
& AJ_DisableRegionAdjust
) && ( flag
& AJ_RegionAdjust
)
272 || ( m_flag
& AJ_AlwaysRegionAdjust
) )
274 wxWindow
* parent
= ctrl
-> GetParent ();
275 wxSizer
* sizer
= parent
-> GetSizer ();
277 //The assertion won't fail if controls are still managed by wxSizer, and it's unlikely to
278 //change in the future.
280 "The GUI that AutoCaptureMechanism working with doesn't manage controls with wxSizer" );
285 +---------+-----------+---------+
287 +---------+-----------+---------+
288 | label | ctrl | label |
289 +---------+-----------+---------+
291 +---------+-----------+---------+
294 m_grid
= new wxFlexGridSizer ( 3 , 3 , m_margin
, m_margin
);
298 for ( int i
= 0 ; i
< 4 ; ++ i
)
299 l
[ i
] = new wxStaticText ( parent
, wxID_ANY
, _T ( " " ));
302 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, _T ( " " )));
304 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, _T ( " " )));
305 m_grid
-> Add ( ctrl
, 1 , wxEXPAND
);
306 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, _T ( " " )));
308 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, _T ( " " )));
312 parent
-> SetSizer ( sizer
);
318 return wxRect ( l
[ 0 ]-> GetScreenRect (). GetBottomRight (),
319 l
[ 3 ]-> GetScreenRect (). GetTopLeft ());
323 return ctrl
-> GetScreenRect (). Inflate ( m_margin
);
327 void AutoCaptureMechanism :: PutBack ( wxWindow
* ctrl
)
331 m_grid
-> Detach ( ctrl
);
333 wxSizerItemList children
= m_grid
-> GetChildren ();
335 for ( wxSizerItemList :: iterator it
= children
. begin (); it
!= children
. end (); ++ it
)
337 wxSizerItem
* item
= * it
;
338 if ( item
-> IsWindow ()) delete (* it
)-> GetWindow ();
341 wxSizer
* sizer
= ctrl
-> GetParent ()-> GetSizer ();
343 //The assertion won't fail if controls are still managed by wxSizer, and it's unlikely to
344 //change in the future.
346 "The GUI that AutoCaptureMechanism working with doesn't manage controls with wxSizer" );
348 sizer
-> Detach ( m_grid
);