diff --git a/Components/ScintEdit.pas b/Components/ScintEdit.pas index 12fcecebf..5b5246455 100644 --- a/Components/ScintEdit.pas +++ b/Components/ScintEdit.pas @@ -84,6 +84,7 @@ TScintEdit = class(TWinControl) FAcceptDroppedFiles: Boolean; FAutoCompleteFontName: String; FAutoCompleteFontSize: Integer; + FChangeHistory: Boolean; FCodePage: Integer; FDirectPtr: Pointer; FDirectStatusFunction: SciFnDirectStatus; @@ -145,6 +146,7 @@ TScintEdit = class(TWinControl) procedure SetCaretLine(const Value: Integer); procedure SetCaretPosition(const Value: Integer); procedure SetCaretVirtualSpace(const Value: Integer); + procedure SetChangeHistory(const Value: Boolean); procedure SetFillSelectionToEdge(const Value: Boolean); procedure SetIndentationGuides(const Value: TScintIndentationGuides); procedure SetLineNumbers(const Value: Boolean); @@ -176,6 +178,7 @@ TScintEdit = class(TWinControl) procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND; procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; procedure WMMouseWheel(var Message: TMessage); message WM_MOUSEWHEEL; + procedure UpdateChangeHistoryWidth; protected procedure Change(const AInserting: Boolean; const AStartPos, ALength, ALinesDelta: Integer); virtual; @@ -190,6 +193,7 @@ TScintEdit = class(TWinControl) procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Notify(const N: TSCNotification); virtual; procedure SetTarget(const StartPos, EndPos: Integer); + function ToCurrentPPI(const XY: Integer): Integer; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -205,7 +209,7 @@ TScintEdit = class(TWinControl) procedure ClearAll; procedure ClearIndicators(const IndicatorNumber: TScintIndicatorNumber); procedure ClearSelection; - procedure ClearUndo; + procedure ClearUndo(const ClearChangeHistory: Boolean = True); function ConvertRawStringToString(const S: TScintRawString): String; function ConvertPCharToRawString(const Text: PChar; const TextLen: Integer): TScintRawString; @@ -322,6 +326,7 @@ TScintEdit = class(TWinControl) write SetAutoCompleteFontName; property AutoCompleteFontSize: Integer read FAutoCompleteFontSize write SetAutoCompleteFontSize default 0; + property ChangeHistory: Boolean read FChangeHistory write SetChangeHistory; property CodePage: Integer read FCodePage write SetCodePage default CP_UTF8; property Color; property FillSelectionToEdge: Boolean read FFillSelectionToEdge write SetFillSelectionToEdge @@ -621,13 +626,18 @@ procedure TScintEdit.ClearSelection; Call(SCI_CLEAR, 0, 0); end; -procedure TScintEdit.ClearUndo; +procedure TScintEdit.ClearUndo(const ClearChangeHistory: Boolean); begin { SCI_EMPTYUNDOBUFFER resets the save point but doesn't send a SCN_SAVEPOINTREACHED notification. Call SetSavePoint manually to get that. SetSavePoint additionally resets FForceModified. } SetSavePoint; Call(SCI_EMPTYUNDOBUFFER, 0, 0); + + if ClearChangeHistory and FChangeHistory then begin + Call(SCI_SETCHANGEHISTORY, SC_CHANGE_HISTORY_DISABLED, 0); + Call(SCI_SETCHANGEHISTORY, SC_CHANGE_HISTORY_ENABLED or SC_CHANGE_HISTORY_MARKERS, 0); + end; end; function TScintEdit.ConvertRawStringToString(const S: TScintRawString): String; @@ -1384,6 +1394,18 @@ procedure TScintEdit.SetCaretVirtualSpace(const Value: Integer); end; end; +procedure TScintEdit.SetChangeHistory(const Value: Boolean); +begin + if FChangeHistory <> Value then begin + FChangeHistory := Value; + UpdateChangeHistoryWidth; + { If change history is True then next call to ClearUndo will enable it and + else we should disable it now } + if not FChangeHistory then + Call(SCI_SETCHANGEHISTORY, SC_CHANGE_HISTORY_DISABLED, 0); + end; +end; + procedure TScintEdit.SetCodePage(const Value: Integer); begin if FCodePage <> Value then begin @@ -1784,11 +1806,28 @@ procedure TScintEdit.StyleNeeded(const EndPos: Integer); end; end; +function TScintEdit.ToCurrentPPI(const XY: Integer): Integer; +begin + Result := MulDiv(XY, CurrentPPI, 96); +end; + procedure TScintEdit.Undo; begin Call(SCI_UNDO, 0, 0); end; +procedure TScintEdit.UpdateChangeHistoryWidth; +begin + var PixelWidth: Integer; + if ChangeHistory then begin + { 6 = 2 pixel bar with 2 pixel margin on both sides because: "SC_MARK_BAR ... + takes ... 1/3 of the margin width" } + PixelWidth := ToCurrentPPI(6) + end else + PixelWidth := 0; + Call(SCI_SETMARGINWIDTHN, 2, PixelWidth); +end; + procedure TScintEdit.UpdateCodePage; procedure InitLeadBytes; diff --git a/Projects/Src/CompForm.pas b/Projects/Src/CompForm.pas index c080d4d1a..e3e147243 100644 --- a/Projects/Src/CompForm.pas +++ b/Projects/Src/CompForm.pas @@ -697,6 +697,7 @@ function TCompileForm.InitializeMemoBase(const Memo: TCompScintEdit; const Popup function TCompileForm.InitializeFileMemo(const Memo: TCompScintFileEdit; const PopupMenu: TPopupMenu): TCompScintFileEdit; begin InitializeMemoBase(Memo, PopupMenu); + Memo.ChangeHistory := True; Memo.CompilerFileIndex := UnknownCompilerFileIndex; Memo.ErrorLine := -1; Memo.StepLine := -1; @@ -1500,7 +1501,7 @@ function TCompileForm.SaveFile(const AMemo: TCompScintFileEdit; const SaveAs: Bo SaveMemoTo(AMemo.Filename); AMemo.SetSavePoint; if not FOptions.UndoAfterSave then - AMemo.ClearUndo; + AMemo.ClearUndo(False); Result := True; if AMemo = FMainMemo then begin ModifyMRUMainFilesList(AMemo.Filename, True); @@ -3444,7 +3445,7 @@ procedure TCompileForm.UpdateMemoMarkerColumns; end; begin - var Width := ToCurrentPPI(20); + var Width := ToCurrentPPI(18); { 3 pixel margin on both sides of the icon } for var Memo in FMemos do Memo.UpdateIconMarkersColumnWidth(Width); diff --git a/Projects/Src/CompScintEdit.pas b/Projects/Src/CompScintEdit.pas index 3f2f857fa..28669b1de 100644 --- a/Projects/Src/CompScintEdit.pas +++ b/Projects/Src/CompScintEdit.pas @@ -21,6 +21,8 @@ interface mmIconBreakpoint = 2; { stop sign } mmIconBreakpointGood = 3; { stop sign + check } mmIconBreakpointBad = 4; { stop sign + X } + mmIconsMask = $1F; + mmLineError = 10; { maroon line highlight } mmLineBreakpointBad = 11; { ugly olive line highlight } mmLineStep = 12; { blue line highlight } @@ -155,6 +157,9 @@ procedure TCompScintEdit.CreateWnd; Scintilla as this allows Scintilla to respond to changes to mouse settings, monitor resolution, colour scheme and similar system properties." + There's also some of our own stuff that doesn't update on DPI + changes, at least the SCI_SETMARGINLEFT call and the width of the + change history column. -5.0.1: Review using SCI_INDICSETSTROKEWIDTH for high DPI support on INDIC_SQUIGGLE. -5.2.3: "Applications should move to SCI_GETTEXTRANGEFULL, SCI_FINDTEXTFULL, @@ -165,9 +170,7 @@ procedure TCompScintEdit.CreateWnd; NativeInt'. Does not actually change anything until there's a 64-bit build... Later SCI_GETSTYLEDTEXTFULL was also added but we don't use it at - the time of writing. - -5.3.0: Add change history: "Added change history which can display document - changes (modified, saved, ...) in the margin or in the text. " } + the time of writing. } Call(SCI_SETCARETWIDTH, 2, 0); Call(SCI_AUTOCSETAUTOHIDE, 0, 0); @@ -206,17 +209,25 @@ procedure TCompScintEdit.CreateWnd; { Set up the gutter column with line numbers - avoid Scintilla's 'reverse arrow' cursor which is not a standard Windows cursor so is just confusing, especially because the line numbers are clickable to select lines. Note: width of the - column is set up by TScintEdit.UpdateLineNumbersWidth. } + column is set up for us by TScintEdit.UpdateLineNumbersWidth. } Call(SCI_SETMARGINCURSORN, 0, SC_CURSORARROW); { Set up the gutter column with breakpoint etc symbols } Call(SCI_SETMARGINTYPEN, 1, SC_MARGIN_SYMBOL); + Call(SCI_SETMARGINMASKN, 1, mmIconsMask); Call(SCI_SETMARGINSENSITIVEN, 1, 1); { Makes it send SCN_MARGIN(RIGHT)CLICK instead of selecting lines } Call(SCI_SETMARGINCURSORN, 1, SC_CURSORARROW); + { Set up the gutter column with change history. Note: width of the column is + set up for us by TScintEdit.UpdateChangeHistoryWidth. Also see + https://scintilla.org/ChangeHistory.html } + Call(SCI_SETMARGINTYPEN, 2, SC_MARGIN_SYMBOL); + Call(SCI_SETMARGINMASKN, 2, not (SC_MASK_FOLDERS or mmIconsMask)); + Call(SCI_SETMARGINCURSORN, 2, SC_CURSORARROW); + { Set 2 pixel margin between gutter and the main text - note: the first parameter is unused so the value '0' doesn't mean anything below } - Call(SCI_SETMARGINLEFT, 0, 2); + Call(SCI_SETMARGINLEFT, 0, ToCurrentPPI(2)); Call(SCI_MARKERDEFINE, mmLineError, SC_MARK_BACKFORE); Call(SCI_MARKERSETFORE, mmLineError, clWhite); @@ -284,6 +295,14 @@ procedure TCompScintEdit.UpdateThemeColorsAndStyleAttributes; Call(SCI_INDICSETFORE, inWordAtCursorOccurrence, FTheme.Colors[tcWordAtCursorOccurrenceBack]); Call(SCI_INDICSETFORE, inSelTextOccurrence, FTheme.Colors[tcSelTextOccurrenceBack]); Call(SCI_MARKERSETBACK, mmLineStep, FTheme.Colors[tcBlue]); + Call(SCI_MARKERSETFORE, SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN, FTheme.Colors[tcBlue]); { To reproduce: open a file, press enter, save, undo } + Call(SCI_MARKERSETBACK, SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN, FTheme.Colors[tcBlue]); + Call(SCI_MARKERSETFORE, SC_MARKNUM_HISTORY_SAVED, FTheme.Colors[tcGreen]); + Call(SCI_MARKERSETBACK, SC_MARKNUM_HISTORY_SAVED, FTheme.Colors[tcGreen]); + Call(SCI_MARKERSETFORE, SC_MARKNUM_HISTORY_MODIFIED, FTheme.Colors[tcOrange]); + Call(SCI_MARKERSETBACK, SC_MARKNUM_HISTORY_MODIFIED, FTheme.Colors[tcOrange]); + Call(SCI_MARKERSETFORE, SC_MARKNUM_HISTORY_REVERTED_TO_MODIFIED, FTheme.Colors[tcTeal]); { To reproduce: ??? - sometimes get it but not sure how to do this with minimal steps } + Call(SCI_MARKERSETBACK, SC_MARKNUM_HISTORY_REVERTED_TO_MODIFIED, FTheme.Colors[tcTeal]); end; UpdateStyleAttributes; end; diff --git a/whatsnew.htm b/whatsnew.htm index 760a96ff4..5f68b86a8 100644 --- a/whatsnew.htm +++ b/whatsnew.htm @@ -45,6 +45,7 @@
Other changes: