diff options
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/bitmap_button.h | 21 | ||||
-rw-r--r-- | wx+/context_menu.h | 36 | ||||
-rw-r--r-- | wx+/dc.h | 15 | ||||
-rw-r--r-- | wx+/image_tools.cpp | 26 | ||||
-rw-r--r-- | wx+/popup_dlg.cpp | 3 | ||||
-rw-r--r-- | wx+/rtl.h | 2 | ||||
-rw-r--r-- | wx+/std_button_layout.h | 2 | ||||
-rw-r--r-- | wx+/tooltip.cpp | 4 |
8 files changed, 77 insertions, 32 deletions
diff --git a/wx+/bitmap_button.h b/wx+/bitmap_button.h index a3e6b0f6..5ab5411b 100644 --- a/wx+/bitmap_button.h +++ b/wx+/bitmap_button.h @@ -9,6 +9,7 @@ #include <wx/bmpbuttn.h> #include <wx/settings.h> +#include <wx/statbmp.h> #include "image_tools.h" #include "dc.h" @@ -37,7 +38,8 @@ public: void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& text, int gap = fastFromDIP(5), int border = fastFromDIP(5)); //set bitmap label flicker free: -void setImage(wxBitmapButton& button, const wxImage& bmp); +void setImage(wxAnyButton& button, const wxImage& bmp); +void setImage(wxStaticBitmap& staticBmp, const wxImage& img); wxBitmap renderSelectedButton(const wxSize& sz); wxBitmap renderPressedButton(const wxSize& sz); @@ -68,14 +70,12 @@ void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& btn.SetMinSize({imgTxt.GetWidth () + 2 * border, std::max(imgTxt.GetHeight() + 2 * border, defaultHeight)}); - btn.SetBitmapLabel(imgTxt); - //SetLabel() calls confuse wxBitmapButton in the disabled state and it won't show the image! workaround: - btn.SetBitmapDisabled(imgTxt.ConvertToDisabled()); + setImage(btn, imgTxt); } inline -void setImage(wxBitmapButton& button, const wxImage& img) +void setImage(wxAnyButton& button, const wxImage& img) { if (!img.IsOk()) { @@ -84,11 +84,18 @@ void setImage(wxBitmapButton& button, const wxImage& img) return; } - button.SetBitmapLabel(img); + button.SetBitmapLabel(toBitmapBundle(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(img.ConvertToDisabled()); //inefficiency: wxBitmap::ConvertToDisabled() implicitly converts to wxImage! + button.SetBitmapDisabled(toBitmapBundle(img.ConvertToDisabled())); //inefficiency: wxBitmap::ConvertToDisabled() implicitly converts to wxImage! +} + + +inline +void setImage(wxStaticBitmap& staticBmp, const wxImage& img) +{ + staticBmp.SetBitmap(toBitmapBundle(img)); } diff --git a/wx+/context_menu.h b/wx+/context_menu.h index c53cec39..728da173 100644 --- a/wx+/context_menu.h +++ b/wx+/context_menu.h @@ -12,6 +12,10 @@ #include <functional> #include <wx/menu.h> #include <wx/app.h> +#include "dc.h" + +warn_static("remove after test") +#include "image_tools.h" /* A context menu supporting lambda callbacks! @@ -23,6 +27,13 @@ namespace zen { +inline +void setImage(wxMenuItem& menuItem, const wxImage& img) +{ + menuItem.SetBitmap(toBitmapBundle(img)); +} + + class ContextMenu : private wxEvtHandler { public: @@ -32,7 +43,7 @@ public: { wxMenuItem* newItem = new wxMenuItem(menu_.get(), wxID_ANY, label); //menu owns item! if (img.IsOk()) - newItem->SetBitmap(img); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason + setImage(*newItem, img); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason menu_->Append(newItem); if (!enabled) newItem->Enable(false); //do not enable BEFORE appending item! wxWidgets screws up for yet another crappy reason @@ -69,7 +80,7 @@ public: wxMenuItem* newItem = new wxMenuItem(menu_.get(), wxID_ANY, label, L"", wxITEM_NORMAL, submenu.menu_.release()); //menu owns item, item owns submenu! if (img.IsOk()) - newItem->SetBitmap(img); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason + setImage(*newItem, img); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason menu_->Append(newItem); if (!enabled) newItem->Enable(false); @@ -93,6 +104,27 @@ private: std::unique_ptr<wxMenu> menu_ = std::make_unique<wxMenu>(); std::map<int /*item id*/, std::function<void()> /*command*/> commandList_; }; + + +//GTK: image must be set *before* adding wxMenuItem to menu or it won't show => workaround: +inline //also needed on Windows + macOS since wxWidgets 3.1.6 (thanks?) +void fixMenuIcons(wxMenu& menu) +{ + std::vector<std::pair<wxMenuItem*, size_t /*pos*/>> itemsWithBmp; + { + size_t pos = 0; + for (wxMenuItem* item : menu.GetMenuItems()) + { + if (item->GetBitmap().IsOk()) + itemsWithBmp.emplace_back(item, pos); + ++pos; + } + } + + for (const auto& [item, pos] : itemsWithBmp) + if (!menu.Insert(pos, menu.Remove(item))) //detach + reinsert + assert(false); +} } #endif //CONTEXT_MENU_H_18047302153418174632141234 @@ -12,6 +12,7 @@ #include <zen/basic_math.h> #include <wx/dcbuffer.h> //for macro: wxALWAYS_NATIVE_DOUBLE_BUFFER #include <wx/dcscreen.h> +#include <wx/bmpbndl.h> #include <gtk/gtk.h> @@ -91,8 +92,8 @@ constexpr int defaultDpi = 96; inline int getDPI() { -#ifndef wxHAVE_DPI_INDEPENDENT_PIXELS -#error why is wxHAVE_DPI_INDEPENDENT_PIXELS not defined? +#ifndef wxHAS_DPI_INDEPENDENT_PIXELS +#error why is wxHAS_DPI_INDEPENDENT_PIXELS not defined? #endif //GTK2 doesn't properly support high DPI: https://freefilesync.org/forum/viewtopic.php?t=6114 //=> requires general fix at wxWidgets-level @@ -117,6 +118,16 @@ int getDpiScalePercent() } +inline +wxBitmapBundle toBitmapBundle(const wxImage& img /*expected to be DPI-scaled!*/) +{ + //return wxBitmap(img, -1 /*depth*/, static_cast<double>(getDPI()) / defaultDpi); not (yet) implemented + wxBitmap bmpScaled(img); + bmpScaled.SetScaleFactor(static_cast<double>(getDPI()) / defaultDpi); + return bmpScaled; +} + + //---------------------- implementation ------------------------ class RecursiveDcClipper { diff --git a/wx+/image_tools.cpp b/wx+/image_tools.cpp index b8876dc3..335cf7b9 100644 --- a/wx+/image_tools.cpp +++ b/wx+/image_tools.cpp @@ -7,6 +7,7 @@ #include "image_tools.h" #include <zen/string_tools.h> #include <zen/zstring.h> +#include <zen/scope_guard.h> #include <wx/app.h> #include <xBRZ/src/xbrz_tools.h> @@ -113,19 +114,6 @@ void copyImageLayover(const wxImage& src, } } } - - -std::vector<std::pair<wxString, wxSize>> getTextExtentInfo(const wxString& text, const wxFont& font) -{ - wxMemoryDC dc; //the context used for bitmaps - dc.SetFont(font); //the font parameter of GetMultiLineTextExtent() is not evaluated on OS X, wxWidgets 2.9.5, so apply it to the DC directly! - - std::vector<std::pair<wxString, wxSize>> lineInfo; //text + extent - for (const wxString& line : split(text, L'\n', SplitOnEmpty::allow)) - lineInfo.emplace_back(line, line.empty() ? wxSize() : dc.GetTextExtent(line)); - - return lineInfo; -} } @@ -180,7 +168,13 @@ wxImage zen::stackImages(const wxImage& img1, const wxImage& img2, ImageStackLay wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const wxColor& col, ImageStackAlignment textAlign) { - const std::vector<std::pair<wxString, wxSize>> lineInfo = getTextExtentInfo(text, font); + wxMemoryDC dc; //the context used for bitmaps + dc.SetFont(font); //the font parameter of GetMultiLineTextExtent() is not evaluated on OS X, wxWidgets 2.9.5, so apply it to the DC directly! + + std::vector<std::pair<wxString, wxSize>> lineInfo; //text + extent + for (const wxString& line : split(text, L'\n', SplitOnEmpty::allow)) + lineInfo.emplace_back(line, line.empty() ? wxSize() : dc.GetTextExtent(line)); + //------------------------------------------------------------------------------------------------ int maxWidth = 0; int lineHeight = 0; @@ -194,7 +188,8 @@ 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); + dc.SelectObject(newBitmap); + ZEN_ON_SCOPE_EXIT(dc.SelectObject(wxNullBitmap)); if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft) dc.SetLayoutDirection(wxLayout_RightToLeft); //handle e.g. "weak" bidi characters: -> arrows in hebrew/arabic @@ -204,7 +199,6 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const dc.SetTextForeground(*wxBLACK); //for proper alpha-channel calculation dc.SetTextBackground(*wxWHITE); // - dc.SetFont(font); int posY = 0; for (const auto& [lineText, lineSize] : lineInfo) diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index 703371c2..c163b037 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -10,6 +10,7 @@ #include <wx/app.h> #include <wx/display.h> #include <wx/sound.h> +#include "bitmap_button.h" #include "no_flicker.h" #include "font_size.h" #include "image_resources.h" @@ -141,7 +142,7 @@ public: titleTmp = cfg.title; //----------------------------------------------- if (iconTmp.IsOk()) - m_bitmapMsgType->SetBitmap(iconTmp); + setImage(*m_bitmapMsgType, iconTmp); if (titleTmp.empty()) SetTitle(wxTheApp->GetAppDisplayName()); @@ -72,7 +72,7 @@ void drawBitmapRtlMirror(wxDC& dc, const wxImage& img, const wxRect& rect, int a memDc.Blit(wxPoint(0, 0), rect.GetSize(), &dc, rect.GetTopLeft()); //blit in: background is mirrored due to memDc, dc having different layout direction! impl::drawBitmapAligned(memDc, img, wxRect(0, 0, rect.width, rect.height), alignment); - //note: we cannot simply use memDc.SetLayoutDirection(wxLayout_RightToLeft) due to some strange 1 pixel bug! + //note: we cannot simply use memDc.SetLayoutDirection(wxLayout_RightToLeft) due to some strange 1 pixel bug! 2022-04-04: maybe fixed in wxWidgets 3.1.6? dc.Blit(rect.GetTopLeft(), rect.GetSize(), &memDc, wxPoint(0, 0)); //blit out: mirror once again } diff --git a/wx+/std_button_layout.h b/wx+/std_button_layout.h index e84b0c78..72756041 100644 --- a/wx+/std_button_layout.h +++ b/wx+/std_button_layout.h @@ -78,7 +78,7 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) if (wxSizerItem& item = *sizer.GetItem(pos); item.IsSpacer() && item.GetProportion() == 0 && item.GetSize().y == 0) { - [[maybe_unused]] bool rv = sizer.Detach(pos); + [[maybe_unused]] const bool rv = sizer.Detach(pos); assert(rv); } diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index 4a3c571f..a3fa770d 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -3,7 +3,6 @@ // * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * // ***************************************************************************** - #include "tooltip.h" #include <wx/dialog.h> #include <wx/stattext.h> @@ -12,6 +11,7 @@ #include <wx/settings.h> #include <wx/app.h> #include "image_tools.h" +#include "bitmap_button.h" #include "dc.h" #include <gtk/gtk.h> @@ -64,7 +64,7 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxImage* img) if (!lastUsedImg_.IsSameAs(newImg)) { lastUsedImg_ = newImg; - tipWindow_->bitmapLeft_->SetBitmap(newImg); + setImage(*tipWindow_->bitmapLeft_, newImg); tipWindow_->Refresh(); //needed if bitmap size changed! } |