diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_custom_controls_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_custom_controls_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,613 @@ + + +TB10.1 Example Applications: examples/AppFramework/UIControls/CustomControls/CustomControls.cpp Source File + + + + +

examples/AppFramework/UIControls/CustomControls/CustomControls.cpp

00001 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+00002 // All rights reserved.
+00003 // This component and the accompanying materials are made available
+00004 // under the terms of "Eclipse Public License v1.0"
+00005 // which accompanies this distribution, and is available
+00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
+00007 //
+00008 // Initial Contributors:
+00009 // Nokia Corporation - initial contribution.
+00010 //
+00011 // Contributors:
+00012 //
+00013 // Description:
+00014 // UI Control Framework example program
+00015 // This example demonstrates how to write new control classes.
+00016 // The example creates three new control classes:
+00017 // 1. CSmiley              - a simple control which displays a 
+00018 // smiley face that can have two moods,
+00019 // happy and sad. The user can change
+00020 // the smiley's mood by pressing the
+00021 // space bar.
+00022 // 2. CSmileyContainer     - a compound control which contains
+00023 // two CSmiley controls, side by side.
+00024 // The user can move the keyboard focus
+00025 // from one CSmiley to the other using
+00026 // the arrow keys, or the pointer.
+00027 // 3. CMainWinControl      - a compound control which does nothing
+00028 // except act as a background window and a 
+00029 // container for other controls in the 
+00030 // application.
+00031 // When the application starts up, it creates a CMainWinControl to cover
+00032 // the entire screen, and a CSmileyContainer inside this main window.
+00033 // The application's menu contains just two options. One of them closes 
+00034 // the application; the other creates a dialog which contains a 
+00035 // CSmileyContainer. CSmileyContainer therefore illustrates how to write 
+00036 // a control that can be created both in a dialog and within the
+00037 // application's main view.
+00038 //
+00039 
+00040 #include "CustomControls.h"
+00041 #include <eikstart.h>
+00042 
+00043 
+00045 //
+00046 // -----> CMainWinControl(implementation)
+00047 //
+00049 CMainWinControl::CMainWinControl()
+00050         {
+00051         }
+00052 
+00053 CMainWinControl::~CMainWinControl()
+00054         {
+00055         delete iContainer;
+00056         }
+00057 
+00058 // CMainWinControl needs a ConstructL(), because it is a compound control
+00059 // (and a window-owning control).
+00060 void CMainWinControl::ConstructL(const TRect& rect)
+00061         {
+00062         // Make this a window-owning control.
+00063         CreateWindowL();
+00064         SetRect(rect);
+00065 
+00066         // Create its only component, a CSmileyContainer
+00067         iContainer = new(ELeave) CSmileyContainer;
+00068         iContainer->SetContainerWindowL(*this);
+00069         TRect containerRect=Rect();
+00070         iContainer->ConstructL(containerRect);
+00071         // Activate the main window control - this will also activate the 
+00072         // CSmileyContainer and its components.
+00073         ActivateL();
+00074         DrawNow();
+00075         }
+00076 
+00077 // The following two functions have to be implemented for all compound controls.
+00078 TInt CMainWinControl::CountComponentControls() const
+00079         {
+00080         return 1;
+00081         }
+00082 
+00083 CCoeControl* CMainWinControl::ComponentControl(TInt /*aIndex*/) const
+00084         {
+00085         return iContainer;
+00086         }
+00087 
+00088 // Draw the main window.
+00089 void CMainWinControl::Draw(const TRect& /*aRect*/) const
+00090         {
+00091         CWindowGc& gc=SystemGc();
+00092         gc.SetBrushColor(KRgbWhite);
+00093         gc.Clear(Rect());
+00094         }
+00095 
+00096 // CSmileyContainer can't be put on the control stack, because it's a component of this 
+00097 // control. The main window control goes on the stack and passes on any key events it gets
+00098 // to the CSmileyContainer.
+00099 TKeyResponse CMainWinControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+00100         {
+00101         return (iContainer->OfferKeyEventL(aKeyEvent, aType));
+00102         }
+00103 
+00105 //
+00106 // -----> CSmileyContainer (implementation)
+00107 //
+00109 CSmileyContainer::CSmileyContainer()
+00110         {}
+00111 
+00112         
+00113 CSmileyContainer::~CSmileyContainer()
+00114         {
+00115           // Delete all the contained controls 
+00116         delete iSmiley1;
+00117         delete iSmiley2;
+00118         }
+00119 
+00120 
+00121 // Because CSmileyContainer is a compound control, it needs a
+00122 // ConstructL() for when it's created outside a dialog, and a
+00123 // ConstructFromResourceL() for when it's created inside a dialog.
+00124 void CSmileyContainer::ConstructL(const TRect& aRect)
+00125         {
+00126         TBool isSmiling=ETrue;
+00127 
+00128         // Create the two CSmileys. Their size and position is 
+00129         // set in CSmileyContainer::SizeChangedL().
+00130         iSmiley1 = new(ELeave) CSmiley(isSmiling);
+00131         iSmiley1->SetContainerWindowL(*this);
+00132 
+00133         isSmiling=EFalse;
+00134 
+00135         iSmiley2 = new(ELeave) CSmiley(isSmiling);
+00136         iSmiley2->SetContainerWindowL(*this);
+00137 
+00138         iSmiley1->SetFocus(ETrue);
+00139 
+00140         // Set the container as the observer of the two CSmileys. This 
+00141         // is for handling keyboard focus. When an arrow key is pressed 
+00142         // or the pointer is clicked on one of the CSmileys, an 
+00143         // EEventRequestFocus event is sent to the container, and the
+00144         // container changes the focus if applicable.
+00145         iSmiley1->SetObserver(this);
+00146         iSmiley2->SetObserver(this);
+00147 
+00148         // Set the bounding rectangle of this control (this will result in 
+00149         // a call to SizeChangedL(). The component controls must be 
+00150         // created before calling this, because SizeChangedL() sets their
+00151         // sizes.
+00152         SetRect(aRect);
+00153         }
+00154 
+00155 
+00156 // This function is used when the CSmileyContainer is created inside a dialog.
+00157 void CSmileyContainer::ConstructFromResourceL(TResourceReader& aReader)
+00158         {
+00159         // Read the smiley mood from the resource file
+00160         TBool isSmiling=(TBool)aReader.ReadInt8();
+00161         // Read the width of the smiley container from the resource file.
+00162         TInt width=aReader.ReadInt16();
+00163         // Set the height of the container to be half its width
+00164         TSize containerSize (width, width/2);
+00165 
+00166         iSmiley1 = new(ELeave) CSmiley(isSmiling);
+00167         iSmiley1->SetContainerWindowL(*this);
+00168 
+00169         iSmiley2 = new(ELeave) CSmiley(isSmiling);
+00170         iSmiley2->SetContainerWindowL(*this);
+00171 
+00172         iSmiley1->SetFocus(ETrue);
+00173 
+00174         iSmiley1->SetObserver(this);
+00175         iSmiley2->SetObserver(this);
+00176 
+00177         SetSize(containerSize);
+00178 
+00179         ActivateL();    
+00180         }
+00181 
+00182 // The following two functions have to be implemented for all compound controls.
+00183 TInt CSmileyContainer::CountComponentControls() const
+00184         {
+00185         return 2;
+00186         }
+00187 
+00188 CCoeControl* CSmileyContainer::ComponentControl(TInt aIndex) const
+00189         {
+00190         if (aIndex==0)
+00191                 return iSmiley1;
+00192         else
+00193                 return iSmiley2;
+00194         }
+00195 
+00196 // This function gets called whenever one of the size-setting functions is called.
+00197 // As this is a compound control, this function calculates and sets the size and  
+00198 // position for its components, based on its own size.
+00199 void CSmileyContainer::SizeChanged()
+00200     {
+00201         TInt containerWidth=Size().iWidth;
+00202         TInt containerHeight=Size().iHeight;
+00203         // Find half of the greater - width or height
+00204         TInt length=containerHeight>containerWidth ? containerWidth/4 : containerHeight/4; 
+00205         TSize smileySize(length,length);
+00206 
+00207         // Do some preliminary calculations so that Draw() is as short
+00208         // as possible.
+00209         TInt xOffset=smileySize.iWidth/4; // x offset from the center
+00210         TInt yOffset=(containerHeight - smileySize.iHeight) / 2;
+00211         iSmiley1->SetPosition(Position() +
+00212                 TPoint(containerWidth/2 - smileySize.iWidth - xOffset, yOffset));
+00213         iSmiley2->SetPosition(Position() + 
+00214                 TPoint(containerWidth/2 + xOffset, yOffset));
+00215         // Calling SetSizeL() causes the components' SizeChanged() to be called.
+00216         iSmiley1->SetSize(smileySize);
+00217         iSmiley2->SetSize(smileySize);
+00218         }
+00219         
+00220 void CSmileyContainer::Draw(const TRect& aRect) const
+00221         {
+00222         // Just draw a rectangle round the edge of the control.
+00223         CWindowGc& gc=SystemGc();
+00224         gc.Clear(aRect);
+00225         gc.SetClippingRect(aRect);
+00226         gc.DrawRect(Rect());
+00227         }
+00228 
+00229 // This function is defined by MCoeControlObserver. It gets called whenever
+00230 // a control that this control is observing calls ReportEventL().
+00231 // In this example, the CSmileyContainer is the observer for both of the 
+00232 // CSmileys.  CCoeControl::ProcessPointerEventL() calls ReportEvent(), 
+00233 // sending an event of type EEventRequestFocus, whenever an EButton1Down event
+00234 // occurs in the CSmiley that doesn't currently have focus.
+00235 void CSmileyContainer::HandleControlEventL(CCoeControl* aControl,
+00236                                                                                 TCoeEvent aEventType)
+00237         {
+00238         switch (aEventType)
+00239                 {
+00240                 case EEventRequestFocus:
+00241                         {
+00242                         if (aControl->IsFocused())
+00243                                 return;
+00244                         SwapFocus(aControl);
+00245                         }
+00246                         break;
+00247                 default:
+00248                         break;
+00249                 }
+00250         }
+00251 
+00252 // This function is called by the framework whenever a component in a dialog is 
+00253 // about to lose focus. It checks that the data in ithe component is valid. In
+00254 // this example, there's a "rule" that both the CSmileys in the container can't
+00255 // be miserable! If they are, the function leaves. The framework issues the message 
+00256 // we give it, and doesn't move focus away from the CSmileyContainer.
+00257 void CSmileyContainer::PrepareForFocusLossL()   
+00258         {
+00259         if (!iSmiley1->IsSmiling() && !iSmiley2->IsSmiling())
+00260                 {
+00261                 CEikonEnv::Static()->LeaveWithInfoMsg(R_EXAMPLE_TEXT_VALIDATE);
+00262                 }
+00263         }
+00264 
+00265 // This function gets called whenever the application calls SetFocus().
+00266 // It redraws the CSmileyContainer, so that they are updated to show 
+00267 // which one now has focus.
+00268 void CSmileyContainer::FocusChanged(TDrawNow aDrawNow)
+00269         {
+00270         if (IsFocused())
+00271                 {
+00272                 iSmiley1->SetFocus(ETrue, EDrawNow);
+00273                 }
+00274         else
+00275                 {
+00276                         if (iSmiley1->IsFocused())
+00277                         iSmiley1->SetFocus(EFalse, EDrawNow);
+00278                         else
+00279                         iSmiley2->SetFocus(EFalse, EDrawNow);
+00280                 }
+00281         if (aDrawNow)
+00282                 DrawNow();
+00283         }
+00284 
+00285 
+00286 void CSmileyContainer::SwapFocus(CCoeControl* aControl)
+00287         {
+00288         if (aControl==iSmiley1)
+00289                 {
+00290                 iSmiley2->SetFocus(EFalse, EDrawNow);
+00291                 iSmiley1->SetFocus(ETrue, EDrawNow);
+00292                 }
+00293         else
+00294                 {
+00295                 iSmiley1->SetFocus(EFalse, EDrawNow);
+00296                 iSmiley2->SetFocus(ETrue, EDrawNow);
+00297                 }
+00298         }
+00299 
+00300 TKeyResponse CSmileyContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+00301         {
+00302         // Use the arrow keys to move focus between the two CSmileys.
+00303         switch (aKeyEvent.iScanCode)
+00304                 {
+00305                 case EStdKeySpace:
+00306                         if (iSmiley1->IsFocused())
+00307                                 return iSmiley1->OfferKeyEventL(aKeyEvent, aType);
+00308                         else if (iSmiley2->IsFocused())
+00309                                 return iSmiley2->OfferKeyEventL(aKeyEvent, aType);
+00310                         break;
+00311                 case EStdKeyRightArrow:
+00312                         if (iSmiley1->IsFocused())
+00313                                 SwapFocus(iSmiley2);
+00314                         else
+00315                         return EKeyWasConsumed;
+00316                         break;
+00317                 case EStdKeyLeftArrow:
+00318                         if (iSmiley2->IsFocused())
+00319                                 SwapFocus(iSmiley1);
+00320                         else
+00321                         return EKeyWasConsumed;
+00322                         break;
+00323                 default:
+00324                         break;
+00325                 }
+00326         // If the CSmileyContainer didn't use the key event, it must return EKeyWasNotConsumed,
+00327         // so that the key event is passed to other controls on the stack.
+00328         return EKeyWasNotConsumed;
+00329         }
+00330 
+00331 
+00332 
+00333 
+00335 //
+00336 // -----> CSmiley (implementation)
+00337 //
+00339 
+00340 // CSmiley doesn't need a ConstructL() because it's a simple control.
+00341 
+00342 CSmiley::CSmiley(TBool aSmiling) : iSmiling(aSmiling)
+00343         {
+00344         }
+00345 
+00346 CSmiley::~CSmiley()
+00347         {
+00348         }
+00349 
+00350 TBool CSmiley::IsSmiling()
+00351         {
+00352         return iSmiling;
+00353         }
+00354 
+00355 void CSmiley::Draw(const TRect& aRect) const
+00356         {
+00357         CWindowGc& gc=SystemGc();
+00358         if (IsFocused())
+00359                 {
+00360                 gc.SetPenColor(KRgbBlack);
+00361                 }
+00362         else
+00363                 {
+00364                 gc.SetPenColor(KRgbWhite);
+00365                 }
+00366         gc.SetBrushColor(KRgbWhite);
+00367         gc.Clear(Rect());
+00368         gc.DrawRect(Rect());
+00369 
+00370         gc.SetClippingRect(aRect);
+00371 
+00372         // Draw the smiley face, smiling or looking sad
+00373         gc.SetPenColor(KRgbBlack);
+00374         // Draw a circle for the face
+00375         gc.DrawEllipse(iSmileyRect);
+00376         // Draw the eyes
+00377         TPoint leftEye(iSmileyWidth/3, iSmileyHeight/3);
+00378         TPoint rightEye(iSmileyWidth*2/3, iSmileyHeight/3);
+00379         gc.SetPenSize(TSize(5,5));
+00380         gc.Plot(iSmileyRect.iTl+leftEye);
+00381         gc.Plot(iSmileyRect.iTl+rightEye);
+00382         //Draw the mouth, smiling or looking sad.
+00383         gc.SetPenSize(TSize(1,1));
+00384         gc.SetPenColor(KRgbWhite);
+00385         if (iSmiling)
+00386                 gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2), 
+00387                                                           iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
+00388         else
+00389                 gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2), 
+00390                                                           iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
+00391         gc.SetPenColor(KRgbBlack);
+00392         if (iSmiling)
+00393                 gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2), 
+00394                                                           iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
+00395         else
+00396                 gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2), 
+00397                                                           iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
+00398         }
+00399 
+00400 void CSmiley::SizeChanged()
+00401         {
+00402         // Calculate sizes of rectangles for drawing face and mouth
+00403         iSmileyRect=Rect();
+00404         // Allow room for the focus rectangle round the outside
+00405         iSmileyRect.Shrink(3,3);
+00406         iSmileyWidth=iSmileyRect.Width();
+00407         iSmileyHeight=iSmileyRect.Height();
+00408         iSmileRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight/2),
+00409                                         TSize(iSmileyWidth/2, iSmileyHeight/3));
+00410         iFrownRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight*2/3),
+00411                                         TSize(iSmileyWidth/2, iSmileyHeight/3));
+00412         }
+00413 
+00414 void CSmiley::FocusChanged(TDrawNow aDrawNow)
+00415         {
+00416         if (aDrawNow)
+00417                 DrawNow();
+00418         }
+00419 
+00420 void CSmiley::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+00421         {
+00422         if (aPointerEvent.iType==TPointerEvent::EButton1Down)
+00423                 {
+00424                 iSmiling = !iSmiling;
+00425                 DrawNow();
+00426                 }
+00427         }
+00428 
+00429 TKeyResponse CSmiley::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+00430         {
+00431         // The space bar changes the "mood" of the CSmiley.
+00432         if (aType==EEventKey && aKeyEvent.iScanCode==EStdKeySpace)
+00433                 {
+00434                 iSmiling = !iSmiling;
+00435                 DrawNow();
+00436                 return EKeyWasConsumed;
+00437                 }
+00438         else
+00439                 {
+00440                 return EKeyWasNotConsumed;
+00441                 }
+00442         }
+00443 
+00445 //
+00446 // -----> CSmileyDialog(implementation)
+00447 //
+00449 TBool CSmileyDialog::RunDlgLD()
+00450         {
+00451         CEikDialog* dialog = new (ELeave) CSmileyDialog();
+00452         return (dialog->ExecuteLD(R_SMILEY_DIALOG));
+00453         }
+00454 
+00455 // This function is used by CEikForm::ConstructByTypeL() to create the custom 
+00456 // control within the dialog.
+00457 SEikControlInfo CSmileyDialog::CreateCustomControlL(TInt aControlType)
+00458         {
+00459         SEikControlInfo controlInfo;
+00460         controlInfo.iControl = NULL;
+00461         controlInfo.iTrailerTextId = 0;
+00462         controlInfo.iFlags = 0;
+00463 
+00464     switch (aControlType)
+00465         {
+00466     case ESmileyControl:
+00467                 controlInfo.iControl = new(ELeave) CSmileyContainer;
+00468                 break;
+00469         default:
+00470                 break;
+00471                 }
+00472     return controlInfo;
+00473         }
+00474 
+00476 //
+00477 // -----> CExampleAppUi (implementation)
+00478 //
+00480 void CExampleAppUi::ConstructL()
+00481         {
+00482           // Allow base class (CEikAppUi) to perform necessary construction
+00483         BaseConstructL();
+00484         // Construct the CMainWinControl which forms the main view
+00485         // for this application.
+00486         iMainWinControl=new(ELeave) CMainWinControl;
+00487         iMainWinControl->ConstructL(ClientRect());
+00488         // The main window is added to the control stack (for key event
+00489         // handling).   
+00490         AddToStackL(iMainWinControl);
+00491         }
+00492         
+00493 
+00494 CExampleAppUi::~CExampleAppUi()
+00495         {
+00496         RemoveFromStack(iMainWinControl);
+00497           // Delete the main window
+00498         delete iMainWinControl;
+00499         }
+00500 
+00501 void CExampleAppUi::HandleCommandL(TInt aCommand)
+00502         {
+00503           // Handle the command generated by:
+00504           //   1. menu item selection
+00505           //   2. short-cut key press
+00506         switch (aCommand)
+00507                 {
+00508         // EXIT comand
+00509         case EEikCmdExit:
+00510                 OnCmdExit();
+00511                 break;
+00512         case ECreateSmileyDialog:
+00513                 CSmileyDialog::RunDlgLD();
+00514                 break;
+00515         default :
+00516                 break;
+00517                 }
+00518         }
+00519 
+00520 void CExampleAppUi::OnCmdExit()
+00521         {
+00522         CBaActiveScheduler::Exit();
+00523         }
+00524 
+00525 void CExampleAppUi::HandleModelChangeL()
+00526         {
+00527         }
+00528 
+00530 //
+00531 // -----> CExampleDocument (implementation)
+00532 //
+00534 
+00535 CExampleDocument::CExampleDocument(CEikApplication& aApp)
+00536          : CEikDocument(aApp)
+00537         {}
+00538 
+00539 CExampleDocument::~CExampleDocument()
+00540         {
+00541         }
+00542 
+00543 CExampleDocument* CExampleDocument::NewL(CEikApplication& aApp)
+00544         {
+00545         CExampleDocument* self=new(ELeave) CExampleDocument(aApp);
+00546         CleanupStack::PushL(self);
+00547         self->CreateModelL();
+00548         CleanupStack::Pop();
+00549         return self;
+00550         }
+00551 
+00552 void CExampleDocument::ResetModelL()
+00553         {
+00554         CreateModelL();
+00555         }
+00556 
+00557 void CExampleDocument::CreateModelL()
+00558         {
+00559         }
+00560 
+00561 CEikAppUi* CExampleDocument::CreateAppUiL()
+00562         {
+00563     return(new(ELeave) CExampleAppUi);
+00564         }
+00565 
+00566 void CExampleDocument::NewDocumentL()
+00567         {
+00568         ResetModelL();
+00569         }
+00570 
+00571 void CExampleDocument::StoreL(CStreamStore& /*aStore*/,CStreamDictionary& /*aStreamDic*/) const
+00572         {
+00573         }
+00574 
+00575 void CExampleDocument::RestoreL(const CStreamStore& /*aStore*/,const CStreamDictionary& /*aStreamDic*/)
+00576         {
+00577         }
+00578 
+00579 
+00581 //
+00582 // -----> CExampleApplication (implementation)
+00583 //
+00585 TUid CExampleApplication::AppDllUid() const
+00586         {
+00587         return(KUidExampleApp);
+00588         }
+00589 
+00590 
+00591 CApaDocument* CExampleApplication::CreateDocumentL()
+00592         {
+00593         return CExampleDocument::NewL(*this);
+00594         }
+00595 
+00596 
+00597 //
+00598 // EXPORTed functions
+00599 //
+00600 
+00601 
+00602 LOCAL_C CApaApplication* NewApplication()
+00603         {
+00604         return new CExampleApplication;
+00605         }
+00606         
+00607 GLDEF_C TInt E32Main()
+00608         {
+00609         return EikStart::RunApplication(NewApplication);
+00610         }
+00611 
+00612 
+00613 
+00614 
+00615 
+

Generated on Thu Jan 21 10:32:55 2010 for TB10.1 Example Applications by  + +doxygen 1.5.3
+ +