diff options
author | B Stack <bgstack15@gmail.com> | 2021-02-02 21:49:34 +0000 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2021-02-02 21:49:34 +0000 |
commit | 26b8bd6eb07b78adad36049e03494a2931b231af (patch) | |
tree | 4d7c950512836f473a6a8cbb521c61e800db6584 /wx+ | |
parent | Merge branch '11.5' into 'master' (diff) | |
parent | add upstream 11.6 (diff) | |
download | FreeFileSync-26b8bd6eb07b78adad36049e03494a2931b231af.tar.gz FreeFileSync-26b8bd6eb07b78adad36049e03494a2931b231af.tar.bz2 FreeFileSync-26b8bd6eb07b78adad36049e03494a2931b231af.zip |
Merge branch '11.6' into 'master'11.6
add upstream 11.6
See merge request opensource-tracking/FreeFileSync!30
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/dc.h | 4 | ||||
-rw-r--r-- | wx+/font_size.h | 4 | ||||
-rw-r--r-- | wx+/graph.cpp | 12 | ||||
-rw-r--r-- | wx+/grid.cpp | 19 | ||||
-rw-r--r-- | wx+/grid.h | 2 | ||||
-rw-r--r-- | wx+/image_resources.cpp | 6 | ||||
-rw-r--r-- | wx+/image_tools.cpp | 48 | ||||
-rw-r--r-- | wx+/image_tools.h | 2 | ||||
-rw-r--r-- | wx+/no_flicker.h | 42 | ||||
-rw-r--r-- | wx+/popup_dlg.cpp | 7 |
10 files changed, 66 insertions, 80 deletions
@@ -66,7 +66,7 @@ void drawFilledRectangle(wxDC& dc, wxRect rect, int borderWidth, const wxColor& macOS: wxWidgets uses DIP (note: wxScreenDC().GetPPI() returns 72 x 72 which is a lie; looks like 96 x 96) */ inline -int fastFromDIP(double d) //like wxWindow::FromDIP (but tied to primary monitor and buffered) +int fastFromDIP(int d) //like wxWindow::FromDIP (but tied to primary monitor and buffered) { #ifndef wxHAVE_DPI_INDEPENDENT_PIXELS #error why is wxHAVE_DPI_INDEPENDENT_PIXELS not defined? @@ -77,7 +77,7 @@ int fastFromDIP(double d) //like wxWindow::FromDIP (but tied to primary monitor //https://github.com/wxWidgets/wxWidgets/blob/d9d05c2bb201078f5e762c42458ca2f74af5b322/include/wx/window.h#L2060 return d; //e.g. macOS, GTK3 } - +int fastFromDIP(double d) = delete; diff --git a/wx+/font_size.h b/wx+/font_size.h index d25dfede..da74eada 100644 --- a/wx+/font_size.h +++ b/wx+/font_size.h @@ -33,7 +33,7 @@ inline void setRelativeFontSize(wxWindow& control, double factor) { wxFont font = control.GetFont(); - font.SetPointSize(numeric::round(wxNORMAL_FONT->GetPointSize() * factor)); + font.SetPointSize(std::round(wxNORMAL_FONT->GetPointSize() * factor)); control.SetFont(font); } @@ -42,7 +42,7 @@ inline void setMainInstructionFont(wxWindow& control) { wxFont font = control.GetFont(); - font.SetPointSize(numeric::round(wxNORMAL_FONT->GetPointSize() * 12.0 / 11)); + font.SetPointSize(std::round(wxNORMAL_FONT->GetPointSize() * 12.0 / 11)); font.SetWeight(wxFONTWEIGHT_BOLD); control.SetFont(font); diff --git a/wx+/graph.cpp b/wx+/graph.cpp index bb320db6..ba87299e 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -87,7 +87,7 @@ public: { //catch large double values: if double is larger than what int can represent => undefined behavior! realPos = std::clamp(realPos, outOfBoundsLow_, outOfBoundsHigh_); - return numeric::round(realToScreen(realPos)); + return std::round(realToScreen(realPos)); } private: @@ -123,7 +123,7 @@ int widenRange(double& valMin, double& valMax, //in/out double blockMin = std::floor(valMin / valRangePerBlock); //store as double, not int: truncation possible, e.g. if valRangePerBlock == 1 double blockMax = std::ceil (valMax / valRangePerBlock); // - int blockCount = numeric::round(blockMax - blockMin); + int blockCount = std::round(blockMax - blockMin); assert(blockCount >= 0); //handle valMin == valMax == integer @@ -770,10 +770,10 @@ void Graph2D::render(wxDC& dc) const screenToX = std::clamp(screenToX, 0.0, graphArea.width - 1.0); screenToY = std::clamp(screenToY, 0.0, graphArea.height - 1.0); - const wxPoint pixelFrom = wxPoint(numeric::round(screenFromX), - numeric::round(screenFromY)) + graphAreaOrigin; - const wxPoint pixelTo = wxPoint(numeric::round(screenToX), - numeric::round(screenToY)) + graphAreaOrigin; + const wxPoint pixelFrom = wxPoint(std::round(screenFromX), + std::round(screenFromY)) + graphAreaOrigin; + const wxPoint pixelTo = wxPoint(std::round(screenToX), + std::round(screenToY)) + graphAreaOrigin; switch (attr_.mouseSelMode) { case GraphSelMode::none: diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 46195a52..cd91b1af 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -13,6 +13,7 @@ #include <wx/tooltip.h> #include <wx/timer.h> #include <wx/utils.h> +#include <zen/basic_math.h> #include <zen/string_tools.h> #include <zen/scope_guard.h> #include <zen/utf.h> @@ -198,12 +199,12 @@ void GridData::drawCellText(wxDC& dc, const wxRect& rect, const std::wstring& te if (alignment & wxALIGN_RIGHT) //note: wxALIGN_LEFT == 0! pt.x += rect.width - extentTrunc.GetWidth(); else if (alignment & wxALIGN_CENTER_HORIZONTAL) - pt.x += static_cast<int>(std::floor((rect.width - extentTrunc.GetWidth()) / 2.0)); //round down negative values, too! + pt.x += numeric::intDivFloor(rect.width - extentTrunc.GetWidth(), 2); //round down negative values, too! if (alignment & wxALIGN_BOTTOM) //note: wxALIGN_TOP == 0! pt.y += rect.height - extentTrunc.GetHeight(); else if (alignment & wxALIGN_CENTER_VERTICAL) - pt.y += static_cast<int>(std::floor((rect.height - extentTrunc.GetHeight()) / 2.0)); //round down negative values, too! + pt.y += numeric::intDivFloor(rect.height - extentTrunc.GetHeight(), 2); //round down negative values, too! //std::unique_ptr<RecursiveDcClipper> clip; -> redundant!? RecursiveDcClipper already used during grid cell rendering //if (extentTrunc.GetWidth() > rect.width) @@ -268,13 +269,9 @@ public: Bind(wxEVT_PAINT, [this](wxPaintEvent& event) { onPaintEvent(event); }); Bind(wxEVT_SIZE, [this](wxSizeEvent& event) { Refresh(); event.Skip(); }); Bind(wxEVT_ERASE_BACKGROUND, [](wxEraseEvent& event) {}); //https://wiki.wxwidgets.org/Flicker-Free_Drawing - - //SetDoubleBuffered(true); slow as hell! - SetBackgroundStyle(wxBG_STYLE_PAINT); + //SetDoubleBuffered(true); -> slow as hell! - Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& event) { onFocus(event); }); - Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& event) { onFocus(event); }); Bind(wxEVT_CHILD_FOCUS, [](wxChildFocusEvent& event) {}); //wxGTK::wxScrolledWindow automatically scrolls to child window when child gets focus -> prevent! Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& event) { onMouseLeftDown (event); }); @@ -328,8 +325,6 @@ protected: private: virtual void render(wxDC& dc, const wxRect& rect) = 0; - virtual void onFocus(wxFocusEvent& event) { event.Skip(); } - virtual void onMouseLeftDown (wxMouseEvent& event) { event.Skip(); } virtual void onMouseLeftUp (wxMouseEvent& event) { event.Skip(); } virtual void onMouseLeftDouble(wxMouseEvent& event) { event.Skip(); } @@ -1312,9 +1307,6 @@ private: event.Skip(); } - warn_static("Refresh() needed!? focus shouldn't affect grid rendering => test + remove it for a while: if not needed scrap onFocus()") - //void onFocus(wxFocusEvent& event) override { Refresh(); event.Skip(); } - class MouseSelection : private wxEvtHandler { public: @@ -2183,8 +2175,7 @@ void Grid::makeRowVisible(size_t row) { auto execScroll = [&](int clientHeight) { - const int scrollPosNewY = std::ceil((labelRect.y - clientHeight + - labelRect.height) / static_cast<double>(pixelsPerUnitY)); + const int scrollPosNewY = numeric::intDivCeil(labelRect.y + labelRect.height - clientHeight, pixelsPerUnitY); Scroll(scrollPosOld.x, scrollPosNewY); updateWindowSizes(); //may show horizontal scroll bar if row column gets wider Refresh(); @@ -12,7 +12,7 @@ #include <optional> #include <set> #include <vector> -#include <zen/basic_math.h> +//#include <zen/basic_math.h> #include <wx/scrolwin.h> diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 6931e82e..42114ebb 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -210,7 +210,7 @@ ImageBuffer::ImageBuffer(const Zstring& zipPath) //throw FileError 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); + const int hqScale = std::clamp(numeric::intDivCeil(fastFromDIP(1000), 1000), 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) hqScaler_ = std::make_unique<HqParallelScaler>(hqScale); @@ -283,7 +283,7 @@ const wxImage& ImageBuffer::getImage(const std::string& name, int maxWidth /*opt int outHeight = dpiSize.y; if (maxWidth >= 0 && maxWidth < dpiSize.x) - outHeight = rawImg.GetHeight() * maxWidth / rawImg.GetWidth(); + outHeight = numeric::intDivRound(maxWidth * rawImg.GetHeight(), rawImg.GetWidth()); if (maxHeight >= 0 && maxHeight < outHeight) outHeight = maxHeight; @@ -297,7 +297,7 @@ const wxImage& ImageBuffer::getImage(const std::string& name, int maxWidth /*opt it = imagesOut_.emplace(imkey, shrinkImage(rawImg, -1 /*maxWidth*/, outHeight)).first; else if (rawImg.GetHeight() >= 0.9 * outHeight) //almost there: also no need for xBRZ-scale //however: for 125% DPI scaling, "2xBRZ + bilinear downscale" gives a better result than mere "125% bilinear upscale"! - it = imagesOut_.emplace(imkey, rawImg.Scale(rawImg.GetWidth() * outHeight / rawImg.GetHeight(), outHeight, wxIMAGE_QUALITY_BILINEAR)).first; + it = imagesOut_.emplace(imkey, rawImg.Scale(numeric::intDivRound(outHeight * rawImg.GetWidth(), rawImg.GetHeight()), outHeight, wxIMAGE_QUALITY_BILINEAR)).first; else it = imagesOut_.emplace(imkey, shrinkImage(getScaledImage(name), -1 /*maxWidth*/, outHeight)).first; } diff --git a/wx+/image_tools.cpp b/wx+/image_tools.cpp index 4569a2a7..6ba95c5e 100644 --- a/wx+/image_tools.cpp +++ b/wx+/image_tools.cpp @@ -37,14 +37,14 @@ void copySubImage(const wxImage& src, wxPoint srcPos, std::clamp(pos.x, 0, img.GetWidth ()), std::clamp(pos.y, 0, img.GetHeight())}; }; - auto pointMinus = [](const wxPoint& lhs, const wxPoint& rhs) { return wxSize{lhs.x - rhs.x, lhs.y - rhs.y}; }; + auto subtract = [](const wxPoint& lhs, const wxPoint& rhs) { return wxSize{lhs.x - rhs.x, lhs.y - rhs.y}; }; //work around yet another wxWidgets screw up: WTF does "operator-(wxPoint, wxPoint)" return wxPoint instead of wxSize!?? const wxPoint trgPos2 = pointClamp(trgPos, trg); const wxPoint trgPos2End = pointClamp(trgPos + blockSize, trg); - blockSize = pointMinus(trgPos2End, trgPos2); - srcPos += pointMinus(trgPos2, trgPos); + blockSize = subtract(trgPos2End, trgPos2); + srcPos += subtract(trgPos2, trgPos); trgPos = trgPos2; if (blockSize.x <= 0 || blockSize.y <= 0) return; @@ -52,8 +52,8 @@ void copySubImage(const wxImage& src, wxPoint srcPos, const wxPoint srcPos2 = pointClamp(srcPos, src); const wxPoint srcPos2End = pointClamp(srcPos + blockSize, src); - blockSize = pointMinus(srcPos2End, srcPos2); - trgPos += pointMinus(srcPos2, srcPos); + blockSize = subtract(srcPos2End, srcPos2); + trgPos += subtract(srcPos2, srcPos); srcPos = srcPos2; if (blockSize.x <= 0 || blockSize.y <= 0) return; @@ -181,12 +181,7 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const //assert(!contains(text, L"&")); //accelerator keys not supported here wxString textFmt = replaceCpy(text, L"&", L"", false); - //for some reason wxDC::DrawText messes up "weak" bidi characters even when wxLayout_RightToLeft is set! (--> arrows in hebrew/arabic) - //=> use mark characters instead: - if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft) - textFmt = RTL_MARK + textFmt + RTL_MARK; - - const std::vector<std::pair<wxString, wxSize>> lineInfo = getTextExtentInfo(textFmt, font); + const std::vector<std::pair<wxString, wxSize>> lineInfo = getTextExtentInfo(textFmt, font); int maxWidth = 0; int lineHeight = 0; @@ -201,6 +196,10 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const wxBitmap newBitmap(maxWidth, lineHeight * lineInfo.size()); //seems we don't need to pass 24-bit depth here even for high-contrast color schemes { wxMemoryDC dc(newBitmap); + + if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft) + dc.SetLayoutDirection(wxLayout_RightToLeft); //handle e.g. "weak" bidi characters: -> arrows in hebrew/arabic + dc.SetBackground(*wxWHITE_BRUSH); dc.Clear(); @@ -296,12 +295,12 @@ wxImage zen::resizeCanvas(const wxImage& img, wxSize newSize, int alignment) if (alignment & wxALIGN_RIGHT) //note: wxALIGN_LEFT == 0! newPos.x = newSize.GetWidth() - img.GetWidth(); else if (alignment & wxALIGN_CENTER_HORIZONTAL) - newPos.x = static_cast<int>(std::floor((newSize.GetWidth() - img.GetWidth()) / 2)); //consistency: round down negative values, too! + newPos.x = numeric::intDivFloor(newSize.GetWidth() - img.GetWidth(), 2); //consistency: round down negative values, too! if (alignment & wxALIGN_BOTTOM) //note: wxALIGN_TOP == 0! newPos.y = newSize.GetHeight() - img.GetHeight(); else if (alignment & wxALIGN_CENTER_VERTICAL) - newPos.y = static_cast<int>(std::floor((newSize.GetHeight() - img.GetHeight()) / 2)); //consistency: round down negative values, too! + newPos.y = numeric::intDivFloor(newSize.GetHeight() - img.GetHeight(), 2); //consistency: round down negative values, too! wxImage output(newSize); output.SetAlpha(); @@ -317,19 +316,16 @@ wxImage zen::shrinkImage(const wxImage& img, int maxWidth /*optional*/, int maxH { wxSize newSize = img.GetSize(); - if (maxWidth >= 0) - if (maxWidth < newSize.x) - { - newSize.y = newSize.y * maxWidth / newSize.x; - newSize.x = maxWidth; - } - if (maxHeight >= 0) - if (maxHeight < newSize.y) - { - newSize = img.GetSize(); //avoid loss of precision - newSize.x = newSize.x * maxHeight / newSize.y; // - newSize.y = maxHeight; - } + if (0 <= maxWidth && maxWidth < newSize.x) + { + newSize.x = maxWidth; + newSize.y = numeric::intDivRound(maxWidth * img.GetHeight(), img.GetWidth()); + } + if (0 <= maxHeight && maxHeight < newSize.y) + { + newSize.x = numeric::intDivRound(maxHeight * img.GetWidth(), img.GetHeight()); //avoid loss of precision + newSize.y = maxHeight; + } if (newSize == img.GetSize()) return img; diff --git a/wx+/image_tools.h b/wx+/image_tools.h index 1b4fbb43..0f0fb9c2 100644 --- a/wx+/image_tools.h +++ b/wx+/image_tools.h @@ -177,7 +177,7 @@ wxColor hsvColor(double h, double s, double v) //h within [0, 360), s, v within auto polish = [](double val) -> unsigned char { - int result = numeric::round(val * 255); + int result = std::round(val * 255); numeric::confine(result, 0, 255); return static_cast<unsigned char>(result); }; diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h index 53e47bb5..a84a7228 100644 --- a/wx+/no_flicker.h +++ b/wx+/no_flicker.h @@ -79,28 +79,28 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText) richCtrl.Clear(); + wxRichTextAttr urlStyle; + urlStyle.SetTextColour(*wxBLUE); + urlStyle.SetFontUnderlined(true); + + for (const auto& [type, text] : blocks) + switch (type) + { + case BlockType::text: + richCtrl.WriteText(text); + break; + + case BlockType::url: + richCtrl.BeginStyle(urlStyle); + ZEN_ON_SCOPE_EXIT(richCtrl.EndStyle()); + richCtrl.BeginURL(text); + ZEN_ON_SCOPE_EXIT(richCtrl.EndURL()); + richCtrl.WriteText(text); + break; + } + if (std::any_of(blocks.begin(), blocks.end(), [](const auto& item) { return item.first == BlockType::url; })) { - wxRichTextAttr urlStyle; - urlStyle.SetTextColour(*wxBLUE); - urlStyle.SetFontUnderlined(true); - - for (const auto& [type, text] : blocks) - switch (type) - { - case BlockType::text: - richCtrl.WriteText(text); - break; - - case BlockType::url: - richCtrl.BeginStyle(urlStyle); - ZEN_ON_SCOPE_EXIT(richCtrl.EndStyle()); - richCtrl.BeginURL(text); - ZEN_ON_SCOPE_EXIT(richCtrl.EndURL()); - richCtrl.WriteText(text); - break; - } - //register only once! => use a global function pointer, so that Unbind() works correctly: using LaunchUrlFun = void(*)(wxTextUrlEvent& event); static const LaunchUrlFun launchUrl = [](wxTextUrlEvent& event) { wxLaunchDefaultBrowser(event.GetString()); }; @@ -108,8 +108,6 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText) [[maybe_unused]] const bool unbindOk = richCtrl.Unbind(wxEVT_TEXT_URL, launchUrl); richCtrl.Bind(wxEVT_TEXT_URL, launchUrl); } - else - richCtrl.WriteText(newText); } } } diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index 0a1ff2a0..88ed590b 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -5,6 +5,7 @@ // ***************************************************************************** #include "popup_dlg.h" +#include <zen/basic_math.h> #include <wx/app.h> #include <wx/display.h> #include "no_flicker.h" @@ -38,7 +39,7 @@ void setBestInitialSize(wxRichTextCtrl& ctrl, const wxString& text, wxSize maxSi { maxLineWidth = std::max(maxLineWidth, sz.x); - const int wrappedRows = numeric::integerDivideRoundUp(sz.x, maxSize.x - scrollbarWidth); //integer round up: consider line-wraps! + const int wrappedRows = numeric::intDivCeil(sz.x, maxSize.x - scrollbarWidth); //round up: consider line-wraps! rowCount += wrappedRows; rowHeight = std::max(rowHeight, sz.y); //all rows *should* have same height if (wrappedRows > 1) @@ -71,8 +72,8 @@ void setBestInitialSize(wxRichTextCtrl& ctrl, const wxString& text, wxSize maxSi const int extraHeight = 0; #endif int extraWidth = 0; - if (haveLineWrap) //compensate for trivial integerDivideRoundUp() not - extraWidth += ctrl.GetTextExtent(L"FreeFileSync").x / 2; //understanding line wrap algorithm + if (haveLineWrap) //compensate for trivial intDivCeil() not... + extraWidth += ctrl.GetTextExtent(L"FreeFileSync").x / 2; //...understanding line wrap algorithm const wxSize bestSize(std::min(maxLineWidth, maxSize.x) + extraWidth, std::min(rowCount * (rowHeight + rowGap) + extraHeight, maxSize.y)); |