]>
git.saurik.com Git - wxWidgets.git/blob - utils/screenshotgen/src/autocapture.cpp
8263e38b7ec0e68acacdad41e6eb5196518547d3
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>
23 #include "autocapture.h"
26 wxBitmap
Capture(int x
, int y
, int width
, int height
)
28 //Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
31 //wxExecute(_T("screencapture -x ") + tempfile, wxEXEC_SYNC);
33 system("screencapture -x /tmp/wx_screen_capture.png");
39 fullscreen
= wxBitmap(_T("/tmp/wx_screen_capture.png"), wxBITMAP_TYPE_PNG
);
41 while(!fullscreen
.IsOk());
43 wxBitmap screenshot
= fullscreen
.GetSubBitmap(wxRect(x
,y
,width
,height
));
45 #else //Under other paltforms, take a real screenshot
47 //Create a DC for the whole screen area
50 //Create a Bitmap that will later on hold the screenshot image
51 //Note that the Bitmap must have a size big enough to hold the screenshot
52 //-1 means using the current default colour depth
53 wxBitmap
screenshot(width
, height
, -1);
55 //Create a memory DC that will be used for actually taking the screenshot
57 //Tell the memory DC to use our Bitmap
58 //all drawing action on the memory DC will go to the Bitmap now
59 memDC
.SelectObject(screenshot
);
60 //Blit (in this case copy) the actual screen on the memory DC
62 memDC
.Blit( 0, //Copy to this X coordinate
63 0, //Copy to this Y coordinate
64 width
, //Copy this width
65 height
, //Copy this height
66 &dcScreen
, //From where do we copy?
67 x
, //What's the X offset in the original DC?
68 y
//What's the Y offset in the original DC?
70 //Select the Bitmap out of the memory DC by selecting a new
71 //uninitialized Bitmap
72 memDC
.SelectObject(wxNullBitmap
);
73 #endif //#ifdef __WXMAC__
75 // wxMessageBox(_(""),_(""));
81 wxBitmap
Capture(wxRect rect
)
83 wxPoint origin
= rect
.GetPosition();
84 return Capture(origin
.x
, origin
.y
, rect
.GetWidth(), rect
.GetHeight());
88 // ----------------------------------------------------------------------------
89 // AutoCaptureMechanism
90 // ----------------------------------------------------------------------------
92 void AutoCaptureMechanism::CaptureAll()
94 m_notebook
->SetSelection(0);
97 for(ControlList::iterator it
= m_controlList
.begin();
98 it
!= m_controlList
.end();
101 Control
& ctrl
= *it
;
103 if(ctrl
.flag
== AJ_TurnPage
) // Turn to next page
105 m_notebook
->SetSelection(m_notebook
->GetSelection() + 1);
110 wxBitmap screenshot
= Capture(ctrl
);
112 if(ctrl
.flag
& AJ_Union
)
114 screenshot
= Union(screenshot
, Capture(*(++it
)));
117 Save(screenshot
, ctrl
.name
);
121 wxBitmap
AutoCaptureMechanism::Capture(Control
& ctrl
)
123 if(ctrl
.name
== wxT("")) //no mannual specification for the control name
125 //Get name from wxRTTI
126 ctrl
.name
= ctrl
.ctrl
->GetClassInfo()->GetClassName();
131 if(ctrl
.flag
& AJ_Dropdown
)
133 wxString caption
= _("Do you wish to capture the dropdown list of ") + ctrl
.name
+ _("?");
134 wxString notice
= _("Click YES to capture it.\nAnd you MUST drop down the ") + ctrl
.name
+ _(" in 3 seconds after close me.\n");
135 notice
+= _("Click NO otherwise.");
137 choice
= wxMessageBox(notice
, caption
, wxYES_NO
, m_notebook
);
145 clock_t start
= clock();
146 while(clock() - start
< CLOCKS_PER_SEC
* 3)
153 wxRect rect
= GetRect(ctrl
.ctrl
, ctrl
.flag
);
155 //Do some rect adjust so it can include the dropdown list
156 //Currently it only works well under MSW, not adjusted for Linux and Mac OS
157 if(ctrl
.flag
& AJ_Dropdown
&& choice
== wxYES
)
160 int h
= rect
.GetHeight();
161 rect
.SetHeight(h
* 4);
165 //cut off "wx" and change them into lowercase.
166 // e.g. wxButton will have a name of "button" at the end
167 ctrl
.name
.StartsWith(_T("wx"), &(ctrl
.name
));
168 ctrl
.name
.MakeLower();
170 wxBitmap screenshot
= ::Capture(rect
);
172 if(ctrl
.flag
& AJ_RegionAdjust
)
180 //if AJ_RegionAdjust is specified, the following line will use the label trick to adjust
181 //the region position and size
182 wxRect
GetRect(wxWindow
* ctrl
, int flag
);
183 //put the control back after the label trick(Using reparent/resizer approach)
184 void PutBack(wxWindow
* ctrl
);
186 wxBitmap
AutoCaptureMechanism::Union(wxBitmap pic1
, wxBitmap pic2
)
188 int w1
, w2
, h1
, h2
, w
, h
;
189 w1
= pic1
.GetWidth();
190 w2
= pic2
.GetWidth();
191 h1
= pic1
.GetHeight();
192 h2
= pic2
.GetHeight();
194 const int gap_between
= 20;
196 w
= (w1
>= w2
) ? w1
: w2
;
197 h
= h1
+ h2
+ gap_between
;
199 wxBitmap
result(w
, h
, -1);
202 dstDC
.SelectObject(result
);
204 dstDC
.DrawBitmap(pic1
, 0, 0, false);
205 dstDC
.DrawBitmap(pic2
, 0, h1
+ gap_between
, false);
207 dstDC
.SelectObject(wxNullBitmap
);
210 wxBitmap
mask(w
, h
, 1);
211 maskDC
.SelectObject(mask
);
213 maskDC
.SetPen(*wxTRANSPARENT_PEN
);
214 maskDC
.SetBrush(*wxBLACK_BRUSH
);
215 maskDC
.DrawRectangle(0, 0, w
+ 1, h
+ 1);
217 maskDC
.SetBrush(*wxWHITE_BRUSH
);
218 maskDC
.DrawRectangle(0, 0, w1
, h1
);
219 maskDC
.DrawRectangle(0, h1
+ gap_between
, w2
, h2
);
220 maskDC
.SelectObject(wxNullBitmap
);
222 result
.SetMask(new wxMask(mask
));
227 void AutoCaptureMechanism::Save(wxBitmap screenshot
, wxString fileName
)
229 //Check if m_defaultDir already existed
230 if(!wxDirExists(m_dir
))
233 wxString fullFileName
= m_dir
+ wxFileName::GetPathSeparator() + fileName
;
235 //to prvent overwritten
236 while(wxFileName::FileExists(fullFileName
+ _T(".png"))) fullFileName
+= _T("_");
238 //Our Bitmap now has the screenshot, so let's save it as an png
239 //The filename itself is without extension.
240 screenshot
.SaveFile(fullFileName
+ _T(".png"), wxBITMAP_TYPE_PNG
);
243 wxRect
AutoCaptureMechanism::GetRect(wxWindow
* ctrl
, int flag
)
245 if(flag
& AJ_RegionAdjust
)
247 wxWindow
* parent
= ctrl
->GetParent();
248 wxSizer
* sizer
= parent
->GetSizer();
255 +---------+-----------+---------+
257 +---------+-----------+---------+
258 | label | ctrl | label |
259 +---------+-----------+---------+
261 +---------+-----------+---------+
264 m_grid
= new wxFlexGridSizer(3, 3, m_border
, m_border
);
268 for(int i
= 0; i
< 4; ++i
)
269 l
[i
] = new wxStaticText(parent
, wxID_ANY
, wxT(" "));
272 m_grid
->Add(new wxStaticText(parent
, wxID_ANY
, wxT(" ")));
274 m_grid
->Add(new wxStaticText(parent
, wxID_ANY
, wxT(" ")));
276 m_grid
->Add(new wxStaticText(parent
, wxID_ANY
, wxT(" ")));
278 m_grid
->Add(new wxStaticText(parent
, wxID_ANY
, wxT(" ")));
282 parent
->SetSizer(sizer
);
288 return wxRect(l
[0]->GetScreenRect().GetBottomRight(),
289 l
[3]->GetScreenRect().GetTopLeft());
292 else //Actually it won't get here working with the current guiframe.h/guiframe.cpp
294 return ctrl
->GetScreenRect().Inflate(m_border
);
299 return ctrl
->GetScreenRect().Inflate(m_border
);
303 void AutoCaptureMechanism::PutBack(wxWindow
* ctrl
)
305 m_grid
->Detach(ctrl
);
307 wxSizerItemList children
= m_grid
->GetChildren();
309 for(wxSizerItemList::iterator it
= children
.begin(); it
!= children
.end(); ++it
)
311 wxSizerItem
* item
= *it
;
312 if(item
->IsWindow()) delete (*it
)->GetWindow();
315 wxSizer
* sizer
= ctrl
->GetParent()->GetSizer();
316 sizer
->Detach(m_grid
);