TextView.WordWrap.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using System.Runtime.CompilerServices;
  2. namespace Terminal.Gui.Views;
  3. /// <summary>Word wrap functionality</summary>
  4. public partial class TextView
  5. {
  6. /// <summary>Invoke the <see cref="UnwrappedCursorPosition"/> event with the unwrapped <see cref="CursorPosition"/>.</summary>
  7. public virtual void OnUnwrappedCursorPosition (int? cRow = null, int? cCol = null)
  8. {
  9. int? row = cRow ?? CurrentRow;
  10. int? col = cCol ?? CurrentColumn;
  11. if (cRow is null && cCol is null && _wordWrap)
  12. {
  13. row = _wrapManager!.GetModelLineFromWrappedLines (CurrentRow);
  14. col = _wrapManager.GetModelColFromWrappedLines (CurrentRow, CurrentColumn);
  15. }
  16. UnwrappedCursorPosition?.Invoke (this, new (col.Value, row.Value));
  17. }
  18. /// <summary>Invoked with the unwrapped <see cref="CursorPosition"/>.</summary>
  19. public event EventHandler<Point>? UnwrappedCursorPosition;
  20. private (int Row, int Col) GetUnwrappedPosition (int line, int col)
  21. {
  22. if (WordWrap)
  23. {
  24. return new ValueTuple<int, int> (
  25. _wrapManager!.GetModelLineFromWrappedLines (line),
  26. _wrapManager.GetModelColFromWrappedLines (line, col)
  27. );
  28. }
  29. return new ValueTuple<int, int> (line, col);
  30. }
  31. /// <summary>Restore from original model.</summary>
  32. private void SetWrapModel ([CallerMemberName] string? caller = null)
  33. {
  34. if (_currentCaller is { })
  35. {
  36. return;
  37. }
  38. if (_wordWrap)
  39. {
  40. _currentCaller = caller;
  41. CurrentColumn = _wrapManager!.GetModelColFromWrappedLines (CurrentRow, CurrentColumn);
  42. CurrentRow = _wrapManager.GetModelLineFromWrappedLines (CurrentRow);
  43. _selectionStartColumn =
  44. _wrapManager.GetModelColFromWrappedLines (_selectionStartRow, _selectionStartColumn);
  45. _selectionStartRow = _wrapManager.GetModelLineFromWrappedLines (_selectionStartRow);
  46. _model = _wrapManager.Model;
  47. }
  48. }
  49. /// <summary>Update the original model.</summary>
  50. private void UpdateWrapModel ([CallerMemberName] string? caller = null)
  51. {
  52. if (_currentCaller is { } && _currentCaller != caller)
  53. {
  54. return;
  55. }
  56. if (_wordWrap)
  57. {
  58. _currentCaller = null;
  59. _wrapManager!.UpdateModel (
  60. _model,
  61. out int nRow,
  62. out int nCol,
  63. out int nStartRow,
  64. out int nStartCol,
  65. CurrentRow,
  66. CurrentColumn,
  67. _selectionStartRow,
  68. _selectionStartColumn,
  69. true
  70. );
  71. CurrentRow = nRow;
  72. CurrentColumn = nCol;
  73. _selectionStartRow = nStartRow;
  74. _selectionStartColumn = nStartCol;
  75. _wrapNeeded = true;
  76. SetNeedsDraw ();
  77. }
  78. if (_currentCaller is { })
  79. {
  80. throw new InvalidOperationException (
  81. $"WordWrap settings was changed after the {_currentCaller} call."
  82. );
  83. }
  84. }
  85. private void WrapTextModel ()
  86. {
  87. if (_wordWrap && _wrapManager is { })
  88. {
  89. _model = _wrapManager.WrapModel (
  90. Math.Max (Viewport.Width - (ReadOnly ? 0 : 1), 0), // For the cursor on the last column of a line
  91. out int nRow,
  92. out int nCol,
  93. out int nStartRow,
  94. out int nStartCol,
  95. CurrentRow,
  96. CurrentColumn,
  97. _selectionStartRow,
  98. _selectionStartColumn,
  99. _tabWidth
  100. );
  101. CurrentRow = nRow;
  102. CurrentColumn = nCol;
  103. _selectionStartRow = nStartRow;
  104. _selectionStartColumn = nStartCol;
  105. SetNeedsDraw ();
  106. }
  107. }
  108. }