diff options
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/graph.cpp | 4 | ||||
-rw-r--r-- | wx+/grid.cpp | 52 | ||||
-rw-r--r-- | wx+/grid.h | 2 | ||||
-rw-r--r-- | wx+/image_resources.cpp | 73 | ||||
-rw-r--r-- | wx+/popup_dlg.cpp | 5 |
5 files changed, 83 insertions, 53 deletions
diff --git a/wx+/graph.cpp b/wx+/graph.cpp index 14661311..192e5513 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -150,7 +150,7 @@ void drawXLabel(wxDC& dc, double xMin, double xMax, int blockCount, const Conver if (blockCount <= 0) return; - wxDCPenChanger dummy(dc, wxPen(wxColor(192, 192, 192))); //light grey => not accessible! but no big deal... + wxDCPenChanger dummy(dc, wxColor(192, 192, 192)); //light grey => not accessible! but no big deal... wxDCTextColourChanger dummy2(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels const double valRangePerBlock = (xMax - xMin) / blockCount; @@ -178,7 +178,7 @@ void drawYLabel(wxDC& dc, double yMin, double yMax, int blockCount, const Conver if (blockCount <= 0) return; - wxDCPenChanger dummy(dc, wxPen(wxColor(192, 192, 192))); //light grey => not accessible! but no big deal... + wxDCPenChanger dummy(dc, wxColor(192, 192, 192)); //light grey => not accessible! but no big deal... wxDCTextColourChanger dummy2(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels const double valRangePerBlock = (yMax - yMin) / blockCount; diff --git a/wx+/grid.cpp b/wx+/grid.cpp index ec0534d2..94bcadd9 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -7,12 +7,13 @@ #include "grid.h" #include <cassert> #include <set> +#include <chrono> #include <wx/settings.h> #include <wx/listbox.h> #include <wx/tooltip.h> #include <wx/timer.h> #include <wx/utils.h> -#include <zen/tick_count.h> +//#include <zen/tick_count.h> #include <zen/string_tools.h> #include <zen/scope_guard.h> #include <zen/utf.h> @@ -100,7 +101,7 @@ int GridData::getBestSize(wxDC& dc, size_t row, ColumnType colType) wxRect GridData::drawCellBorder(wxDC& dc, const wxRect& rect) //returns remaining rectangle { - wxDCPenChanger dummy2(dc, wxPen(getColorGridLine(), 1, wxSOLID)); + wxDCPenChanger dummy2(dc, getColorGridLine()); dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight()); dc.DrawLine(rect.GetBottomRight(), rect.GetTopRight() + wxPoint(0, -1)); @@ -212,7 +213,7 @@ wxRect GridData::drawColumnLabelBorder(wxDC& dc, const wxRect& rect) //returns r //draw border (with gradient) { - wxDCPenChanger dummy(dc, wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID)); + wxDCPenChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); dc.GradientFillLinear(wxRect(rect.GetTopRight(), rect.GetBottomRight()), getColorLabelGradientFrom(), dc.GetPen().GetColour(), wxSOUTH); dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight() + wxPoint(1, 0)); } @@ -397,7 +398,7 @@ private: dc.GradientFillLinear(clientRect, getColorLabelGradientFrom(), getColorLabelGradientTo(), wxSOUTH); - dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID)); + dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); { wxDCPenChanger dummy(dc, getColorLabelGradientFrom()); @@ -540,7 +541,7 @@ private: dc.DrawLine(rect.GetTopLeft(), rect.GetTopRight()); } { - wxDCPenChanger dummy(dc, wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID)); + wxDCPenChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); dc.DrawLine(rect.GetTopLeft(), rect.GetBottomLeft()); dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight()); dc.DrawLine(rect.GetBottomRight(), rect.GetTopRight() + wxPoint(0, -1)); @@ -633,7 +634,7 @@ private: wxDCTextColourChanger dummy(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); //use user setting for labels - const int colLabelHeight = refParent().colLabelHeight; + const int colLabelHeight = refParent().colLabelHeight_; wxPoint labelAreaTL(refParent().CalcScrolledPosition(wxPoint(0, 0)).x, 0); //client coordinates @@ -1150,13 +1151,9 @@ private: void evalMousePos() { - double deltaTime = 0; - if (ticksPerSec_ > 0) - { - const TickVal now = getTicks(); //!isValid() on error - deltaTime = static_cast<double>(dist(tickCountLast, now)) / ticksPerSec_; //unit: [sec] - tickCountLast = now; - } + const auto now = std::chrono::steady_clock::now(); + const double deltaSecs = std::chrono::duration<double>(now - lastEvalTime).count(); //unit: [sec] + lastEvalTime = now; const wxPoint clientPos = wnd_.ScreenToClient(wxGetMousePosition()); const wxSize clientSize = wnd_.GetClientSize(); @@ -1179,7 +1176,7 @@ private: if (overlapPix != 0) { const double scrollSpeed = overlapPix * mouseDragSpeedIncScrollU; //unit: [scroll units / sec] - toScroll += scrollSpeed * deltaTime; + toScroll += scrollSpeed * deltaSecs; } else toScroll = 0; @@ -1220,8 +1217,7 @@ private: wxTimer timer; double toScrollX = 0; //count outstanding scroll unit fractions while dragging mouse double toScrollY = 0; // - TickVal tickCountLast = getTicks(); - const std::int64_t ticksPerSec_ = ticksPerSec(); + std::chrono::steady_clock::time_point lastEvalTime = std::chrono::steady_clock::now(); }; struct MouseHighlight @@ -1243,7 +1239,7 @@ private: //=> don't use plain async event => severe performance issues on wxGTK! //=> can't use idle event neither: too few idle events on Windows, e.g. NO idle events while mouse drag-scrolling! //=> solution: send single async event at most! - if (!gridUpdatePending) //without guarding, the number of outstanding async events can get very high during scrolling!! test case: Ubuntu: 170; Windows: 20 + if (!gridUpdatePending) //without guarding, the number of outstanding async events can become very high during scrolling!! test case: Ubuntu: 170; Windows: 20 { gridUpdatePending = true; wxCommandEvent scrollEvent(EVENT_GRID_HAS_SCROLLED); @@ -1301,7 +1297,7 @@ Grid::Grid(wxWindow* parent, colLabelWin_ = new ColLabelWin(*this); // mainWin_ = new MainWin (*this, *rowLabelWin_, *colLabelWin_); // - colLabelHeight = 2 * DEFAULT_COL_LABEL_BORDER + [&]() -> int + colLabelHeight_ = 2 * DEFAULT_COL_LABEL_BORDER + [&]() -> int { //coordinate with ColLabelWin::render(): wxFont labelFont = colLabelWin_->GetFont(); @@ -1353,7 +1349,7 @@ void Grid::updateWindowSizes(bool updateScrollbar) //harmonize with Grid::GetSizeAvailableForScrollTarget()! //1. calculate row label width independent from scrollbars - const int mainWinHeightGross = std::max(GetSize().GetHeight() - colLabelHeight, 0); //independent from client sizes and scrollbars! + const int mainWinHeightGross = std::max(GetSize().GetHeight() - colLabelHeight_, 0); //independent from client sizes and scrollbars! const ptrdiff_t logicalHeight = rowLabelWin_->getLogicalHeight(); // int rowLabelWidth = 0; @@ -1370,7 +1366,7 @@ void Grid::updateWindowSizes(bool updateScrollbar) rowLabelWidth = rowLabelWin_->getBestWidth(rowFrom, rowTo); } - auto getMainWinSize = [&](const wxSize& clientSize) { return wxSize(std::max(0, clientSize.GetWidth() - rowLabelWidth), std::max(0, clientSize.GetHeight() - colLabelHeight)); }; + auto getMainWinSize = [&](const wxSize& clientSize) { return wxSize(std::max(0, clientSize.GetWidth() - rowLabelWidth), std::max(0, clientSize.GetHeight() - colLabelHeight_)); }; auto setScrollbars2 = [&](int logWidth, int logHeight) //replace SetScrollbars, which loses precision of pixelsPerUnitX for some brain-dead reason { @@ -1393,10 +1389,10 @@ void Grid::updateWindowSizes(bool updateScrollbar) //this ensures mainWin_->SetVirtualSize() and AdjustScrollbars() are working with the correct main window size, unless sb change later, which triggers a recalculation anyway! const wxSize mainWinSize = getMainWinSize(GetClientSize()); - cornerWin_ ->SetSize(0, 0, rowLabelWidth, colLabelHeight); - rowLabelWin_->SetSize(0, colLabelHeight, rowLabelWidth, mainWinSize.GetHeight()); - colLabelWin_->SetSize(rowLabelWidth, 0, mainWinSize.GetWidth(), colLabelHeight); - mainWin_ ->SetSize(rowLabelWidth, colLabelHeight, mainWinSize.GetWidth(), mainWinSize.GetHeight()); + cornerWin_ ->SetSize(0, 0, rowLabelWidth, colLabelHeight_); + rowLabelWin_->SetSize(0, colLabelHeight_, rowLabelWidth, mainWinSize.GetHeight()); + colLabelWin_->SetSize(rowLabelWidth, 0, mainWinSize.GetWidth(), colLabelHeight_); + mainWin_ ->SetSize(rowLabelWidth, colLabelHeight_, mainWinSize.GetWidth(), mainWinSize.GetHeight()); //avoid flicker in wxWindowMSW::HandleSize() when calling ::EndDeferWindowPos() where the sub-windows are moved only although they need to be redrawn! colLabelWin_->Refresh(); @@ -1461,7 +1457,7 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) //harmonize with Grid::updateWindowSizes()! //1. calculate row label width independent from scrollbars - const int mainWinHeightGross = std::max(size.GetHeight() - colLabelHeight, 0); //independent from client sizes and scrollbars! + const int mainWinHeightGross = std::max(size.GetHeight() - colLabelHeight_, 0); //independent from client sizes and scrollbars! const ptrdiff_t logicalHeight = rowLabelWin_->getLogicalHeight(); // int rowLabelWidth = 0; @@ -1478,7 +1474,7 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) rowLabelWidth = rowLabelWin_->getBestWidth(rowFrom, rowTo); } - return size - wxSize(rowLabelWidth, colLabelHeight); + return size - wxSize(rowLabelWidth, colLabelHeight_); } @@ -1621,7 +1617,7 @@ void Grid::onKeyDown(wxKeyEvent& event) void Grid::setColumnLabelHeight(int height) { - colLabelHeight = std::max(0, height); + colLabelHeight_ = std::max(0, height); updateWindowSizes(); } @@ -1955,7 +1951,7 @@ wxRect Grid::getColumnLabelArea(ColumnType colType) const for (auto it = absWidths.begin(); it != itCol; ++it) posX += it->width_; - return wxRect(wxPoint(posX, 0), wxSize(itCol->width_, colLabelHeight)); + return wxRect(wxPoint(posX, 0), wxSize(itCol->width_, colLabelHeight_)); } return wxRect(); } @@ -348,7 +348,7 @@ private: ScrollBarStatus showScrollbarX = SB_SHOW_AUTOMATIC; ScrollBarStatus showScrollbarY = SB_SHOW_AUTOMATIC; - int colLabelHeight = 0; + int colLabelHeight_ = 0; bool drawRowLabel = true; std::shared_ptr<GridData> dataView_; diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 1157e15b..110539e7 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -7,11 +7,13 @@ #include "image_resources.h" #include <memory> #include <map> +#include <zen/utf.h> +#include <zen/globals.h> +#include <zen/thread.h> #include <wx/wfstream.h> #include <wx/zipstrm.h> #include <wx/image.h> #include <wx/mstream.h> -#include <zen/utf.h> #include "image_tools.h" using namespace zen; @@ -19,6 +21,10 @@ using namespace zen; namespace { +#ifndef NDEBUG + const std::thread::id mainThreadId = std::this_thread::get_id(); +#endif + void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim) { //work around wxWidgets bug: @@ -37,18 +43,19 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim) } -class GlobalResources +class GlobalBitmaps { public: - static GlobalResources& instance() + static std::shared_ptr<GlobalBitmaps> instance() { -#if defined _MSC_VER && _MSC_VER < 1900 -#error function scope static initialization is not yet thread-safe! -#endif - static GlobalResources inst; - return inst; + static Global<GlobalBitmaps> inst(std::make_unique<GlobalBitmaps>()); + assert(std::this_thread::get_id() == mainThreadId); //wxWidgets is not thread-safe! + return inst.get(); } + GlobalBitmaps() {} + ~GlobalBitmaps() { assert(bitmaps.empty() && anims.empty()); } //don't leave wxWidgets objects for static destruction! + void init(const Zstring& filepath); void cleanup() { @@ -60,17 +67,15 @@ public: const wxAnimation& getAnimation(const wxString& name) const; private: - GlobalResources() {} - ~GlobalResources() { assert(bitmaps.empty() && anims.empty()); } //don't leave wxWidgets objects for static destruction! - GlobalResources (const GlobalResources&) = delete; - GlobalResources& operator=(const GlobalResources&) = delete; + GlobalBitmaps (const GlobalBitmaps&) = delete; + GlobalBitmaps& operator=(const GlobalBitmaps&) = delete; std::map<wxString, wxBitmap> bitmaps; std::map<wxString, wxAnimation> anims; }; -void GlobalResources::init(const Zstring& filepath) +void GlobalBitmaps::init(const Zstring& filepath) { assert(bitmaps.empty() && anims.empty()); @@ -109,32 +114,58 @@ void GlobalResources::init(const Zstring& filepath) } -const wxBitmap& GlobalResources::getImage(const wxString& name) const +const wxBitmap& GlobalBitmaps::getImage(const wxString& name) const { auto it = bitmaps.find(contains(name, L'.') ? name : name + L".png"); //assume .png ending if nothing else specified if (it != bitmaps.end()) return it->second; - assert(false); return wxNullBitmap; } -const wxAnimation& GlobalResources::getAnimation(const wxString& name) const +const wxAnimation& GlobalBitmaps::getAnimation(const wxString& name) const { auto it = anims.find(contains(name, L'.') ? name : name + L".gif"); if (it != anims.end()) return it->second; - assert(false); return wxNullAnimation; } } -void zen::initResourceImages(const Zstring& filepath) { GlobalResources::instance().init(filepath); } -void zen::cleanupResourceImages() { GlobalResources::instance().cleanup(); } +void zen::initResourceImages(const Zstring& filepath) +{ + if (std::shared_ptr<GlobalBitmaps> inst = GlobalBitmaps::instance()) + inst->init(filepath); + else + assert(false); +} + + +void zen::cleanupResourceImages() +{ + if (std::shared_ptr<GlobalBitmaps> inst = GlobalBitmaps::instance()) + inst->cleanup(); + else + assert(false); +} + + +const wxBitmap& zen::getResourceImage(const wxString& name) +{ + if (std::shared_ptr<GlobalBitmaps> inst = GlobalBitmaps::instance()) + return inst->getImage(name); + assert(false); + return wxNullBitmap; +} -const wxBitmap& zen::getResourceImage(const wxString& name) { return GlobalResources::instance().getImage(name); } -const wxAnimation& zen::getResourceAnimation(const wxString& name) { return GlobalResources::instance().getAnimation(name); } +const wxAnimation& zen::getResourceAnimation(const wxString& name) +{ + if (std::shared_ptr<GlobalBitmaps> inst = GlobalBitmaps::instance()) + return inst->getAnimation(name); + assert(false); + return wxNullAnimation; +} diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index e05a4240..189343e9 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -121,9 +121,12 @@ public: int maxWidth = 500; int maxHeight = 400; //try to determine better value based on actual display resolution: - int disPos = wxDisplay::GetFromWindow(parent); //window must be visible + if (parent) + { + const int disPos = wxDisplay::GetFromWindow(parent); //window must be visible if (disPos != wxNOT_FOUND) maxHeight = wxDisplay(disPos).GetClientArea().GetHeight() * 2 / 3; + } assert(!cfg.textMain.empty() || !cfg.textDetail.empty()); if (!cfg.textMain.empty()) |