Change DoGetPreferredSize() to use a callback function
Instead of taking an array of scales, call GetNextAvailableScale() to get them. This allows centralising the logic for returning the available scales in a single place, where it will be reused in the upcoming commits.
This commit is contained in:
parent
66d4f75c86
commit
36abfe973a
4 changed files with 107 additions and 63 deletions
|
|
@ -227,10 +227,19 @@ protected:
|
|||
// Standard implementation of GetPreferredBitmapSizeAtScale(): choose the
|
||||
// scale closest to the given one from the available bitmap scales.
|
||||
//
|
||||
// Note that scales *must* be sorted in increasing scale order and there
|
||||
// must be at least 1 of them.
|
||||
wxSize
|
||||
DoGetPreferredSize(double scale, size_t n, const double *availableScales) const;
|
||||
// If this function is used, GetNextAvailableScale() must be overridden!
|
||||
wxSize DoGetPreferredSize(double scale) const;
|
||||
|
||||
// Override this function if DoGetPreferredSize() is used: it can use the
|
||||
// provided parameter as an internal index, it's guaranteed to be 0 when
|
||||
// calling this function for the first time. When there are no more scales,
|
||||
// return 0.
|
||||
//
|
||||
// This function is not pure virtual because it doesn't need to be
|
||||
// implemented if DoGetPreferredSize() is never used, but it will assert if
|
||||
// it's called.
|
||||
virtual double GetNextAvailableScale(size_t& i) const;
|
||||
|
||||
|
||||
virtual ~wxBitmapBundleImpl();
|
||||
|
||||
|
|
|
|||
|
|
@ -500,25 +500,28 @@ protected:
|
|||
trying to choose one of the available scales, to avoid actually
|
||||
rescaling the bitmaps.
|
||||
|
||||
Typically this function is used in the derived classes implementation,
|
||||
e.g.
|
||||
It relies on GetNextAvailableScale() to get information about the
|
||||
available bitmaps, so that function must be overridden if this one is
|
||||
used.
|
||||
|
||||
Typically this function is used in the derived classes implementation
|
||||
to forward GetPreferredBitmapSizeAtScale() to it, e.g.
|
||||
@code
|
||||
class MyCustomBitmapBundleImpl : public wxBitmapBundleImpl
|
||||
{
|
||||
public:
|
||||
wxSize GetPreferredBitmapSizeAtScale(double scale) const wxOVERRIDE
|
||||
{
|
||||
std::vector<double> vec;
|
||||
vec.push_back(1);
|
||||
return DoGetPreferredSize(scale);
|
||||
}
|
||||
|
||||
// Note that the vector must be sorted, so we must add this
|
||||
// scale before adding 2 below.
|
||||
if ( MyIntermediateBitmapIsAvailable() )
|
||||
vec.push_back(1.5);
|
||||
protected:
|
||||
double GetNextAvailableScale(size_t& i) const wxOVERRIDE
|
||||
{
|
||||
const double availableScales[] = { 1, 1.5, 2, 0 };
|
||||
|
||||
vec.push_back(2);
|
||||
|
||||
return DoGetPreferredSize(scale, vec.size(), vec.data());
|
||||
// We can rely on not being called again once we return 0.
|
||||
return availableScales[i++];
|
||||
}
|
||||
|
||||
...
|
||||
|
|
@ -527,17 +530,29 @@ protected:
|
|||
|
||||
@param scale The required scale, typically the same one as passed to
|
||||
GetPreferredBitmapSizeAtScale().
|
||||
@param n The number of elements in @a availableScales, must be strictly
|
||||
positive (i.e. there must always be at least one available scale).
|
||||
@param availableScales The scales in which bitmaps are available, i.e.
|
||||
scales such that GetBitmap() wouldn't need to scale the bitmap if
|
||||
it were called with them. This array @e must be in sorted order,
|
||||
with 1 being its first element.
|
||||
|
||||
@since 3.1.7
|
||||
*/
|
||||
wxSize
|
||||
DoGetPreferredSize(double scale, size_t n, const double *availableScales) const;
|
||||
wxSize DoGetPreferredSize(double scale) const;
|
||||
|
||||
/**
|
||||
Return information about the available bitmaps.
|
||||
|
||||
Overriding this function is optional and only needs to be done if
|
||||
DoGetPreferredSize() is called. If you do override it, this function
|
||||
must return the next available scale or 0.0 if there are no more.
|
||||
|
||||
The returned scales must be in ascending order and the first returned
|
||||
scale, for the initial @a i value of 0, should be 1. The function must
|
||||
change @a i, but the values of this index don't have to be consecutive
|
||||
and it's only used by this function itself, the caller only initializes
|
||||
it to 0 before the first call.
|
||||
|
||||
See DoGetPreferredSize() for an example of implementing this function.
|
||||
|
||||
@since 3.1.7
|
||||
*/
|
||||
virtual double GetNextAvailableScale(size_t& i) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -133,6 +133,9 @@ public:
|
|||
virtual wxSize GetPreferredBitmapSizeAtScale(double scale) const wxOVERRIDE;
|
||||
virtual wxBitmap GetBitmap(const wxSize& size) wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual double GetNextAvailableScale(size_t& i) const wxOVERRIDE;
|
||||
|
||||
private:
|
||||
// Struct containing bitmap itself as well as a flag indicating whether we
|
||||
// generated it by rescaling the existing bitmap or not.
|
||||
|
|
@ -236,22 +239,24 @@ wxSize wxBitmapBundleImplSet::GetDefaultSize() const
|
|||
return m_sizeDefault;
|
||||
}
|
||||
|
||||
wxSize wxBitmapBundleImplSet::GetPreferredBitmapSizeAtScale(double scale) const
|
||||
double wxBitmapBundleImplSet::GetNextAvailableScale(size_t& i) const
|
||||
{
|
||||
const double baseY = GetDefaultSize().y;
|
||||
|
||||
const size_t n = m_entries.size();
|
||||
wxVector<double> scales;
|
||||
scales.reserve(n);
|
||||
for ( size_t i = 0; i < n; ++i )
|
||||
while ( i < m_entries.size() )
|
||||
{
|
||||
if ( m_entries[i].generated )
|
||||
const Entry& entry = m_entries[i++];
|
||||
|
||||
if ( entry.generated )
|
||||
continue;
|
||||
|
||||
scales.push_back(m_entries[i].bitmap.GetSize().y / baseY);
|
||||
return static_cast<double>(entry.bitmap.GetSize().y) / GetDefaultSize().y;
|
||||
}
|
||||
|
||||
return DoGetPreferredSize(scale, scales.size(), &scales[0]);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
wxSize wxBitmapBundleImplSet::GetPreferredBitmapSizeAtScale(double scale) const
|
||||
{
|
||||
return DoGetPreferredSize(scale);
|
||||
}
|
||||
|
||||
wxBitmap wxBitmapBundleImplSet::GetBitmap(const wxSize& size)
|
||||
|
|
@ -703,19 +708,47 @@ wxBitmapBundle::CreateImageList(wxWindow* win,
|
|||
// wxBitmapBundleImpl implementation
|
||||
// ============================================================================
|
||||
|
||||
wxSize
|
||||
wxBitmapBundleImpl::DoGetPreferredSize(double scaleTarget,
|
||||
size_t n,
|
||||
const double* availableScales) const
|
||||
double
|
||||
wxBitmapBundleImpl::GetNextAvailableScale(size_t& WXUNUSED(i)) const
|
||||
{
|
||||
wxCHECK_MSG( n > 0, wxSize(), wxS("must have at least one scale") );
|
||||
wxFAIL_MSG( wxS("must be overridden if called") );
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
wxSize
|
||||
wxBitmapBundleImpl::DoGetPreferredSize(double scaleTarget) const
|
||||
{
|
||||
double scaleBest = 0.0;
|
||||
double scaleLast = 0.0;
|
||||
|
||||
for ( size_t i = 0; i < n; ++i )
|
||||
for ( size_t i = 0;; )
|
||||
{
|
||||
const double scaleThis = availableScales[i];
|
||||
const double scaleThis = GetNextAvailableScale(i);
|
||||
if ( scaleThis == 0.0 )
|
||||
{
|
||||
// We only get here if the target scale is bigger than all the
|
||||
// available scales, in which case we have no choice but to use the
|
||||
// biggest bitmap, which corresponds to the last used scale that we
|
||||
// should have by now.
|
||||
wxASSERT_MSG( scaleLast != 0.0, "must have some available scales" );
|
||||
|
||||
// But check how far is it from the requested scale: if it's more than
|
||||
// 1.5 times larger, we should still scale it, notably to ensure that
|
||||
// bitmaps of standard size are scaled when 2x DPI scaling is used.
|
||||
if ( scaleTarget > 1.5*scaleLast )
|
||||
{
|
||||
// However scaling by non-integer scales doesn't work well at all, so
|
||||
// round it to the closest integer in this case.
|
||||
scaleBest = wxRound(scaleTarget);
|
||||
}
|
||||
else // Target scale is not much greater than the biggest one we have.
|
||||
{
|
||||
scaleBest = scaleLast;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Ensure we remember the last used scale value.
|
||||
wxON_BLOCK_EXIT_SET(scaleLast, scaleThis);
|
||||
|
|
@ -735,7 +768,7 @@ wxBitmapBundleImpl::DoGetPreferredSize(double scaleTarget,
|
|||
// We've found the closest bigger bitmap.
|
||||
|
||||
// If there is no smaller bitmap, we have no choice but to use this one.
|
||||
if ( i == 0 )
|
||||
if ( scaleLast == 0.0 )
|
||||
{
|
||||
scaleBest = scaleThis;
|
||||
break;
|
||||
|
|
@ -751,27 +784,6 @@ wxBitmapBundleImpl::DoGetPreferredSize(double scaleTarget,
|
|||
break;
|
||||
}
|
||||
|
||||
if ( scaleBest == 0.0 )
|
||||
{
|
||||
// We only get here if the target scale is bigger than all the
|
||||
// available scales, in which case we have no choice but to use the
|
||||
// biggest bitmap, which corresponds to the last used scale.
|
||||
|
||||
// But check how far is it from the requested scale: if it's more than
|
||||
// 1.5 times larger, we should still scale it, notably to ensure that
|
||||
// bitmaps of standard size are scaled when 2x DPI scaling is used.
|
||||
if ( scaleTarget > 1.5*scaleLast )
|
||||
{
|
||||
// However scaling by non-integer scales doesn't work well at all, so
|
||||
// round it to the closest integer in this case.
|
||||
scaleBest = wxRound(scaleTarget);
|
||||
}
|
||||
else // Target scale is not much greater than the biggest one we have.
|
||||
{
|
||||
scaleBest = scaleLast;
|
||||
}
|
||||
}
|
||||
|
||||
return GetDefaultSize()*scaleBest;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ public:
|
|||
virtual wxSize GetPreferredBitmapSizeAtScale(double scale) const wxOVERRIDE;
|
||||
virtual wxBitmap GetBitmap(const wxSize& size) wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual double GetNextAvailableScale(size_t& i) const wxOVERRIDE;
|
||||
|
||||
private:
|
||||
// Load the bitmap from the given resource and add it m_bitmaps, after
|
||||
// rescaling it to the given size if necessary, i.e. if the needed size is
|
||||
|
|
@ -189,6 +192,11 @@ wxSize wxBitmapBundleImplRC::GetDefaultSize() const
|
|||
return m_bitmaps[0].GetSize();
|
||||
}
|
||||
|
||||
double wxBitmapBundleImplRC::GetNextAvailableScale(size_t& i) const
|
||||
{
|
||||
return i < m_resourceInfos.size() ? m_resourceInfos[i++].scale : 0.0;
|
||||
}
|
||||
|
||||
wxSize wxBitmapBundleImplRC::GetPreferredBitmapSizeAtScale(double scale) const
|
||||
{
|
||||
const size_t n = m_resourceInfos.size();
|
||||
|
|
@ -198,7 +206,7 @@ wxSize wxBitmapBundleImplRC::GetPreferredBitmapSizeAtScale(double scale) const
|
|||
scales[i] = m_resourceInfos[i].scale;
|
||||
}
|
||||
|
||||
return DoGetPreferredSize(scale, n, &scales[0]);
|
||||
return DoGetPreferredSize(scale);
|
||||
}
|
||||
|
||||
wxBitmap
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue