15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 // System includes |
18 // System includes |
19 #include <AknUtils.h> |
19 #include <AknUtils.h> |
20 #include <AknPriv.hrh> |
|
21 |
20 |
22 // User includes |
21 // User includes |
23 #include "xnappuiadapter.h" |
22 #include "xnappuiadapter.h" |
24 #include "xnviewadapter.h" |
|
25 #include "xnfocuscontrol.h" |
23 #include "xnfocuscontrol.h" |
26 #include "xnkeyeventdispatcher.h" |
24 #include "xnkeyeventdispatcher.h" |
27 #include "xntype.h" |
25 #include "xntype.h" |
28 #include "xncomponentnodeimpl.h" |
26 #include "xncomponentnodeimpl.h" |
29 #include "xnproperty.h" |
27 #include "xnproperty.h" |
40 // Local macros |
38 // Local macros |
41 #define IS_ARROW_KEY( k ) \ |
39 #define IS_ARROW_KEY( k ) \ |
42 ( k == EStdKeyLeftArrow || k == EStdKeyRightArrow || \ |
40 ( k == EStdKeyLeftArrow || k == EStdKeyRightArrow || \ |
43 k == EStdKeyUpArrow || k == EStdKeyDownArrow ) |
41 k == EStdKeyUpArrow || k == EStdKeyDownArrow ) |
44 |
42 |
45 // Constants |
43 const TInt KOneView = 1; |
46 const TInt KOneView( 1 ); |
|
47 |
|
48 _LIT8( KEnablePartialInput, "splitinputenabled" ); |
|
49 _LIT8( KTextEditor, "texteditor" ); |
|
50 |
44 |
51 // ----------------------------------------------------------------------------- |
45 // ----------------------------------------------------------------------------- |
52 // SetInitialFocusL |
46 // SetInitialFocusL |
53 // ----------------------------------------------------------------------------- |
47 // ----------------------------------------------------------------------------- |
54 // |
48 // |
179 // |
169 // |
180 void CXnKeyEventDispatcher::ConstructL() |
170 void CXnKeyEventDispatcher::ConstructL() |
181 { |
171 { |
182 MakeVisible( EFalse ); |
172 MakeVisible( EFalse ); |
183 |
173 |
184 CXnAppUiAdapter& appui( iUiEngine.AppUiAdapter() ); |
174 iUiEngine.ViewManager()->AddObserver( *this ); |
185 |
|
186 appui.UiStateListener().AddObserver( *this ); |
|
187 |
|
188 appui.ViewManager().AddObserver( *this ); |
|
189 |
175 |
190 iCoeEnv->AddMessageMonitorObserverL( *this ); |
176 iCoeEnv->AddMessageMonitorObserverL( *this ); |
191 } |
177 } |
192 |
178 |
193 // ----------------------------------------------------------------------------- |
179 // ----------------------------------------------------------------------------- |
240 } |
226 } |
241 } |
227 } |
242 } |
228 } |
243 |
229 |
244 // ----------------------------------------------------------------------------- |
230 // ----------------------------------------------------------------------------- |
245 // CXnKeyEventDispatcher::NotifyStatusPaneSizeChanged() |
|
246 // |
|
247 // ----------------------------------------------------------------------------- |
|
248 // |
|
249 void CXnKeyEventDispatcher::NotifyStatusPaneSizeChanged() |
|
250 { |
|
251 // No implementation required |
|
252 } |
|
253 |
|
254 // ----------------------------------------------------------------------------- |
|
255 // CXnKeyEventDispatcher::NotifyResourceChanged() |
|
256 // |
|
257 // ----------------------------------------------------------------------------- |
|
258 // |
|
259 void CXnKeyEventDispatcher::NotifyResourceChanged( TInt aType ) |
|
260 { |
|
261 if ( aType == KAknSplitInputEnabled ) |
|
262 { |
|
263 if ( iActiveTextEditor ) |
|
264 { |
|
265 CXnProperty* prop( NULL ); |
|
266 |
|
267 TRAP_IGNORE( prop = |
|
268 iActiveTextEditor->GetPropertyL( KEnablePartialInput ) ); |
|
269 |
|
270 if ( prop && prop->StringValue() == XnPropertyNames::KTrue ) |
|
271 { |
|
272 iUiEngine.EnablePartialTouchInput( iActiveTextEditor, ETrue ); |
|
273 } |
|
274 } |
|
275 } |
|
276 else if ( aType == KAknSplitInputDisabled ) |
|
277 { |
|
278 iUiEngine.EnablePartialTouchInput( NULL, EFalse ); |
|
279 } |
|
280 } |
|
281 |
|
282 // ----------------------------------------------------------------------------- |
|
283 // CXnKeyEventDispatcher::PointerEvent() |
231 // CXnKeyEventDispatcher::PointerEvent() |
284 // |
232 // |
285 // ----------------------------------------------------------------------------- |
233 // ----------------------------------------------------------------------------- |
286 // |
234 // |
287 const TPointerEvent& CXnKeyEventDispatcher::PointerEvent() const |
235 const TPointerEvent& CXnKeyEventDispatcher::PointerEvent() const |
288 { |
236 { |
289 return iPointerEvent; |
237 return iPointerEvent; |
290 } |
|
291 |
|
292 // ----------------------------------------------------------------------------- |
|
293 // CXnKeyEventDispatcher::SetTextEditorActive() |
|
294 // |
|
295 // ----------------------------------------------------------------------------- |
|
296 // |
|
297 void CXnKeyEventDispatcher::SetTextEditorActive( CXnNode* aNode, |
|
298 TBool aActivate ) |
|
299 { |
|
300 if ( iActiveTextEditor && iActiveTextEditor != aNode ) |
|
301 { |
|
302 CXnNode* activeTextEditor( iActiveTextEditor ); |
|
303 iActiveTextEditor = NULL; |
|
304 |
|
305 // Run lose focus to text editor node |
|
306 TRAP_IGNORE( SetNodeL( activeTextEditor, NULL, ETrue ) ); |
|
307 } |
|
308 |
|
309 if ( aActivate && aNode && aNode->Type()->Type() == KTextEditor ) |
|
310 { |
|
311 iActiveTextEditor = aNode; |
|
312 } |
|
313 else |
|
314 { |
|
315 iActiveTextEditor = NULL; |
|
316 } |
|
317 } |
|
318 |
|
319 // ----------------------------------------------------------------------------- |
|
320 // CXnKeyEventDispatcher::IsTextEditorActive |
|
321 // |
|
322 // ----------------------------------------------------------------------------- |
|
323 // |
|
324 TBool CXnKeyEventDispatcher::IsTextEditorActive() const |
|
325 { |
|
326 return iActiveTextEditor ? ETrue : EFalse; |
|
327 } |
238 } |
328 |
239 |
329 // ----------------------------------------------------------------------------- |
240 // ----------------------------------------------------------------------------- |
330 // CXnKeyEventDispatcher::OfferKeyEventL |
241 // CXnKeyEventDispatcher::OfferKeyEventL |
331 // Handles key events. |
242 // Handles key events. |
356 aKeyEvent.iScanCode == EStdKeyYes || |
267 aKeyEvent.iScanCode == EStdKeyYes || |
357 aKeyEvent.iScanCode == EStdKeyNo ) |
268 aKeyEvent.iScanCode == EStdKeyNo ) |
358 { |
269 { |
359 keyYesNoApps = ETrue; |
270 keyYesNoApps = ETrue; |
360 |
271 |
361 if ( aKeyEvent.iScanCode == EStdKeyNo && aType == EEventKey ) |
|
362 { |
|
363 iUiEngine.AppUiAdapter().ViewAdapter().CloseAllPopupsL(); |
|
364 } |
|
365 |
|
366 iFocusChanged = EFalse; |
272 iFocusChanged = EFalse; |
367 |
273 |
368 // AppsKey, YesKey, NoKey events must be always handled, and if we don't |
274 // AppsKey, YesKey, NoKey events must be always handled, and if we don't |
369 // have a focused node, then let the view handle the event |
275 // have a focused node, then let the view handle the event |
370 node = ( !iNode ) ? iUiEngine.ActiveView() : iNode; |
276 node = ( !iNode ) ? iUiEngine.ActiveView() : iNode; |
373 { |
279 { |
374 CXnAppUiAdapter& appui( iUiEngine.AppUiAdapter() ); |
280 CXnAppUiAdapter& appui( iUiEngine.AppUiAdapter() ); |
375 |
281 |
376 if ( IS_ARROW_KEY( aKeyEvent.iScanCode ) && aType == EEventKey ) |
282 if ( IS_ARROW_KEY( aKeyEvent.iScanCode ) && aType == EEventKey ) |
377 { |
283 { |
378 if ( !appui.FocusShown() || !iNode ) |
284 if ( !appui.FocusShown() ) |
379 { |
285 { |
380 appui.ShowFocus(); |
286 appui.ShowFocus(); |
381 |
287 |
382 if ( !iNode ) |
288 if ( !iNode ) |
383 { |
289 { |
384 if ( iActiveTextEditor ) |
290 // Find initial location for focus |
|
291 ResolveAndSetFocusL(); |
|
292 |
|
293 // If focus is still not set, we are in normal mode and the view is empty. |
|
294 // left and right arrows lead to next/previous view. When other arrows |
|
295 // are pressed, the focus is hidden. |
|
296 if( !iNode ) |
385 { |
297 { |
386 iNode = iActiveTextEditor; |
298 if( iUiEngine.ViewManager()->ViewAmount() != KOneView && |
|
299 aKeyEvent.iScanCode == EStdKeyRightArrow ) |
|
300 { |
|
301 iUiEngine.ViewManager()->ActivateNextViewL(); |
|
302 } |
|
303 else if( iUiEngine.ViewManager()->ViewAmount() != KOneView && |
|
304 aKeyEvent.iScanCode == EStdKeyLeftArrow ) |
|
305 { |
|
306 iUiEngine.ViewManager()->ActivatePreviousViewL(); |
|
307 } |
|
308 else |
|
309 { |
|
310 // hide focus if view is not switched |
|
311 appui.HideFocus(); |
|
312 } |
387 } |
313 } |
388 else |
314 |
389 { |
315 return EKeyWasConsumed; |
390 // Find initial location for focus |
|
391 ResolveAndSetFocusL(); |
|
392 |
|
393 // If focus is still not set, we are in normal mode and the view is empty. |
|
394 // left and right arrows lead to next/previous view. When other arrows |
|
395 // are pressed, the focus is hidden. |
|
396 if( !iNode ) |
|
397 { |
|
398 if( iUiEngine.ViewManager()->ViewAmount() != KOneView && |
|
399 aKeyEvent.iScanCode == EStdKeyRightArrow ) |
|
400 { |
|
401 iUiEngine.ViewManager()->ActivateNextViewL(); |
|
402 } |
|
403 else if( iUiEngine.ViewManager()->ViewAmount() != KOneView && |
|
404 aKeyEvent.iScanCode == EStdKeyLeftArrow ) |
|
405 { |
|
406 iUiEngine.ViewManager()->ActivatePreviousViewL(); |
|
407 } |
|
408 else |
|
409 { |
|
410 // hide focus if view is not switched |
|
411 appui.HideFocus(); |
|
412 } |
|
413 } |
|
414 |
|
415 return EKeyWasConsumed; |
|
416 } |
|
417 } |
316 } |
418 } |
317 } |
419 } |
318 } |
420 |
319 |
421 CCoeControl* editmode( iUiEngine.EditMode() ); |
320 CCoeControl* editmode( iUiEngine.EditMode() ); |
530 void CXnKeyEventDispatcher::SetNodeL( CXnNode* aToLose, CXnNode* aToGain, |
429 void CXnKeyEventDispatcher::SetNodeL( CXnNode* aToLose, CXnNode* aToGain, |
531 TBool aNotify, TInt aSource ) |
430 TBool aNotify, TInt aSource ) |
532 { |
431 { |
533 if ( aToLose ) |
432 if ( aToLose ) |
534 { |
433 { |
535 CXnControlAdapter* adapter( aToLose->Control() ); |
|
536 |
|
537 // Don't change control focus when <texteditor> element is focused |
|
538 if ( adapter && !iActiveTextEditor ) |
|
539 { |
|
540 adapter->SetFocus( EFalse ); |
|
541 } |
|
542 |
|
543 aToLose->SetDirtyL( XnDirtyLevel::ERender ); |
434 aToLose->SetDirtyL( XnDirtyLevel::ERender ); |
544 |
435 |
545 aToLose->UnsetStateL( XnPropertyNames::style::common::KFocus ); |
436 aToLose->UnsetStateL( XnPropertyNames::style::common::KFocus ); |
546 aToLose->UnsetStateL( XnPropertyNames::style::common::KHold ); |
437 aToLose->UnsetStateL( XnPropertyNames::style::common::KHold ); |
547 aToLose->UnsetStateL( XnPropertyNames::style::common::KActive ); |
438 aToLose->UnsetStateL( XnPropertyNames::style::common::KActive ); |
551 if ( !iLoseFocus ) |
442 if ( !iLoseFocus ) |
552 { |
443 { |
553 iLoseFocus = BuildTriggerNodeL( iUiEngine, |
444 iLoseFocus = BuildTriggerNodeL( iUiEngine, |
554 XnPropertyNames::action::trigger::name::KLoseFocus ); |
445 XnPropertyNames::action::trigger::name::KLoseFocus ); |
555 } |
446 } |
556 |
447 |
557 if ( iActiveTextEditor != aToLose ) |
448 aToLose->ReportXuikonEventL( *iLoseFocus ); |
558 { |
449 } |
559 aToLose->ReportXuikonEventL( *iLoseFocus ); |
450 |
560 } |
451 CXnControlAdapter* adapter( aToLose->Control() ); |
|
452 |
|
453 if ( adapter ) |
|
454 { |
|
455 adapter->SetFocus( EFalse ); |
561 } |
456 } |
562 } |
457 } |
563 |
458 |
564 if ( aToGain ) |
459 if ( aToGain ) |
565 { |
460 { |
566 TBool isTextEditor( aToGain->Type()->Type() == KTextEditor ); |
|
567 |
|
568 if ( iActiveTextEditor && ( ( aSource != XnEventSource::EStylus && !isTextEditor ) || |
|
569 ( iActiveTextEditor->Namespace() != aToGain->Namespace() ) || |
|
570 ( isTextEditor && iActiveTextEditor != aToGain ) ) ) |
|
571 { |
|
572 // Remove focus from active <texteditor> element |
|
573 SetTextEditorActive( NULL, EFalse ); |
|
574 } |
|
575 |
|
576 CXnControlAdapter* adapter( aToGain->Control() ); |
|
577 |
|
578 // Don't change control focus when <texteditor> element is focused |
|
579 if ( adapter && !iActiveTextEditor ) |
|
580 { |
|
581 adapter->SetFocus( ETrue ); |
|
582 } |
|
583 |
|
584 aToGain->SetDirtyL( XnDirtyLevel::ERender ); |
461 aToGain->SetDirtyL( XnDirtyLevel::ERender ); |
585 |
462 |
586 if ( aNotify ) |
463 if ( aNotify ) |
587 { |
464 { |
588 if ( !iGainFocus ) |
465 if ( !iGainFocus ) |
589 { |
466 { |
590 iGainFocus = BuildTriggerNodeL( iUiEngine, |
467 iGainFocus = BuildTriggerNodeL( iUiEngine, |
591 XnPropertyNames::action::trigger::name::KGainFocus ); |
468 XnPropertyNames::action::trigger::name::KGainFocus ); |
592 } |
469 } |
593 |
470 |
594 if ( iActiveTextEditor != aToGain ) |
471 aToGain->ReportXuikonEventL( *iGainFocus, aSource ); |
595 { |
472 } |
596 aToGain->ReportXuikonEventL( *iGainFocus, aSource ); |
473 |
597 } |
474 CXnControlAdapter* adapter( aToGain->Control() ); |
598 } |
475 |
599 |
476 if ( adapter ) |
600 if ( isTextEditor ) |
477 { |
601 { |
478 adapter->SetFocus( ETrue ); |
602 // Set active <texteditor> element |
479 } |
603 SetTextEditorActive( aToGain, ETrue ); |
|
604 } |
|
605 } |
480 } |
606 } |
481 } |
607 |
482 |
608 // ----------------------------------------------------------------------------- |
483 // ----------------------------------------------------------------------------- |
609 // CXnKeyEventDispatcher::FocusedNode |
484 // CXnKeyEventDispatcher::FocusedNode |
793 { |
665 { |
794 if ( aPluginData.Active() ) |
666 if ( aPluginData.Active() ) |
795 { |
667 { |
796 ClearPassiveFocusedNodesL(); |
668 ClearPassiveFocusedNodesL(); |
797 |
669 |
798 CXnViewData& activeViewData( |
|
799 iUiEngine.ViewManager()->ActiveViewData() ); |
|
800 |
|
801 if ( iNode ) |
670 if ( iNode ) |
802 { |
671 { |
|
672 CXnViewData& activeViewData( |
|
673 iUiEngine.ViewManager()->ActiveViewData() ); |
|
674 |
803 const CXnPluginData* pluginData( |
675 const CXnPluginData* pluginData( |
804 activeViewData.Plugin( iNode ) ); |
676 activeViewData.Plugin( iNode ) ); |
805 |
677 |
806 if ( pluginData == &aPluginData ) |
678 if ( pluginData == &aPluginData ) |
807 { |
679 { |
808 // The plugin is removed which was holding focus |
680 // The plugin is removed which was holding focus |
809 ClearStateL(); |
681 ClearStateL(); |
810 } |
682 } |
811 } |
|
812 |
|
813 if ( iActiveTextEditor ) |
|
814 { |
|
815 const CXnPluginData* pluginData( |
|
816 activeViewData.Plugin( iActiveTextEditor ) ); |
|
817 |
|
818 if ( pluginData == &aPluginData ) |
|
819 { |
|
820 SetTextEditorActive( NULL, EFalse ); |
|
821 } |
|
822 } |
683 } |
823 } |
684 } |
824 } |
685 } |
825 |
686 |
826 // ----------------------------------------------------------------------------- |
687 // ----------------------------------------------------------------------------- |