summaryrefslogtreecommitdiff
path: root/shared/custom_button.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/custom_button.cpp')
-rw-r--r--shared/custom_button.cpp89
1 files changed, 75 insertions, 14 deletions
diff --git a/shared/custom_button.cpp b/shared/custom_button.cpp
index df65a401..98c0a3cd 100644
--- a/shared/custom_button.cpp
+++ b/shared/custom_button.cpp
@@ -12,6 +12,44 @@
#include <cmath>
+namespace
+{
+bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs)
+{
+ if (lhs.IsOk() != rhs.IsOk())
+ return false;
+
+ if (!lhs.IsOk())
+ return true;
+
+ const int pixelCount = lhs.GetWidth() * lhs.GetHeight();
+ if (pixelCount != rhs.GetWidth() * rhs.GetHeight())
+ return false;
+
+ wxImage imLhs = lhs.ConvertToImage();
+ wxImage imRhs = rhs.ConvertToImage();
+
+ if (imLhs.HasAlpha() != imRhs.HasAlpha())
+ return false;
+
+ if (imLhs.HasAlpha())
+ {
+ if (!std::equal(imLhs.GetAlpha(), imLhs.GetAlpha() + pixelCount, imRhs.GetAlpha()))
+ return false;
+ }
+
+ return std::equal(imLhs.GetData(), imLhs.GetData() + pixelCount * 3, imRhs.GetData());
+}
+}
+
+
+void setBitmapLabel(wxBitmapButton& button, const wxBitmap& bmp)
+{
+ if (!isEqual(button.GetBitmapLabel(), bmp))
+ button.SetBitmapLabel(bmp);
+}
+
+
wxButtonWithImage::wxButtonWithImage(wxWindow* parent,
wxWindowID id,
const wxString& label,
@@ -30,25 +68,34 @@ wxButtonWithImage::wxButtonWithImage(wxWindow* parent,
void wxButtonWithImage::setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter)
{
- bitmapFront = bitmap;
- m_spaceAfter = spaceAfter;
- refreshButtonLabel();
+ if (!isEqual(bitmap, bitmapFront) || spaceAfter != m_spaceAfter) //avoid flicker
+ {
+ bitmapFront = bitmap;
+ m_spaceAfter = spaceAfter;
+ refreshButtonLabel();
+ }
}
void wxButtonWithImage::setTextLabel(const wxString& text)
{
- textLabel = text;
- wxBitmapButton::SetLabel(text);
- refreshButtonLabel();
+ if (text != textLabel) //avoid flicker
+ {
+ textLabel = text;
+ wxBitmapButton::SetLabel(text);
+ refreshButtonLabel();
+ }
}
void wxButtonWithImage::setBitmapBack(const wxBitmap& bitmap, unsigned spaceBefore)
{
- bitmapBack = bitmap;
- m_spaceBefore = spaceBefore;
- refreshButtonLabel();
+ if (!isEqual(bitmap, bitmapBack) || spaceBefore != m_spaceBefore) //avoid flicker
+ {
+ bitmapBack = bitmap;
+ m_spaceBefore = spaceBefore;
+ refreshButtonLabel();
+ }
}
@@ -293,19 +340,33 @@ void writeToImage(const wxImage& source, const wxPoint pos, wxImage& target)
}
+namespace
+{
+inline
+wxSize getSize(const wxBitmap& bmp)
+{
+ return bmp.IsOk() ? wxSize(bmp.GetWidth(), bmp.GetHeight()) : wxSize(0, 0);
+}
+}
+
+
void wxButtonWithImage::refreshButtonLabel()
{
wxBitmap bitmapText = createBitmapFromText(textLabel);
+ wxSize szFront = getSize(bitmapFront); //
+ wxSize szText = getSize(bitmapText); //make sure to NOT access null-bitmaps!
+ wxSize szBack = getSize(bitmapBack); //
+
//calculate dimensions of new button
- const int height = std::max(std::max(bitmapFront.GetHeight(), bitmapText.GetHeight()), bitmapBack.GetHeight());
- const int width = bitmapFront.GetWidth() + m_spaceAfter + bitmapText.GetWidth() + m_spaceBefore + bitmapBack.GetWidth();
+ const int height = std::max(std::max(szFront.GetHeight(), szText.GetHeight()), szBack.GetHeight());
+ const int width = szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore + szBack.GetWidth();
//create a transparent image
wxImage transparentImage(width, height, false);
transparentImage.SetAlpha();
unsigned char* alpha = transparentImage.GetAlpha();
- memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, width * height);
+ ::memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, width * height);
//wxDC::DrawLabel() unfortunately isn't working for transparent images on Linux, so we need to use custom image-concatenation
if (bitmapFront.IsOk())
@@ -315,12 +376,12 @@ void wxButtonWithImage::refreshButtonLabel()
if (bitmapText.IsOk())
writeToImage(bitmapText.ConvertToImage(),
- wxPoint(bitmapFront.GetWidth() + m_spaceAfter, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2),
+ wxPoint(szFront.GetWidth() + m_spaceAfter, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2),
transparentImage);
if (bitmapBack.IsOk())
writeToImage(bitmapBack.ConvertToImage(),
- wxPoint(bitmapFront.GetWidth() + m_spaceAfter + bitmapText.GetWidth() + m_spaceBefore, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2),
+ wxPoint(szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2),
transparentImage);
//adjust button size
bgstack15