diff options
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/bitmap_button.h | 12 | ||||
-rw-r--r-- | wx+/file_drop.h | 2 | ||||
-rw-r--r-- | wx+/graph.cpp | 8 | ||||
-rw-r--r-- | wx+/grid.cpp | 55 | ||||
-rw-r--r-- | wx+/grid.h | 4 | ||||
-rw-r--r-- | wx+/image_resources.cpp | 127 | ||||
-rw-r--r-- | wx+/image_resources.h | 2 | ||||
-rw-r--r-- | wx+/image_tools.cpp | 24 | ||||
-rw-r--r-- | wx+/image_tools.h | 50 | ||||
-rw-r--r-- | wx+/popup_dlg_generated.cpp | 5 | ||||
-rw-r--r-- | wx+/popup_dlg_generated.h | 6 | ||||
-rw-r--r-- | wx+/rtl.h | 5 | ||||
-rw-r--r-- | wx+/std_button_layout.h | 2 | ||||
-rw-r--r-- | wx+/tooltip.cpp | 2 |
14 files changed, 146 insertions, 158 deletions
diff --git a/wx+/bitmap_button.h b/wx+/bitmap_button.h index bcbc7328..b40d8dd3 100644 --- a/wx+/bitmap_button.h +++ b/wx+/bitmap_button.h @@ -56,13 +56,13 @@ void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& wxImage dynImage = createImageFromText(text, btn.GetFont(), btn.GetForegroundColour()); if (img.IsOk()) dynImage = btn.GetLayoutDirection() != wxLayout_RightToLeft ? - stackImages(img, dynImage, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, gap) : - stackImages(dynImage, img, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, gap); + stackImages(img, dynImage, ImageStackLayout::horizontal, ImageStackAlignment::center, gap) : + stackImages(dynImage, img, ImageStackLayout::horizontal, ImageStackAlignment::center, gap); - //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly + //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work correctly const int defaultHeight = wxButton::GetDefaultSize().GetHeight(); - btn.SetMinSize(wxSize(dynImage.GetWidth () + 2 * border, - std::max(dynImage.GetHeight() + 2 * border, defaultHeight))); + btn.SetMinSize({dynImage.GetWidth () + 2 * border, + std::max(dynImage.GetHeight() + 2 * border, defaultHeight)}); btn.SetBitmapLabel(wxBitmap(dynImage)); //SetLabel() calls confuse wxBitmapButton in the disabled state and it won't show the image! workaround: @@ -73,7 +73,7 @@ void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& inline void setImage(wxBitmapButton& button, const wxBitmap& bmp) { - if (!isEqual(button.GetBitmapLabel(), bmp)) + if (!button.GetBitmapLabel().IsSameAs(bmp)) { button.SetBitmapLabel(bmp); diff --git a/wx+/file_drop.h b/wx+/file_drop.h index ee5393b7..9826bf27 100644 --- a/wx+/file_drop.h +++ b/wx+/file_drop.h @@ -60,8 +60,6 @@ using FileDropEventFunction = void (wxEvtHandler::*)(FileDropEvent&); void setupFileDrop(wxWindow& wnd); - - } #endif //FILE_DROP_H_09457802957842560325626 diff --git a/wx+/graph.cpp b/wx+/graph.cpp index a6d0f19d..ec338e99 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -226,11 +226,11 @@ void drawCornerText(wxDC& dc, const wxRect& graphArea, const wxString& txt, Grap break; } - //add text shadow to improve readability: - wxDCTextColourChanger textColor(dc, colorBack); - dc.DrawText(txt, drawPos + border + wxSize(fastFromDIP(1), fastFromDIP(1))); + //add text shadow to improve readability: + wxDCTextColourChanger textColor(dc, colorBack); + dc.DrawText(txt, drawPos + border + wxSize(fastFromDIP(1), fastFromDIP(1))); - textColor.Set(colorText); + textColor.Set(colorText); dc.DrawText(txt, drawPos + border); } diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 0613e14f..fe168df6 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -35,7 +35,7 @@ int GridData::getColumnGapLeft() { return fastFromDIP(4); } namespace { //------------------------------ Grid Parameters -------------------------------- -inline wxColor getColorLabelText() { return wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); } +inline wxColor getColorLabelText(bool enabled) { return wxSystemSettings::GetColour(enabled ? wxSYS_COLOUR_WINDOWTEXT : wxSYS_COLOUR_GRAYTEXT); } inline wxColor getColorGridLine() { return { 192, 192, 192 }; } //light grey inline wxColor getColorLabelGradientFrom() { return wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); } @@ -213,13 +213,13 @@ wxSize GridData::drawCellText(wxDC& dc, const wxRect& rect, const std::wstring& } -void GridData::renderColumnLabel(Grid& grid, wxDC& dc, const wxRect& rect, ColumnType colType, bool highlighted) +void GridData::renderColumnLabel(wxDC& dc, const wxRect& rect, ColumnType colType, bool enabled, bool highlighted) { wxRect rectRemain = drawColumnLabelBackground(dc, rect, highlighted); rectRemain.x += getColumnGapLeft(); rectRemain.width -= getColumnGapLeft(); - drawColumnLabelText(dc, rectRemain, getColumnLabel(colType)); + drawColumnLabelText(dc, rectRemain, getColumnLabel(colType), enabled); } @@ -247,9 +247,9 @@ wxRect GridData::drawColumnLabelBackground(wxDC& dc, const wxRect& rect, bool hi } -void GridData::drawColumnLabelText(wxDC& dc, const wxRect& rect, const std::wstring& text) +void GridData::drawColumnLabelText(wxDC& dc, const wxRect& rect, const std::wstring& text, bool enabled) { - wxDCTextColourChanger textColor(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors! + wxDCTextColourChanger textColor(dc, getColorLabelText(enabled)); //accessibility: always set both foreground AND background colors! drawCellText(dc, rect, text, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); } @@ -500,7 +500,8 @@ private: void render(wxDC& dc, const wxRect& rect) override { - clearArea(dc, rect, wxSystemSettings::GetColour(/*!renderAsEnabled(*this) ? wxSYS_COLOUR_BTNFACE :*/wxSYS_COLOUR_WINDOW)); + const bool enabled = renderAsEnabled(*this); + clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); dc.SetFont(GetFont()); //harmonize with RowLabelWin::getBestWidth()! @@ -511,16 +512,16 @@ private: if (singleLabelArea.height > 0) { singleLabelArea.y = refParent().CalcScrolledPosition(singleLabelArea.GetTopLeft()).y; - drawRowLabel(dc, singleLabelArea, row); + drawRowLabel(dc, singleLabelArea, row, enabled); } } } - void drawRowLabel(wxDC& dc, const wxRect& rect, size_t row) + void drawRowLabel(wxDC& dc, const wxRect& rect, size_t row, bool enabled) { //clearArea(dc, rect, getColorRowLabel()); dc.GradientFillLinear(rect, getColorLabelGradientFrom(), getColorLabelGradientTo(), wxEAST); //clear overlapping cells - wxDCTextColourChanger textColor(dc, getColorLabelText()); //accessibility: always set both foreground AND background colors! + wxDCTextColourChanger textColor(dc, getColorLabelText(enabled)); //accessibility: always set both foreground AND background colors! //label text wxRect textRect = rect; @@ -615,7 +616,8 @@ private: void render(wxDC& dc, const wxRect& rect) override { - clearArea(dc, rect, wxSystemSettings::GetColour(/*!renderAsEnabled(*this) ? wxSYS_COLOUR_BTNFACE :*/wxSYS_COLOUR_WINDOW)); + const bool enabled = renderAsEnabled(*this); + clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); //coordinate with "colLabelHeight" in Grid constructor: wxFont labelFont = GetFont(); @@ -637,7 +639,7 @@ private: if (labelAreaTL.x > rect.GetRight()) return; //done, rect is fully covered if (labelAreaTL.x + width > rect.x) - drawColumnLabel(dc, wxRect(labelAreaTL, wxSize(width, colLabelHeight)), col, it->type); + drawColumnLabel(dc, wxRect(labelAreaTL, wxSize(width, colLabelHeight)), col, it->type, enabled); labelAreaTL.x += width; } if (labelAreaTL.x > rect.GetRight()) @@ -652,11 +654,11 @@ private: const int clientWidth = GetClientSize().GetWidth(); //need reliable, stable width in contrast to rect.width if (totalWidth < clientWidth) - drawColumnLabel(dc, wxRect(labelAreaTL, wxSize(clientWidth - totalWidth, colLabelHeight)), absWidths.size(), ColumnType::NONE); + drawColumnLabel(dc, wxRect(labelAreaTL, wxSize(clientWidth - totalWidth, colLabelHeight)), absWidths.size(), ColumnType::NONE, enabled); } } - void drawColumnLabel(wxDC& dc, const wxRect& rect, size_t col, ColumnType colType) + void drawColumnLabel(wxDC& dc, const wxRect& rect, size_t col, ColumnType colType, bool enabled) { if (auto dataView = refParent().getDataProvider()) { @@ -666,7 +668,7 @@ private: false; RecursiveDcClipper clip(dc, rect); - dataView->renderColumnLabel(refParent(), dc, rect, colType, isHighlighted); + dataView->renderColumnLabel(dc, rect, colType, enabled, isHighlighted); //draw move target location if (refParent().allowColumnMove_) @@ -885,7 +887,8 @@ public: private: void render(wxDC& dc, const wxRect& rect) override { - clearArea(dc, rect, wxSystemSettings::GetColour(/*!renderAsEnabled(*this) ? wxSYS_COLOUR_BTNFACE :*/wxSYS_COLOUR_WINDOW)); + const bool enabled = renderAsEnabled(*this); + clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); dc.SetFont(GetFont()); //harmonize with Grid::getBestColumnSize() @@ -914,7 +917,7 @@ private: { const wxRect rowRect(cellAreaTL + wxPoint(0, row * rowHeight), wxSize(totalRowWidth, rowHeight)); RecursiveDcClipper dummy3(dc, rowRect); - prov->renderRowBackgound(dc, rowRect, row, renderAsEnabled(*this), drawAsSelected(row)); + prov->renderRowBackgound(dc, rowRect, row, enabled, drawAsSelected(row)); } //draw single cells, column by column @@ -928,7 +931,7 @@ private: { const wxRect cellRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, cw.width, rowHeight); RecursiveDcClipper dummy3(dc, cellRect); - prov->renderCell(dc, cellRect, row, cw.type, renderAsEnabled(*this), drawAsSelected(row), getRowHoverToDraw(row)); + prov->renderCell(dc, cellRect, row, cw.type, enabled, drawAsSelected(row), getRowHoverToDraw(row)); } cellAreaTL.x += cw.width; } @@ -1488,10 +1491,10 @@ 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! */ + /* 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); @@ -1509,9 +1512,9 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) 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 + //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(scrollBarSizeTmp.x == 0 || scrollBarSizeTmp.x == 6 || scrollBarSizeTmp.x == 13); //lame hard-coded numbers (from Ubuntu 19.10) @@ -1522,7 +1525,7 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) 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_); @@ -1904,7 +1907,7 @@ void Grid::showScrollBars(Grid::ScrollBarStatus horizontal, Grid::ScrollBarStatu assert(false); return GTK_POLICY_AUTOMATIC; }; - + GtkScrolledWindow* scrollWin = GTK_SCROLLED_WINDOW(wxWindow::m_widget); assert(scrollWin); ::gtk_scrolled_window_set_policy(scrollWin, @@ -115,7 +115,7 @@ public: //label area: virtual std::wstring getColumnLabel(ColumnType colType) const = 0; - virtual void renderColumnLabel(Grid& grid, wxDC& dc, const wxRect& rect, ColumnType colType, bool highlighted); //default implementation + virtual void renderColumnLabel(wxDC& dc, const wxRect& rect, ColumnType colType, bool enabled, bool highlighted); //default implementation virtual std::wstring getToolTip(ColumnType colType) const { return std::wstring(); } static int getColumnGapLeft(); //for left-aligned text @@ -128,7 +128,7 @@ public: static void drawCellBackground(wxDC& dc, const wxRect& rect, bool enabled, bool selected, const wxColor& backgroundColor); static wxRect drawColumnLabelBackground(wxDC& dc, const wxRect& rect, bool highlighted); //returns inner rectangle - static void drawColumnLabelText (wxDC& dc, const wxRect& rect, const std::wstring& text); + static void drawColumnLabelText (wxDC& dc, const wxRect& rect, const std::wstring& text, bool enabled); }; diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 91189ba6..2a3b7039 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -12,6 +12,7 @@ #include <zen/perf.h> #include <zen/thread.h> #include <zen/file_io.h> +#include <zen/file_traverser.h> #include <wx/zipstrm.h> #include <wx/mstream.h> #include <wx/image.h> @@ -182,63 +183,81 @@ private: }; -void GlobalBitmaps::init(const Zstring& filePath) +void GlobalBitmaps::init(const Zstring& zipPath) { assert(bitmaps_.empty() && anims_.empty()); - //wxFFileInputStream/wxZipInputStream loads in junks of 512 bytes => WTF!!! => implement sane file loading: - try + std::vector<std::pair<Zstring /*file name*/, std::string /*byte stream*/>> streams; + + try //to load from ZIP first: + { + //wxFFileInputStream/wxZipInputStream loads in junks of 512 bytes => WTF!!! => implement sane file loading: + const std::string rawStream = loadBinContainer<std::string>(zipPath, 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)'!" + + while (const auto& entry = std::unique_ptr<wxZipEntry>(zipStream.GetNextEntry())) //take ownership! + if (std::string stream(entry->GetSize(), '\0'); !stream.empty() && zipStream.ReadAll(&stream[0], stream.size())) + streams.emplace_back(utfTo<Zstring>(entry->GetName()), std::move(stream)); + else + assert(false); + } + catch (FileError&) //fall back to folder + { + traverseFolder(beforeLast(zipPath, Zstr(".zip"), IF_MISSING_RETURN_NONE), [&](const FileInfo& fi) + { + if (endsWith(fi.fullPath, Zstr(".png"))) + try + { + std::string stream = loadBinContainer<std::string>(fi.fullPath, nullptr /*notifyUnbufferedIO*/); //throw FileError + streams.emplace_back(fi.itemName, std::move(stream)); + } + catch (FileError&) { assert(false); } + }, nullptr, nullptr, [](const std::wstring& errorMsg) { assert(false); }); //errors are not really critical in this context + } + //-------------------------------------------------------------------- + + //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); + + for (const auto& [fileName, stream] : streams) { - 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); - } + const wxString& name = utfTo<wxString>(afterLast(fileName, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL)); + + wxMemoryInputStream wxstream(stream.c_str(), stream.size()); //stream does not take ownership of data + //bonus: work around wxWidgets bug: wxAnimation::Load() requires seekable input stream (zip-input stream is not seekable) + + if (endsWith(name, L".png")) + { + wxImage img(wxstream, 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); + } +#if 0 + else if (endsWith(name, L".gif")) + { + [[maybe_unused]] const bool loadSuccess = anims_[name].Load(wxstream, wxANIMATION_TYPE_GIF); + assert(loadSuccess); + } +#endif + else + assert(false); } - catch (FileError&) { assert(false); } } @@ -272,10 +291,10 @@ const wxAnimation& GlobalBitmaps::getAnimation(const wxString& name) const } -void zen::initResourceImages(const Zstring& filepath) +void zen::initResourceImages(const Zstring& zipPath) { if (std::shared_ptr<GlobalBitmaps> inst = GlobalBitmaps::instance()) - inst->init(filepath); + inst->init(zipPath); else assert(false); } diff --git a/wx+/image_resources.h b/wx+/image_resources.h index 5ea56679..ff1d5648 100644 --- a/wx+/image_resources.h +++ b/wx+/image_resources.h @@ -14,7 +14,7 @@ namespace zen { -void initResourceImages(const Zstring& filePath); //pass resources .zip file at application startup +void initResourceImages(const Zstring& zipPath); //pass resources .zip file at application startup void cleanupResourceImages(); const wxBitmap& getResourceImage (const wxString& name); diff --git a/wx+/image_tools.cpp b/wx+/image_tools.cpp index 0f248057..8f94d1bc 100644 --- a/wx+/image_tools.cpp +++ b/wx+/image_tools.cpp @@ -72,7 +72,7 @@ wxImage zen::stackImages(const wxImage& img1, const wxImage& img2, ImageStackLay int width = std::max(img1Width, img2Width); int height = std::max(img1Height, img2Height); - if (dir == ImageStackLayout::HORIZONTAL) + if (dir == ImageStackLayout::horizontal) width = img1Width + gap + img2Width; else height = img1Height + gap + img2Height; @@ -85,11 +85,11 @@ wxImage zen::stackImages(const wxImage& img1, const wxImage& img2, ImageStackLay { switch (align) { - case ImageStackAlignment::CENTER: + case ImageStackAlignment::center: return static_cast<int>(std::floor((totalExtent - imageExtent) / 2.0)); //consistency: round down negative values, too! - case ImageStackAlignment::LEFT: + case ImageStackAlignment::left: return 0; - case ImageStackAlignment::RIGHT: + case ImageStackAlignment::right: return totalExtent - imageExtent; } assert(false); @@ -98,12 +98,12 @@ wxImage zen::stackImages(const wxImage& img1, const wxImage& img2, ImageStackLay switch (dir) { - case ImageStackLayout::HORIZONTAL: + case ImageStackLayout::horizontal: writeToImage(output, img1, wxPoint(0, calcPos(img1Height, height))); writeToImage(output, img2, wxPoint(img1Width + gap, calcPos(img2Height, height))); break; - case ImageStackLayout::VERTICAL: + case ImageStackLayout::vertical: writeToImage(output, img1, wxPoint(calcPos(img1Width, width), 0)); writeToImage(output, img2, wxPoint(calcPos(img2Width, width), img1Height + gap)); break; @@ -165,13 +165,13 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const if (!lineText.empty()) switch (textAlign) { - case ImageStackAlignment::LEFT: + case ImageStackAlignment::left: dc.DrawText(lineText, wxPoint(0, posY)); break; - case ImageStackAlignment::RIGHT: + case ImageStackAlignment::right: dc.DrawText(lineText, wxPoint(maxWidth - lineSize.GetWidth(), posY)); break; - case ImageStackAlignment::CENTER: + case ImageStackAlignment::center: dc.DrawText(lineText, wxPoint((maxWidth - lineSize.GetWidth()) / 2, posY)); break; } @@ -191,7 +191,7 @@ wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const for (int i = 0; i < pixelCount; ++i) { //black(0,0,0) becomes wxIMAGE_ALPHA_OPAQUE(255), while white(255,255,255) becomes wxIMAGE_ALPHA_TRANSPARENT(0) - *alpha++ = static_cast<unsigned char>((255 - rgb[0] + 255 - rgb[1] + 255 - rgb[2]) / 3); //mixed mode arithmetics! + *alpha++ = static_cast<unsigned char>((255 - rgb[0] + 255 - rgb[1] + 255 - rgb[2]) / 3); //mixed-mode arithmetics! rgb[0] = col.Red (); // rgb[1] = col.Green(); //apply actual text color @@ -211,7 +211,7 @@ wxImage zen::layOver(const wxImage& back, const wxImage& front, int alignment) const int width = std::max(back.GetWidth(), front.GetWidth()); const int height = std::max(back.GetHeight(), front.GetHeight()); - const int offsetX = [&] + const int offsetX = [&] { if (alignment & wxALIGN_RIGHT) return back.GetWidth() - front.GetWidth(); @@ -239,7 +239,7 @@ wxImage zen::layOver(const wxImage& back, const wxImage& front, int alignment) ::memset(output.GetAlpha(), wxIMAGE_ALPHA_TRANSPARENT, width * height); const wxPoint posBack(std::max(-offsetX, 0), std::max(-offsetY, 0)); - writeToImage(output, back , posBack); + 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 d72597ef..e2d42fb0 100644 --- a/wx+/image_tools.h +++ b/wx+/image_tools.h @@ -18,25 +18,25 @@ namespace zen { enum class ImageStackLayout { - HORIZONTAL, - VERTICAL + horizontal, + vertical }; enum class ImageStackAlignment //one-dimensional unlike wxAlignment { - CENTER, - LEFT, - RIGHT, - TOP = LEFT, - BOTTOM = RIGHT, + center, + left, + right, + top = left, + bottom = right, }; wxImage stackImages(const wxImage& img1, const wxImage& img2, ImageStackLayout dir, ImageStackAlignment align, int gap = 0); -wxImage createImageFromText(const wxString& text, const wxFont& font, const wxColor& col, ImageStackAlignment textAlign = ImageStackAlignment::LEFT); //CENTER/LEFT/RIGHT +wxImage createImageFromText(const wxString& text, const wxFont& font, const wxColor& col, ImageStackAlignment textAlign = ImageStackAlignment::left); //center/left/right wxImage layOver(const wxImage& back, const wxImage& front, int alignment = wxALIGN_CENTER); -wxImage greyScale(const wxImage& img); //greyscale + brightness adaption +wxImage greyScale(const wxImage& img); //greyscale + brightness adaption wxBitmap greyScale(const wxBitmap& bmp); // //void moveImage(wxImage& img, int right, int up); @@ -44,8 +44,6 @@ void adjustBrightness(wxImage& img, int targetLevel); double getAvgBrightness(const wxImage& img); //in [0, 255] void brighten(wxImage& img, int level); //level: delta per channel in points -bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs); //pixel-wise equality (respecting alpha channel) - void convertToVanillaImage(wxImage& img); //add alpha channel if missing + remove mask if existing //wxColor gradient(const wxColor& from, const wxColor& to, double fraction); //maps fraction within [0, 1] to an intermediate color @@ -153,36 +151,6 @@ void adjustBrightness(wxImage& img, int targetLevel) inline -bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs) -{ - if (lhs.IsOk() != rhs.IsOk()) - return false; - if (!lhs.IsOk()) - return true; - - if (lhs.GetSize() != rhs.GetSize()) - return false; - - wxImage imLhs = lhs.ConvertToImage(); - wxImage imRhs = rhs.ConvertToImage(); - - if (imLhs.HasAlpha() != imRhs.HasAlpha()) - return false; - - const int pixelCount = lhs.GetWidth() * lhs.GetHeight(); - - if (!std::equal(imLhs.GetData(), imLhs.GetData() + pixelCount * 3, imRhs.GetData())) - return false; - - if (imLhs.HasAlpha()) - if (!std::equal(imLhs.GetAlpha(), imLhs.GetAlpha() + pixelCount, imRhs.GetAlpha())) - return false; - - return true; -} - - -inline wxImage shrinkImage(const wxImage& img, int requestedSize) { const int maxExtent = std::max(img.GetWidth(), img.GetHeight()); diff --git a/wx+/popup_dlg_generated.cpp b/wx+/popup_dlg_generated.cpp index 3e490757..af43c85b 100644 --- a/wx+/popup_dlg_generated.cpp +++ b/wx+/popup_dlg_generated.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version May 29 2018) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -39,7 +39,7 @@ PopupDialogGenerated::PopupDialogGenerated( wxWindow* parent, wxWindowID id, con bSizer16->Add( 0, 5, 0, 0, 5 ); - m_textCtrlTextDetail = new wxTextCtrl( m_panel33, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxNO_BORDER ); + m_textCtrlTextDetail = new wxTextCtrl( m_panel33, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxBORDER_NONE ); bSizer16->Add( m_textCtrlTextDetail, 1, wxEXPAND, 5 ); @@ -63,6 +63,7 @@ PopupDialogGenerated::PopupDialogGenerated( wxWindow* parent, wxWindowID id, con bSizerStdButtons = new wxBoxSizer( wxHORIZONTAL ); m_buttonAccept = new wxButton( this, wxID_YES, _("dummy"), wxDefaultPosition, wxSize( -1, -1 ), 0 ); + m_buttonAccept->SetDefault(); bSizerStdButtons->Add( m_buttonAccept, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); diff --git a/wx+/popup_dlg_generated.h b/wx+/popup_dlg_generated.h index 9d9bc3f8..2b09289b 100644 --- a/wx+/popup_dlg_generated.h +++ b/wx+/popup_dlg_generated.h @@ -1,12 +1,11 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version May 29 2018) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#ifndef __POPUP_DLG_GENERATED_H__ -#define __POPUP_DLG_GENERATED_H__ +#pragma once #include <wx/artprov.h> #include <wx/xrc/xmlres.h> @@ -70,4 +69,3 @@ public: }; -#endif //__POPUP_DLG_GENERATED_H__ @@ -94,13 +94,14 @@ void drawBitmapRtlNoMirror(wxDC& dc, const wxBitmap& bmp, const wxRect& rect, in } -inline +inline wxImage mirrorIfRtl(const wxImage& bmp) { if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft) return bmp.Mirror(); else - return bmp;} + return bmp; +} inline diff --git a/wx+/std_button_layout.h b/wx+/std_button_layout.h index cf0152de..d2c5fc32 100644 --- a/wx+/std_button_layout.h +++ b/wx+/std_button_layout.h @@ -83,7 +83,7 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) { assert(btn->GetMinSize().GetHeight() == -1); //let OS or this routine do the sizing! note: OS X does not allow changing the (visible!) button height! const int defaultHeight = wxButton::GetDefaultSize().GetHeight(); //buffered by wxWidgets - btn->SetMinSize(wxSize(-1, std::max(defaultHeight, fastFromDIP(30)))); //default button height is much too small => increase! + btn->SetMinSize({-1, std::max(defaultHeight, fastFromDIP(31))}); //default button height is much too small => increase! if (settingFirstButton) settingFirstButton = false; diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index 42fb058a..0beef0bf 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -61,7 +61,7 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp) const wxBitmap& newBmp = bmp ? *bmp : wxNullBitmap; - if (!isEqual(tipWindow_->bitmapLeft_->GetBitmap(), newBmp)) + if (!tipWindow_->bitmapLeft_->GetBitmap().IsSameAs(newBmp)) { tipWindow_->bitmapLeft_->SetBitmap(newBmp); tipWindow_->Refresh(); //needed if bitmap size changed! |