Improve Document Map precision

Fix #8294, close #8295
pull/8315/head
Udo Hoffmann 2020-05-20 14:19:10 +02:00 committed by Don HO
parent cf2175e479
commit bb6b24ce50
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
2 changed files with 29 additions and 58 deletions

View File

@ -191,6 +191,7 @@ void DocumentMap::wrapMap(const ScintillaEditView *editView)
_pMapView->execute(SCI_SETWRAPINDENTMODE, pEditView->execute(SCI_GETWRAPINDENTMODE)); _pMapView->execute(SCI_SETWRAPINDENTMODE, pEditView->execute(SCI_GETWRAPINDENTMODE));
} }
doMove();
} }
int DocumentMap::getEditorTextZoneWidth(const ScintillaEditView *editView) int DocumentMap::getEditorTextZoneWidth(const ScintillaEditView *editView)
@ -212,58 +213,32 @@ void DocumentMap::scrollMap()
{ {
if (_pMapView && _ppEditView) if (_pMapView && _ppEditView)
{ {
// Visible document line for the code view (but not displayed line) // Get the position of the 1st and last showing chars from the original edit view
auto firstVisibleDisplayLine = (*_ppEditView)->execute(SCI_GETFIRSTVISIBLELINE); RECT rcEditView;
const auto firstVisibleDocLine = (*_ppEditView)->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine); (*_ppEditView)->getClientRect(rcEditView);
const auto nbLine = (*_ppEditView)->execute(SCI_LINESONSCREEN, firstVisibleDisplayLine); LRESULT higherPos = (*_ppEditView)->execute(SCI_POSITIONFROMPOINT, 0, 0);
const auto lastVisibleDocLine = (*_ppEditView)->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine + nbLine); LRESULT lowerPos = (*_ppEditView)->execute(SCI_POSITIONFROMPOINT, rcEditView.right - rcEditView.left, rcEditView.bottom - rcEditView.top);
// Visible document line for the map view // Let Scintilla scroll the map
auto firstVisibleDisplayLineMap = _pMapView->execute(SCI_GETFIRSTVISIBLELINE); _pMapView->execute(SCI_GOTOPOS, higherPos);
auto firstVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap); _pMapView->execute(SCI_GOTOPOS, lowerPos);
auto nbLineMap = _pMapView->execute(SCI_LINESONSCREEN, firstVisibleDocLineMap);
auto lastVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap + nbLineMap);
// If part of editor view is out of map, then scroll map // Get top position of orange marker window
LRESULT mapLineToScroll = 0; RECT rcMapView;
if (lastVisibleDocLineMap < lastVisibleDocLine) _pMapView->getClientRect(rcMapView);
mapLineToScroll = lastVisibleDocLine; LRESULT higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, higherPos);
else
mapLineToScroll = firstVisibleDocLine;
//
// Scroll to make whole view zone visible
//
_pMapView->execute(SCI_GOTOLINE, mapLineToScroll);
// Get the editor's higher/lower Y, then compute the map's higher/lower Y // Get bottom position of orange marker window
LRESULT higherY = 0;
LRESULT lowerY = 0; LRESULT lowerY = 0;
LRESULT higherPos = -1 ; // -1 => not (*_ppEditView)->isWrap() LRESULT lineHeightMapView = _pMapView->execute(SCI_TEXTHEIGHT, 0);
if (not (*_ppEditView)->isWrap()) if (not (*_ppEditView)->isWrap())
{ { // not wrapped: mimic height of edit view
higherPos = _pMapView->execute(SCI_POSITIONFROMLINE, firstVisibleDocLine); LRESULT lineHeightEditView = (*_ppEditView)->execute(SCI_TEXTHEIGHT, 0);
auto lowerPos = _pMapView->execute(SCI_POSITIONFROMLINE, lastVisibleDocLine); lowerY = higherY + lineHeightMapView * (rcEditView.bottom - rcEditView.top) / lineHeightEditView;
higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, higherPos);
lowerY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, lowerPos);
if (lowerY == 0)
{
auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, firstVisibleDocLine);
lowerY = nbLine * lineHeight + higherY;
}
} }
else else
{ { // wrapped: ask Scintilla, since in the map view the current range of edit view might be wrapped differently
// Get the position of the 1st showing char from the original edit view lowerY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, lowerPos) + lineHeightMapView;
higherPos = (*_ppEditView)->execute(SCI_POSITIONFROMPOINT, 0, 0);
// Get the map higher Y point from the position in map
higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, static_cast<int32_t>(higherPos));
// Get line height
auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, firstVisibleDocLine);
// Get the map lower Y point
lowerY = nbLine * lineHeight + higherY;
} }
// //
@ -326,8 +301,9 @@ void DocumentMap::scrollMapWith(const MapPosition & mapPos)
void DocumentMap::doMove() void DocumentMap::doMove()
{ {
RECT rc; RECT rc;
getClientRect(rc); ::GetClientRect (_hwndScintilla, & rc);
::MoveWindow(_vzDlg.getHSelf(), 0, 0, (rc.right - rc.left), (rc.bottom - rc.top), TRUE); ::MapWindowPoints (_hwndScintilla, _pMapView->getHParent(), reinterpret_cast<POINT*>(& rc), 2);
::MoveWindow(_vzDlg.getHSelf(), rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), TRUE);
} }
void DocumentMap::fold(size_t line, bool foldOrNot) void DocumentMap::fold(size_t line, bool foldOrNot)
@ -362,8 +338,8 @@ INT_PTR CALLBACK DocumentMap::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
{ {
case WM_INITDIALOG : case WM_INITDIALOG :
{ {
HWND hwndScintilla = reinterpret_cast<HWND>(::SendMessage(_hParent, NPPM_CREATESCINTILLAHANDLE, 0, reinterpret_cast<LPARAM>(_hSelf))); _hwndScintilla = reinterpret_cast<HWND>(::SendMessage(_hParent, NPPM_CREATESCINTILLAHANDLE, 0, reinterpret_cast<LPARAM>(_hSelf)));
_pMapView = reinterpret_cast<ScintillaEditView *>(::SendMessage(_hParent, NPPM_INTERNAL_GETSCINTEDTVIEW, 0, reinterpret_cast<LPARAM>(hwndScintilla))); _pMapView = reinterpret_cast<ScintillaEditView *>(::SendMessage(_hParent, NPPM_INTERNAL_GETSCINTEDTVIEW, 0, reinterpret_cast<LPARAM>(_hwndScintilla)));
_pMapView->execute(SCI_SETZOOM, static_cast<WPARAM>(-10), 0); _pMapView->execute(SCI_SETZOOM, static_cast<WPARAM>(-10), 0);
_pMapView->execute(SCI_SETVSCROLLBAR, FALSE, 0); _pMapView->execute(SCI_SETVSCROLLBAR, FALSE, 0);
_pMapView->execute(SCI_SETHSCROLLBAR, FALSE, 0); _pMapView->execute(SCI_SETHSCROLLBAR, FALSE, 0);
@ -399,8 +375,8 @@ INT_PTR CALLBACK DocumentMap::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
{ {
if (!_pMapView->isWrap()) if (!_pMapView->isWrap())
::MoveWindow(_pMapView->getHSelf(), 0, 0, width, height, TRUE); ::MoveWindow(_pMapView->getHSelf(), 0, 0, width, height, TRUE);
::MoveWindow(_vzDlg.getHSelf(), 0, 0, width, height, TRUE); doMove();
} }
} }
break; break;
@ -432,12 +408,7 @@ INT_PTR CALLBACK DocumentMap::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
case DMN_FLOATDROPPED: case DMN_FLOATDROPPED:
{ {
RECT rc; doMove();
getClientRect(rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;
::MoveWindow(_vzDlg.getHSelf(), 0, 0, width, height, TRUE);
scrollMap(); scrollMap();
return TRUE; return TRUE;
} }

View File

@ -144,7 +144,7 @@ private:
ScintillaEditView **_ppEditView = nullptr; ScintillaEditView **_ppEditView = nullptr;
ScintillaEditView *_pMapView = nullptr; ScintillaEditView *_pMapView = nullptr;
ViewZoneDlg _vzDlg; ViewZoneDlg _vzDlg;
HWND _hwndScintilla;
bool _isTemporarilyShowing = false; bool _isTemporarilyShowing = false;
// for needToRecomputeWith function // for needToRecomputeWith function