summaryrefslogtreecommitdiff
path: root/wx+
diff options
context:
space:
mode:
Diffstat (limited to 'wx+')
-rw-r--r--wx+/dc.h2
-rw-r--r--wx+/graph.cpp14
-rw-r--r--wx+/grid.cpp28
-rw-r--r--wx+/grid.h1
-rw-r--r--wx+/image_resources.cpp16
-rw-r--r--wx+/no_flicker.h10
-rw-r--r--wx+/popup_dlg.cpp1
-rw-r--r--wx+/rtl.h24
8 files changed, 57 insertions, 39 deletions
diff --git a/wx+/dc.h b/wx+/dc.h
index e22820a7..48d0fe72 100644
--- a/wx+/dc.h
+++ b/wx+/dc.h
@@ -136,7 +136,7 @@ wxBitmap toScaledBitmap(const wxImage& img /*expected to be DPI-scaled!*/)
//all this shit just because wxDC::SetScaleFactor() is missing:
-inline
+inline
void setScaleFactor(wxDC& dc, double scale)
{
struct wxDcSurgeon : public wxDCImpl
diff --git a/wx+/graph.cpp b/wx+/graph.cpp
index eb9256f4..f9094386 100644
--- a/wx+/graph.cpp
+++ b/wx+/graph.cpp
@@ -232,7 +232,7 @@ void drawCornerText(wxDC& dc, const wxRect& graphArea, const wxString& txt, Grap
//calculate intersection of polygon with half-plane
template <class Function, class Function2>
-void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarker, Function isInside, Function2 getIntersection, bool doPolygonCut)
+void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<unsigned char>& oobMarker, Function isInside, Function2 getIntersection, bool doPolygonCut)
{
assert(curvePoints.size() == oobMarker.size());
@@ -240,8 +240,8 @@ void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarke
auto isMarkedOob = [&](size_t index) { return oobMarker[index] != 0; }; //test if point is start of an OOB line
- std::vector<CurvePoint> curvePointsTmp;
- std::vector<char> oobMarkerTmp;
+ std::vector<CurvePoint> curvePointsTmp;
+ std::vector<unsigned char> oobMarkerTmp;
curvePointsTmp.reserve(curvePoints.size()); //allocating memory for these containers is one
oobMarkerTmp .reserve(oobMarker .size()); //of the more expensive operations of Graph2D!
@@ -308,13 +308,13 @@ private:
const double y_;
};
-void cutPointsOutsideX(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarker, double minX, double maxX, bool doPolygonCut)
+void cutPointsOutsideX(std::vector<CurvePoint>& curvePoints, std::vector<unsigned char>& oobMarker, double minX, double maxX, bool doPolygonCut)
{
cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.x >= minX; }, GetIntersectionX(minX), doPolygonCut);
cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.x <= maxX; }, GetIntersectionX(maxX), doPolygonCut);
}
-void cutPointsOutsideY(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarker, double minY, double maxY, bool doPolygonCut)
+void cutPointsOutsideY(std::vector<CurvePoint>& curvePoints, std::vector<unsigned char>& oobMarker, double minY, double maxY, bool doPolygonCut)
{
cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.y >= minY; }, GetIntersectionY(minY), doPolygonCut);
cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.y <= maxY; }, GetIntersectionY(maxY), doPolygonCut);
@@ -615,8 +615,8 @@ void Graph2D::render(wxDC& dc) const
double minY = attr_.minY ? *attr_.minY : std::numeric_limits<double>::infinity(); //automatic: ensure values are initialized by first curve
double maxY = attr_.maxY ? *attr_.maxY : -std::numeric_limits<double>::infinity(); //
- std::vector<std::vector<CurvePoint>> curvePoints(curves_.size());
- std::vector<std::vector<char>> oobMarker (curves_.size()); //effectively a std::vector<bool> marking points that start an out-of-bounds line
+ std::vector<std::vector<CurvePoint>> curvePoints(curves_.size());
+ std::vector<std::vector<unsigned char>> oobMarker (curves_.size()); //effectively a std::vector<bool> marking points that start an out-of-bounds line
for (size_t index = 0; index < curves_.size(); ++index)
{
diff --git a/wx+/grid.cpp b/wx+/grid.cpp
index a32de84e..5d2adc1a 100644
--- a/wx+/grid.cpp
+++ b/wx+/grid.cpp
@@ -164,7 +164,7 @@ void GridData::drawCellText(wxDC& dc, const wxRect& rect, const std::wstring& te
if (extentTrunc.GetWidth() > rect.width)
{
- //unlike Windows Explorer, we truncate UTF-16 correctly: e.g. CJK-Ideogramm encodes to TWO wchar_t: utfTo<std::wstring>("\xf0\xa4\xbd\x9c");
+ //unlike Windows Explorer, we truncate UTF-16 correctly: e.g. CJK-Ideograph encodes to TWO wchar_t: utfTo<std::wstring>("\xf0\xa4\xbd\x9c");
size_t low = 0; //number of unicode chars!
size_t high = unicodeLength(text); //
if (high > 1)
@@ -285,7 +285,7 @@ public:
Bind(wxEVT_MOUSE_CAPTURE_LOST, [this](wxMouseCaptureLostEvent& event) { onMouseCaptureLost(event); });
Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent& event) { onKeyDown(event); });
- Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { onKeyUp (event); });
+ //Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { onKeyUp (event); }); -> superfluous?
assert(GetClientAreaOrigin() == wxPoint()); //generally assumed when dealing with coordinates below
}
@@ -340,12 +340,6 @@ private:
event.Skip();
}
- void onKeyUp(wxKeyEvent& event)
- {
- if (!sendEventToParent(event)) //let parent collect all key events
- event.Skip();
- }
-
void onMouseWheel(wxMouseEvent& event)
{
/* MSDN, WM_MOUSEWHEEL: "Sent to the focus window when the mouse wheel is rotated.
@@ -969,6 +963,17 @@ public:
colLabelWin_(colLabelWin)
{
Bind(EVENT_GRID_HAS_SCROLLED, [this](wxCommandEvent& event) { onRequestWindowUpdate(event); });
+
+ Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent& event)
+ {
+ if (event.GetKeyCode() == WXK_ESCAPE && activeSelection_) //allow Escape key to cancel active selection!
+ {
+ wxMouseCaptureLostEvent evt;
+ GetEventHandler()->ProcessEvent(evt); //better integrate into event handling rather than calling onMouseCaptureLost() directly!?
+ }
+ else
+ event.Skip();
+ });
}
~MainWin() { assert(!gridUpdatePending_); }
@@ -1099,6 +1104,13 @@ private:
void onMouseDown(wxMouseEvent& event) //handle left and right mouse button clicks (almost) the same
{
+ if (activeSelection_) //allow other mouse button to cancel active selection!
+ {
+ wxMouseCaptureLostEvent evt;
+ GetEventHandler()->ProcessEvent(evt);
+ return;
+ }
+
if (auto prov = refParent().getDataProvider())
{
evalMouseMovement(event.GetPosition()); //update highlight in obscure cases (e.g. right-click while other context menu is open)
diff --git a/wx+/grid.h b/wx+/grid.h
index 867abf35..3b3e76b7 100644
--- a/wx+/grid.h
+++ b/wx+/grid.h
@@ -10,7 +10,6 @@
#include <memory>
#include <numeric>
#include <optional>
-//#include <set>
#include <vector>
#include <zen/stl_tools.h>
#include <wx/scrolwin.h>
diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp
index 36055f3f..58ae4d25 100644
--- a/wx+/image_resources.cpp
+++ b/wx+/image_resources.cpp
@@ -70,7 +70,7 @@ ImageHolder xbrzScale(int width, int height, const unsigned char* imageRgb, cons
}
-auto getScalerTask(const std::string& imageName, const wxImage& img, int hqScale, Protected<std::vector<std::pair<std::string, ImageHolder>>>& result)
+auto createScalerTask(const std::string& imageName, const wxImage& img, int hqScale, Protected<std::vector<std::pair<std::string, ImageHolder>>>& result)
{
assert(runningOnMainThread());
return [imageName,
@@ -97,7 +97,7 @@ public:
{
assert(runningOnMainThread());
imgKeeper_.push_back(img); //retain (ref-counted) wxImage so that the rgb/alpha pointers remain valid after passed to threads
- threadGroup_->run(getScalerTask(imageName, img, hqScale_, result_));
+ threadGroup_->run(createScalerTask(imageName, img, hqScale_, result_));
}
std::unordered_map<std::string, wxImage> waitAndGetResult()
@@ -125,7 +125,7 @@ private:
std::vector<wxImage> imgKeeper_;
Protected<std::vector<std::pair<std::string, ImageHolder>>> result_;
- using TaskType = FunctionReturnTypeT<decltype(&getScalerTask)>;
+ using TaskType = FunctionReturnTypeT<decltype(&createScalerTask)>;
std::optional<ThreadGroup<TaskType>> threadGroup_{ThreadGroup<TaskType>(std::max<int>(std::thread::hardware_concurrency(), 1), Zstr("xBRZ Scaler"))};
//hardware_concurrency() == 0 if "not computable or well defined"
};
@@ -192,11 +192,13 @@ ImageBuffer::ImageBuffer(const Zstring& zipPath) //throw FileError
else
assert(false);
}
- catch (FileError&) //fall back to folder
+ catch (FileError&) //fall back to folder: dev build (only!?)
{
const Zstring fallbackFolder = beforeLast(zipPath, Zstr(".zip"), IfNotFoundReturn::none);
- if (dirAvailable(fallbackFolder)) //Debug build (only!?)
- traverseFolder(fallbackFolder, [&](const FileInfo& fi)
+ if (!itemStillExists(fallbackFolder)) //throw FileError
+ throw;
+
+ traverseFolder(fallbackFolder, [&](const FileInfo& fi)
{
if (endsWith(fi.fullPath, Zstr(".png")))
{
@@ -204,8 +206,6 @@ ImageBuffer::ImageBuffer(const Zstring& zipPath) //throw FileError
streams.emplace_back(fi.itemName, std::move(stream));
}
}, nullptr, nullptr, [](const std::wstring& errorMsg) { throw FileError(errorMsg); });
- else
- throw;
}
//--------------------------------------------------------------------
diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h
index d8f2d6cd..7fa4ae23 100644
--- a/wx+/no_flicker.h
+++ b/wx+/no_flicker.h
@@ -85,20 +85,26 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText)
urlStyle.SetTextColour(*wxBLUE);
urlStyle.SetFontUnderlined(true);
- for (const auto& [type, text] : blocks)
+ for (auto& [type, text] : blocks)
switch (type)
{
case BlockType::text:
+ if (endsWith(text, L"\n\n")) //bug: multiple newlines before a URL are condensed to only one;
+ //Why? fuck knows why! no such issue with double newlines *after* URL => hack this shit
+ text.RemoveLast().Append(ZERO_WIDTH_SPACE).Append(L'\n');
+
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;
+ }
+ break;
}
if (std::any_of(blocks.begin(), blocks.end(), [](const auto& item) { return item.first == BlockType::url; }))
diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp
index 0a4c75c0..dfa5494f 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 "app_main.h"
#include "bitmap_button.h"
#include "no_flicker.h"
#include "font_size.h"
diff --git a/wx+/rtl.h b/wx+/rtl.h
index 42af52e1..80a75671 100644
--- a/wx+/rtl.h
+++ b/wx+/rtl.h
@@ -66,22 +66,22 @@ void drawBitmapRtlMirror(wxDC& dc, const wxImage& img, const wxRect& rect, int a
case wxLayout_RightToLeft:
if (rect.GetWidth() > 0 && rect.GetHeight() > 0)
- {
- if (!buffer || buffer->GetSize() != rect.GetSize()) //[!] since we do a mirror, width needs to match exactly!
- buffer.emplace(rect.GetSize());
+ {
+ if (!buffer || buffer->GetSize() != rect.GetSize()) //[!] since we do a mirror, width needs to match exactly!
+ buffer.emplace(rect.GetSize());
- if (buffer->GetScaleFactor() != dc.GetContentScaleFactor()) //needed here?
- buffer->SetScaleFactor(dc.GetContentScaleFactor()); //
+ if (buffer->GetScaleFactor() != dc.GetContentScaleFactor()) //needed here?
+ buffer->SetScaleFactor(dc.GetContentScaleFactor()); //
- wxMemoryDC memDc(*buffer); //copies scale factor from wxBitmap
- memDc.Blit(wxPoint(0, 0), rect.GetSize(), &dc, rect.GetTopLeft()); //blit in: background is mirrored due to memDc, dc having different layout direction!
+ wxMemoryDC memDc(*buffer); //copies scale factor from wxBitmap
+ 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! 2022-04-04: maybe fixed in wxWidgets 3.1.6?
+ 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! 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
- }
- break;
+ dc.Blit(rect.GetTopLeft(), rect.GetSize(), &memDc, wxPoint(0, 0)); //blit out: mirror once again
+ }
+ break;
case wxLayout_Default: //CAVEAT: wxPaintDC/wxMemoryDC on wxGTK/wxMAC does not implement SetLayoutDirection()!!! => GetLayoutDirection() == wxLayout_Default
if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft)
bgstack15