From 0887aee8c54d0ed51bb2031431e2bcdafebb4c6e Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:23:19 +0200 Subject: 5.13 --- wx+/button.cpp | 44 +++++++++++++++++++--------------------- wx+/button.h | 20 +++++++++++------- wx+/font_size.h | 25 +++++++++++++++++++++++ wx+/graph.cpp | 31 ++++++++-------------------- wx+/grid.cpp | 58 ++++++++++++++++++++++++++++++++++++++++------------- wx+/grid.h | 5 ++++- wx+/shell_execute.h | 5 +++-- wx+/tooltip.cpp | 7 +++++-- wx+/zlib_wrap.cpp | 2 +- 9 files changed, 124 insertions(+), 73 deletions(-) create mode 100644 wx+/font_size.h (limited to 'wx+') diff --git a/wx+/button.cpp b/wx+/button.cpp index a67624b8..75e4bfe1 100644 --- a/wx+/button.cpp +++ b/wx+/button.cpp @@ -32,41 +32,40 @@ BitmapButton::BitmapButton(wxWindow* parent, const wxValidator& validator, const wxString& name) : wxBitmapButton(parent, id, wxNullBitmap, pos, size, style | wxBU_AUTODRAW, validator, name), - m_spaceAfter(0), - m_spaceBefore(0) + spaceAfter_(0), + spaceBefore_(0), + innerBorderSize(5) { - setTextLabel(label); + SetLabel(label); } -void BitmapButton::setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter) +void BitmapButton::setBitmapFront(const wxBitmap& bitmap, int spaceAfter) { - if (!isEqual(bitmap, bitmapFront) || spaceAfter != m_spaceAfter) //avoid flicker + if (!isEqual(bitmap, bitmapFront) || spaceAfter_ != spaceAfter) //avoid flicker { bitmapFront = bitmap; - m_spaceAfter = static_cast(spaceAfter); + spaceAfter_ = spaceAfter; refreshButtonLabel(); } } -void BitmapButton::setTextLabel(const wxString& text) +void BitmapButton::SetLabel(const wxString& label) { - if (text != textLabel) //avoid flicker + if (wxBitmapButton::GetLabel() != label) //avoid flicker { - textLabel = text; - wxBitmapButton::SetLabel(text); + wxBitmapButton::SetLabel(label); refreshButtonLabel(); } } - -void BitmapButton::setBitmapBack(const wxBitmap& bitmap, size_t spaceBefore) +void BitmapButton::setBitmapBack(const wxBitmap& bitmap, int spaceBefore) { - if (!isEqual(bitmap, bitmapBack) || spaceBefore != m_spaceBefore) //avoid flicker + if (!isEqual(bitmap, bitmapBack) || spaceBefore_ != spaceBefore) //avoid flicker { bitmapBack = bitmap; - m_spaceBefore = static_cast(spaceBefore); + spaceBefore_ = spaceBefore; refreshButtonLabel(); } } @@ -136,9 +135,9 @@ wxBitmap BitmapButton::createBitmapFromText(const wxString& text) //find position of accelerator int indexAccel = -1; - size_t accelPos; wxString textLabelFormatted = text; - if ((accelPos = text.find(wxT("&"))) != wxString::npos) + size_t accelPos = text.find(L"&"); + if (accelPos != wxString::npos) { replace(textLabelFormatted, L"&", L"", false); //remove accelerator indexAccel = static_cast(accelPos); @@ -232,8 +231,7 @@ void writeToImage(const wxImage& source, const wxPoint& pos, wxImage& target) if (!target.HasAlpha()) { target.SetAlpha(); - unsigned char* alpha = target.GetAlpha(); - memset(alpha, wxIMAGE_ALPHA_OPAQUE, target.GetWidth() * target.GetHeight()); + memset(target.GetAlpha(), wxIMAGE_ALPHA_OPAQUE, target.GetWidth() * target.GetHeight()); } //copy alpha channel @@ -275,7 +273,7 @@ wxSize getSize(const wxBitmap& bmp) void BitmapButton::refreshButtonLabel() { - wxBitmap bitmapText = createBitmapFromText(textLabel); + wxBitmap bitmapText = createBitmapFromText(GetLabel()); wxSize szFront = getSize(bitmapFront); // wxSize szText = getSize(bitmapText); //make sure to NOT access null-bitmaps! @@ -283,7 +281,7 @@ void BitmapButton::refreshButtonLabel() //calculate dimensions of new button const int height = std::max(std::max(szFront.GetHeight(), szText.GetHeight()), szBack.GetHeight()); - const int width = szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore + szBack.GetWidth(); + const int width = szFront.GetWidth() + spaceAfter_ + szText.GetWidth() + spaceBefore_ + szBack.GetWidth(); //create a transparent image wxImage transparentImage(width, height, false); @@ -299,19 +297,19 @@ void BitmapButton::refreshButtonLabel() if (bitmapText.IsOk()) writeToImage(bitmapText.ConvertToImage(), - wxPoint(szFront.GetWidth() + m_spaceAfter, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2), + wxPoint(szFront.GetWidth() + spaceAfter_, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2), transparentImage); if (bitmapBack.IsOk()) writeToImage(bitmapBack.ConvertToImage(), - wxPoint(szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2), + wxPoint(szFront.GetWidth() + spaceAfter_ + szText.GetWidth() + spaceBefore_, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2), transparentImage); //adjust button size wxSize minSize = GetMinSize(); //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly - wxBitmapButton::SetMinSize(wxSize(std::max(width + 10, minSize.GetWidth()), std::max(height + 5, minSize.GetHeight()))); + wxBitmapButton::SetMinSize(wxSize(std::max(width + 2 * innerBorderSize, minSize.GetWidth()), std::max(height + 2 * innerBorderSize, minSize.GetHeight()))); //finally set bitmap wxBitmapButton::SetBitmapLabel(wxBitmap(transparentImage)); diff --git a/wx+/button.h b/wx+/button.h index 5a704840..42174a44 100644 --- a/wx+/button.h +++ b/wx+/button.h @@ -24,19 +24,25 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxButtonNameStr); - void setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter = 0); //...and enlarge button if required! - void setTextLabel( const wxString& text); - void setBitmapBack( const wxBitmap& bitmap, size_t spaceBefore = 0); // + void setBitmapFront(const wxBitmap& bitmap, int spaceAfter = 0); //...and enlarge button if required! + void setBitmapBack (const wxBitmap& bitmap, int spaceBefore = 0); // + + void setInnerBorderSize(int sz) { innerBorderSize = sz; refreshButtonLabel(); } + + virtual void SetLabel(const wxString& label); + + void refreshButtonLabel(); //e.g. after font change private: wxBitmap createBitmapFromText(const wxString& text); - void refreshButtonLabel(); wxBitmap bitmapFront; - unsigned int m_spaceAfter; - wxString textLabel; - unsigned int m_spaceBefore; + int spaceAfter_; + ///wxString textLabel; + int spaceBefore_; wxBitmap bitmapBack; + + int innerBorderSize; }; //set bitmap label flicker free! diff --git a/wx+/font_size.h b/wx+/font_size.h new file mode 100644 index 00000000..773be928 --- /dev/null +++ b/wx+/font_size.h @@ -0,0 +1,25 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef FONT_SIZE_HEADER_23849632846734343234532 +#define FONT_SIZE_HEADER_23849632846734343234532 + +#include +#include + +namespace zen +{ +//set portable font size in multiples of the operating system's default font size +inline +void setRelativeFontSize(wxWindow& control, double factor) +{ + wxFont fnt = control.GetFont(); + fnt.SetPointSize(numeric::round(wxNORMAL_FONT->GetPointSize() * factor)); + control.SetFont(fnt); +}; +} + +#endif //FONT_SIZE_HEADER_23849632846734343234532 diff --git a/wx+/graph.cpp b/wx+/graph.cpp index a32c8e22..540f86a5 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -13,7 +13,6 @@ #include "rtl.h" using namespace zen; -using namespace numeric; //todo: support zoom via mouse wheel @@ -22,12 +21,6 @@ const wxEventType zen::wxEVT_GRAPH_SELECTION = wxNewEventType(); const std::shared_ptr Graph2D::MainAttributes::defaultFormat = std::make_shared(); //for some buggy reason MSVC isn't able to use a temporary as a default argument -namespace -{ -inline -double bestFit(double val, double low, double high) { return val < (high + low) / 2 ? low : high; } -} - double zen::nextNiceNumber(double blockSize) //round to next number which is a convenient to read block size { @@ -36,24 +29,14 @@ double zen::nextNiceNumber(double blockSize) //round to next number which is a c const double k = std::floor(std::log10(blockSize)); const double e = std::pow(10, k); - if (isNull(e)) + if (numeric::isNull(e)) return 0; const double a = blockSize / e; //blockSize = a * 10^k with a in (1, 10) + assert(1 < a && a < 10); //have a look at leading two digits: "nice" numbers start with 1, 2, 2.5 and 5 - if (a <= 2) - return bestFit(a, 1, 2) * e; - else if (a <= 2.5) - return bestFit(a, 2, 2.5) * e; - else if (a <= 5) - return bestFit(a, 2.5, 5) * e; - else if (a < 10) - return bestFit(a, 5, 10) * e; - else - { - assert(false); - return 10 * e; - } + const double steps[] = { 1, 2, 2.5, 5, 10 }; + return e * numeric::nearMatch(a, std::begin(steps), std::end(steps)); } @@ -95,7 +78,7 @@ public: ConvertCoord(double valMin, double valMax, size_t screenSize) : min_(valMin), scaleToReal(screenSize == 0 ? 0 : (valMax - valMin) / screenSize), - scaleToScr(isNull((valMax - valMin)) ? 0 : screenSize / (valMax - valMin)) {} + scaleToScr(numeric::isNull((valMax - valMin)) ? 0 : screenSize / (valMax - valMin)) {} double screenToReal(double screenPos) const //input value: [0, screenSize - 1] { @@ -128,7 +111,7 @@ void widenRange(double& valMin, double& valMax, //in/out { double valRangePerBlock = (valMax - valMin) * optimalBlockSize / graphAreaSize; //proposal valRangePerBlock = labelFmt.getOptimalBlockSize(valRangePerBlock); - if (!isNull(valRangePerBlock)) + if (!numeric::isNull(valRangePerBlock)) { valMin = std::floor(valMin / valRangePerBlock) * valRangePerBlock; valMax = std::ceil (valMax / valRangePerBlock) * valRangePerBlock; @@ -319,6 +302,8 @@ struct CurveSamples void Graph2D::render(wxDC& dc) const { + using namespace numeric; + const wxRect clientRect = GetClientRect(); //DON'T use wxDC::GetSize()! DC may be larger than visible area! { //clear complete client area; set label background color diff --git a/wx+/grid.cpp b/wx+/grid.cpp index f6d0e6b8..4eb3b00e 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -291,7 +291,6 @@ void GridData::drawColumnLabelText(wxDC& dc, const wxRect& rect, const wxString& CornerWin RowLabelWin ColLabelWin MainWin */ - class Grid::SubWindow : public wxWindow { public: @@ -323,6 +322,7 @@ public: Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(SubWindow::onMouseRightUp ), nullptr, this); Connect(wxEVT_MOTION, wxMouseEventHandler(SubWindow::onMouseMovement ), nullptr, this); Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SubWindow::onLeaveWindow ), nullptr, this); + Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(SubWindow::onMouseWheel ), nullptr, this); Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), nullptr, this); Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), nullptr, this); @@ -331,7 +331,6 @@ public: assert(GetClientAreaOrigin() == wxPoint()); //generally assumed when dealing with coordinates below } - Grid& refParent() { return parent_; } const Grid& refParent() const { return parent_; } @@ -380,11 +379,26 @@ private: virtual void onMouseMovement (wxMouseEvent& event) { event.Skip(); } virtual void onLeaveWindow (wxMouseEvent& event) { event.Skip(); } virtual void onMouseCaptureLost(wxMouseCaptureLostEvent& event) { event.Skip(); } - virtual void onChar (wxKeyEvent& event) { event.Skip(); } virtual void onKeyUp (wxKeyEvent& event) { event.Skip(); } virtual void onKeyDown(wxKeyEvent& event) { event.Skip(); } + void onMouseWheel(wxMouseEvent& event) + { + /* + MSDN, WM_MOUSEWHEEL: "Sent to the focus window when the mouse wheel is rotated. + The DefWindowProc function propagates the message to the window's parent. + There should be no internal forwarding of the message, since DefWindowProc propagates + it up the parent chain until it finds a window that processes it." + + On OS X there is no such propagation! => we need a redirection (the same wxGrid implements) + */ + if (wxEvtHandler* evtHandler = parent_.GetEventHandler()) + if (evtHandler->ProcessEvent(event)) + return; + event.Skip(); + } + void onPaintEvent(wxPaintEvent& event) { //wxAutoBufferedPaintDC dc(this); -> this one happily fucks up for RTL layout by not drawing the first column (x = 0)! @@ -515,8 +529,6 @@ private: labelFont.SetWeight(wxFONTWEIGHT_BOLD); dc.SetFont(labelFont); - wxDCTextColourChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels - auto rowRange = getRowsOnClient(rect); //returns range [begin, end) for (auto row = rowRange.first; row < rowRange.second; ++row) { @@ -838,7 +850,7 @@ private: virtual void onLeaveWindow(wxMouseEvent& event) { - highlight.reset(); //onLeaveWindow() does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize! + highlight.reset(); //wxEVT_LEAVE_WINDOW does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize! Refresh(); event.Skip(); } @@ -1414,8 +1426,8 @@ private: void onRequestWindowUpdate(wxEvent& event) { - ZEN_ON_SCOPE_EXIT(gridUpdatePending = false); assert(gridUpdatePending); + ZEN_ON_SCOPE_EXIT(gridUpdatePending = false); refParent().updateWindowSizes(false); //row label width has changed -> do *not* update scrollbars: recursion on wxGTK! -> still a problem, now that we're called async?? rowLabelWin_.Update(); //update while dragging scroll thumb @@ -1732,16 +1744,30 @@ std::vector Grid::getColumnConfig(size_t compPos) const void Grid::showScrollBars(Grid::ScrollBarStatus horizontal, Grid::ScrollBarStatus vertical) { -#if wxCHECK_VERSION(2, 9, 1) - int weShouldMigrateToWxWidgetsShowScrollBarsInstead; //lousy compile-time warning, I know ;) -#endif - if (showScrollbarX == horizontal && showScrollbarY == vertical) return; //support polling! showScrollbarX = horizontal; showScrollbarY = vertical; +#if wxCHECK_VERSION(2, 9, 0) + auto mapStatus = [](ScrollBarStatus sbStatus) -> wxScrollbarVisibility + { + switch (sbStatus) + { + case SB_SHOW_AUTOMATIC: + return wxSHOW_SB_DEFAULT; + case SB_SHOW_ALWAYS: + return wxSHOW_SB_ALWAYS; + case SB_SHOW_NEVER: + return wxSHOW_SB_NEVER; + } + assert(false); + return wxSHOW_SB_DEFAULT; + }; + ShowScrollbars(mapStatus(horizontal), mapStatus(vertical)); +#else //support older wxWidgets API + #ifdef FFS_LINUX //get rid of scrollbars, but preserve scrolling behavior! //the following wxGTK approach is pretty much identical to wxWidgets 2.9 ShowScrollbars() code! @@ -1765,12 +1791,15 @@ void Grid::showScrollBars(Grid::ScrollBarStatus horizontal, Grid::ScrollBarStatu gtk_scrolled_window_set_policy(scrolledWindow, mapStatus(horizontal), mapStatus(vertical)); +#elif defined FFS_MAC +#error function not implemented! Upgrade to wxWidgets 2.9 or newer +#endif #endif + updateWindowSizes(); } - -#ifdef FFS_WIN //get rid of scrollbars, but preserve scrolling behavior! +#if defined FFS_WIN && !wxCHECK_VERSION(2, 9, 0) //support older wxWidgets API void Grid::SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh) { ScrollBarStatus sbStatus = SB_SHOW_AUTOMATIC; @@ -1799,8 +1828,9 @@ void Grid::SetScrollbar(int orientation, int position, int thumbSize, int range, break; } } +#endif - +#ifdef FFS_WIN //get rid of scrollbars, but preserve scrolling behavior! #ifndef WM_MOUSEHWHEEL //MinGW is clueless... #define WM_MOUSEHWHEEL 0x020E #endif diff --git a/wx+/grid.h b/wx+/grid.h index 11317fd8..918b4a4f 100644 --- a/wx+/grid.h +++ b/wx+/grid.h @@ -202,9 +202,12 @@ private: void redirectRowLabelEvent(wxMouseEvent& event); +#if defined FFS_WIN && !wxCHECK_VERSION(2, 9, 0) + virtual void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh); //get rid of scrollbars, but preserve scrolling behavior! +#endif + #ifdef FFS_WIN virtual WXLRESULT MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); //support horizontal mouse wheel - void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh); //get rid of scrollbars, but preserve scrolling behavior! #endif ptrdiff_t getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error diff --git a/wx+/shell_execute.h b/wx+/shell_execute.h index 2531c91f..a07f40cb 100644 --- a/wx+/shell_execute.h +++ b/wx+/shell_execute.h @@ -7,6 +7,7 @@ #ifndef EXECUTE_HEADER_23482134578134134 #define EXECUTE_HEADER_23482134578134134 +#include #include #ifdef FFS_WIN @@ -16,7 +17,7 @@ #include //includes "windows.h" //#include -#elif defined FFS_LINUX +#elif defined FFS_LINUX || defined FFS_MAC #include #include #include @@ -82,7 +83,7 @@ void shellExecute(const Zstring& command, ExecutionType type = EXEC_TYPE_ASYNC) ::CloseHandle(execInfo.hProcess); } -#elif defined FFS_LINUX +#elif defined FFS_LINUX || defined FFS_MAC if (type == EXEC_TYPE_SYNC) { //Posix::system - execute a shell command diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index 447cbb1f..3431e339 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -50,8 +50,8 @@ public: Tooltip::Tooltip() : tipWindow(new PopupFrameGenerated(nullptr)) { -#ifdef FFS_WIN //neither looks good nor works at all on Linux - tipWindow->Disable(); //prevent window stealing focus! +#if defined FFS_WIN //prevent window stealing focus! + tipWindow->Disable(); //neither looks good nor works at all on Linux; no visible difference on OS X #endif hide(); } @@ -68,7 +68,10 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp) const wxBitmap& newBmp = bmp ? *bmp : wxNullBitmap; if (!isEqual(tipWindow->m_bitmapLeft->GetBitmap(), newBmp)) + { tipWindow->m_bitmapLeft->SetBitmap(newBmp); + tipWindow->Refresh(); //needed if bitmap size changed! + } if (text != tipWindow->m_staticTextMain->GetLabel()) { diff --git a/wx+/zlib_wrap.cpp b/wx+/zlib_wrap.cpp index 6fad0383..cfa0f615 100644 --- a/wx+/zlib_wrap.cpp +++ b/wx+/zlib_wrap.cpp @@ -7,7 +7,7 @@ #include "zlib_wrap.h" #ifdef FFS_WIN #include //not really a "nice" place to look for a stable solution -#elif defined FFS_LINUX +#elif defined FFS_LINUX || defined FFS_MAC #include //let's pray this is the same version wxWidgets is linking against! #endif -- cgit