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
|
// *****************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 *
// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
// *****************************************************************************
#ifndef BITMAP_BUTTON_H_83415718945878341563415
#define BITMAP_BUTTON_H_83415718945878341563415
#include <wx/bmpbuttn.h>
#include <wx/settings.h>
#include <wx/statbmp.h>
#include "image_tools.h"
#include "std_button_layout.h"
#include "dc.h"
namespace zen
{
//zen::BitmapTextButton is identical to wxBitmapButton, but preserves the label via SetLabel(), which wxFormbuilder would ditch!
class BitmapTextButton : public wxBitmapButton
{
public:
BitmapTextButton(wxWindow* parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr)) :
wxBitmapButton(parent, id, wxNullBitmap, pos, size, style, validator, name)
{
SetLabel(label);
}
};
//wxButton::SetBitmap() also supports "image + text", but screws up proper gap and border handling
void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& text, int gap = dipToWxsize(5), int border = dipToWxsize(5));
//set bitmap label flicker free:
void setImage(wxAnyButton& button, const wxImage& bmp);
void setImage(wxStaticBitmap& staticBmp, const wxImage& img);
wxImage renderPressedButton(const wxSize& sz);
inline wxColor getColorToggleButtonBorder() { return {0x79, 0xbc, 0xed}; } //medium blue
inline wxColor getColorToggleButtonFill () { return {0xcc, 0xe4, 0xf8}; } //light blue
//################################### implementation ###################################
inline
void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& text, int gap, int border)
{
assert(gap >= 0 && border >= 0);
gap = std::max(0, gap);
border = std::max(0, border);
wxImage imgTxt = createImageFromText(text, btn.GetFont(), btn.GetForegroundColour());
if (img.IsOk())
imgTxt = btn.GetLayoutDirection() != wxLayout_RightToLeft ?
stackImages(img, imgTxt, ImageStackLayout::horizontal, ImageStackAlignment::center, wxsizeToScreen(gap)) :
stackImages(imgTxt, img, ImageStackLayout::horizontal, ImageStackAlignment::center, wxsizeToScreen(gap));
//SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work correctly
btn.SetMinSize({screenToWxsize(imgTxt.GetWidth()) + 2 * border,
std::max(screenToWxsize(imgTxt.GetHeight()) + 2 * border, getDefaultButtonHeight())});
setImage(btn, imgTxt);
}
inline
void setImage(wxAnyButton& button, const wxImage& img)
{
if (!img.IsOk())
{
button.SetBitmapLabel (wxNullBitmap);
button.SetBitmapDisabled(wxNullBitmap);
return;
}
button.SetBitmapLabel(toScaledBitmap(img));
//wxWidgets excels at screwing up consistently once again:
//the first call to SetBitmapLabel() *implicitly* sets the disabled bitmap, too, subsequent calls, DON'T!
button.SetBitmapDisabled(toScaledBitmap(img.ConvertToDisabled())); //inefficiency: wxBitmap::ConvertToDisabled() implicitly converts to wxImage!
}
inline
void setImage(wxStaticBitmap& staticBmp, const wxImage& img)
{
staticBmp.SetBitmap(toScaledBitmap(img));
}
inline
wxImage generatePressedButtonBack(const wxSize& sz)
{
#if 1
return rectangleImage(sz, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), {0x11, 0x79, 0xfe} /*light blue*/, dipToScreen(2));
#else //rectangle border with gradient as background
wxBitmap bmp(wxsizeToScreen(sz.x),
wxsizeToScreen(sz.y)); //seems we don't need to pass 24-bit depth here even for high-contrast color schemes
bmp.SetScaleFactor(getScreenDpiScale());
{
//draw rectangle border with gradient
const wxColor colFrom = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
const wxColor colTo(0x11, 0x79, 0xfe); //light blue
wxMemoryDC dc(bmp);
dc.SetPen(*wxTRANSPARENT_PEN); //wxTRANSPARENT_PEN is about 2x faster than redundantly drawing with col!
wxRect rect(sz);
const int borderSize = dipToWxsize(3);
for (int i = 1 ; i <= borderSize; ++i)
{
const wxColor colGradient((colFrom.Red () * (borderSize - i) + colTo.Red () * i) / borderSize,
(colFrom.Green() * (borderSize - i) + colTo.Green() * i) / borderSize,
(colFrom.Blue () * (borderSize - i) + colTo.Blue () * i) / borderSize);
dc.SetBrush(colGradient);
dc.DrawRectangle(rect);
rect.Deflate(dipToWxsize(1));
}
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.DrawRectangle(rect);
}
wxImage img = bmp.ConvertToImage();
convertToVanillaImage(img);
return img;
#endif
}
}
#endif //BITMAP_BUTTON_H_83415718945878341563415
|