chxavnavipanecontrol.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:22k
源码类别:

Symbian

开发平台:

C/C++

  1. /*============================================================================*
  2.  *
  3.  * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
  4.  *
  5.  *============================================================================*/
  6. /*
  7.    Description: 
  8.    draws and manages navi pane area; display comprises a status area at the
  9.    left and a timer area at the right; the status area displays status text
  10.    or status images
  11. */
  12. #include <aknutils.h>
  13. #include "chxavmisc.h"
  14. #include "chxavcleanupstack.h"
  15. #include "chxavcleanstring.h"
  16. #include "hxsym_debug.h"
  17. #include "hxsym_leaveutil.h"
  18. #include "realplayer.mbg"
  19. #include "chxavnavipanecontrol.h"
  20. namespace
  21. {
  22. _LIT(KEllipse, "...");
  23. const TUint KTimerTextMaxChars = 10;
  24. const TUint k_msStatusBlinkInterval = 700;
  25. const TUint k_msAnimateEllipseInterval = 800;
  26. const TUint CX_PANE_LEFT_BORDER             = 0;
  27. const TUint CX_PAUSE_INDIC_RIGHT_BORDER     = 4;
  28. const TUint CX_MUTE_INDIC_RIGHT_BORDER      = 4;
  29. const TUint CX_STATUS_TEXT_RIGHT_BORDER     = 2;
  30. const TUint CX_PANE_RIGHT_BORDER            = 2;
  31. const TUint CX_TIMER_TEXT_RIGHT_BORDER      = 2;
  32. // control ids
  33. enum
  34. {   
  35.     CID_TIMER_TEXT = 1,
  36.     CID_STATUS_TEXT,
  37.     CID_ELLIPSE_TEXT
  38. };
  39. ////////////////////////////////////////////
  40. // (re) initialize image control; create control
  41. // if not created yet; position defaults to parent 
  42. // left, vertically centered
  43. void InitStatusImage
  44. (
  45. refptr<CEikImage>& spImageOut,
  46. const CCoeControl& parentControl,
  47. bool bVisible, 
  48. TInt idxImage, 
  49. TInt idxMask
  50. )
  51. {
  52.     if(!spImageOut)
  53.     {
  54.         spImageOut = new (ELeave) CEikImage();
  55.         spImageOut->SetContainerWindowL(parentControl);
  56.     }
  57.     const TRect& rcParent = parentControl.Rect();
  58.     // set the images from image file
  59.     TFileName* pImageFilePath = CHXAvFile::AllocAppFolderPathL(CHXAvUtil::KImagesMBMName);
  60.     AUTO_PUSH_POP_DEL(pImageFilePath);
  61.     spImageOut->CreatePictureFromFileL(*pImageFilePath, idxImage, idxMask);
  62.     TRect rc;
  63.     TSize size = spImageOut->MinimumSize();
  64.     // set image top-left
  65.     rc.iTl.iX = rcParent.iTl.iX;
  66.     
  67.     // center vertically
  68.     rc.iTl.iY = (rcParent.Height() - size.iHeight) / 2;
  69.     
  70.     // set and update image rect
  71.     rc.SetSize(size);
  72.     spImageOut->SetRect(rc);
  73.     spImageOut->MakeVisible(bVisible);
  74.     spImageOut->ActivateL();
  75. }
  76. } // ns anon
  77. ////////////////////////////////
  78. //
  79. CHXAvNaviPaneControl* CHXAvNaviPaneControl::NewL(CHXAvPlayer* pPlayer, const CCoeControl& parent)
  80. {
  81.     CHXAvNaviPaneControl* pSelf = new(ELeave) CHXAvNaviPaneControl();
  82.     AUTO_PUSH_POP(pSelf);
  83.     pSelf->ConstructL(pPlayer, parent);
  84.     return pSelf;
  85. }
  86. ////////////////////////////////////////
  87. //
  88. CHXAvNaviPaneControl::CHXAvNaviPaneControl()
  89. : m_bBlinkIsVisible(false)
  90. , m_bHideTimerForStatusText(false)
  91. , m_bNeedRefresh(false)
  92. , m_ellipseCount(0)
  93. {
  94. }
  95. ////////////////////////////////////////
  96. //
  97. CHXAvNaviPaneControl::~CHXAvNaviPaneControl()
  98. {
  99.     if(m_spPlayer)
  100.     {
  101.         m_spPlayer->GetPlayerState().RemoveObserver(this);
  102.     }
  103. }
  104. ////////////////////////////
  105. //
  106. void CHXAvNaviPaneControl::ConstructL(CHXAvPlayer* pPlayer, const CCoeControl& parent)
  107. {
  108.   
  109.     m_spPlayer = pPlayer;
  110.     m_spPlayer->GetPlayerState().AddObserver(this);
  111.     SetContainerWindowL(parent);
  112.     TRect rc(parent.Rect());
  113.     SetRect(rc);
  114.     // save this; we want to draw over whole navi control (see SizeChanged)
  115.     m_rcParent = rc;
  116.     // XXXLCM move blink and animate logic to subclass of text control!
  117.     // blink callback for pause indicator
  118.     const CHXAvCommand& cmdToggle =
  119.         MakeCommand(this, &CHXAvNaviPaneControl::ToggleStatusBlinkAndDraw);
  120.     m_cbBlink.ConstructL(cmdToggle);
  121.     // animate callback for ellipses (e.g., connecting...)
  122.     const CHXAvCommand& cmdAnimate =
  123.         MakeCommand(this, &CHXAvNaviPaneControl::OnAnimateEllipseTick);
  124.     m_cbAnimateEllipse.ConstructL(cmdAnimate);
  125.     
  126.   
  127.     //
  128.     // play state image (pause indicator)
  129.     //
  130.     InitStatusImage(m_spPlayStateImage, *this, false,
  131.         EMbmRealplayerQgn_indi_paused, EMbmRealplayerQgn_indi_paused_mask);
  132.  
  133.     //
  134.     // vol state image (mute indicator)
  135.     //
  136.     InitStatusImage(m_spVolStateImage, *this, m_spPlayer->IsMuted(),
  137.         EMbmRealplayerVol_mute,EMbmRealplayerVol_mute_mask);
  138.     //
  139.     // live state images
  140.     //
  141.     InitStatusImage(m_spLiveStateOnImage, *this, false,
  142.         EMbmRealplayerQgn_indi_live_enabled, EMbmRealplayerQgn_indi_live_enabled_mask);
  143.     InitStatusImage(m_spLiveStateOffImage, *this, false,
  144.         EMbmRealplayerQgn_indi_live_disabled, EMbmRealplayerQgn_indi_live_disabled_mask);
  145.     
  146.     //
  147.     // timer text
  148.     //
  149.    
  150.     m_spTimerText = CHXAvTextControl::NewL(*this, CID_TIMER_TEXT);
  151.     m_spTimerText->SetTruncateWithEllipsis(false);
  152.     m_spTimerText->SetJustification(CGraphicsContext::ERight);
  153.     m_spTimerText->SetTextColor(KRgbWhite);
  154.     //m_spTimerText->SetBackgroundColor(TRgb(0,0,225));
  155.     //NumberPlain5 (very small and rectangular)
  156.     m_spTimerText->UpdateFont(LatinBold12());
  157.     //
  158.     // status text
  159.     //
  160.     m_spStatusText = CHXAvTextControl::NewL(*this, CID_STATUS_TEXT);
  161.     m_spStatusText->SetTextColor(KRgbWhite);
  162.     m_spStatusText->UpdateFont(LatinPlain12());
  163.     m_spStatusText->MakeVisible(EFalse);
  164.     //
  165.     // ellipse following (part of) status text
  166.     //
  167.     m_spEllipseText = CHXAvTextControl::NewL(*this, CID_ELLIPSE_TEXT);
  168.     m_spEllipseText->SetTextColor(KRgbWhite);
  169.     m_spEllipseText->UpdateFont(LatinPlain12());
  170.     m_spEllipseText->MakeVisible(EFalse);
  171.     // position controls that never change size/location unless parent rect changes
  172.     DoStaticLayout();
  173.     // temporary rects (adjusted as text is displayed)
  174.     m_spTimerText->SetRect(rc);
  175.     m_spStatusText->SetRect(rc);
  176.     m_bNeedRefresh = true;
  177.    
  178. }
  179. ////////////////////////////////////////////////////
  180. //
  181. void CHXAvNaviPaneControl::SizeChanged()
  182. {
  183.     // navi control container re-sizes us (a decorator) to fit within
  184.     // its window; this is the parent rect size less space for scroll
  185.     // arrows; we want to draw over the area where the scroll arrows would
  186.     // go (we never use them), so we ignore our true rect (XXXLCM nicer 
  187.     // if we could just turn off scroll arrows)
  188.  
  189.     // if( constructed ) { DoStaticLayout(); } // no!
  190. }
  191. ////////////////////////////////////////////////
  192. //
  193. // layout controls in their proper positions; vertical positions should be set
  194. // during construction and never change; henceforth, these positions never change
  195. //
  196. void CHXAvNaviPaneControl::DoStaticLayout()
  197. {
  198.     // {pause indic}{mute indic}{timer text}{live status}
  199.     TRect rcRegion = m_rcParent; //Rect();
  200.     // pause indicator goes at far left (plus border)
  201.     TPoint ptPause = m_spPlayStateImage->Position();
  202.     ptPause.iX = CX_PANE_LEFT_BORDER;
  203.     m_spPlayStateImage->SetPosition(ptPause);
  204.     // mute image goes just to right of pause indicator (plus border)
  205.     TPoint ptMute = m_spVolStateImage->Position();
  206.     ptMute.iX = m_spPlayStateImage->Rect().iBr.iX + CX_PAUSE_INDIC_RIGHT_BORDER;
  207.     m_spVolStateImage->SetPosition(ptMute);
  208.     // live status images go at far right (minus right border)
  209.     TPoint ptLiveState = m_spLiveStateOnImage->Position();
  210.     ptLiveState.iX = rcRegion.iBr.iX - (m_spLiveStateOnImage->Size().iWidth + CX_PANE_RIGHT_BORDER);
  211.     m_spLiveStateOnImage->SetPosition(ptLiveState);
  212.     m_spLiveStateOffImage->SetPosition(ptLiveState);
  213. }
  214. ////////////////////////////////////////////////////
  215. // calculate max area available for timer text
  216. void CHXAvNaviPaneControl::GetTimerTextMaxArea(TRect& rc)
  217. {
  218.     bool bLiveStateVisible = (m_spLiveStateOnImage->IsVisible() || m_spLiveStateOffImage->IsVisible());
  219.     // area (between left-most visible image and right-most visible image) goes to timer text
  220.     rc = m_rcParent;
  221.     if( bLiveStateVisible )
  222.     {
  223.         rc.iBr.iX = m_spLiveStateOnImage->Position().iX - CX_TIMER_TEXT_RIGHT_BORDER;
  224.     }
  225.     else
  226.     {
  227.         rc.iBr.iX -= CX_PANE_RIGHT_BORDER;
  228.     }
  229.     rc.iTl.iX = m_spPlayStateImage->Rect().iBr.iX + CX_PAUSE_INDIC_RIGHT_BORDER;
  230.     HX_ASSERT(rc.iTl.iX < rc.iBr.iX);
  231.     
  232. }
  233.     
  234. ////////////////////////////////////////////////////
  235. // update status text to reflect player state and show
  236. // if necessary; hide or show status images
  237. //
  238. // timer text should be updated first
  239. //
  240. void CHXAvNaviPaneControl::UpdateStatusAreaL()
  241. {    
  242.     const CHXAvPlayerState& state = m_spPlayer->GetPlayerState(); 
  243.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::UpdateStatusAreaL(): state = '%s'n", dbg::State(state.GetState())));
  244.     
  245.     HBufC* pbuff = 0;
  246.     bool bAnimateEllipse = false;
  247.     
  248.     switch(state.GetState())
  249.     {
  250.     case CHXAvPlayerState::Connecting:
  251.         HX_ASSERT(m_spPlayer->IsRemotePlayback());
  252.         HX_ASSERT(!m_spPlayer->HasPresStarted());
  253.         pbuff = CHXAvStringUtils::AllocResTextL(R_AVP_ST_CONNECTING);
  254.         bAnimateEllipse = true;
  255. break; 
  256.     case CHXAvPlayerState::Playing:
  257.         {
  258.             // only show buffering messages for remote clips
  259.             if(m_spPlayer->IsRemotePlayback())
  260.             {
  261.                 TInt resId;
  262.                 switch(state.GetBufferingState())
  263.                 {
  264.                     // show 'loading' when first buffering and after a seek
  265.                     case CHXAvPlayerState::BufferLoad:
  266.                     case CHXAvPlayerState::BufferSeek:
  267.                 resId = R_AVP_ST_LOADING_FORMAT;
  268.                 break;
  269.                     // show 'communicating' when buffering after congestion
  270.                     case CHXAvPlayerState::BufferPlain:
  271.                         resId = R_AVP_ST_BUFFERING_FORMAT;
  272.                         break;
  273.                     default:
  274.                         resId = -1;
  275.                         break;
  276.                 }
  277.                 if(resId != -1)
  278.                 {
  279.                     pbuff = CHXAvStringUtils::AllocResFormatTextL(resId, state.GetLastBufferPercent());
  280.                 }
  281.             }
  282.         }
  283. break;
  284.     default:
  285.         //
  286. // no status text for this state
  287.         //
  288.         // note: we can be in a buffering sub-state while paused and/or seeking, but
  289.         // we opt not to show a buffering message in these cases because it results
  290.         // in a nicer user experience
  291.         //
  292. break;
  293.     }
  294.     
  295.     if(pbuff)
  296.     {
  297.         AUTO_PUSH_POP_DEL(pbuff);
  298.         //
  299.         // Ideally we want clip timer text to remain visible to right of 
  300.         // status text. However, if status text is too long, we hide the
  301.         // clip timer text rather than partially obscure it (which looks bad)
  302.         //
  303.         // width of status text
  304.         const CFont* pFont = m_spStatusText->GetFont();
  305.         TInt cxStatus = CX_PANE_LEFT_BORDER + pFont->TextWidthInPixels(*pbuff) + CX_STATUS_TEXT_RIGHT_BORDER;
  306.         // width of ellipse
  307.         TInt cxEllipse = 0;
  308.         if(bAnimateEllipse)
  309.         {
  310.             pFont = m_spStatusText->GetFont();
  311.             cxEllipse += pFont->TextWidthInPixels(KEllipse);
  312.         }
  313.             
  314.         // width needed to display status and timer text
  315.         TInt cxNeeded =  cxStatus + cxEllipse + m_spTimerText->Size().iWidth + CX_TIMER_TEXT_RIGHT_BORDER;
  316.         TInt cxAvail = m_rcParent.Width();
  317.         if( cxNeeded > cxAvail )
  318.         {
  319.             // not enough room to show status and timer text
  320.             m_bHideTimerForStatusText = true;
  321.         }
  322.         // status text starts at far left
  323.         TRect rcStatus = m_rcParent;
  324.         rcStatus.iTl.iX += CX_PANE_LEFT_BORDER;
  325.         rcStatus.SetWidth(cxStatus);
  326.         // set and show status text
  327.         UpdateRectHelper(m_spStatusText.Ptr(), rcStatus);
  328.         UpdateTextHelper(m_spStatusText.Ptr(), *pbuff);
  329.         UpdateVisibilityHelper(m_spStatusText.Ptr(), true);
  330.         if(bAnimateEllipse)
  331.         {
  332.             // set and show ellipses after status
  333.             HX_ASSERT(cxEllipse > 0);
  334.          
  335.             TRect rcEllipse(rcStatus.iBr.iX, rcStatus.iTl.iY, rcStatus.iBr.iX + cxEllipse, rcStatus.iBr.iY);
  336.             UpdateRectHelper(m_spEllipseText.Ptr(), rcEllipse);
  337.             // start with empty ellipse - animation will fill it out as time goes by
  338.             UpdateTextHelper(m_spEllipseText.Ptr(), _L("")); 
  339.             m_ellipseCount = 0;
  340.         }
  341.        
  342.         
  343.         // hide status images
  344.         ShowPauseIndication(false);
  345.         UpdateVisibilityHelper(m_spVolStateImage.Ptr(), false);
  346.     }
  347.     else
  348.     {
  349.         // hide status control
  350.         UpdateVisibilityHelper(m_spStatusText.Ptr(), false);
  351.         
  352.         // restore status images
  353.         bool bIsPaused = (CHXAvPlayerState::Paused == m_spPlayer->GetPlayerState().GetState());
  354.         ShowPauseIndication(bIsPaused);
  355.         UpdateVisibilityHelper(m_spVolStateImage.Ptr(), m_spPlayer->IsMuted());
  356.         // timer doesn't need to be hidden anymore
  357.         m_bHideTimerForStatusText = false;
  358.     }
  359.     // set ellipse animation and visibility
  360.     ToggleEllipseAnimation(bAnimateEllipse);
  361.     UpdateVisibilityHelper(m_spEllipseText.Ptr(), bAnimateEllipse);
  362.     
  363. }
  364. ////////////////////////////////////////////////
  365. // helper
  366. //
  367. // calculate rect and set text for control that goes in timer area
  368. //
  369. void 
  370. CHXAvNaviPaneControl::SizeAndSetTimerAreaText(refptr<CHXAvTextControl>& pControl, const TDesC& text)
  371. {
  372.     // determine width needed
  373.     const CFont* pFont = pControl->GetFont();
  374.     TInt cxText = pFont->TextWidthInPixels(text);
  375.     TRect rcText;
  376.     GetTimerTextMaxArea(rcText);
  377.     if(cxText <= rcText.Width())
  378.     {
  379.         // shrink actual rect's left side so there is just enough
  380.         // so that text just fits
  381.         rcText.iTl.iX = rcText.iBr.iX - cxText;
  382.     } // else, clip...
  383.     
  384.     UpdateTextHelper(pControl.Ptr(), text);
  385.     UpdateRectHelper(pControl.Ptr(), rcText); 
  386. }
  387. ////////////////////////////////////////////////
  388. // helper
  389. void 
  390. CHXAvNaviPaneControl::GetTimerTextL(TUint msNow, TDes& timerTextOut) const
  391. {
  392.     HBufC* pTimeNow = CHXAvMisc::AllocTimerTextL(msNow);
  393.     AUTO_PUSH_POP_DEL(pTimeNow);
  394.     timerTextOut.Copy(*pTimeNow);
  395.     
  396.     const CHXSymClipInfo& info = m_spPlayer->GetClipInfo();
  397.     if( info.IsLive() )
  398.     {
  399.         // show current time only
  400.     }
  401.     else
  402.     {
  403.         // show current time and possibly total time
  404.         TUint msTotal = m_spPlayer->GetClipDuration();
  405.         if(msTotal)
  406.         {
  407.             if(msTotal < k_msPerHour)
  408.             {
  409.                 // only show total time if clip duration is under an hour
  410.                 HBufC* pTimeTotal = CHXAvMisc::AllocTimerTextL(msTotal);
  411.                 AUTO_PUSH_POP_DEL(pTimeTotal);
  412.                 timerTextOut.Append(_L("/"));
  413.         timerTextOut.Append(*pTimeTotal);
  414.             }
  415.         }
  416.         else
  417.         {
  418.             timerTextOut.Zero();
  419.         }
  420.     }
  421. }
  422. void CHXAvNaviPaneControl::DoTimerTextUpdateAndDraw()
  423. {
  424.     m_bNeedRefresh = false;
  425.     TRAPD(err, UpdateTimerTextL());
  426.     if(KErrNone == err)
  427.     {
  428.         UpdateTimerTextVisibility();
  429.         if( m_bNeedRefresh )
  430.         {
  431.             m_spRefreshCmd->Execute();
  432.         }
  433.     }
  434. }
  435. void CHXAvNaviPaneControl::DoUpdateEverythingAndDraw()
  436. {
  437.     m_bNeedRefresh = false;
  438.     TRAPD(err, UpdateEverythingL());
  439.     if( (KErrNone == err) && m_bNeedRefresh )
  440.     {
  441.         m_spRefreshCmd->Execute();
  442.     }
  443.     
  444. }
  445. void CHXAvNaviPaneControl::UpdateRectHelper(CCoeControl* pControl, const TRect& rc)
  446. {
  447.     if(pControl->Rect() != rc)
  448.     {
  449.         m_bNeedRefresh = true;
  450.         pControl->SetRect(rc);
  451.     }
  452. }
  453. void CHXAvNaviPaneControl::UpdateTextHelper(CHXAvTextControl* pControl, const TDesC& text)
  454. {
  455.     if( pControl->GetText().Compare(text) != 0 )
  456.     {
  457.         // text needs to change
  458.         m_bNeedRefresh = true;
  459.         pControl->SetText(text);
  460.     }
  461. }
  462. void CHXAvNaviPaneControl::UpdateVisibilityHelper(CCoeControl* pControl, bool bShow)
  463. {
  464.     if( bool(pControl->IsVisible()) != bShow)
  465.     {
  466.         // visibility needs to change
  467.         m_bNeedRefresh = true;
  468.         pControl->MakeVisible(bShow);
  469.     }
  470. }
  471. ////////////////////////////////////////
  472. //IHXSymPlayerStateObserver
  473. void CHXAvNaviPaneControl::OnNewPos(ULONG32 /*msNewTime*/)
  474. {
  475.     //DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnNewPos(): time = %lun", msNewTime));
  476.     DoTimerTextUpdateAndDraw();
  477. }
  478. ////////////////////////////////////////
  479. // and sometimes if status text is long
  480. //
  481. void CHXAvNaviPaneControl::UpdateTimerTextVisibility()
  482. {
  483.     bool bShow = !m_bHideTimerForStatusText; //!(m_spPlayer->IsConnecting() | m_bHideTimerForStatusText);
  484.     UpdateVisibilityHelper(m_spTimerText.Ptr(), bShow);
  485. }
  486. void 
  487. CHXAvNaviPaneControl::OnAdvancePlaylist()
  488. {
  489.     DoUpdateEverythingAndDraw();
  490. }
  491. ////////////////////////////////////////
  492. //
  493. void CHXAvNaviPaneControl::UpdateTimerTextL()
  494. {
  495.     TUint msNow = m_spPlayer->GetClipTime();
  496.     
  497.     // draw position timer text
  498.     TBuf<50> timerText;
  499.     GetTimerTextL(msNow, timerText); 
  500.     SizeAndSetTimerAreaText(m_spTimerText, timerText);
  501. }
  502. void
  503. CHXAvNaviPaneControl::UpdateEverythingL()
  504. {
  505.     // live state first
  506.     UpdateLiveStateIndicator();
  507.     // then text
  508.     UpdateTimerTextL();
  509.     // then status area (text and status bitmaps) - based on size of timer text
  510.     UpdateStatusAreaL();
  511.     // then timer visibility - based on size of status text
  512.     UpdateTimerTextVisibility();
  513. }
  514. void 
  515. CHXAvNaviPaneControl::ShowPauseIndication(bool bShow)
  516. {
  517.     if(bShow)
  518.     {
  519.         m_bBlinkIsVisible = true;
  520.         UpdateVisibilityHelper(m_spPlayStateImage.Ptr(), true);
  521.         
  522.         // start blinking
  523.         if( !m_cbBlink.IsPending() )
  524.         {
  525.             m_cbBlink.Set(k_msStatusBlinkInterval, CHXAvCallback::REPEAT);
  526.         }
  527.     }
  528.     else
  529.     {
  530.         m_cbBlink.Stop();
  531.         UpdateVisibilityHelper(m_spPlayStateImage.Ptr(), false);
  532.     }
  533. }
  534. // from animate ellipse callback
  535. void
  536. CHXAvNaviPaneControl::OnAnimateEllipseTick()
  537. {
  538.     HX_ASSERT(m_spEllipseText->IsVisible());
  539.     // count 0 - 3
  540.     const TUint end = litSize(KEllipse) + 1;
  541.     HX_ASSERT(m_ellipseCount < end);
  542.     TPtrC text = KEllipse().Left(m_ellipseCount);
  543.     UpdateTextHelper(m_spEllipseText.Ptr(), text);
  544.     m_ellipseCount = ++m_ellipseCount % end;
  545.     m_spRefreshCmd->Execute();
  546. }
  547. void
  548. CHXAvNaviPaneControl::ToggleEllipseAnimation(bool bOn)
  549. {
  550.     if(bOn)
  551.     {
  552.         if( !m_cbAnimateEllipse.IsPending() )
  553.         {
  554.             m_cbAnimateEllipse.Set(k_msAnimateEllipseInterval, CHXAvCallback::REPEAT);
  555.         }
  556.     }
  557.     else
  558.     {
  559.         m_cbAnimateEllipse.Stop();
  560.     }
  561. }
  562. // from blink callback
  563. void
  564. CHXAvNaviPaneControl::ToggleStatusBlinkAndDraw()
  565. {
  566.     m_bBlinkIsVisible = !m_bBlinkIsVisible;
  567.     m_spPlayStateImage->MakeVisible(m_bBlinkIsVisible);
  568.     m_spRefreshCmd->Execute();
  569. }
  570. void
  571. CHXAvNaviPaneControl::OnPlayInitiate(const char* /*url*/)
  572. {
  573.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnPlayInitiate()n"));
  574.     DoUpdateEverythingAndDraw();
  575. }
  576. void
  577. CHXAvNaviPaneControl::OnNetConnect()
  578. {
  579.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnNetConnect()n"));
  580.     DoUpdateEverythingAndDraw();
  581. }
  582. void CHXAvNaviPaneControl::UpdateLiveStateIndicator()
  583. {
  584.     const CHXSymClipInfo& info = m_spPlayer->GetClipInfo();
  585.     bool bShowOn = info.IsLive() && m_spPlayer->IsPlaying() && !m_spPlayer->IsBuffering();
  586.     bool bShowOff = info.IsLive() && !bShowOn;
  587.     
  588.     UpdateVisibilityHelper(m_spLiveStateOnImage.Ptr(), bShowOn);
  589.     UpdateVisibilityHelper(m_spLiveStateOffImage.Ptr(), bShowOff);
  590. }
  591. void
  592. CHXAvNaviPaneControl::OnLoadSession(IHXRequest* /*request*/)
  593. {
  594.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnLoadSession()n")); 
  595.     DoUpdateEverythingAndDraw();
  596. }
  597. void
  598. CHXAvNaviPaneControl::OnResume()
  599. {
  600.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnResume()n"));
  601.     DoUpdateEverythingAndDraw();
  602. }
  603. void
  604. CHXAvNaviPaneControl::OnStop()
  605. {
  606.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnStop()n"));
  607.     DoUpdateEverythingAndDraw();
  608. }
  609. void
  610. CHXAvNaviPaneControl::OnPause()
  611. {
  612.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnPause()n"));
  613.     DoUpdateEverythingAndDraw();
  614. }
  615. void 
  616. CHXAvNaviPaneControl::OnBeginSeek()
  617. {
  618.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnBeginSeek()n"));
  619.     DoUpdateEverythingAndDraw();
  620. }
  621. void
  622. CHXAvNaviPaneControl::OnBeginBuffering(bool bIsBegin)
  623. {
  624.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnBeginBuffering(): is start = '%s'n", dbg::Bool(bIsBegin)));
  625.     DoUpdateEverythingAndDraw();   
  626. }
  627. void
  628. CHXAvNaviPaneControl::OnBuffering(UINT16 percent)
  629. {
  630.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnBuffering(): %u percentn", percent));
  631.     DoUpdateEverythingAndDraw(); 
  632. }
  633. void CHXAvNaviPaneControl::OnMute(bool bMute)
  634. {
  635.     DPRINTF(SYMP_INFO, ("CHXAvNaviPaneControl::OnMute('%s')n", dbg::Bool(bMute)));
  636.     if( !m_spStatusText->IsVisible() )
  637.     {
  638.         // show mute image when mute
  639.         m_spVolStateImage->MakeVisible(bMute);
  640.         m_spRefreshCmd->Execute();
  641.     }
  642. }
  643. ////////////////////////////////////////
  644. //
  645. void 
  646. CHXAvNaviPaneControl::Draw(const TRect& /* rect */) const
  647. {
  648.     // don't draw background; navi pane container draws background for us
  649. }
  650. //////////////////////////////
  651. //
  652. // CCoeControl
  653. //
  654. TInt CHXAvNaviPaneControl::CountComponentControls() const
  655.     return 7;
  656. }
  657. //////////////////////////////
  658. //
  659. // CCoeControl
  660. //
  661. CCoeControl* CHXAvNaviPaneControl::ComponentControl(TInt aIndex) const
  662. {
  663.     switch( aIndex )
  664.     {
  665.     case 0:
  666. return m_spTimerText.Ptr();
  667.     case 1:
  668. return m_spPlayStateImage.Ptr();
  669.     case 2:
  670. return m_spStatusText.Ptr();
  671.     case 3:
  672. return m_spVolStateImage.Ptr();
  673.     case 4:
  674.         return m_spLiveStateOnImage.Ptr();
  675.     case 5:
  676.         return m_spLiveStateOffImage.Ptr();
  677.     case 6:
  678.         return m_spEllipseText.Ptr();
  679.     default:
  680.         break;
  681.     }
  682.     HX_ASSERT(false);
  683.     return 0;
  684. }