1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
///////////////////////////////////////////////////////////////////////////////
// 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_
|