|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "HuiFxGroupLayer.h" |
|
21 |
|
22 EXPORT_C CHuiFxGroupLayer::CHuiFxGroupLayer() |
|
23 { |
|
24 #ifdef HUIFX_TRACE |
|
25 RDebug::Print(_L("CHuiFxGroupLayer::CHuiFxGroupLayer - 0x%x "), this); |
|
26 #endif |
|
27 } |
|
28 |
|
29 EXPORT_C CHuiFxGroupLayer::~CHuiFxGroupLayer() |
|
30 { |
|
31 /*for (TInt i = 0; i < iLayers.Count(); i++) |
|
32 { |
|
33 delete iLayers[i]; |
|
34 } |
|
35 iLayers.Close();*/ |
|
36 iLayers.ResetAndDestroy(); |
|
37 iLayers.Close(); |
|
38 #ifdef HUIFX_TRACE |
|
39 RDebug::Print(_L("CHuiFxGroupLayer::~CHuiFxGroupLayer - 0x%x "), this); |
|
40 #endif |
|
41 } |
|
42 |
|
43 EXPORT_C CHuiFxGroupLayer* CHuiFxGroupLayer::NewL(TBool aIsRoot) |
|
44 { |
|
45 CHuiFxGroupLayer* e = new (ELeave) CHuiFxGroupLayer(); |
|
46 CleanupStack::PushL(e); |
|
47 e->ConstructL(aIsRoot); |
|
48 CleanupStack::Pop(e); |
|
49 return e; |
|
50 } |
|
51 |
|
52 EXPORT_C CHuiFxGroupLayer *CHuiFxGroupLayer::CloneL() const |
|
53 { |
|
54 CHuiFxGroupLayer *gl = new (ELeave)CHuiFxGroupLayer; |
|
55 gl->CHuiFxLayer::CopyFromL(this); |
|
56 for(int i=0;i<iLayers.Count();i++) |
|
57 { |
|
58 CHuiFxLayer *layer = iLayers[i]; |
|
59 CHuiFxLayer *layer2 = layer->CloneL(); |
|
60 gl->iLayers.AppendL(layer2); |
|
61 } |
|
62 gl->iIsRoot = iIsRoot; |
|
63 gl->iBackbufferRect = iBackbufferRect; |
|
64 return gl; |
|
65 } |
|
66 EXPORT_C void CHuiFxGroupLayer::SetExtRect( TRect *aExtRect ) |
|
67 { |
|
68 for(int i=0;i<iLayers.Count();i++) |
|
69 { |
|
70 CHuiFxLayer *layer = iLayers[i]; |
|
71 layer->SetExtRect( aExtRect ); |
|
72 } |
|
73 } |
|
74 EXPORT_C void CHuiFxGroupLayer::SetVisual( CHuiVisual *aVisual ) |
|
75 { |
|
76 for(int i=0;i<iLayers.Count();i++) |
|
77 { |
|
78 CHuiFxLayer *layer = iLayers[i]; |
|
79 layer->SetVisual(aVisual); |
|
80 } |
|
81 } |
|
82 EXPORT_C void CHuiFxGroupLayer::SetVisual( MHuiEffectable *aVisual ) |
|
83 { |
|
84 for(int i=0;i<iLayers.Count();i++) |
|
85 { |
|
86 CHuiFxLayer *layer = iLayers[i]; |
|
87 layer->SetVisual(aVisual); |
|
88 } |
|
89 } |
|
90 EXPORT_C void CHuiFxGroupLayer::ConstructL(TBool aIsRoot) |
|
91 { |
|
92 CHuiFxLayer::ConstructL( ELayerTypeGroup ); |
|
93 iIsRoot = aIsRoot; |
|
94 } |
|
95 |
|
96 EXPORT_C TBool CHuiFxGroupLayer::PrepareDrawL(CHuiFxEngine& aEngine) |
|
97 { |
|
98 // TODO: fast path |
|
99 if (!VisualArea(iBackbufferRect)) |
|
100 { |
|
101 ApplyMargin( iBackbufferRect ); |
|
102 |
|
103 // Clip to display area (if set) |
|
104 iBackbufferRect.Intersection(iDisplayArea); |
|
105 |
|
106 SetVisualRect(iBackbufferRect); |
|
107 //iBackbufferRect = TargetRect(); |
|
108 } |
|
109 else |
|
110 { |
|
111 ApplyMargin( iBackbufferRect ); |
|
112 // Restrict rendering to the output area |
|
113 |
|
114 // Clip to display area (if set) |
|
115 iBackbufferRect.Intersection(iDisplayArea); |
|
116 |
|
117 SetVisualRect(iBackbufferRect); |
|
118 //iBackbufferRect.Intersection(TargetRect()); |
|
119 } |
|
120 |
|
121 TRect targetRect; |
|
122 TRect sourceRect; |
|
123 |
|
124 if (!iIsRoot) |
|
125 { |
|
126 sourceRect = targetRect = TRect(TPoint(0, 0), iBackbufferRect.Size()); |
|
127 } |
|
128 else |
|
129 { |
|
130 sourceRect = targetRect = iBackbufferRect; |
|
131 } |
|
132 |
|
133 TRect newBackbufferRect(0,0,0,0); |
|
134 for (TInt i = 0; i < iLayers.Count(); i++) |
|
135 { |
|
136 iLayers[i]->SetDisplayArea(iDisplayArea); |
|
137 |
|
138 // Should we shrink the visual area? |
|
139 if (i > 0 && iLayers[i]->VisualArea(newBackbufferRect)) |
|
140 { |
|
141 ApplyMargin( newBackbufferRect ); |
|
142 SetVisualRect(newBackbufferRect); |
|
143 //newBackbufferRect.Intersection(TargetRect()); |
|
144 |
|
145 // Clip to display area (if set) |
|
146 newBackbufferRect.Intersection(iDisplayArea); |
|
147 |
|
148 ASSERT(newBackbufferRect.Size().iWidth <= iBackbufferRect.Size().iWidth && |
|
149 newBackbufferRect.Size().iHeight <= iBackbufferRect.Size().iHeight); |
|
150 if (iIsRoot) |
|
151 { |
|
152 sourceRect = targetRect = newBackbufferRect; |
|
153 } |
|
154 else |
|
155 { |
|
156 targetRect.iTl.iX = newBackbufferRect.iTl.iX - iBackbufferRect.iTl.iX; |
|
157 targetRect.iTl.iY = newBackbufferRect.iTl.iY - iBackbufferRect.iTl.iY; |
|
158 targetRect.iBr.iX = newBackbufferRect.iBr.iX - iBackbufferRect.iTl.iX; |
|
159 targetRect.iBr.iY = newBackbufferRect.iBr.iY - iBackbufferRect.iTl.iY; |
|
160 sourceRect = targetRect; |
|
161 } |
|
162 } |
|
163 iLayers[i]->SetSourceRect(sourceRect); |
|
164 iLayers[i]->SetTargetRect(targetRect); |
|
165 iLayers[i]->SetVisualRect(VisualRect()); |
|
166 if (!iLayers[i]->PrepareDrawL(aEngine)) |
|
167 { |
|
168 return EFalse; |
|
169 } |
|
170 } |
|
171 return ETrue; |
|
172 } |
|
173 |
|
174 EXPORT_C void CHuiFxGroupLayer::Draw(CHuiFxEngine& aEngine, CHuiGc& aGc, CHuiFxRenderbuffer& aTarget, |
|
175 CHuiFxRenderbuffer& aSource) |
|
176 { |
|
177 #ifdef HUIFX_TRACE |
|
178 RDebug::Print(_L("CHuiFxGroupLayer::Draw - 0x%x "), this); |
|
179 #endif |
|
180 // TODO: fast path |
|
181 CHuiFxRenderbuffer* backBuffer = &aTarget; |
|
182 CHuiFxRenderbuffer* sourceBuffer = &aSource; |
|
183 THuiFxEngineType engineType = aEngine.EngineType(); |
|
184 |
|
185 // The root group does not require a back buffer |
|
186 if (!iIsRoot) |
|
187 { |
|
188 backBuffer = aEngine.AcquireRenderbuffer(iBackbufferRect.Size()); |
|
189 if (!backBuffer) |
|
190 { |
|
191 return; |
|
192 } |
|
193 sourceBuffer = backBuffer; |
|
194 |
|
195 // Translate the graphics context so that the content appears in the correct place |
|
196 backBuffer->BindAsRenderTarget(); |
|
197 aGc.Push(EHuiGcMatrixModel); |
|
198 if(engineType == EHuiFxEngineVg10) |
|
199 { |
|
200 aGc.Scale(EHuiGcMatrixModel, 1.0f, -1.0f, 1.0f); |
|
201 aGc.Translate(EHuiGcMatrixModel, 0.0f, -iBackbufferRect.Size().iHeight, 0.0f); |
|
202 } |
|
203 |
|
204 aGc.Translate(EHuiGcMatrixModel, -iBackbufferRect.iTl.iX, -iBackbufferRect.iTl.iY, 0.0f); |
|
205 backBuffer->UnbindAsRenderTarget(); |
|
206 } |
|
207 else if (iIsRoot && (&aTarget != aEngine.DefaultRenderbuffer())) |
|
208 { |
|
209 // We are rendering to offscreen buffer |
|
210 // Translate the graphics context so that the content appears in the correct place |
|
211 backBuffer->BindAsRenderTarget(); |
|
212 aGc.Push(EHuiGcMatrixModel); |
|
213 if(engineType == EHuiFxEngineVg10) |
|
214 { |
|
215 aGc.Scale(EHuiGcMatrixModel, 1.0f, -1.0f, 1.0f); |
|
216 aGc.Translate(EHuiGcMatrixModel, 0.0f, -iBackbufferRect.Size().iHeight, 0.0f); |
|
217 } |
|
218 |
|
219 aGc.Translate(EHuiGcMatrixModel, -iBackbufferRect.iTl.iX, -iBackbufferRect.iTl.iY, 0.0f); |
|
220 backBuffer->UnbindAsRenderTarget(); |
|
221 } |
|
222 |
|
223 for (TInt i = 0; i < iLayers.Count(); i++) |
|
224 { |
|
225 iLayers[i]->Draw(aEngine, aGc, *backBuffer, *sourceBuffer); |
|
226 } |
|
227 |
|
228 // The root group does not support composition |
|
229 if (!iIsRoot) |
|
230 { |
|
231 TRect compSourceRect(TPoint(0, 0), iBackbufferRect.Size()); |
|
232 TInt alpha = 0xff; // TODO |
|
233 if(engineType == EHuiFxEngineVg10) |
|
234 { |
|
235 backBuffer->BindAsRenderTarget(); |
|
236 aGc.Pop(EHuiGcMatrixModel); |
|
237 backBuffer->UnbindAsRenderTarget(); |
|
238 } |
|
239 else |
|
240 { |
|
241 aGc.Pop(EHuiGcMatrixModel); |
|
242 } |
|
243 |
|
244 // Composite the result |
|
245 TRect compositionTargetRect(TargetRect()); |
|
246 compositionTargetRect.Move(-aTarget.Position()); |
|
247 |
|
248 aEngine.Composite(aTarget, *backBuffer, compositionTargetRect, compSourceRect, BlendingMode(), alpha); |
|
249 aEngine.ReleaseRenderbuffer(backBuffer); |
|
250 } |
|
251 else if (iIsRoot && (&aTarget != aEngine.DefaultRenderbuffer())) |
|
252 { |
|
253 // We did rendering to offscreen buffer |
|
254 if(engineType == EHuiFxEngineVg10) |
|
255 { |
|
256 backBuffer->BindAsRenderTarget(); |
|
257 aGc.Pop(EHuiGcMatrixModel); |
|
258 backBuffer->UnbindAsRenderTarget(); |
|
259 } |
|
260 else |
|
261 { |
|
262 aGc.Pop(EHuiGcMatrixModel); |
|
263 } |
|
264 } |
|
265 } |
|
266 |
|
267 EXPORT_C void CHuiFxGroupLayer::AddLayerL(const CHuiFxLayer* aLayer) |
|
268 { |
|
269 iLayers.AppendL(aLayer); |
|
270 } |
|
271 |
|
272 EXPORT_C TBool CHuiFxGroupLayer::VisualArea( TRect& aRect ) |
|
273 { |
|
274 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
275 { |
|
276 if( iLayers[i]->Type() == ELayerTypeFilter ) |
|
277 { |
|
278 // found filter layer before visual => should apply to whole screen |
|
279 return EFalse; |
|
280 } |
|
281 else if(iLayers[i]->VisualArea( aRect )) |
|
282 { |
|
283 return ETrue; |
|
284 } |
|
285 } |
|
286 return EFalse; |
|
287 } |
|
288 |
|
289 EXPORT_C void CHuiFxGroupLayer::ApplyMargin( TRect &aRect ) |
|
290 { |
|
291 if (IsMarginEnabled()) |
|
292 { |
|
293 TMargins m; |
|
294 Margin(m); |
|
295 aRect.iTl.iX -= m.iLeft; |
|
296 aRect.iTl.iY -= m.iTop; |
|
297 aRect.iBr.iX += m.iRight; |
|
298 aRect.iBr.iY += m.iBottom; |
|
299 } |
|
300 } |
|
301 |
|
302 EXPORT_C TBool CHuiFxGroupLayer::Margin( TMargins &aMargin ) |
|
303 { |
|
304 TMargins m; |
|
305 m.iLeft = 0; |
|
306 m.iRight = 0; |
|
307 m.iTop = 0; |
|
308 m.iBottom = 0; |
|
309 for( TInt i=0; i < iLayers.Count() ; i++) |
|
310 { |
|
311 TMargins m2; |
|
312 if ( iLayers[i]->Margin(m2) ) |
|
313 { |
|
314 m.iLeft += m2.iLeft; |
|
315 m.iRight += m2.iRight; |
|
316 m.iTop += m2.iTop; |
|
317 m.iBottom += m2.iBottom; |
|
318 } |
|
319 } |
|
320 aMargin = m; |
|
321 return ETrue; |
|
322 } |
|
323 void CHuiFxGroupLayer::EnableMarginApplyChildren(TBool aEnable) |
|
324 { |
|
325 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
326 { |
|
327 iLayers[i]->EnableMargin(aEnable); |
|
328 } |
|
329 } |
|
330 |
|
331 EXPORT_C void CHuiFxGroupLayer::AdvanceTime(TReal32 aElapsedTime) |
|
332 { |
|
333 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
334 { |
|
335 iLayers[i]->AdvanceTime(aElapsedTime); |
|
336 } |
|
337 } |
|
338 |
|
339 EXPORT_C TBool CHuiFxGroupLayer::Changed() const |
|
340 { |
|
341 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
342 { |
|
343 if (iLayers[i]->Changed()) |
|
344 { |
|
345 #ifdef HUIFX_TRACE |
|
346 RDebug::Print(_L("CHuiFxGroupLayer::Changed true - 0x%x,"), this); |
|
347 #endif |
|
348 return ETrue; |
|
349 } |
|
350 } |
|
351 #ifdef HUIFX_TRACE |
|
352 RDebug::Print(_L("CHuiFxGroupLayer::Changed false- 0x%x,"), this); |
|
353 #endif |
|
354 return EFalse; |
|
355 } |
|
356 |
|
357 TBool CHuiFxGroupLayer::IsAnimated() const |
|
358 { |
|
359 if (CHuiFxLayer::IsAnimated()) |
|
360 { |
|
361 return ETrue; |
|
362 } |
|
363 else |
|
364 { |
|
365 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
366 { |
|
367 if (iLayers[i]->IsAnimated()) |
|
368 { |
|
369 return ETrue; |
|
370 } |
|
371 } |
|
372 } |
|
373 return EFalse; |
|
374 } |
|
375 |
|
376 TBool CHuiFxGroupLayer::IsTransformed() const |
|
377 { |
|
378 if (CHuiFxLayer::IsTransformed()) |
|
379 { |
|
380 return ETrue; |
|
381 } |
|
382 else |
|
383 { |
|
384 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
385 { |
|
386 if (iLayers[i]->IsTransformed()) |
|
387 { |
|
388 return ETrue; |
|
389 } |
|
390 } |
|
391 } |
|
392 return EFalse; |
|
393 } |
|
394 |
|
395 TBool CHuiFxGroupLayer::IsFiltered() const |
|
396 { |
|
397 if (CHuiFxLayer::IsFiltered()) |
|
398 { |
|
399 return ETrue; |
|
400 } |
|
401 else |
|
402 { |
|
403 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
404 { |
|
405 if (iLayers[i]->IsFiltered()) |
|
406 { |
|
407 return ETrue; |
|
408 } |
|
409 } |
|
410 } |
|
411 return EFalse; |
|
412 } |
|
413 |
|
414 TBool CHuiFxGroupLayer::IsSemitransparent() const |
|
415 { |
|
416 if (CHuiFxLayer::IsSemitransparent()) |
|
417 { |
|
418 return ETrue; |
|
419 } |
|
420 else |
|
421 { |
|
422 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
423 { |
|
424 if (iLayers[i]->IsSemitransparent()) |
|
425 { |
|
426 return ETrue; |
|
427 } |
|
428 } |
|
429 } |
|
430 return EFalse; |
|
431 } |
|
432 |
|
433 |
|
434 TInt CHuiFxGroupLayer::LayerCount() const |
|
435 { |
|
436 return iLayers.Count(); |
|
437 } |
|
438 |
|
439 CHuiFxLayer& CHuiFxGroupLayer::Layer(TInt aIndex) const |
|
440 { |
|
441 return *iLayers[aIndex]; |
|
442 } |
|
443 void CHuiFxGroupLayer::FxmlVisualInputs(RArray<THuiFxVisualSrcType> &aArray) |
|
444 { |
|
445 for( TInt i=0 ; i < iLayers.Count() ; i++ ) |
|
446 { |
|
447 iLayers[i]->FxmlVisualInputs(aArray); |
|
448 } |
|
449 } |