|
1 /* |
|
2 * Name : ARContainer.cpp |
|
3 * Description : |
|
4 * Project : This file is part of OpenMAR, an Open Mobile Augmented Reality browser |
|
5 * Website : http://OpenMAR.org |
|
6 * |
|
7 * Copyright (c) 2010 David Caabeiro |
|
8 * |
|
9 * All rights reserved. This program and the accompanying materials are made available |
|
10 * under the terms of the Eclipse Public License v1.0 which accompanies this |
|
11 * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html |
|
12 * |
|
13 */ |
|
14 |
|
15 #include "ARContainer.h" |
|
16 |
|
17 #include <coemain.h> |
|
18 #include <eikenv.h> |
|
19 |
|
20 #include <AknButton.h> |
|
21 #include <AknNoteWrappers.h> |
|
22 #include <AknView.h> |
|
23 |
|
24 #include "Application.hrh" |
|
25 |
|
26 #include <OpenMAR_0x2002E1AB.rsg> |
|
27 #include <Button_0x2002E1AB.mbg> |
|
28 |
|
29 #include "IconLoader.h" |
|
30 #include "ResetAndDestroy.h" |
|
31 |
|
32 #include "Logger.h" |
|
33 |
|
34 // Constant definitions |
|
35 _LIT(KButtonFile, "\\resource\\apps\\Button_0x2002E1AB.mif"); |
|
36 const TSize KButtonSize(36, 36); |
|
37 |
|
38 CARContainer* CARContainer::NewL(CAknView& aView, const TRect& aRect) |
|
39 { |
|
40 CARContainer* self = new(ELeave) CARContainer(aView); |
|
41 CleanupStack::PushL(self); |
|
42 self->ConstructL(aRect); |
|
43 CleanupStack::Pop(self); |
|
44 |
|
45 return self; |
|
46 } |
|
47 |
|
48 CARContainer::CARContainer(CAknView& aView) |
|
49 : iView(aView) |
|
50 {} |
|
51 |
|
52 void CARContainer::ConstructL(const TRect& aRect) |
|
53 { |
|
54 CreateWindowL(); |
|
55 |
|
56 CreateButtonGroupL(); |
|
57 |
|
58 // This bitmap will contain the camera frame and overlays |
|
59 iBitmap = new(ELeave) CFbsBitmap; |
|
60 iBitmap->Create(aRect.Size(), Window().DisplayMode()); |
|
61 |
|
62 iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
63 User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapContext)); |
|
64 |
|
65 // Make black background to be shown immediately to the user |
|
66 iBitmapContext->SetBrushColor(KRgbBlack); |
|
67 iBitmapContext->SetBrushStyle(CFbsBitGc::ESolidBrush); |
|
68 iBitmapContext->Clear(); |
|
69 |
|
70 SetRect(aRect); |
|
71 |
|
72 LOGARG("Control rect size is %d x %d", aRect.Width(), aRect.Height()); |
|
73 |
|
74 iCoeEnv->AddForegroundObserverL(*this); |
|
75 |
|
76 #if defined(__MARM__) |
|
77 iCamera = CDigitalCamera::NewL(*this); |
|
78 |
|
79 // The rect will be the intersection between the camera frame |
|
80 // and the window rect |
|
81 TRect cameraRect(TPoint(0, 0), iCamera->ViewportSize()); |
|
82 cameraRect.Intersection(aRect); |
|
83 #else |
|
84 TRect cameraRect(aRect); |
|
85 #endif |
|
86 |
|
87 LOGARG("Viewport rect is (%d, %d, %d, %d)", |
|
88 cameraRect.iTl.iX, cameraRect.iTl.iY, cameraRect.iBr.iX, cameraRect.iBr.iY); |
|
89 |
|
90 iScreenshot = CScreenshot::NewL(*this, cameraRect.Size(), Window().DisplayMode()); |
|
91 |
|
92 // Instantiate overlay implementations |
|
93 RImplInfoPtrArray implementations; |
|
94 REComSession::ListImplementationsL(TUid::Uid(KOverlayInterfaceUidValue), implementations); |
|
95 CleanupResetAndDestroyPushL(implementations); |
|
96 |
|
97 // Pass container window and rect size to each overlay |
|
98 OpenMAR::CPOIOverlay::SParameter param = { Window(), cameraRect }; |
|
99 |
|
100 for (TInt i = 0; i < implementations.Count(); ++i) |
|
101 { |
|
102 const CImplementationInformation* info = implementations[i]; |
|
103 OpenMAR::CPOIOverlay* plugin = OpenMAR::CPOIOverlay::NewL(info->ImplementationUid(), param); |
|
104 iOverlayList.AppendL(plugin); |
|
105 } |
|
106 |
|
107 CleanupStack::PopAndDestroy(&implementations); |
|
108 |
|
109 // Start camera in low priority task |
|
110 iSensorTask = CIdle::NewL(CActive::EPriorityIdle); |
|
111 |
|
112 TCallBack sensorStart(SensorStart, this); |
|
113 iSensorTask->Start(sensorStart); |
|
114 |
|
115 ActivateL(); |
|
116 } |
|
117 |
|
118 CARContainer::~CARContainer() |
|
119 { |
|
120 DoSensorStop(); |
|
121 |
|
122 iOverlayList.ResetAndDestroy(); |
|
123 iOverlayList.Close(); |
|
124 |
|
125 delete iCamera; |
|
126 delete iScreenshot; |
|
127 |
|
128 iCoeEnv->RemoveForegroundObserver(*this); |
|
129 |
|
130 delete iBitmapContext; |
|
131 delete iBitmapDevice; |
|
132 delete iBitmap; |
|
133 |
|
134 DeleteButtonGroup(); |
|
135 } |
|
136 |
|
137 void CARContainer::CreateButtonGroupL() |
|
138 { |
|
139 // Screenshot button |
|
140 CGulIcon* screenshotNormal = CreateIconL(KButtonFile, EMbmButton_0x2002e1abScreenshotbuttonnormal, EMbmButton_0x2002e1abScreenshotbuttonnormal_mask, KButtonSize); |
|
141 |
|
142 iScreenshotButton = CAknButton::NewL(screenshotNormal, 0, 0, 0, KNullDesC, KNullDesC, KAknButtonNoFrame, 0); |
|
143 iScreenshotButton->SetContainerWindowL(*this); |
|
144 iScreenshotButton->SetObserver(this); |
|
145 } |
|
146 |
|
147 void CARContainer::DeleteButtonGroup() |
|
148 { |
|
149 delete iScreenshotButton; |
|
150 } |
|
151 |
|
152 TInt CARContainer::SensorStart(TAny* aPtr) |
|
153 { |
|
154 CARContainer* self = static_cast<CARContainer*>(aPtr); |
|
155 self->DoSensorStart(); |
|
156 return KErrNone; |
|
157 } |
|
158 |
|
159 void CARContainer::DoSensorStart() |
|
160 { |
|
161 LOGTXT("Starting sensors.."); |
|
162 |
|
163 #if defined(__MARM__) |
|
164 iCamera->Start(); |
|
165 #endif |
|
166 |
|
167 for (TInt i = 0; i < iOverlayList.Count(); ++i) |
|
168 iOverlayList[i]->StartL(); |
|
169 } |
|
170 |
|
171 TInt CARContainer::SensorStop(TAny* aPtr) |
|
172 { |
|
173 CARContainer* self = static_cast<CARContainer*>(aPtr); |
|
174 self->DoSensorStop(); |
|
175 return KErrNone; |
|
176 } |
|
177 |
|
178 void CARContainer::DoSensorStop() |
|
179 { |
|
180 LOGTXT("Stopping sensors.."); |
|
181 |
|
182 for (TInt i = 0; i < iOverlayList.Count(); ++i) |
|
183 iOverlayList[i]->Stop(); |
|
184 |
|
185 #if defined(__MARM__) |
|
186 iCamera->Stop(); |
|
187 #endif |
|
188 } |
|
189 |
|
190 /* |
|
191 * Before performing the screenshot, disable overlay and sensor activity. |
|
192 * This way the screenshot image is generated fast. |
|
193 */ |
|
194 |
|
195 void CARContainer::ScreenshotStartL() |
|
196 { |
|
197 iScreenshotButton->SetDimmed(ETrue); |
|
198 |
|
199 HandleLosingForeground(); |
|
200 iScreenshot->RequestL(*iBitmap, iBitmap->SizeInPixels()); |
|
201 } |
|
202 |
|
203 /* |
|
204 * Resume overlay and sensor activity. |
|
205 */ |
|
206 void CARContainer::ScreenshotStop() |
|
207 { |
|
208 HandleGainingForeground(); |
|
209 |
|
210 iScreenshotButton->SetDimmed(EFalse); |
|
211 } |
|
212 |
|
213 void CARContainer::SizeChanged() |
|
214 { |
|
215 TRect screenshotButtonRect(TPoint(0, 0), KButtonSize); |
|
216 screenshotButtonRect.Move(TPoint(Rect().Width() - KButtonSize.iWidth, Rect().Height() - KButtonSize.iHeight)); |
|
217 |
|
218 iScreenshotButton->SetRect(screenshotButtonRect); |
|
219 } |
|
220 |
|
221 void CARContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
222 { |
|
223 // if (aPointerEvent.iType == TPointerEvent::EButton1Down && iCamera) |
|
224 // iCamera->StartFocus(); |
|
225 CCoeControl::HandlePointerEventL(aPointerEvent); |
|
226 } |
|
227 |
|
228 void CARContainer::HandleResourceChange(TInt aType) |
|
229 { |
|
230 LOGARG("CARContainer::HandleResourceChange(%d)", aType); |
|
231 |
|
232 CCoeControl::HandleResourceChange(aType); |
|
233 /* |
|
234 if (aType == KEikDynamicLayoutVariantSwitch) |
|
235 { |
|
236 TRect rect; |
|
237 AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EApplicationWindow, rect); |
|
238 SetRect(rect); |
|
239 } |
|
240 */ |
|
241 } |
|
242 |
|
243 void CARContainer::Draw(const TRect& /*aRect*/) const |
|
244 { |
|
245 CWindowGc& gc = SystemGc(); |
|
246 gc.BitBlt(TPoint(0, 0), iBitmap); |
|
247 } |
|
248 |
|
249 TInt CARContainer::CountComponentControls() const |
|
250 { |
|
251 return ETotal; |
|
252 } |
|
253 |
|
254 CCoeControl* CARContainer::ComponentControl(TInt aIndex) const |
|
255 { |
|
256 switch (aIndex) |
|
257 { |
|
258 case EScreenshot: |
|
259 return iScreenshotButton; |
|
260 |
|
261 default: |
|
262 return 0; |
|
263 } |
|
264 } |
|
265 |
|
266 void CARContainer::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType) |
|
267 { |
|
268 if (aEventType == EEventStateChanged) |
|
269 { |
|
270 if (aControl == iScreenshotButton) |
|
271 { |
|
272 LOGTXT("Screenshot requested"); |
|
273 |
|
274 ScreenshotStartL(); |
|
275 } |
|
276 } |
|
277 } |
|
278 |
|
279 void CARContainer::HandleGainingForeground() |
|
280 { |
|
281 LOGTXT("Gaining ForegroundL"); |
|
282 |
|
283 // Clear bitmap to avoid showing screen capture when back |
|
284 iBitmapContext->SetBrushColor(KRgbBlack); |
|
285 iBitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
286 iBitmapContext->Clear(); |
|
287 |
|
288 iSensorTask->Cancel(); |
|
289 TCallBack sensor(SensorStart, this); |
|
290 iSensorTask->Start(sensor); |
|
291 } |
|
292 |
|
293 void CARContainer::HandleLosingForeground() |
|
294 { |
|
295 LOGTXT("Losing foreground"); |
|
296 /* |
|
297 iSensorTask->Cancel(); |
|
298 TCallBack sensor(SensorStop, this); |
|
299 iSensorTask->Start(sensor); |
|
300 */ |
|
301 DoSensorStop(); |
|
302 } |
|
303 |
|
304 void CARContainer::CameraReady(TInt aError) |
|
305 { |
|
306 LOGARG("Camera ready (error %d)", aError); |
|
307 |
|
308 // Perform some error handling |
|
309 } |
|
310 |
|
311 void CARContainer::CameraFrame(CFbsBitmap& aFrame) |
|
312 { |
|
313 // Use camera frame as background |
|
314 iBitmapContext->BitBlt(TPoint(0, 0), &aFrame); |
|
315 |
|
316 for (TInt i = 0; i < iOverlayList.Count(); ++i) |
|
317 { |
|
318 // Perform overlay rendering |
|
319 const CFbsBitmap& overlay = iOverlayList[i]->RenderScene(); |
|
320 // Blend it with the background image |
|
321 iBitmapContext->BitBlt(TPoint(0, 0), &overlay); |
|
322 } |
|
323 |
|
324 const CFont* font = iEikonEnv->LegendFont(); |
|
325 iBitmapContext->UseFont(font); |
|
326 |
|
327 _LIT(KText, "Focus: %d"); |
|
328 TBuf<32> text; |
|
329 text.Format(KText, iOverlayList[0]->GetFocusedPOI()); |
|
330 |
|
331 const TPoint pos(10, 20); |
|
332 |
|
333 iBitmapContext->DrawText(text, pos); |
|
334 |
|
335 // TODO: should call this every Nth frame |
|
336 User::ResetInactivityTime(); |
|
337 |
|
338 DrawNow(); |
|
339 } |
|
340 |
|
341 void CARContainer::FocusReady(TInt aError) |
|
342 { |
|
343 if (aError == KErrNone) |
|
344 LOGTXT("Focused correctly"); |
|
345 // else if (aError == KErrECamNotOptimalFocus) |
|
346 // LOGTXT("Focus not optimal"); |
|
347 } |
|
348 |
|
349 void CARContainer::ScreenshotReadyL(TInt aError, const TDesC& aFilename) |
|
350 { |
|
351 ScreenshotStop(); |
|
352 |
|
353 TBuf<128> text; |
|
354 |
|
355 if (aError) |
|
356 { |
|
357 CAknErrorNote* note = new(ELeave) CAknErrorNote; |
|
358 HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_ERROR); |
|
359 text.Format(*format, aError); |
|
360 CleanupStack::PopAndDestroy(format); |
|
361 note->ExecuteLD(text); |
|
362 } |
|
363 else |
|
364 { |
|
365 CAknInformationNote* note = new(ELeave) CAknInformationNote; |
|
366 HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_OK); |
|
367 text.Format(*format, &aFilename); |
|
368 CleanupStack::PopAndDestroy(format); |
|
369 note->ExecuteLD(text); |
|
370 } |
|
371 } |