summaryrefslogtreecommitdiff
path: root/wx+
diff options
context:
space:
mode:
authorDaniel Wilhelm <shieldwed@outlook.com>2019-12-14 15:52:53 +0000
committerDaniel Wilhelm <shieldwed@outlook.com>2019-12-14 15:52:53 +0000
commitcc75e50ca861529d50601d247fd66f806fcb23a8 (patch)
treee2c5c7b1f98e64011b1ee8ca4e9bb9157510dfe7 /wx+
parentMerge branch '10.17' into 'master' (diff)
parentadd upstream 10.18 (diff)
downloadFreeFileSync-cc75e50ca861529d50601d247fd66f806fcb23a8.tar.gz
FreeFileSync-cc75e50ca861529d50601d247fd66f806fcb23a8.tar.bz2
FreeFileSync-cc75e50ca861529d50601d247fd66f806fcb23a8.zip
Merge branch '10.18' into 'master'10.18
add upstream 10.18 See merge request opensource-tracking/FreeFileSync!15
Diffstat (limited to 'wx+')
-rw-r--r--wx+/async_task.h2
-rw-r--r--wx+/context_menu.h5
-rw-r--r--wx+/dc.h2
-rw-r--r--wx+/font_size.h4
-rw-r--r--wx+/graph.cpp13
-rw-r--r--wx+/grid.cpp67
-rw-r--r--wx+/grid.h16
-rw-r--r--wx+/image_resources.cpp109
-rw-r--r--wx+/image_tools.cpp10
-rw-r--r--wx+/image_tools.h4
-rw-r--r--wx+/rtl.h10
-rw-r--r--wx+/toggle_button.h25
12 files changed, 150 insertions, 117 deletions
diff --git a/wx+/async_task.h b/wx+/async_task.h
index 04eac61c..1599c4d7 100644
--- a/wx+/async_task.h
+++ b/wx+/async_task.h
@@ -85,7 +85,7 @@ public:
std::vector<std::unique_ptr<Task>> readyTasks; //Reentrancy; access to AsyncTasks::add is not protected! => evaluate outside eraseIf
- eraseIf(tasks_, [&](std::unique_ptr<Task>& task)
+ std::erase_if(tasks_, [&](std::unique_ptr<Task>& task)
{
if (task->resultReady())
{
diff --git a/wx+/context_menu.h b/wx+/context_menu.h
index d856db03..08a313bf 100644
--- a/wx+/context_menu.h
+++ b/wx+/context_menu.h
@@ -14,7 +14,7 @@
#include <wx/app.h>
/*
-A context menu supporting C++11 lambda callbacks!
+A context menu supporting lambda callbacks!
Usage:
ContextMenu menu;
@@ -56,7 +56,7 @@ public:
void addSeparator() { menu_->AppendSeparator(); }
- void addSubmenu(const wxString& label, ContextMenu& submenu, const wxBitmap* bmp = nullptr) //invalidates submenu!
+ void addSubmenu(const wxString& label, ContextMenu& submenu, const wxBitmap* bmp = nullptr, bool enabled = true) //invalidates submenu!
{
//transfer submenu commands:
commandList_.insert(submenu.commandList_.begin(), submenu.commandList_.end());
@@ -67,6 +67,7 @@ public:
wxMenuItem* newItem = new wxMenuItem(menu_.get(), wxID_ANY, label, L"", wxITEM_NORMAL, submenu.menu_.release()); //menu owns item, item owns submenu!
if (bmp) newItem->SetBitmap(*bmp); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason
menu_->Append(newItem);
+ if (!enabled) newItem->Enable(false);
}
void popup(wxWindow& wnd, const wxPoint& pos = wxDefaultPosition) //show popup menu + process lambdas
diff --git a/wx+/dc.h b/wx+/dc.h
index 894fb473..757942ca 100644
--- a/wx+/dc.h
+++ b/wx+/dc.h
@@ -56,7 +56,7 @@ int fastFromDIP(int d) //like wxWindow::FromDIP (but tied to primary monitor and
#else //https://github.com/wxWidgets/wxWidgets/blob/master/src/common/wincmn.cpp#L2865
static_assert(GTK_MAJOR_VERSION == 2);
//GTK2 doesn't properly support high DPI: https://freefilesync.org/forum/viewtopic.php?t=6114
- //=> requires general fix at wxWidgets-level
+ //=> requires general fix at wxWidgets-level
assert(wxTheApp); //only call after wxWidgets was initalized!
static const int dpiY = wxScreenDC().GetPPI().y; //perf: buffering for calls to ::GetDeviceCaps() needed!?
const int defaultDpi = 96;
diff --git a/wx+/font_size.h b/wx+/font_size.h
index 2f2d377c..d25dfede 100644
--- a/wx+/font_size.h
+++ b/wx+/font_size.h
@@ -35,7 +35,7 @@ void setRelativeFontSize(wxWindow& control, double factor)
wxFont font = control.GetFont();
font.SetPointSize(numeric::round(wxNORMAL_FONT->GetPointSize() * factor));
control.SetFont(font);
-};
+}
inline
@@ -46,7 +46,7 @@ void setMainInstructionFont(wxWindow& control)
font.SetWeight(wxFONTWEIGHT_BOLD);
control.SetFont(font);
-};
+}
}
#endif //FONT_SIZE_H_23849632846734343234532
diff --git a/wx+/graph.cpp b/wx+/graph.cpp
index aac2cc10..a6d0f19d 100644
--- a/wx+/graph.cpp
+++ b/wx+/graph.cpp
@@ -151,7 +151,7 @@ void drawXLabel(wxDC& dc, double xMin, double xMax, int blockCount, const Conver
return;
wxDCPenChanger dummy(dc, wxColor(192, 192, 192)); //light grey => not accessible! but no big deal...
- wxDCTextColourChanger dummy2(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+ wxDCTextColourChanger textColor(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
const double valRangePerBlock = (xMax - xMin) / blockCount;
@@ -179,7 +179,7 @@ void drawYLabel(wxDC& dc, double yMin, double yMax, int blockCount, const Conver
return;
wxDCPenChanger dummy(dc, wxColor(192, 192, 192)); //light grey => not accessible! but no big deal...
- wxDCTextColourChanger dummy2(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+ wxDCTextColourChanger textColor(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
const double valRangePerBlock = (yMax - yMin) / blockCount;
@@ -225,13 +225,12 @@ void drawCornerText(wxDC& dc, const wxRect& graphArea, const wxString& txt, Grap
drawPos.y += graphArea.height - boxExtent.GetHeight();
break;
}
- {
+
//add text shadow to improve readability:
- wxDCTextColourChanger dummy(dc, colorBack);
- dc.DrawText(txt, drawPos + border + wxSize(fastFromDIP(1), fastFromDIP(1)));
- }
+ wxDCTextColourChanger textColor(dc, colorBack);
+ dc.DrawText(txt, drawPos + border + wxSize(fastFromDIP(1), fastFromDIP(1)));
- wxDCTextColourChanger dummy(dc, colorText);
+ textColor.Set(colorText);
dc.DrawText(txt, drawPos + border);
}
diff --git a/wx+/grid.cpp b/wx+/grid.cpp
index 851146bc..0613e14f 100644
--- a/wx+/grid.cpp
+++ b/wx+/grid.cpp
@@ -249,7 +249,7 @@ wxRect GridData::drawColumnLabelBackground(wxDC& dc, const wxRect& rect, bool hi
void GridData::drawColumnLabelText(wxDC& dc, const wxRect& rect, const std::wstring& text)
{
- wxDCTextColourChanger dummy(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors!
+ wxDCTextColourChanger textColor(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors!
drawCellText(dc, rect, text, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
}
@@ -452,9 +452,7 @@ public:
{
wxClientDC dc(this);
- wxFont labelFont = GetFont();
- //labelFont.SetWeight(wxFONTWEIGHT_BOLD);
- dc.SetFont(labelFont); //harmonize with RowLabelWin::render()!
+ dc.SetFont(GetFont()); //harmonize with RowLabelWin::render()!
int bestWidth = 0;
for (ptrdiff_t i = rowFrom; i <= rowTo; ++i)
@@ -504,9 +502,7 @@ private:
{
clearArea(dc, rect, wxSystemSettings::GetColour(/*!renderAsEnabled(*this) ? wxSYS_COLOUR_BTNFACE :*/wxSYS_COLOUR_WINDOW));
- wxFont labelFont = GetFont();
- //labelFont.SetWeight(wxFONTWEIGHT_BOLD);
- dc.SetFont(labelFont); //harmonize with RowLabelWin::getBestWidth()!
+ dc.SetFont(GetFont()); //harmonize with RowLabelWin::getBestWidth()!
auto rowRange = getRowsOnClient(rect); //returns range [begin, end)
for (auto row = rowRange.first; row < rowRange.second; ++row)
@@ -524,7 +520,7 @@ private:
{
//clearArea(dc, rect, getColorRowLabel());
dc.GradientFillLinear(rect, getColorLabelGradientFrom(), getColorLabelGradientTo(), wxEAST); //clear overlapping cells
- wxDCTextColourChanger dummy3(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors!
+ wxDCTextColourChanger textColor(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors!
//label text
wxRect textRect = rect;
@@ -623,10 +619,10 @@ private:
//coordinate with "colLabelHeight" in Grid constructor:
wxFont labelFont = GetFont();
- labelFont.SetWeight(wxFONTWEIGHT_BOLD);
+ labelFont.MakeBold();
dc.SetFont(labelFont);
- wxDCTextColourChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels
+ wxDCTextColourChanger textColor(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels
const int colLabelHeight = refParent().colLabelHeight_;
@@ -893,7 +889,7 @@ private:
dc.SetFont(GetFont()); //harmonize with Grid::getBestColumnSize()
- wxDCTextColourChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels
+ wxDCTextColourChanger textColor(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels
std::vector<ColumnWidth> absWidths = refParent().getColWidths(); //resolve stretched widths
{
@@ -1313,7 +1309,7 @@ Grid::Grid(wxWindow* parent,
{
//coordinate with ColLabelWin::render():
wxFont labelFont = colLabelWin_->GetFont();
- labelFont.SetWeight(wxFONTWEIGHT_BOLD);
+ labelFont.MakeBold();
return labelFont.GetPixelSize().GetHeight();
}();
@@ -1491,22 +1487,51 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size)
}();
//2. try(!) to determine scrollbar sizes:
+#if GTK_MAJOR_VERSION == 2
+ /* Ubuntu 19.10: "scrollbar-spacing" has a default value of 3: https://developer.gnome.org/gtk2/stable/GtkScrolledWindow.html#GtkScrolledWindow--s-scrollbar-spacing
+ => the default Ubuntu theme (but also our Gtk2Styles.rc) set it to 0, but still the first call to gtk_widget_style_get() returns 3: why?
+ => maybe styles are applied asynchronously? GetClientSize() is affected by this, so can't use!
+ => always ignore spacing to get consistent scrollbar dimensions! */
+ GtkScrolledWindow* scrollWin = GTK_SCROLLED_WINDOW(wxWindow::m_widget);
+ assert(scrollWin);
+ GtkWidget* rangeH = ::gtk_scrolled_window_get_hscrollbar(scrollWin);
+ GtkWidget* rangeV = ::gtk_scrolled_window_get_vscrollbar(scrollWin);
+
+ GtkRequisition reqH = {};
+ GtkRequisition reqV = {};
+ if (rangeH) ::gtk_widget_size_request(rangeH, &reqH);
+ if (rangeV) ::gtk_widget_size_request(rangeV, &reqV);
+ assert(reqH.width > 0 && reqH.height > 0);
+ assert(reqV.width > 0 && reqV.height > 0);
+
+ const wxSize scrollBarSizeTmp(reqV.width, reqH.height);
+ assert(scrollBarHeightH_ == 0 || scrollBarHeightH_ == scrollBarSizeTmp.y);
+ assert(scrollBarWidthV_ == 0 || scrollBarWidthV_ == scrollBarSizeTmp.x);
+
+#elif GTK_MAJOR_VERSION == 3
+ //scrollbar size increases dynamically on mouse-hover!
+ //see "overlay scrolling": https://developer.gnome.org/gtk3/stable/GtkScrolledWindow.html#gtk-scrolled-window-set-overlay-scrolling
+ //luckily "scrollbar-spacing" is stable on GTK3
const wxSize scrollBarSizeTmp = GetSize() - GetClientSize();
- assert(scrollBarHeightH_ == 0 || scrollBarSizeTmp.y == 0 || scrollBarHeightH_ == scrollBarSizeTmp.y);
- assert(scrollBarWidthV_ == 0 || scrollBarSizeTmp.x == 0 || scrollBarWidthV_ == scrollBarSizeTmp.x);
+
+ assert(scrollBarSizeTmp.x == 0 || scrollBarSizeTmp.x == 6 || scrollBarSizeTmp.x == 13); //lame hard-coded numbers (from Ubuntu 19.10)
+ assert(scrollBarSizeTmp.y == 0 || scrollBarSizeTmp.y == 6 || scrollBarSizeTmp.y == 13); //=> but let's have a *close* eye on scrollbar fluctuation!
+#else
+#error unknown GTK version!
+#endif
scrollBarHeightH_ = std::max(scrollBarHeightH_, scrollBarSizeTmp.y);
scrollBarWidthV_ = std::max(scrollBarWidthV_, scrollBarSizeTmp.x);
//this function is called again by wxScrollHelper::AdjustScrollbars() if SB_SHOW_ALWAYS-scrollbars are not yet shown => scrollbar size > 0 eventually!
-
+
//-----------------------------------------------------------------------------
//harmonize with Grid::updateWindowSizes()!
wxSize sizeAvail = size - wxSize(rowLabelWidth, colLabelHeight_);
//EXCEPTION: space consumed by SB_SHOW_ALWAYS-scrollbars is *never* available for "scroll target"; see wxScrollHelper::AdjustScrollbars()
if (showScrollbarH_ == SB_SHOW_ALWAYS)
- sizeAvail.y -= scrollBarHeightH_;
+ sizeAvail.y -= (scrollBarHeightH_ > 0 ? scrollBarHeightH_ : /*fallback:*/ scrollBarWidthV_);
if (showScrollbarV_ == SB_SHOW_ALWAYS)
- sizeAvail.x -= scrollBarWidthV_;
+ sizeAvail.x -= (scrollBarWidthV_ > 0 ? scrollBarWidthV_ : /*fallback:*/ scrollBarHeightH_);
return wxSize(std::max(0, sizeAvail.x),
std::max(0, sizeAvail.y));
@@ -1879,10 +1904,10 @@ void Grid::showScrollBars(Grid::ScrollBarStatus horizontal, Grid::ScrollBarStatu
assert(false);
return GTK_POLICY_AUTOMATIC;
};
-
- GtkWidget* gridWidget = wxWindow::m_widget;
- GtkScrolledWindow* scrolledWindow = GTK_SCROLLED_WINDOW(gridWidget);
- ::gtk_scrolled_window_set_policy(scrolledWindow,
+
+ GtkScrolledWindow* scrollWin = GTK_SCROLLED_WINDOW(wxWindow::m_widget);
+ assert(scrollWin);
+ ::gtk_scrolled_window_set_policy(scrollWin,
mapStatus(horizontal),
mapStatus(vertical));
diff --git a/wx+/grid.h b/wx+/grid.h
index cecdfafe..74dc25b2 100644
--- a/wx+/grid.h
+++ b/wx+/grid.h
@@ -333,15 +333,13 @@ private:
ColumnType colToType(size_t col) const; //returns ColumnType::NONE on error
- /*
- Visual layout:
- --------------------------------
- |CornerWin | ColLabelWin |
- |------------------------------|
- |RowLabelWin | MainWin |
- | | |
- --------------------------------
- */
+ /* Grid window layout:
+ _______________________________
+ | CornerWin | ColLabelWin |
+ |_____________|_______________|
+ | RowLabelWin | MainWin |
+ | | |
+ |_____________|_______________| */
CornerWin* cornerWin_;
RowLabelWin* rowLabelWin_;
ColLabelWin* colLabelWin_;
diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp
index faabbb2a..91189ba6 100644
--- a/wx+/image_resources.cpp
+++ b/wx+/image_resources.cpp
@@ -11,10 +11,10 @@
#include <zen/globals.h>
#include <zen/perf.h>
#include <zen/thread.h>
-#include <wx/wfstream.h>
+#include <zen/file_io.h>
#include <wx/zipstrm.h>
-#include <wx/image.h>
#include <wx/mstream.h>
+#include <wx/image.h>
#include <xBRZ/src/xbrz.h>
#include <xBRZ/src/xbrz_tools.h>
#include "image_tools.h"
@@ -143,24 +143,6 @@ private:
//hardware_concurrency() == 0 if "not computable or well defined"
};
-
-void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim)
-{
- //work around wxWidgets bug:
- //construct seekable input stream (zip-input stream is not seekable) for wxAnimation::Load()
- //luckily this method call is very fast: below measurement precision!
- std::vector<std::byte> data;
- data.reserve(10000);
-
- int newValue = 0;
- while ((newValue = zipInput.GetC()) != wxEOF)
- data.push_back(static_cast<std::byte>(newValue));
-
- wxMemoryInputStream seekAbleStream(&data.front(), data.size()); //stream does not take ownership of data
-
- anim.Load(seekAbleStream, wxANIMATION_TYPE_GIF);
-}
-
//================================================================================================
//================================================================================================
@@ -204,44 +186,59 @@ void GlobalBitmaps::init(const Zstring& filePath)
{
assert(bitmaps_.empty() && anims_.empty());
- wxFFileInputStream input(utfTo<wxString>(filePath));
- if (input.IsOk()) //if not... we don't want to react too harsh here
+ //wxFFileInputStream/wxZipInputStream loads in junks of 512 bytes => WTF!!! => implement sane file loading:
+ try
{
- //activate support for .png files
- wxImage::AddHandler(new wxPNGHandler); //ownership passed
-
- wxZipInputStream streamIn(input, wxConvUTF8);
- //do NOT rely on wxConvLocal! On failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!"
-
- //do we need xBRZ scaling for high quality DPI images?
- const int hqScale = std::clamp<int>(std::ceil(fastFromDIP(1000) / 1000.0), 1, xbrz::SCALE_FACTOR_MAX);
- //even for 125% DPI scaling, "2xBRZ + bilinear downscale" gives a better result than mere "125% bilinear upscale"!
- if (hqScale > 1)
- dpiScaler_ = std::make_unique<DpiParallelScaler>(hqScale);
-
- while (const auto& entry = std::unique_ptr<wxZipEntry>(streamIn.GetNextEntry())) //take ownership!)
- {
- const wxString name = entry->GetName();
-
- if (endsWith(name, L".png"))
- {
- wxImage img(streamIn, wxBITMAP_TYPE_PNG);
-
- //end this alpha/no-alpha/mask/wxDC::DrawBitmap/RTL/high-contrast-scheme interoperability nightmare here and now!!!!
- //=> there's only one type of wxImage: with alpha channel, no mask!!!
- convertToVanillaImage(img);
-
- if (dpiScaler_)
- dpiScaler_->add(name, img); //scale in parallel!
- else
- bitmaps_.emplace(name, img);
- }
- else if (endsWith(name, L".gif"))
- loadAnimFromZip(streamIn, anims_[name]);
- else
- assert(false);
- }
+ const std::string rawStream = loadBinContainer<std::string>(filePath, nullptr /*notifyUnbufferedIO*/); //throw FileError
+ wxMemoryInputStream memStream(rawStream.c_str(), rawStream.size()); //does not take ownership
+ wxZipInputStream zipStream(memStream, wxConvUTF8);
+ //do NOT rely on wxConvLocal! On failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!"
+
+ //activate support for .png files
+ wxImage::AddHandler(new wxPNGHandler); //ownership passed
+
+ //do we need xBRZ scaling for high quality DPI images?
+ const int hqScale = std::clamp<int>(std::ceil(fastFromDIP(1000) / 1000.0), 1, xbrz::SCALE_FACTOR_MAX);
+ //even for 125% DPI scaling, "2xBRZ + bilinear downscale" gives a better result than mere "125% bilinear upscale"!
+ if (hqScale > 1)
+ dpiScaler_ = std::make_unique<DpiParallelScaler>(hqScale);
+
+ while (const auto& entry = std::unique_ptr<wxZipEntry>(zipStream.GetNextEntry())) //take ownership!)
+ {
+ const wxString name = entry->GetName();
+
+ if (endsWith(name, L".png"))
+ {
+ wxImage img(zipStream, wxBITMAP_TYPE_PNG);
+ assert(img.IsOk());
+
+ //end this alpha/no-alpha/mask/wxDC::DrawBitmap/RTL/high-contrast-scheme interoperability nightmare here and now!!!!
+ //=> there's only one type of wxImage: with alpha channel, no mask!!!
+ convertToVanillaImage(img);
+
+ if (dpiScaler_)
+ dpiScaler_->add(name, img); //scale in parallel!
+ else
+ bitmaps_.emplace(name, img);
+ }
+ else if (endsWith(name, L".gif"))
+ {
+ //work around wxWidgets bug: wxAnimation::Load() requires seekable input stream (zip-input stream is not seekable)
+ std::string stream(entry->GetSize(), '\0');
+ if (!stream.empty() && zipStream.ReadAll(&stream[0], stream.size()))
+ {
+ wxMemoryInputStream seekAbleStream(stream.c_str(), stream.size()); //stream does not take ownership of data
+ [[maybe_unused]] const bool loadSuccess = anims_[name].Load(seekAbleStream, wxANIMATION_TYPE_GIF);
+ assert(loadSuccess);
+ }
+ else
+ assert(false);
+ }
+ else
+ assert(false);
+ }
}
+ catch (FileError&) { assert(false); }
}
diff --git a/wx+/image_tools.cpp b/wx+/image_tools.cpp
index b314e801..0f248057 100644
--- a/wx+/image_tools.cpp
+++ b/wx+/image_tools.cpp
@@ -203,15 +203,15 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const
}
-wxBitmap zen::layOver(const wxBitmap& back, const wxBitmap& front, int alignment)
+wxImage zen::layOver(const wxImage& back, const wxImage& front, int alignment)
{
if (!front.IsOk()) return back;
+ assert(front.HasAlpha() && back.HasAlpha());
const int width = std::max(back.GetWidth(), front.GetWidth());
const int height = std::max(back.GetHeight(), front.GetHeight());
- assert(front.HasAlpha() == back.HasAlpha()); //we don't support mixed-mode brittleness!
- const int offsetX = [&]
+ const int offsetX = [&]
{
if (alignment & wxALIGN_RIGHT)
return back.GetWidth() - front.GetWidth();
@@ -239,8 +239,8 @@ wxBitmap zen::layOver(const wxBitmap& back, const wxBitmap& front, int alignmen
::memset(output.GetAlpha(), wxIMAGE_ALPHA_TRANSPARENT, width * height);
const wxPoint posBack(std::max(-offsetX, 0), std::max(-offsetY, 0));
- writeToImage(output, back .ConvertToImage(), posBack);
- writeToImage(output, front.ConvertToImage(), posBack + wxPoint(offsetX, offsetY));
+ writeToImage(output, back , posBack);
+ writeToImage(output, front, posBack + wxPoint(offsetX, offsetY));
return output;
}
diff --git a/wx+/image_tools.h b/wx+/image_tools.h
index 2a0dd0d4..d72597ef 100644
--- a/wx+/image_tools.h
+++ b/wx+/image_tools.h
@@ -34,7 +34,7 @@ wxImage stackImages(const wxImage& img1, const wxImage& img2, ImageStackLayout d
wxImage createImageFromText(const wxString& text, const wxFont& font, const wxColor& col, ImageStackAlignment textAlign = ImageStackAlignment::LEFT); //CENTER/LEFT/RIGHT
-wxBitmap layOver(const wxBitmap& back, const wxBitmap& front, int alignment = wxALIGN_CENTER);
+wxImage layOver(const wxImage& back, const wxImage& front, int alignment = wxALIGN_CENTER);
wxImage greyScale(const wxImage& img); //greyscale + brightness adaption
wxBitmap greyScale(const wxBitmap& bmp); //
@@ -213,7 +213,7 @@ wxColor gradient(const wxColor& from, const wxColor& to, double fraction)
inline
wxColor hsvColor(double h, double s, double v) //h within [0, 360), s, v within [0, 1]
{
- //https://de.wikipedia.org/wiki/HSV-Farbraum
+ //https://en.wikipedia.org/wiki/HSL_and_HSV
//make input values fit into bounds
if (h > 360)
diff --git a/wx+/rtl.h b/wx+/rtl.h
index 0cae9bac..0adb6037 100644
--- a/wx+/rtl.h
+++ b/wx+/rtl.h
@@ -20,6 +20,7 @@ void drawBitmapRtlNoMirror(wxDC& dc, const wxBitmap& bmp, const wxRect& rect, in
//wxDC::DrawIcon DOES mirror by default -> implement RTL support when needed
wxBitmap mirrorIfRtl(const wxBitmap& bmp);
+wxImage mirrorIfRtl(const wxImage& bmp);
//manual text flow correction: https://www.w3.org/International/articles/inline-bidi-markup/
@@ -93,6 +94,15 @@ void drawBitmapRtlNoMirror(wxDC& dc, const wxBitmap& bmp, const wxRect& rect, in
}
+inline
+wxImage mirrorIfRtl(const wxImage& bmp)
+{
+ if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft)
+ return bmp.Mirror();
+ else
+ return bmp;}
+
+
inline
wxBitmap mirrorIfRtl(const wxBitmap& bmp)
{
diff --git a/wx+/toggle_button.h b/wx+/toggle_button.h
index f61c3857..98ca32b3 100644
--- a/wx+/toggle_button.h
+++ b/wx+/toggle_button.h
@@ -28,8 +28,8 @@ public:
SetLayoutDirection(wxLayout_LeftToRight); //avoid mirroring RTL languages like Hebrew or Arabic
}
- void init(const wxBitmap& activeBmp,
- const wxBitmap& inactiveBmp);
+ void init(const wxBitmap& bmpActive,
+ const wxBitmap& bmpInactive);
void setActive(bool value);
bool isActive() const { return active_; }
@@ -37,8 +37,8 @@ public:
private:
bool active_ = false;
- wxBitmap activeBmp_;
- wxBitmap inactiveBmp_;
+ wxBitmap bmpActive_;
+ wxBitmap bmpInactive_;
};
@@ -49,21 +49,24 @@ private:
//######################## implementation ########################
inline
-void ToggleButton::init(const wxBitmap& activeBmp,
- const wxBitmap& inactiveBmp)
+void ToggleButton::init(const wxBitmap& bmpActive,
+ const wxBitmap& bmpInactive)
{
- activeBmp_ = activeBmp;
- inactiveBmp_ = inactiveBmp;
+ bmpActive_ = bmpActive;
+ bmpInactive_ = bmpInactive;
- setActive(active_);
+ setImage(*this, active_ ? bmpActive_ : bmpInactive_);
}
inline
void ToggleButton::setActive(bool value)
{
- active_ = value;
- setImage(*this, active_ ? activeBmp_ : inactiveBmp_);
+ if (active_ != value)
+ {
+ active_ = value;
+ setImage(*this, active_ ? bmpActive_ : bmpInactive_);
+ }
}
}
bgstack15