]>
git.saurik.com Git - wxWidgets.git/blob - utils/screenshotgen/src/autocapture.cpp
48cadb86ef71e2bb011ca1d8d2136edcc1143d4c
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
21 #include <wx/filename.h>
22 #include "autocapture.h"
29 // ----------------------------------------------------------------------------
30 // AutoCaptureMechanism
31 // ----------------------------------------------------------------------------
34 void AutoCaptureMechanism :: Delay ( int seconds
)
40 clock_t start
= clock ();
41 while ( clock () - start
< CLOCKS_PER_SEC
* seconds
)
46 wxBitmap
AutoCaptureMechanism :: Capture ( int x
, int y
, int width
, int height
, int delay
)
48 // Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
51 // wxExecute(_T("screencapture -x ") + tempfile, wxEXEC_SYNC);
53 char captureCommand
[ 80 ] = "" ; // a reasonable max size is 80
55 sprintf ( captureCommand
, "sleep %d ; %s " , delay
, "screencapture -x /tmp/wx_screen_capture.png" );
57 system ( captureCommand
);
61 if ( delay
) Delay ( delay
);
65 fullscreen
= wxBitmap ( _T ( "/tmp/wx_screen_capture.png" ), wxBITMAP_TYPE_PNG
);
67 while (! fullscreen
. IsOk ());
69 wxBitmap screenshot
= fullscreen
. GetSubBitmap ( wxRect ( x
, y
, width
, height
));
71 // to prevent loading the old screenshot next time
72 system ( "rm /tmp/wx_screen_capture.png" );
74 #else // Under other paltforms, take a real screenshot
76 // Create a DC for the whole screen area
79 // Create a Bitmap that will later on hold the screenshot image
80 // Note that the Bitmap must have a size big enough to hold the screenshot
81 // -1 means using the current default colour depth
82 wxBitmap
screenshot ( width
, height
, - 1 );
84 // Create a memory DC that will be used for actually taking the screenshot
87 // Tell the memory DC to use our Bitmap
88 // all drawing action on the memory DC will go to the Bitmap now
89 memDC
. SelectObject ( screenshot
);
91 // Blit (in this case copy) the actual screen on the memory DC
92 // and thus the Bitmap
93 memDC
. Blit ( 0 , // Copy to this X coordinate
94 0 , // Copy to this Y coordinate
95 width
, // Copy this width
96 height
, // Copy this height
97 & dcScreen
, // From where do we copy?
98 x
, // What's the X offset in the original DC?
99 y
// What's the Y offset in the original DC?
102 // Select the Bitmap out of the memory DC by selecting a new
103 // uninitialized Bitmap
104 memDC
. SelectObject ( wxNullBitmap
);
105 #endif // #ifdef __WXMAC__
111 wxBitmap
AutoCaptureMechanism :: Capture ( wxRect rect
, int delay
)
113 wxPoint origin
= rect
. GetPosition ();
114 return Capture ( origin
. x
, origin
. y
, rect
. GetWidth (), rect
. GetHeight (), delay
);
117 void AutoCaptureMechanism :: CaptureAll ()
119 // start from the first page
120 m_notebook
-> SetSelection ( 0 );
123 for ( ControlList :: iterator it
= m_controlList
. begin ();
124 it
!= m_controlList
. end ();
129 if ( ctrl
. flag
== AJ_TurnPage
) // Turn to next page
131 m_notebook
-> SetSelection ( m_notebook
-> GetSelection () + 1 );
136 // create the screenshot
137 wxBitmap screenshot
= Capture ( ctrl
);
138 if ( ctrl
. flag
& AJ_Union
)
139 screenshot
= Union ( screenshot
, Capture (*(++ it
)));
142 Save ( screenshot
, ctrl
. name
);
146 wxBitmap
AutoCaptureMechanism :: Capture ( Control
& ctrl
)
148 if ( ctrl
. name
== wxT ( "" )) // no manual specification for the control name
150 // Get its name from wxRTTI
151 ctrl
. name
= ctrl
. ctrl
-> GetClassInfo ()-> GetClassName ();
156 // for drop-down controls we need the help of the user
157 if ( ctrl
. flag
& AJ_Dropdown
)
159 wxString caption
= _ ( "Drop-down screenshot..." );
161 wxString :: Format ( _ ( "Do you wish to capture the drop-down list of ' %s ' ? \n\n If you click YES you must drop-down the list of ' %s ' in 3 seconds after closing this message box. \n If you click NO the screenshot for this control won't contain its drop-down list." ),
162 ctrl
. name
, ctrl
. name
);
164 choice
= wxMessageBox ( msg
, caption
, wxYES_NO
, m_notebook
);
166 #ifndef __WXMAC__ //not __WXMAC__
167 if ( choice
== wxYES
) Delay ( 3 );
171 wxRect rect
= GetRect ( ctrl
. ctrl
, ctrl
. flag
);
173 // Do some rect adjust so it can include the dropdown list;
174 // currently this only works well under MSW; not adjusted for Linux and Mac OS
175 if ( ctrl
. flag
& AJ_Dropdown
&& choice
== wxYES
)
178 int h
= rect
. GetHeight ();
179 rect
. SetHeight ( h
* 4 );
183 // cut off "wx" and change the name into lowercase.
184 // e.g. wxButton will have a name of "button" at the end
185 ctrl
. name
. StartsWith ( _T ( "wx" ), &( ctrl
. name
));
186 ctrl
. name
. MakeLower ();
188 // AD-HOC FIX for wxHyperlink
189 if ( ctrl
. name
== "generichyperlinkctrl" )
190 ctrl
. name
= "hyperlinkctrl" ;
192 // take the screenshot
193 wxBitmap screenshot
= Capture ( rect
);
195 if ( ctrl
. flag
& AJ_RegionAdjust
)
201 wxBitmap
AutoCaptureMechanism :: Union ( wxBitmap pic1
, wxBitmap pic2
)
203 int w1
, w2
, h1
, h2
, w
, h
;
204 w1
= pic1
. GetWidth ();
205 w2
= pic2
. GetWidth ();
206 h1
= pic1
. GetHeight ();
207 h2
= pic2
. GetHeight ();
209 const int gap_between
= 20 ;
211 w
= ( w1
>= w2
) ? w1
: w2
;
212 h
= h1
+ h2
+ gap_between
;
214 wxBitmap
result ( w
, h
, - 1 );
217 dstDC
. SelectObject ( result
);
219 dstDC
. DrawBitmap ( pic1
, 0 , 0 , false );
220 dstDC
. DrawBitmap ( pic2
, 0 , h1
+ gap_between
, false );
222 dstDC
. SelectObject ( wxNullBitmap
);
225 wxBitmap
mask ( w
, h
, 1 );
226 maskDC
. SelectObject ( mask
);
228 maskDC
. SetPen (* wxTRANSPARENT_PEN
);
229 maskDC
. SetBrush (* wxBLACK_BRUSH
);
230 maskDC
. DrawRectangle ( 0 , 0 , w
+ 1 , h
+ 1 );
232 maskDC
. SetBrush (* wxWHITE_BRUSH
);
233 maskDC
. DrawRectangle ( 0 , 0 , w1
, h1
);
234 maskDC
. DrawRectangle ( 0 , h1
+ gap_between
, w2
, h2
);
235 maskDC
. SelectObject ( wxNullBitmap
);
237 result
. SetMask ( new wxMask ( mask
));
242 void AutoCaptureMechanism :: Save ( wxBitmap screenshot
, wxString fileName
)
244 // make sure m_dir exists
245 if (! wxDirExists ( m_dir
))
248 wxFileName
fullFileName ( m_dir
, fileName
+ ".png" );
250 // do not overwrite already existing files with this name
251 while ( fullFileName
. FileExists ())
252 fullFileName
. SetName ( fullFileName
. GetName () + "_" );
254 // save the screenshot as a PNG
255 screenshot
. SaveFile ( fullFileName
. GetFullPath (), wxBITMAP_TYPE_PNG
);
258 wxRect
AutoCaptureMechanism :: GetRect ( wxWindow
* ctrl
, int flag
)
260 if ( flag
& AJ_RegionAdjust
)
262 wxWindow
* parent
= ctrl
-> GetParent ();
263 wxSizer
* sizer
= parent
-> GetSizer ();
270 +---------+-----------+---------+
272 +---------+-----------+---------+
273 | label | ctrl | label |
274 +---------+-----------+---------+
276 +---------+-----------+---------+
279 m_grid
= new wxFlexGridSizer ( 3 , 3 , m_border
, m_border
);
283 for ( int i
= 0 ; i
< 4 ; ++ i
)
284 l
[ i
] = new wxStaticText ( parent
, wxID_ANY
, wxT ( " " ));
287 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
289 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
291 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
293 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
297 parent
-> SetSizer ( sizer
);
303 return wxRect ( l
[ 0 ]-> GetScreenRect (). GetBottomRight (),
304 l
[ 3 ]-> GetScreenRect (). GetTopLeft ());
307 else // Actually it won't get here working with the current guiframe.h/guiframe.cpp
309 return ctrl
-> GetScreenRect (). Inflate ( m_border
);
314 return ctrl
-> GetScreenRect (). Inflate ( m_border
);
318 void AutoCaptureMechanism :: PutBack ( wxWindow
* ctrl
)
320 m_grid
-> Detach ( ctrl
);
322 wxSizerItemList children
= m_grid
-> GetChildren ();
324 for ( wxSizerItemList :: iterator it
= children
. begin (); it
!= children
. end (); ++ it
)
326 wxSizerItem
* item
= * it
;
327 if ( item
-> IsWindow ()) delete (* it
)-> GetWindow ();
330 wxSizer
* sizer
= ctrl
-> GetParent ()-> GetSizer ();
331 sizer
-> Detach ( m_grid
);