]>
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 licence
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx/wx.h".
10 #include "wx/wxprec.h"
16 #include "autocapture.h"
22 #include "wx/bitmap.h"
23 #include "wx/filename.h"
24 #include "wx/notebook.h"
33 // ----------------------------------------------------------------------------
34 // AutoCaptureMechanism
35 // ----------------------------------------------------------------------------
37 AutoCaptureMechanism :: AutoCaptureMechanism ( wxNotebook
* notebook
,
39 : m_notebook ( notebook
),
47 wxString
AutoCaptureMechanism :: default_dir
= wxT ( "screenshots" );
50 wxString
AutoCaptureMechanism :: GetDefaultDirectoryAbsPath ()
52 wxFileName output
= wxFileName :: DirName ( GetDefaultDirectory ());
53 output
. MakeAbsolute ();
54 return output
. GetFullPath ();
58 void AutoCaptureMechanism :: Delay ( int seconds
)
60 // TODO: Switch this to use wxTimer.
63 clock_t start
= clock ();
64 while ( clock () - start
< ( clock_t ) CLOCKS_PER_SEC
* seconds
)
69 bool AutoCaptureMechanism :: Capture ( wxBitmap
* bitmap
, int x
, int y
,
70 int width
, int height
, int delay
)
72 // Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
75 // wxExecute(wxT("screencapture -x ") + tempfile, wxEXEC_SYNC);
77 char captureCommand
[ 80 ] = "" ; // a reasonable max size is 80
78 sprintf ( captureCommand
, "sleep %d ; %s " , delay
, "screencapture -x /tmp/wx_screen_capture.png" );
79 system ( captureCommand
);
81 if ( delay
) Delay ( delay
);
86 fullscreen
= wxBitmap ( wxT ( "/tmp/wx_screen_capture.png" ), wxBITMAP_TYPE_PNG
);
88 while (! fullscreen
. IsOk ());
90 * bitmap
= fullscreen
. GetSubBitmap ( wxRect ( x
, y
, width
, height
));
92 // to prevent loading the old screenshot next time
93 system ( "rm /tmp/wx_screen_capture.png" );
97 #else // Under other paltforms, take a real screenshot
99 if ( delay
) Delay ( delay
);
101 // Create a DC for the whole screen area
104 bitmap
-> Create ( width
, height
);
106 // Create a memory DC that will be used for actually taking the screenshot
108 memDC
. SelectObject ((* bitmap
));
111 // Blit (in this case copy) the actual screen on the memory DC
112 // and thus the Bitmap
113 memDC
. Blit ( 0 , // Copy to this X coordinate
114 0 , // Copy to this Y coordinate
115 width
, // Copy this width
116 height
, // Copy this height
117 & dcScreen
, // From where do we copy?
118 x
, // What's the X offset in the original DC?
119 y
// What's the Y offset in the original DC?
122 // Select the Bitmap out of the memory DC by selecting a new
123 // uninitialized Bitmap
124 memDC
. SelectObject ( wxNullBitmap
);
125 #endif // #ifdef __WXMAC__
131 bool AutoCaptureMechanism :: Capture ( wxBitmap
* bitmap
, wxRect rect
, int delay
)
133 wxPoint origin
= rect
. GetPosition ();
134 return Capture ( bitmap
, origin
. x
, origin
. y
, rect
. GetWidth (), rect
. GetHeight (), delay
);
138 void AutoCaptureMechanism :: Save ( wxBitmap
* screenshot
, const wxString
& fileName
)
140 // make sure default_dir exists
141 if (! wxDirExists ( default_dir
))
142 wxMkdir ( default_dir
);
144 wxFileName
fullFileName ( default_dir
, "appear-" + fileName
+
145 "-" + wxPlatformInfo :: Get (). GetPortIdShortName () + ".png" );
147 // do not overwrite already existing files with this name
148 while ( fullFileName
. FileExists ())
149 fullFileName
. SetName ( fullFileName
. GetName () + "_" );
151 // save the screenshot as a PNG
152 screenshot
-> SaveFile ( fullFileName
. GetFullPath (), wxBITMAP_TYPE_PNG
);
155 void AutoCaptureMechanism :: CaptureAll ()
157 // start from the first page
158 m_notebook
-> SetSelection ( 0 );
161 for ( ControlList :: iterator it
= m_controlList
. begin ();
162 it
!= m_controlList
. end ();
167 if ( ctrl
. flag
== AJ_TurnPage
) // Turn to next page
169 m_notebook
-> SetSelection ( m_notebook
-> GetSelection () + 1 );
174 // create the screenshot
175 wxBitmap
screenshot ( 1 , 1 );
176 Capture (& screenshot
, ctrl
);
178 if ( ctrl
. flag
& AJ_Union
)
180 // union screenshots until AJ_UnionEnd
184 it
-> name
= ctrl
. name
; //preserving the name
185 wxBitmap
screenshot2 ( 1 , 1 );
186 Capture (& screenshot2
, * it
);
187 wxBitmap
combined ( 1 , 1 );
188 Union (& screenshot
, & screenshot2
, & combined
);
189 screenshot
= combined
;
191 while (!( it
-> flag
& AJ_UnionEnd
));
195 Save (& screenshot
, ctrl
. name
);
199 bool AutoCaptureMechanism :: Capture ( wxBitmap
* bitmap
, Control
& ctrl
)
201 // no manual specification for the control name
202 // or name adjustment is disabled globally
203 if ( ctrl
. name
== wxT ( "" ) || m_flag
& AJ_DisableNameAdjust
)
205 // Get its name from wxRTTI
206 ctrl
. name
= ctrl
. ctrl
-> GetClassInfo ()-> GetClassName ();
211 wxRect rect
= GetRect ( ctrl
. ctrl
, ctrl
. flag
);
213 if ( ctrl
. flag
& AJ_Dropdown
&& !( m_flag
& AJ_DisableDropdown
))
215 // for drop-down controls we need the help of the user
216 wxString caption
= _ ( "Drop-down screenshot..." );
218 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." ),
219 ctrl
. name
, ctrl
. name
);
221 choice
= wxMessageBox ( msg
, caption
, wxYES_NO
, m_notebook
);
226 ctrl
. ctrl
-> SetCursor ( wxCursor ( wxCURSOR_HAND
));
228 // Do some rect adjust so it can include the dropdown list
229 // This adjust isn't pretty, but it works fine on all three paltforms.
230 // Looking forward to a better solution
231 int h
= rect
. GetHeight ();
232 rect
. SetHeight ( h
* 4 );
236 // cut off "wx" and change the name into lowercase.
237 // e.g. wxButton will have a name of "button" at the end
238 ctrl
. name
. StartsWith ( wxT ( "wx" ), &( ctrl
. name
));
239 ctrl
. name
. MakeLower ();
241 // take the screenshot
242 Capture ( bitmap
, rect
, ( choice
== wxYES
)? 5 : 0 );
244 if ( choice
== wxYES
) ctrl
. ctrl
-> SetCursor ( wxNullCursor
);
246 if ( ctrl
. flag
& AJ_RegionAdjust
)
253 bool AutoCaptureMechanism :: Union ( wxBitmap
* top
, wxBitmap
* bottom
, wxBitmap
* result
)
255 int w1
, w2
, h1
, h2
, w
, h
;
256 w1
= top
-> GetWidth ();
257 w2
= bottom
-> GetWidth ();
258 h1
= top
-> GetHeight ();
259 h2
= bottom
-> GetHeight ();
261 const int gap_between
= 20 ;
263 w
= ( w1
>= w2
) ? w1
: w2
;
264 h
= h1
+ h2
+ gap_between
;
266 result
-> Create ( w
, h
);
269 dstDC
. SelectObject ((* result
));
271 dstDC
. SetBrush (* wxWHITE_BRUSH
);
273 dstDC
. DrawBitmap ((* top
), 0 , 0 );
274 dstDC
. DrawBitmap ((* bottom
), 0 , h1
+ gap_between
);
276 dstDC
. SelectObject ( wxNullBitmap
);
281 wxRect
AutoCaptureMechanism :: GetRect ( wxWindow
* ctrl
, int flag
)
283 if ( (!( m_flag
& AJ_DisableRegionAdjust
) && ( flag
& AJ_RegionAdjust
))
284 || ( m_flag
& AJ_AlwaysRegionAdjust
) )
286 wxWindow
* parent
= ctrl
-> GetParent ();
287 wxSizer
* sizer
= parent
-> GetSizer ();
289 //The assertion won't fail if controls are still managed by wxSizer, and it's unlikely to
290 //change in the future.
292 "The GUI that AutoCaptureMechanism working with doesn't manage controls with wxSizer" );
297 +---------+-----------+---------+
299 +---------+-----------+---------+
300 | label | ctrl | label |
301 +---------+-----------+---------+
303 +---------+-----------+---------+
306 m_grid
= new wxFlexGridSizer ( 3 , 3 , m_margin
, m_margin
);
310 for ( int i
= 0 ; i
< 4 ; ++ i
)
311 l
[ i
] = new wxStaticText ( parent
, wxID_ANY
, wxT ( " " ));
314 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
316 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
317 m_grid
-> Add ( ctrl
, 1 , wxEXPAND
);
318 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
320 m_grid
-> Add ( new wxStaticText ( parent
, wxID_ANY
, wxT ( " " )));
324 parent
-> SetSizer ( sizer
);
330 return wxRect ( l
[ 0 ]-> GetScreenRect (). GetBottomRight (),
331 l
[ 3 ]-> GetScreenRect (). GetTopLeft ());
335 return ctrl
-> GetScreenRect (). Inflate ( m_margin
);
339 void AutoCaptureMechanism :: PutBack ( wxWindow
* ctrl
)
343 m_grid
-> Detach ( ctrl
);
345 wxSizerItemList children
= m_grid
-> GetChildren ();
347 for ( wxSizerItemList :: iterator it
= children
. begin (); it
!= children
. end (); ++ it
)
349 wxSizerItem
* item
= * it
;
350 if ( item
-> IsWindow ()) delete (* it
)-> GetWindow ();
353 wxSizer
* sizer
= ctrl
-> GetParent ()-> GetSizer ();
355 //The assertion won't fail if controls are still managed by wxSizer, and it's unlikely to
356 //change in the future.
358 "The GUI that AutoCaptureMechanism working with doesn't manage controls with wxSizer" );
360 sizer
-> Detach ( m_grid
);