]> git.saurik.com Git - wxWidgets.git/blob - utils/screenshotgen/src/autocapture.cpp
many fixes; now the application correctly starts up
[wxWidgets.git] / utils / screenshotgen / src / autocapture.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: autocapture.cpp
3 // Purpose: Implement wxCtrlMaskOut class
4 // Author: Utensil Candel (UtensilCandel@@gmail.com)
5 // RCS-ID: $Id$
6 // Licence: wxWindows license
7 /////////////////////////////////////////////////////////////////////////////
8
9 // For compilers that support precompilation, includes "wx/wx.h".
10 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 // for all others, include the necessary headers
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20
21 #include <wx/filename.h>
22
23 #include "autocapture.h"
24
25
26 wxBitmap Capture(int x, int y, int width, int height)
27 {
28 //Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
29 #ifdef __WXMAC__
30
31 //wxExecute(_T("screencapture -x ") + tempfile, wxEXEC_SYNC);
32
33 system("screencapture -x /tmp/wx_screen_capture.png");
34
35 wxBitmap fullscreen;
36
37 do
38 {
39 fullscreen = wxBitmap(_T("/tmp/wx_screen_capture.png"), wxBITMAP_TYPE_PNG);
40 }
41 while(!fullscreen.IsOk());
42
43 wxBitmap screenshot = fullscreen.GetSubBitmap(wxRect(x,y,width,height));
44
45 #else //Under other paltforms, take a real screenshot
46
47 //Create a DC for the whole screen area
48 wxScreenDC dcScreen;
49
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);
54
55 //Create a memory DC that will be used for actually taking the screenshot
56 wxMemoryDC memDC;
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
61 //and thus the Bitmap
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?
69 );
70 //Select the Bitmap out of the memory DC by selecting a new
71 //uninitialized Bitmap
72 memDC.SelectObject(wxNullBitmap);
73 #endif //#ifdef __WXMAC__
74
75 // wxMessageBox(_(""),_(""));
76
77 return screenshot;
78
79 }
80
81 wxBitmap Capture(wxRect rect)
82 {
83 wxPoint origin = rect.GetPosition();
84 return Capture(origin.x, origin.y, rect.GetWidth(), rect.GetHeight());
85 }
86
87
88 // ----------------------------------------------------------------------------
89 // AutoCaptureMechanism
90 // ----------------------------------------------------------------------------
91
92 wxBitmap AutoCaptureMechanism::Capture(Control & ctrl)
93 {
94 if(ctrl.name == wxT("")) //no mannual specification for the control name
95 {
96 //Get name from wxRTTI
97 ctrl.name = ctrl.ctrl->GetClassInfo()->GetClassName();
98 }
99
100 int choice = wxNO;
101
102 if(ctrl.flag & AJ_Dropdown)
103 {
104 wxString caption = _("Do you wish to capture the dropdown list of ") + ctrl.name + _("?");
105 wxString notice = _("Click YES to capture it.\nAnd you MUST drop down the ") + ctrl.name + _(" in 3 seconds after close me.\n");
106 notice += _("Click NO otherwise.");
107
108 choice = wxMessageBox(notice, caption, wxYES_NO, m_notebook);
109
110 if(choice == wxYES)
111 {
112 //Wait for 3 seconds
113 using std::clock;
114 using std::clock_t;
115
116 clock_t start = clock();
117 while(clock() - start < CLOCKS_PER_SEC * 3)
118 {
119 wxYieldIfNeeded();
120 }
121 }
122 }
123
124 wxRect rect = GetRect(ctrl.ctrl, ctrl.flag);
125
126 //Do some rect adjust so it can include the dropdown list
127 //Currently it only works well under MSW, not adjusted for Linux and Mac OS
128 if(ctrl.flag & AJ_Dropdown && choice == wxYES)
129 {
130 // #ifdef __WXMSW__
131 int h = rect.GetHeight();
132 rect.SetHeight(h * 4);
133 // #endif
134 }
135
136 //cut off "wx" and change them into lowercase.
137 // e.g. wxButton will have a name of "button" at the end
138 ctrl.name.StartsWith(_T("wx"), &(ctrl.name));
139 ctrl.name.MakeLower();
140
141 wxBitmap screenshot = ::Capture(rect);
142
143 if(ctrl.flag & AJ_RegionAdjust)
144 {
145 PutBack(ctrl.ctrl);
146 }
147
148 return screenshot;
149 }
150
151 //if AJ_RegionAdjust is specified, the following line will use the label trick to adjust
152 //the region position and size
153 wxRect GetRect(wxWindow* ctrl, int flag);
154 //put the control back after the label trick(Using reparent/resizer approach)
155 void PutBack(wxWindow * ctrl);
156
157 wxBitmap AutoCaptureMechanism::Union(wxBitmap pic1, wxBitmap pic2)
158 {
159 int w1, w2, h1, h2, w, h;
160 w1 = pic1.GetWidth();
161 w2 = pic2.GetWidth();
162 h1 = pic1.GetHeight();
163 h2 = pic2.GetHeight();
164
165 const int gap_between = 20;
166
167 w = (w1 >= w2) ? w1 : w2;
168 h = h1 + h2 + gap_between;
169
170 wxBitmap result(w, h, -1);
171
172 wxMemoryDC dstDC;
173 dstDC.SelectObject(result);
174
175 dstDC.DrawBitmap(pic1, 0, 0, false);
176 dstDC.DrawBitmap(pic2, 0, h1 + gap_between, false);
177
178 dstDC.SelectObject(wxNullBitmap);
179
180 wxMemoryDC maskDC;
181 wxBitmap mask(w, h, 1);
182 maskDC.SelectObject(mask);
183
184 maskDC.SetPen(*wxTRANSPARENT_PEN);
185 maskDC.SetBrush(*wxBLACK_BRUSH);
186 maskDC.DrawRectangle(0, 0, w + 1, h + 1);
187
188 maskDC.SetBrush(*wxWHITE_BRUSH);
189 maskDC.DrawRectangle(0, 0, w1, h1);
190 maskDC.DrawRectangle(0, h1 + gap_between, w2, h2);
191 maskDC.SelectObject(wxNullBitmap);
192
193 result.SetMask(new wxMask(mask));
194
195 return result;
196 }
197
198 void AutoCaptureMechanism::Save(wxBitmap screenshot, wxString fileName)
199 {
200 //Check if m_defaultDir already existed
201 if(!wxDirExists(m_dir))
202 wxMkdir(m_dir);
203
204 wxString fullFileName = m_dir + wxFileName::GetPathSeparator() + fileName;
205
206 //to prvent overwritten
207 while(wxFileName::FileExists(fullFileName + _T(".png"))) fullFileName += _T("_");
208
209 //Our Bitmap now has the screenshot, so let's save it as an png
210 //The filename itself is without extension.
211 screenshot.SaveFile(fullFileName + _T(".png"), wxBITMAP_TYPE_PNG);
212 }
213
214 wxRect AutoCaptureMechanism::GetRect(wxWindow* ctrl, int flag)
215 {
216 if(flag & AJ_RegionAdjust)
217 {
218 wxWindow * parent = ctrl->GetParent();
219 wxSizer * sizer = parent->GetSizer();
220
221 if(sizer)
222 {
223 sizer->Detach(ctrl);
224
225 /*
226 +---------+-----------+---------+
227 | 0 | label | 1 |
228 +---------+-----------+---------+
229 | label | ctrl | label |
230 +---------+-----------+---------+
231 | 2 | label | 3 |
232 +---------+-----------+---------+
233 */
234
235 m_grid = new wxFlexGridSizer(3, 3, m_border, m_border);
236
237 wxStaticText* l[4];
238
239 for(int i = 0; i < 4; ++i)
240 l[i] = new wxStaticText(parent, wxID_ANY, wxT(" "));
241
242 m_grid->Add(l[0]);
243 m_grid->Add(new wxStaticText(parent, wxID_ANY, wxT(" ")));
244 m_grid->Add(l[1]);
245 m_grid->Add(new wxStaticText(parent, wxID_ANY, wxT(" ")));
246 m_grid->Add(ctrl);
247 m_grid->Add(new wxStaticText(parent, wxID_ANY, wxT(" ")));
248 m_grid->Add(l[2]);
249 m_grid->Add(new wxStaticText(parent, wxID_ANY, wxT(" ")));
250 m_grid->Add(l[3]);
251
252 sizer->Add(m_grid);
253 parent->SetSizer(sizer);
254 parent->Layout();
255
256 parent->Refresh();
257 wxYield();
258
259 return wxRect(l[0]->GetScreenRect().GetBottomRight(),
260 l[3]->GetScreenRect().GetTopLeft());
261
262 }
263 else //Actually it won't get here working with the current guiframe.h/guiframe.cpp
264 {
265 return ctrl->GetScreenRect().Inflate(m_border);
266 }
267 }
268 else
269 {
270 return ctrl->GetScreenRect().Inflate(m_border);
271 }
272 }
273
274 void AutoCaptureMechanism::PutBack(wxWindow * ctrl)
275 {
276 m_grid->Detach(ctrl);
277
278 wxSizerItemList children = m_grid->GetChildren();
279
280 for(wxSizerItemList::iterator it = children.begin(); it != children.end(); ++it)
281 {
282 wxSizerItem* item = *it;
283 if(item->IsWindow()) delete (*it)->GetWindow();
284 }
285
286 wxSizer * sizer = ctrl->GetParent()->GetSizer();
287 sizer->Detach(m_grid);
288 delete m_grid;
289 sizer->Add(ctrl);
290 }
291