posted by Jean-Louis Villecroze on Wed 8th Dec 2004 21:40 UTC

"Zinzala, Page 8/11"
Animation When a button is active, we want to display a pulsating effect on the active button. To render this, we need to redraw the button at a given interval in time. We have used the flag kFlgBeatNeeded in the cDConsoleView base class initialization. Now let's have a look at the implementation of the method Beat(), which will be called at the rate set by the parent window:

void cDConsoleView::Beat()
{
   // if there is an active button
   if(iActiveButton < kButtonsCount)
   {
      if(iButtons[iActiveButton].iState >= kStateActive)
      {

Because this method will still be called even when there is no button active, we will only draw the animation effect if there is an active button.

	 // set the state of the button
         iButtons[iActiveButton].iState += iActiveDir;

The pulsating effect is rendered by incrementing the state of the button from kStateActive to kStateActive2 and then reversing back to kStateActive.

         if(iButtons[iActiveButton].iState > kStateActive2)
         {
            iButtons[iActiveButton].iState = kStateActive2;
            iActiveDir = -1;
         }
         else
         if(iButtons[iActiveButton].iState < kStateActive)
         {
            iButtons[iActiveButton].iState = kStateActive;
            iActiveDir = 1;
         }

We use the data member iActiveDir to store the direction we are going. The only thing left to do, is to redraw the button. We simply call the method Render() which use the button state to render it:

	 // redraw the button
         Render(iActiveButton);
      }
   }
}

Later, we will see how to setup the window to beat.

Changing state

All that is left to be done, is SetState(). This method will be used from outside the class in order to change the state of the console. For example, when the user presses the Play button and playback successfully starts, the state should be changed to ePlaying.

Here's the method implementation:

void cDConsoleView::SetState(tConsoleState aState)
{
   if(!iFault)
   {
      TheLooperMustBeLocked();

Since we do not know who will be calling this method and when, we need to insure that the looper (the window) is locked. The macro TheLooperMustBeLocked() will check this for us. If it is not locked, an exception will be raised and the application will likely be terminated. This helps us to easily detect situations where we are executing code that should only be executed when the window is locked. Don't forget that the Zinzala SDK, is multithreaded and that only one thread should be changing the button's state or widget internals at any given time.

      switch(aState)
      {
         case ePlaying:
         {
	    // enable the buttons (all of them)
            for(tUint8 i=0;i<kButtonsCount;i++)
               iButtons[i].iState = kStateNormal;
				
	    // change the label of the play button
            iButtons[kButtonPlay].iLabel = kLabelStop;
	    // and set it as active
            iButtons[kButtonPlay].iState = kStateActive;
            iActiveButton = kButtonPlay;
		
            break;
         }
         case eStopped:
         {
	    // disable the buttons (all of them)
            for(tUint8 i=0;i<kButtonsCount;i++)
               iButtons[i].iState = kStateDimmed;

	    // change the label of the play button
            iButtons[kButtonPlay].iLabel = kLabelPlay;
	    // and enable it
            iButtons[kButtonPlay].iState = kStateNormal;
	    // there is no active button
            iActiveButton = kButtonsCount;
	
            break;
         }
         case ePaused:
         {
	    // disable some of the buttons
            iButtons[kButtonBwd].iState = kStateDimmed;
            iButtons[kButtonFwd].iState = kStateDimmed;
	
	    // and set it as active
            iButtons[kButtonPause].iState = kStateActive;
            iActiveButton = kButtonPause;
		
            break;
         }
         case eForward:
         {
	    // disable some of the buttons
            iButtons[kButtonBwd].iState = kStateDimmed;
            iButtons[kButtonPause].iState = kStateDimmed;
				
	    // and set it as active
            iButtons[kButtonFwd].iState = kStateActive;
            iActiveButton = kButtonFwd;
		
            break;
         }
         case eBackward:
         {
	    // disable some of the buttons
            iButtons[kButtonFwd].iState = kStateDimmed;
            iButtons[kButtonPause].iState = kStateDimmed;
				
	    // and set it as active
            iButtons[kButtonBwd].iState = kStateActive;
            iActiveButton = kButtonBwd;

            break;
         }
      }

      iState = aState;

Because several button states may have changed, we simply redraw them all:

      // render all the buttons
      Render(kButtonsCount);
   }
}

As you have noticed, this method does not check the logic of state changes. The derived class or whoever else called this method, is responsible for this check.

If you would like to see the complete source code of the cDConsoleView class, here's the header and the C++ file.

4. Using cMyConsoleView

In order to test the console class we just created, we are going to derive it and implement the button pressed callbacks. Then, we will assemble a simple test application.

Table of contents
  1. "Zinzala, Page 1/11"
  2. "Zinzala, Page 2/11"
  3. "Zinzala, Page 3/11"
  4. "Zinzala, Page 4/11"
  5. "Zinzala, Page 5/11"
  6. "Zinzala, Page 6/11"
  7. "Zinzala, Page 7/11"
  8. "Zinzala, Page 8/11"
  9. "Zinzala, Page 9/11"
  10. "Zinzala, Page 10/11"
  11. "Zinzala, Page 11/11"
e p (0)    12 Comment(s)

Technology White Papers

See More