diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h index ffb3999ba..3d4733d07 100644 --- a/scintilla/include/Platform.h +++ b/scintilla/include/Platform.h @@ -236,38 +236,38 @@ constexpr float componentMaximum = 255.0F; class ColourDesired { unsigned int co; public: - explicit ColourDesired(unsigned int co_ = 0) noexcept : co(co_) {} + constexpr explicit ColourDesired(unsigned int co_ = 0) noexcept : co(co_) {} ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept : co(red | (green << 8) | (blue << 16)) {} - bool operator==(const ColourDesired &other) const noexcept { + constexpr bool operator==(const ColourDesired &other) const noexcept { return co == other.co; } - unsigned int AsInteger() const noexcept { + constexpr unsigned int AsInteger() const noexcept { return co; } // Red, green and blue values as bytes 0..255 - unsigned char GetRed() const noexcept { + constexpr unsigned char GetRed() const noexcept { return co & 0xff; } - unsigned char GetGreen() const noexcept { + constexpr unsigned char GetGreen() const noexcept { return (co >> 8) & 0xff; } - unsigned char GetBlue() const noexcept { + constexpr unsigned char GetBlue() const noexcept { return (co >> 16) & 0xff; } // Red, green and blue values as float 0..1.0 - float GetRedComponent() const noexcept { + constexpr float GetRedComponent() const noexcept { return GetRed() / componentMaximum; } - float GetGreenComponent() const noexcept { + constexpr float GetGreenComponent() const noexcept { return GetGreen() / componentMaximum; } - float GetBlueComponent() const noexcept { + constexpr float GetBlueComponent() const noexcept { return GetBlue() / componentMaximum; } }; @@ -277,7 +277,7 @@ public: */ class ColourAlpha : public ColourDesired { public: - explicit ColourAlpha(unsigned int co_ = 0) noexcept : ColourDesired(co_) {} + constexpr explicit ColourAlpha(unsigned int co_ = 0) noexcept : ColourDesired(co_) {} ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept : ColourDesired(red | (green << 8) | (blue << 16)) {} @@ -287,15 +287,15 @@ public: ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept : ColourDesired(cd.AsInteger() | (alpha << 24)) {} - ColourDesired GetColour() const noexcept { + constexpr ColourDesired GetColour() const noexcept { return ColourDesired(AsInteger() & 0xffffff); } - unsigned char GetAlpha() const noexcept { + constexpr unsigned char GetAlpha() const noexcept { return (AsInteger() >> 24) & 0xff; } - float GetAlphaComponent() const noexcept { + constexpr float GetAlphaComponent() const noexcept { return GetAlpha() / componentMaximum; } diff --git a/scintilla/win32/PlatWin.cxx b/scintilla/win32/PlatWin.cxx index 95211e1ea..fc9b25029 100644 --- a/scintilla/win32/PlatWin.cxx +++ b/scintilla/win32/PlatWin.cxx @@ -538,7 +538,7 @@ public: }; using TextPositions = VarBuffer; -class SurfaceGDI : public Surface { +class SurfaceGDI final : public Surface { bool unicodeMode = false; HDC hdc{}; bool hdcOwned = false; @@ -798,7 +798,7 @@ constexpr byte AlphaScaled(unsigned char component, unsigned int alpha) noexcept return static_cast(component * alpha / 255); } -const inline DWORD dwordMultiplied(ColourDesired colour, unsigned int alpha) noexcept { +constexpr DWORD dwordMultiplied(ColourDesired colour, unsigned int alpha) noexcept { return dwordFromBGRA( AlphaScaled(colour.GetBlue(), alpha), AlphaScaled(colour.GetGreen(), alpha), @@ -1206,7 +1206,7 @@ constexpr D2D1_RECT_F RectangleFromPRectangle(PRectangle rc) noexcept { class BlobInline; -class SurfaceD2D : public Surface { +class SurfaceD2D final : public Surface { bool unicodeMode = false; int x = 0; int y = 0; @@ -1553,25 +1553,27 @@ void SurfaceD2D::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesir void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /* flags*/) { if (pRenderTarget) { + float const left = std::round(rc.left); + float const right = std::round(rc.right); if (cornerSize == 0) { // When corner size is zero, draw square rectangle to prevent blurry pixels at corners - const D2D1_RECT_F rectFill = D2D1::RectF(std::round(rc.left) + 1.0f, rc.top + 1.0f, std::round(rc.right) - 1.0f, rc.bottom - 1.0f); + const D2D1_RECT_F rectFill = D2D1::RectF(left + 1.0f, rc.top + 1.0f, right - 1.0f, rc.bottom - 1.0f); D2DPenColour(fill, alphaFill); pRenderTarget->FillRectangle(rectFill, pBrush); - const D2D1_RECT_F rectOutline = D2D1::RectF(std::round(rc.left) + 0.5f, rc.top + 0.5f, std::round(rc.right) - 0.5f, rc.bottom - 0.5f); + const D2D1_RECT_F rectOutline = D2D1::RectF(left + 0.5f, rc.top + 0.5f, right - 0.5f, rc.bottom - 0.5f); D2DPenColour(outline, alphaOutline); pRenderTarget->DrawRectangle(rectOutline, pBrush); } else { const float cornerSizeF = static_cast(cornerSize); D2D1_ROUNDED_RECT roundedRectFill = { - D2D1::RectF(std::round(rc.left) + 1.0f, rc.top + 1.0f, std::round(rc.right) - 1.0f, rc.bottom - 1.0f), + D2D1::RectF(left + 1.0f, rc.top + 1.0f, right - 1.0f, rc.bottom - 1.0f), cornerSizeF - 1.0f, cornerSizeF - 1.0f }; D2DPenColour(fill, alphaFill); pRenderTarget->FillRoundedRectangle(roundedRectFill, pBrush); D2D1_ROUNDED_RECT roundedRect = { - D2D1::RectF(std::round(rc.left) + 0.5f, rc.top + 0.5f, std::round(rc.right) - 0.5f, rc.bottom - 0.5f), + D2D1::RectF(left + 0.5f, rc.top + 0.5f, right - 0.5f, rc.bottom - 0.5f), cornerSizeF, cornerSizeF }; D2DPenColour(outline, alphaOutline); pRenderTarget->DrawRoundedRectangle(roundedRect, pBrush); @@ -1581,12 +1583,13 @@ void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fil namespace { -inline D2D_COLOR_F ColorFromColourAlpha(ColourAlpha colour) noexcept { - D2D_COLOR_F col; - col.r = colour.GetRedComponent(); - col.g = colour.GetGreenComponent(); - col.b = colour.GetBlueComponent(); - col.a = colour.GetAlphaComponent(); +constexpr D2D_COLOR_F ColorFromColourAlpha(ColourAlpha colour) noexcept { + D2D_COLOR_F col = { + colour.GetRedComponent(), + colour.GetGreenComponent(), + colour.GetBlueComponent(), + colour.GetAlphaComponent() + }; return col; } @@ -1623,8 +1626,9 @@ void SurfaceD2D::GradientRectangle(PRectangle rc, const std::vector if (SUCCEEDED(hr) && pBrushLinear) { const D2D1_RECT_F rectangle = D2D1::RectF(std::round(rc.left), rc.top, std::round(rc.right), rc.bottom); pRenderTarget->FillRectangle(&rectangle, pBrushLinear); + ReleaseUnknown(pBrushLinear); } - ReleaseUnknown(pBrushLinear); + ReleaseUnknown(pGradientStops); } } @@ -2570,7 +2574,7 @@ ListBox::ListBox() noexcept = default; ListBox::~ListBox() = default; -class ListBoxX : public ListBox { +class ListBoxX final : public ListBox { int lineHeight; FontID fontCopy; int technology; @@ -3462,13 +3466,7 @@ LRESULT ListBoxX::WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); if (std::abs(wheelDelta) >= WHEEL_DELTA) { const int nRows = GetVisibleRows(); - int linesToScroll = 1; - if (nRows > 1) { - linesToScroll = nRows - 1; - } - if (linesToScroll > 3) { - linesToScroll = 3; - } + int linesToScroll = std::clamp(nRows - 1, 1, 3); linesToScroll *= (wheelDelta / WHEEL_DELTA); int top = ListBox_GetTopIndex(lb) + linesToScroll; if (top < 0) { diff --git a/scintilla/win32/ScintillaWin.cxx b/scintilla/win32/ScintillaWin.cxx index ef4df9256..b6bdc4663 100644 --- a/scintilla/win32/ScintillaWin.cxx +++ b/scintilla/win32/ScintillaWin.cxx @@ -231,7 +231,7 @@ class ScintillaWin; // Forward declaration for COM interface subobjects /** */ -class FormatEnumerator : public IEnumFORMATETC { +class FormatEnumerator final : public IEnumFORMATETC { ULONG ref; ULONG pos; std::vector formats; @@ -254,7 +254,7 @@ public: /** */ -class DropSource : public IDropSource { +class DropSource final : public IDropSource { public: ScintillaWin *sci = nullptr; DropSource() noexcept = default; @@ -272,7 +272,7 @@ public: /** */ -class DataObject : public IDataObject { +class DataObject final : public IDataObject { public: ScintillaWin *sci = nullptr; DataObject() noexcept = default; @@ -297,7 +297,7 @@ public: /** */ -class DropTarget : public IDropTarget { +class DropTarget final : public IDropTarget { public: ScintillaWin *sci = nullptr; DropTarget() noexcept = default; @@ -434,7 +434,8 @@ class ScintillaWin final : SetCoalescableTimerSig SetCoalescableTimerFn; #endif - unsigned int linesPerScroll; ///< Intellimouse support + UINT linesPerScroll; ///< Intellimouse support + UINT charsPerScroll; ///< Intellimouse support int wheelDelta; ///< Wheel delta from roll DPI_T dpi = { USER_DEFAULT_SCREEN_DPI, USER_DEFAULT_SCREEN_DPI }; @@ -676,6 +677,7 @@ ScintillaWin::ScintillaWin(HWND hwnd) { #endif linesPerScroll = 0; + charsPerScroll = 0; wheelDelta = 0; // Wheel delta from roll dpi = GetWindowDPI(hwnd); @@ -763,8 +765,8 @@ void ScintillaWin::Init() noexcept { void ScintillaWin::Finalise() noexcept { ScintillaBase::Finalise(); - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - FineTickerCancel(tr); + for (int tr = tickCaret; tr <= tickDwell; tr = tr + 1) { + FineTickerCancel(static_cast(tr)); } SetIdle(false); #if defined(USE_D2D) @@ -884,7 +886,7 @@ bool ScintillaWin::DragThreshold(Point ptStart, Point ptNow) noexcept { const XYPOSITION xMove = std::trunc(std::abs(ptDifference.x)); const XYPOSITION yMove = std::trunc(std::abs(ptDifference.y)); return (xMove > SystemMetricsForDpi(SM_CXDRAG, dpi.x)) || - (yMove > SystemMetricsForDpi(SM_CYDRAG, dpi.y)); + (yMove > SystemMetricsForDpi(SM_CYDRAG, dpi.y)); } void ScintillaWin::StartDrag() { @@ -1457,16 +1459,16 @@ unsigned int SciMessageFromEM(unsigned int iMessage) noexcept { case EM_LINEINDEX: return SCI_POSITIONFROMLINE; case EM_LINESCROLL: return SCI_LINESCROLL; case EM_REDO: return SCI_REDO; - case EM_UNDO: return SCI_UNDO; - case EM_SCROLL: return WM_VSCROLL; case EM_REPLACESEL: return SCI_REPLACESEL; + case EM_SCROLL: return WM_VSCROLL; case EM_SCROLLCARET: return SCI_SCROLLCARET; case EM_SETREADONLY: return SCI_SETREADONLY; + case EM_UNDO: return SCI_UNDO; case WM_CLEAR: return SCI_CLEAR; case WM_COPY: return SCI_COPY; case WM_CUT: return SCI_CUT; - case WM_SETTEXT: return SCI_SETTEXT; case WM_PASTE: return SCI_PASTE; + case WM_SETTEXT: return SCI_SETTEXT; case WM_UNDO: return SCI_UNDO; } return iMessage; @@ -1709,21 +1711,40 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l // (A good idea for datazoom would be to "fold" or "unfold" details. // i.e. if datazoomed out only class structures are visible, when datazooming in the control // structures appear, then eventually the individual statements...) - if (wParam & (MK_SHIFT | MK_RBUTTON)) { - // send to client - return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); + //@@@if (wParam & (MK_SHIFT | MK_RBUTTON)) { + if (wParam & MK_SHIFT) { + if (vs.wrapState != WrapMode::none || charsPerScroll == 0) { + return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); + } } // Either SCROLL or ZOOM. We handle the wheel steppings calculation wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); - if (std::abs(wheelDelta) >= WHEEL_DELTA && linesPerScroll > 0) { + if (std::abs(wheelDelta) < WHEEL_DELTA) { + return 0; + } + if (wParam & MK_SHIFT) { + int charsToScroll = charsPerScroll; + if (charsPerScroll == WHEEL_PAGESCROLL) { + const PRectangle rcText = GetTextRectangle(); + const int pageWidth = static_cast(rcText.Width() * 2 / 3); + charsToScroll = pageWidth; + } else { + charsToScroll = 1 + static_cast(std::max(charsToScroll, 1) * vs.aveCharWidth); + } + charsToScroll *= (wheelDelta / WHEEL_DELTA); + if (wheelDelta >= 0) { + wheelDelta = wheelDelta % WHEEL_DELTA; + } else { + wheelDelta = -(-wheelDelta % WHEEL_DELTA); + } + HorizontalScrollTo(xOffset + charsToScroll); + } else if (linesPerScroll > 0) { Sci::Line linesToScroll = linesPerScroll; if (linesPerScroll == WHEEL_PAGESCROLL) { linesToScroll = LinesOnScreen() - 1; } - if (linesToScroll == 0) { - linesToScroll = 1; - } + linesToScroll = std::max(linesToScroll, 1); linesToScroll *= (wheelDelta / WHEEL_DELTA); if (wheelDelta >= 0) { wheelDelta = wheelDelta % WHEEL_DELTA; @@ -1739,10 +1760,8 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l } else { KeyCommand(SCI_ZOOMOUT); } - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - // send to main window too ! + // send to main window too (trigger Zoom CallTip) ! ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< } else { // Scroll ScrollTo(topLine + linesToScroll); @@ -3251,6 +3270,7 @@ LRESULT ScintillaWin::ImeOnReconvert(LPARAM lParam) { void ScintillaWin::GetIntelliMouseParameters() noexcept { // This retrieves the number of lines per scroll as configured in the Mouse Properties sheet in Control Panel ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &linesPerScroll, 0); + ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &charsPerScroll, 0); } void ScintillaWin::CopyToGlobal(GlobalMemory &gmUnicode, const SelectionText &selectedText, CopyEncoding encoding) { @@ -3341,7 +3361,7 @@ void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { } void ScintillaWin::ScrollMessage(WPARAM wParam) { - //DWORD dwStart = timeGetTime(); + //DWORD dwStart = GetTickCount(); //Platform::DebugPrintf("Scroll %x %d\n", wParam, lParam); SCROLLINFO sci = {}; @@ -3752,7 +3772,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, PO NotifyURIDropped(putf.c_str()); } else { FORMATETC fmtr = { cfColumnSelect, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - const bool isRectangular = (S_OK == pIDataSource->QueryGetData(&fmtr)); + const bool isRectangular = S_OK == pIDataSource->QueryGetData(&fmtr); POINT rpt = { pt.x, pt.y }; ::ScreenToClient(MainHWND(), &rpt); @@ -3824,7 +3844,7 @@ bool ScintillaWin::Register(HINSTANCE hInstance_) noexcept { wndclass.lpszClassName = L"Scintilla"; scintillaClassAtom = ::RegisterClassExW(&wndclass); - const bool result = (0 != scintillaClassAtom); + const bool result = 0 != scintillaClassAtom; return result; } @@ -4002,7 +4022,7 @@ namespace Scintilla { } #else extern "C" -sptr_t __stdcall Scintilla_DirectFunction( +sptr_t SCI_METHOD Scintilla_DirectFunction( ScintillaWin* sci, UINT iMessage, uptr_t wParam, sptr_t lParam) { return sci->WndProc(iMessage, wParam, lParam); }