156 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/private/rowheightcache.h
 | 
						|
// Purpose:     height cache of rows in a dataview
 | 
						|
// Author:      Jens Goepfert (mail@jensgoepfert.de)
 | 
						|
// Created:     2018-03-06
 | 
						|
// Copyright:   (c) wxWidgets team
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_PRIVATE_ROWHEIGHTCACHE_H_
 | 
						|
#define _WX_PRIVATE_ROWHEIGHTCACHE_H_
 | 
						|
 | 
						|
#include "wx/hashmap.h"
 | 
						|
#include "wx/vector.h"
 | 
						|
 | 
						|
// struct describing a range of rows which contains rows <from> .. <to-1>
 | 
						|
struct RowRange
 | 
						|
{
 | 
						|
    unsigned int from;
 | 
						|
    unsigned int to;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
    A helper class that manages a set of RowRange objects.
 | 
						|
 | 
						|
    It stores the indices that are members of a group in a memory
 | 
						|
    efficient way.
 | 
						|
*/
 | 
						|
class WXDLLIMPEXP_CORE RowRanges
 | 
						|
{
 | 
						|
public:
 | 
						|
    /**
 | 
						|
        Adds a row index to this group by adding it to an existing RowRange
 | 
						|
        or by creating a new one.
 | 
						|
    */
 | 
						|
    void Add(unsigned int row);
 | 
						|
 | 
						|
    /**
 | 
						|
        Removes a row index and all indices after idx from this group.
 | 
						|
    */
 | 
						|
    void Remove(unsigned int row);
 | 
						|
 | 
						|
    /**
 | 
						|
        Checks whether a row index is contained in this group.
 | 
						|
    */
 | 
						|
    bool Has(unsigned int row) const;
 | 
						|
 | 
						|
    /**
 | 
						|
        Returns the number of row indices that are contained in this group.
 | 
						|
    */
 | 
						|
    unsigned int CountAll() const;
 | 
						|
 | 
						|
    /**
 | 
						|
        Returns the number of rows that are in this group before the given row
 | 
						|
        index.
 | 
						|
 | 
						|
        Not that this doesn't include the given row.
 | 
						|
    */
 | 
						|
    unsigned int CountTo(unsigned int row) const;
 | 
						|
 | 
						|
    /**
 | 
						|
        Returns the size of the range.
 | 
						|
 | 
						|
        This is only used for testing and debugging.
 | 
						|
     */
 | 
						|
    unsigned int GetSize() const { return m_ranges.size(); }
 | 
						|
 | 
						|
private:
 | 
						|
    wxVector<RowRange> m_ranges;
 | 
						|
 | 
						|
    /**
 | 
						|
        If a new row index was inserted, Cleanup() checks if the neighbour
 | 
						|
        ranges of idx can includes the same row indices and discards
 | 
						|
        unnecessary RowRange objects.
 | 
						|
    */
 | 
						|
    void CleanUp(unsigned int idx);
 | 
						|
};
 | 
						|
 | 
						|
WX_DECLARE_HASH_MAP(unsigned int, RowRanges*, wxIntegerHash, wxIntegerEqual,
 | 
						|
    HeightToRowRangesMap);
 | 
						|
 | 
						|
/**
 | 
						|
    HeightCache implements a cache mechanism for wxDataViewCtrl.
 | 
						|
 | 
						|
    It gives fast access to:
 | 
						|
    * the height of one line (GetLineHeight)
 | 
						|
    * the y-coordinate where a row starts (GetLineStart)
 | 
						|
    * and vice versa (GetLineAt)
 | 
						|
 | 
						|
    The layout of the cache is a hashmap where the keys are all existing row
 | 
						|
    heights in pixels. The values are RowRange objects that represent all rows
 | 
						|
    having the specified height.
 | 
						|
 | 
						|
    An example:
 | 
						|
    @code
 | 
						|
    {
 | 
						|
    22: RowRange([0..10], [15..17], [20..2000]),
 | 
						|
    42: RowRange([11..12], [18..18]),
 | 
						|
    62: RowRange([13..14], [19..19])
 | 
						|
    }
 | 
						|
    @endcode
 | 
						|
 | 
						|
    Examples
 | 
						|
    ========
 | 
						|
 | 
						|
    GetLineStart
 | 
						|
    ------------
 | 
						|
    To retrieve the y-coordinate of item 1000 it is necessary to look into
 | 
						|
    each key of the hashmap *m_heightToRowRange*. Get the row count of
 | 
						|
    indices lower than 1000 (RowRange::CountTo) and multiplies it which the
 | 
						|
    according height.
 | 
						|
 | 
						|
    RowRange([0..10], [15..17], [20..2000]).CountTo(1000)
 | 
						|
    --> 0..10 are 11 items, 15..17 are 3 items and 20..1000 are 980 items (1000-20)
 | 
						|
    = 11 + 3 + 980 = 994 items
 | 
						|
 | 
						|
    GetLineStart(1000) --> (22 * 994) + (42 * 3) + (62 * 3) = 22180
 | 
						|
 | 
						|
    GetLineHeight
 | 
						|
    -------------
 | 
						|
    To retrieve the line height look into each key and check if row is
 | 
						|
    contained in RowRange (RowRange::Has)
 | 
						|
 | 
						|
    GetLineAt
 | 
						|
    ---------
 | 
						|
    To retrieve the row that starts at a specific y-coordinate.
 | 
						|
    Look into each key and count all rows.
 | 
						|
    Use bisect algorithm in combination with GetLineStart() to
 | 
						|
    find the appropriate item
 | 
						|
*/
 | 
						|
class WXDLLIMPEXP_CORE HeightCache
 | 
						|
{
 | 
						|
public:
 | 
						|
    ~HeightCache();
 | 
						|
    bool GetLineStart(unsigned int row, int& start);
 | 
						|
    bool GetLineHeight(unsigned int row, int& height);
 | 
						|
    bool GetLineAt(int y, unsigned int& row);
 | 
						|
    bool GetLineInfo(unsigned int row, int &start, int &height);
 | 
						|
 | 
						|
    void Put(unsigned int row, int height);
 | 
						|
 | 
						|
    /**
 | 
						|
        Removes the stored height of the given row from the cache and
 | 
						|
        invalidates all cached rows (including the given one).
 | 
						|
    */
 | 
						|
    void Remove(unsigned int row);
 | 
						|
 | 
						|
    void Clear();
 | 
						|
 | 
						|
private:
 | 
						|
    HeightToRowRangesMap m_heightToRowRange;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
#endif // _WX_PRIVATE_ROWHEIGHTCACHE_H_
 |