×

Discussion Board

Results 1 to 6 of 6
  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    9

    Creating listbox takes long time?

    Hi,

    I have listboxes which have about 40 items.

    In mbm file there are 80 icons (19x19x16). Mask icons are gray scaled.

    When creating listbox, setting listbox icons takes about 5 seconds!

    This wouldn't be a big problem if I have only one view. I have 5 views. So, switching views takes about 5 second every time.

    Thank you in advance if you can give me some hints.

    Bsekerci

  2. #2
    Nokia Developer Expert
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,143
    try to change your application structure in a way that you anly need to load any icon array once.

    And try loading other in background, aften the first is shown, and then you need to disable any navigational options that needs to have some icon arrays (untill they are ready to be shown).

    It is basically just about structural desing decisions.

    yucca

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    9
    Thank you for quick reply.

    That's a good idea. I will try.

    But, this will fix only switching delay.

    My application loads list as soon as it starts. I have to wait at least 5 secons when starting it. This is more acceptable than my current situation :-)

    I calculated elapsed time; the following loop takes about 5 seconds. Is this normal?

    for (int i=0;i<aXmlListBox->IconCount()-1;i+=2)
    iconList->AppendL( iEikonEnv->CreateIconL(iconsFileName, i+0, i+1) );

    iconsFileName has 80 icons including masks.

    As I said before my icon size is 19x19 color dept is 16.
    Here is mmp definition;

    SOURCE C4 acil00.bmp
    SOURCE C4 acil00_mask.bmp
    ...
    ...

    Does it depend bitmap size, color, mask?

    Thank you again.

    Bsekerci

  4. #4
    Nokia Developer Expert
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,143
    looks perfectly normal. I basically had to time it as well for one of my papers, where I was proposing a modeling method for smart phone performance evaluation.

    Anyway I measured with 20 thumbnail images (with no mask) and found out that in 3660 it took average of 2.7 seconds and in 7610 the average time was 1.7 seconds.

    anyway in that time 8 % was spend on the GetDir() and from the rest 48% for loading the thumbnail and 42% for some special operations with file.

    I think the file size matters a bit, but in icon size, it should not be really the main factor, propably the file system is just very slow.

    yucca

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    9
    I solved problem with your help yucca.

    I wrote CIconManager, which loads MBM files. It is an active object.

    The key points;

    I did not use "iEnv->CreateIconL()", instead I used CFbsBitmap()->Load(). Maybe this is not nesessary. I did not calculate time. It looked a little bit faster.

    When a list box needs icon array I created an icon array, but in this array I call "newGulIcon->SetBitmapsOwnedExternally(ETrue);". In this way, If I load an icon it will remain until program ends.

    I am not an expert with active objects. This works for me.

    Here is source code;

    //----------------------------------------------------------------------------
    #ifndef _ICON_MANAGER_H
    #define _ICON_MANAGER_H

    #include <e32base.h>
    #include <e32std.h>
    #include <gulicon.h>


    class CEikonEnv;

    typedef CArrayPtrFlat<CGulIcon> TIconList;

    class TIconItem
    {
    public:
    TIconItem()
    {
    Reset();
    }

    ~TIconItem()
    {
    if (iIconList != NULL)
    {
    iIconList->ResetAndDestroy();
    delete iIconList;
    iIconList = NULL;
    }
    }

    void Reset()
    {
    iIconList = NULL;
    iFileName.Zero();
    iIconCount = 0;
    }

    TIconList* iIconList;
    TFileName iFileName;
    TInt iIconCount;
    };


    class CIconManager : public CActive
    {

    public:
    static CIconManager * NewL();
    ~CIconManager();

    // Request
    void SetHello(TUint32 aDelay);

    // Request
    void LoadIconListL(const TFileName aFileName, const TInt aIconCount);
    TIconList* GetOutIconListL(const TFileName aFileName, TInt& aIconCount);

    void ExecuteRunL();

    private:

    CIconManager();
    void ConstructL();

    // From CActive
    void RunL();
    void DoCancel();

    RTimer iTimer;
    CEikonEnv *iEnv;

    CArrayPtrFlat<TIconItem> *iIconListArray;
    TIconItem* iIconItem;

    };

    #endif

    // CPP FILE
    //----------------------------------------------------------------------------

    #include "IconManager.h"

    #include <eikenv.h>
    #include <eikdef.h>
    #include <akniconarray.h>
    #include <aknutils.h>

    //----------------------------------------------------------------------------
    //****************************************************************************
    //----------------------------------------------------------------------------

    CIconManager* CIconManager::NewL()
    {
    CIconManager * self = new(ELeave) CIconManager;
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(); // self
    return self;
    }
    //----------------------------------------------------------------------------

    CIconManager::CIconManager()
    : CActive(CActive::EPriorityStandard)
    {
    }
    //----------------------------------------------------------------------------

    void CIconManager::ConstructL()
    {
    iEnv = CEikonEnv::Static();
    User::LeaveIfError(iTimer.CreateLocal());
    iIconListArray = new (ELeave) CArrayPtrFlat<TIconItem>(10);
    iIconItem = NULL;
    CActiveScheduler::Add(this);
    }

    //----------------------------------------------------------------------------

    CIconManager::~CIconManager()
    {
    Cancel(); // Has DoCancel-> Must call Cancel in destructor
    iTimer.Close();

    if (iIconItem) delete iIconItem;

    for (TInt j=iIconListArray->Count()-1;j>=0;j--)
    {
    TIconItem* aIconItem = (*iIconListArray)[j];
    delete aIconItem;
    iIconListArray->Delete(j);
    }

    delete iIconListArray;
    }
    //----------------------------------------------------------------------------

    void CIconManager::DoCancel()
    {
    iTimer.Cancel();
    }
    //----------------------------------------------------------------------------
    // adds this file to array to be loaded async
    void CIconManager::LoadIconListL(const TFileName aFileName, const TInt aIconCount)
    {
    TIconItem* aIconItem = new (ELeave) TIconItem;
    aIconItem->iFileName.Copy(aFileName);
    aIconItem->iIconCount = aIconCount;
    iIconListArray->AppendL(aIconItem);

    if (!IsActive())
    {
    iTimer.After(iStatus, 10000);
    SetActive();
    }
    }
    //----------------------------------------------------------------------------
    TIconList* CIconManager::GetOutIconListL(const TFileName aFileName, TInt& aIconCount)
    {
    // aIconCount shows this file is added to list
    aIconCount = 0;

    for (TInt j=0;j<iIconListArray->Count();j++)
    {
    TIconItem* aIconItem = (*iIconListArray)[j];
    if (aIconItem->iFileName.Compare(aFileName) == 0)
    {
    aIconCount = aIconItem->iIconCount;
    if (aIconItem->iIconList != NULL)
    {

    // dont transfer ownership

    CArrayPtrFlat<CGulIcon>* iconList = new (ELeave) CAknIconArray(aIconItem->iIconCount / 2);
    CleanupStack::PushL(iconList);

    for (TInt i=0;i<aIconItem->iIconList->Count();i++)
    {
    CGulIcon* aGulIcon = (*(aIconItem->iIconList))[i];

    CGulIcon* newGulIcon = CGulIcon::NewL();
    newGulIcon->SetBitmapsOwnedExternally(ETrue);
    newGulIcon->SetBitmap(aGulIcon->Bitmap());
    //newGulIcon->SetMask(aGulIcon->Mask());

    iconList->AppendL( newGulIcon );
    }
    //iconList->ResetAndDestroy();

    CleanupStack::Pop();
    return iconList;


    /*
    TIconList* iconList = aIconItem->iIconList;
    aIconItem->iIconList = NULL;
    // active object reload this filename again
    if (!IsActive())
    {
    iTimer.After(iStatus, 10000);
    SetActive();
    }
    return iconList;
    */
    }
    }
    }

    // start timer just in case
    if (!IsActive())
    {
    iTimer.After(iStatus, 10000);
    SetActive();
    }

    return NULL;
    }
    //----------------------------------------------------------------------------

    void CIconManager::RunL()
    {
    iTimer.Cancel();

    for (TInt j=0;j<iIconListArray->Count();j++)
    {
    TIconItem* aIconItem = (*iIconListArray)[j];
    if (aIconItem->iIconList == NULL)
    {
    // CGulIcon packages two bitmaps: icon image and its mask
    // CAknIconArray inherits from CArrayPtrFlat<CGulIcon>
    CArrayPtrFlat<CGulIcon>* iconList = new (ELeave) CAknIconArray(aIconItem->iIconCount / 2);
    CleanupStack::PushL(iconList);

    TFileName filename = aIconItem->iFileName;
    CompleteWithAppPath(filename);

    for (TInt i=0;i<aIconItem->iIconCount-1;i+=2)
    {
    CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
    TInt ret1 = bitmap->Load(filename, i+0);
    CFbsBitmap* mask = new (ELeave) CFbsBitmap();
    TInt ret2 = mask->Load(filename, i+1);
    if (ret1 == KErrNone && ret2 == KErrNone)
    {
    CGulIcon* newGulIcon = CGulIcon::NewL();
    //newGulIcon->SetBitmapsOwnedExternally(ETrue);
    newGulIcon->SetBitmap(bitmap);
    newGulIcon->SetMask(mask);
    iconList->AppendL(newGulIcon);
    }
    else
    {
    delete bitmap;
    delete mask;
    }
    //iconList->AppendL( iEnv->CreateIconL(aIconItem->iFileName, i+0, i+1) );
    }
    CleanupStack::Pop();

    aIconItem->iIconList = iconList;
    // load remaining next time
    iTimer.After(iStatus, 10000);
    SetActive();
    break;
    }
    }

    /*
    if (!IsActive())
    {
    // newer stop!
    iTimer.After(iStatus, 10000);
    SetActive();
    }
    */
    }
    //----------------------------------------------------------------------------
    void CIconManager::ExecuteRunL()
    {
    RunL();
    }
    //----------------------------------------------------------------------------


    Thank you.

    Bsekerci

  6. #6
    Super Contributor
    Join Date
    Apr 2003
    Location
    Czech Republic
    Posts
    915
    by the way, you can save some space if you put your "mask" bitmaps as 1 bit versions.

    So instead of:

    SOURCE C4 acil00.bmp
    SOURCE C4 acil00_mask.bmp
    ...

    Use:

    SOURCE C4 acil00.bmp
    SOURCE 1 acil00_mask.bmp
    ...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •