photosgallery/viewframework/medialists/inc/glxnavigablelist.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:45:44 +0200
changeset 0 4e91876724a2
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:    List of media items, which has focus
*
*/




#ifndef __C_GLXNAVIGABLELIST_H__
#define __C_GLXNAVIGABLELIST_H__

#include <e32base.h>
#include <glxlistdefs.h>


#include "glxmediaid.h"
#include "mglxitemlistobserver.h"

/** @todo
Other required changes:
-Media list must not media for static items to be requested: Remove static item indexes from the list attribute context returned
-Thumbnail context needs to give a low score (very low) to static items, so that it does not stop requesting thumbnails
*/ 

// Forward declarations
class TGlxMedia;
class CGlxMedia;
class CGlxStaticItemList;
class CMPXCollectionPath;
class MGlxMediaPool;
class MGlxMediaUser;
class MGlxNavigableListObserver;

/** 
 * Namespace for CGlxNavigableList class' helpers
 */
namespace NGlxNavigableList
    {
    class MSelectionIndexStrategy;
    }

/**
 * CGlxNavigableList
 *
 * List that has 
 *  - non-static items
 *  - static items
 *  - focus
 *  - selection
 *
 * @author Aki Vanhatalo
 *
 * @internal reviewed 16/07/2007 by Kimmo Hoikka
 *
 * @ingroup mlm_media_list_manager_design
 */
NONSHARABLE_CLASS( CGlxNavigableList ) : public CBase, public MGlxItemListObserver
    {
public:
    /**
     * Two-phase constructor
     * @param aIdSpaceId id of the "space" in which all item ids are unique
     * @param aObserver Observer to be notified
     * @param aMediaUser User of media objects - media objects that 
     *                   this list links to will be linked to the user, so that 
     *                   cache manager is able to quickly access the media lists 
     *                   that use particular media objects
     */
    static CGlxNavigableList* NewL( const TGlxIdSpaceId& aIdSpaceId,
        MGlxNavigableListObserver& aObserver, MGlxMediaUser& aMediaUser );
    
    /** 
     * Destructor
     */
    ~CGlxNavigableList();
    
    /**
     * @return id space id
     */
    const TGlxIdSpaceId& IdSpaceId() const;
    
    /**
     * Synchronises the list with new path 
     * Sends added/removed notifications as necessary
     * Note: Does not copy the selected items or focus
     *
     * @param aSource path with item ids
     * @param aMediaPool interface from which to ask for media items
     */
    void SetContentsL( const CMPXCollectionPath& aSource, 
        const MGlxMediaPool& aMediaPool );

    /**
     * Re-orders the list with new path
     * Sends all items removed followed by all items added (from new path) notifications
     * Maintains the selected items and focus
     *
     * @param aSource path with item ids
     * @param aMediaPool interface from which to ask for media items
     */
    void ReorderContentsL( const CMPXCollectionPath& aSource, 
        const MGlxMediaPool& aMediaPool );
    
    /**
     * Remove an item form the list
     * Sends removed notification
     *
     * @param aIdSpaceId Id space of the item. Use KGlxStaticItemIdSpaceId
     *                   if you want to permanently remove a static item.
     * @param aItemId Id of item to remove
     */
    void Remove( const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aItemId );
        
    /**
     * Remove any pointers to the media object at the specified index
     * @param aIndex index of media object from which to remove a reference
     */
    void RemoveReference( TInt aIndex );

    /**
     * Adds a static item and takes ownership
     * Note: In case of a leave, aStaticItem may have been modified.
     *       It is assumed that since ownership of the static item is passed,
     *       the object is free to be modified.
     * @param aStaticItem Static item to be added
     * @param aTargetPosition Whether to be added at beginning or end
     */
    void AddStaticItemL( CGlxMedia* aStaticItem,
        NGlxListDefs::TInsertionPosition aTargetPosition );

    /**
     * Enables or disables static items
     * @param aEnabled true if static items should be enabled
     *                 false if static items should be disabled
     */
    void SetStaticItemsEnabled( TBool aEnabled );

    /**
     * @return ETrue if static items are enabled
     */
    TBool IsStaticItemsEnabled() const;

    /** 
     * @param aType type of count wanted
     * @return count of items, as specified in aType
     */
    TInt Count( NGlxListDefs::TCountType aType = NGlxListDefs::ECountAll ) const;

    /** 
     * @return item at index
     */
    TGlxMedia& Item( TInt aIndex );

    /** 
     * @param aId Id of item for which index is needed
     * @return item with id aId or KErrNotFound
     */
    TInt Index(const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aId ) const;

    /** 
     * Sets the initial focus position, first or last item
     * @param aFocusInitialPosition initial focus on first or last item
     */
    void SetFocusInitialPosition(NGlxListDefs::TFocusInitialPosition aFocusInitialPosition);

    /** 
     * @return index of focused item
     */
    TInt FocusIndex() const;

    /** 
     * Sets focus to item at index 
     * Notifies observer via HandleFocusChangedL
     * @param aType EAbsolute or ERelative
     * @param aValue If aType is EAbsolute, the new index value
     *               If aType is ERelative, the amount of indexes to move focus
     */
    void SetFocus( NGlxListDefs::TFocusSetType aType, TInt aValue );

    /** 
     * Resets the focus to the initial position
     */
    void ResetFocus();

    /** 
     * @return ETrue if item is selected, EFalse if not
     */
    TBool IsSelected( TInt aIndex ) const;

    /** 
     * Selects or deselects an item.
     * If item is already at desired selection state, does nothing.
     * Otherwise, calls back via HandleItemSelected.
     *
     * @param aIndex index of item to be selected/deselected
     * @param aSelected true if item should be selected
     *                  false if item should be deselected
     */
    void SetSelectedL( TInt aIndex, TBool aSelected );

    /** 
     * @return Array of indexes of items that are selected
     */
    const TArray< TInt > SelectedItemIndices() const;

    // From MGlxItemListObserver
    void HandleItemsAdded( TInt aFirstInsertedIndex, TInt aCount );
    void HandleItemsRemoved( TInt aRemovedFromIndex, TInt aCount );

private:
    /**
     * Constructor
     * @param aObserver Observer to be notified
     */
    CGlxNavigableList( MGlxNavigableListObserver& aObserver );

    /** 
     * Second-phase constructor 
     * @param aIdSpaceId id of the "space" in which all item ids are unique
     * @param aMediaUser User of media objects 
     */
    void ConstructL( const TGlxIdSpaceId& aIdSpaceId, 
        MGlxMediaUser& aMediaUser );
    
    /** @return id of focused item or KGlxIdNone if nothing focused */
    TGlxMediaId FocusId() const;

    /** 
     * Populates provided array with currently selected item ids
     * @param aItemIds array to contain selected item ids
     */
    void SelectionL( RArray< TGlxMediaId >& aItemIds ) const;
    
    /** 
     * Sets list contents to nothing, but leaves static items
     * @param aMediaPool interface from which to ask for media items
     */
    void ClearContentsL( const MGlxMediaPool& aMediaPool );
    
    /** 
     * Selects items by id
     * Ok to call if item does not exist in list
     * @param aItemIds List of ids of items to select
     */
    void SelectL( const RArray< TGlxMediaId >& aItemIds );
   
    /** 
     * Select item at index
     * @param aIndex index to be selected
     */
    void SelectL( TInt aIndex );
    
    /** 
     * Select item at index
     * Must call ReserveFreeSpaceInSelectionL first
     * @param aIndex index to be selected
     */
    void Select( TInt aIndex );
    
    /** 
     * Reserve free space in selection, so that Select
     * can be safely called
     * @param aCount Number of times Select will be called (or larger)
     */
    void ReserveFreeSpaceInSelectionL( TInt aCount );

    /** 
     * Deselect item at index
     * @param aIndex index to be deselected
     */
    void Deselect( TInt aIndex );

    /** 
     * Sets the initial focus
     */
    void SetInitialFocus();

    /** 
     * Set focus by id. Notifies observer
     * Does nothing if id does not exist in list
     * @param aItemId Id of the item to be focused
     */
    void SetFocus( const TGlxMediaId& aItemId );

    /** 
     * Set focus index
     * @param aIndex New focus index
     * @return Focus change type
     */
    NGlxListDefs::TFocusChangeType SetFocus( TInt aIndex );
        
    /** 
     * Move focus index
     * @param aDelta amount of indexes to move focus by
     * @return Focus change type
     */
    NGlxListDefs::TFocusChangeType MoveFocus( TInt aDelta );

    /**
     * Optionally, notify observer of focus change
     * @param aType Focus change type
     * @param aOldFocusIndex Focus index before focus being moved
     * @param aNotify if ETrue, notifies observer
     *                if EFalse, does nothing
     */
    void NotifyFocusChange( NGlxListDefs::TFocusChangeType aType, 
        TInt aNewIndex, TBool aNotify );
        
    /** 
     * Update focus after items have been inserted to the list
     * @param aInsertionIndex Insertion point
     * @param aInsertionCount Number of items inserted
     * @return ETrue if observer should be notified of focus change
     *         EFalse if not
     */
    TInt UpdateFocusAfterInsertion( TInt aInsertionIndex, TInt aInsertionCount );

    /** 
     * Update selection item indexes after removal of items
     * @param aRemovedFromIndex First removed item index
     * @param aRemovedCount Number of items removed
     */
    void UpdateSelectionAfterRemove( TInt aRemovedFromIndex, TInt aRemovedCount );
    
    /** 
     * Update focus after items have been removed from the list
     * @param aRemovedFromIndex index of first removed item
     * @param aRemovedCount Number of items removed
     * @return ETrue if observer should be notified of focus change
     *         EFalse if not
     */
    TBool UpdateFocusAfterRemoval( TInt aRemovedFromIndex, TInt aRemovedCount ); 

    /** 
     * Move focus if index changed.
     * @param aChangedIndex Only move focus if index changed.
     * @param aMoveBy Amount to move by
     * @return ETrue if observer should be notified of focus change
     *         EFalse if not
     */
    TBool MoveFocusIfIndexChanged( TInt aChangedIndex, TInt aMoveBy );
    
    
    /** 
     * Run selection index strategy for all selection item indexes that point 
     * to items between aFromIndex and aToIndex (inclusive)
     * @param aFromIndex First item index to be processed (not selection item index, 
     *                   but item index)
     * @param aToIndex Last item index to be processed (not selection item index, 
     *                 but item index)
     * @param aStrategy Strategy object that contains the logic of what to do 
     *                  with the selection index
     */
    void ProcessSelectionItemIndicesBetweenIndexes( TInt aFromIndex, 
        TInt aToIndex, NGlxNavigableList::MSelectionIndexStrategy& aStrategy );
        
    /**
     * Find the first selected item index that points to an item index
     * smaller aMaxIndex
     * @aMaxIndex The item index pointed to by the returned selection index has 
     *            to be smaller than this parameter
     * @return selected item index (in iSelectedItemIndices)
     */
    TInt FindFirstSelectedItemIndexBefore( TInt aMaxIndex );
        
private:
    /// list of items
    CGlxStaticItemList* iItemList; // own
    
    
    /// Focus initial position, first or last item
    NGlxListDefs::TFocusInitialPosition iFocusInitialPosition;

    /// Focus index or KErrNotFound
    TInt iFocusIndex;
    
    /// Indexes of selected items
    RArray<TInt> iSelectedItemIndices;
    
    /// Observer for changes
    MGlxNavigableListObserver& iObserver;
    
    /// Free space in iSelectedItemIndices. Used to make sure Select(...) is not
    /// called without calling ReserveFreeSpaceInSelectionL first
    __DEBUG_ONLY( TInt _iSelectionReserveCount );
    
    __DECLARE_TEST;
    };
    
#endif // __C_GLXNAVIGABLELIST_H__