|
1 | 1 | using System.Collections.Generic; |
2 | | -using Avalonia.Collections; |
3 | 2 | using CommunityToolkit.Mvvm.ComponentModel; |
4 | 3 |
|
5 | 4 | namespace SourceGit.ViewModels |
6 | 5 | { |
7 | 6 | public class BlockNavigation : ObservableObject |
8 | 7 | { |
9 | | - public class Block |
| 8 | + public record Block(int Start, int End) |
10 | 9 | { |
11 | | - public int Start { get; set; } = 0; |
12 | | - public int End { get; set; } = 0; |
13 | | - |
14 | | - public Block(int start, int end) |
15 | | - { |
16 | | - Start = start; |
17 | | - End = end; |
18 | | - } |
19 | | - |
20 | 10 | public bool IsInRange(int line) |
21 | 11 | { |
22 | 12 | return line >= Start && line <= End; |
23 | 13 | } |
24 | 14 | } |
25 | 15 |
|
26 | | - public AvaloniaList<Block> Blocks |
27 | | - { |
28 | | - get; |
29 | | - } = []; |
30 | | - |
31 | | - public int Current |
32 | | - { |
33 | | - get => _current; |
34 | | - private set => SetProperty(ref _current, value); |
35 | | - } |
36 | | - |
37 | 16 | public string Indicator |
38 | 17 | { |
39 | 18 | get |
40 | 19 | { |
41 | | - if (Blocks.Count == 0) |
| 20 | + if (_blocks.Count == 0) |
42 | 21 | return "-/-"; |
43 | 22 |
|
44 | | - if (_current >= 0 && _current < Blocks.Count) |
45 | | - return $"{_current + 1}/{Blocks.Count}"; |
| 23 | + if (_current >= 0 && _current < _blocks.Count) |
| 24 | + return $"{_current + 1}/{_blocks.Count}"; |
46 | 25 |
|
47 | | - return $"-/{Blocks.Count}"; |
| 26 | + return $"-/{_blocks.Count}"; |
48 | 27 | } |
49 | 28 | } |
50 | 29 |
|
51 | 30 | public BlockNavigation(List<Models.TextDiffLine> lines) |
52 | 31 | { |
53 | | - Blocks.Clear(); |
54 | | - Current = -1; |
| 32 | + _blocks.Clear(); |
| 33 | + _current = -1; |
55 | 34 |
|
56 | 35 | if (lines.Count == 0) |
57 | 36 | return; |
@@ -85,90 +64,89 @@ public BlockNavigation(List<Models.TextDiffLine> lines) |
85 | 64 | if (!isNewBlock) |
86 | 65 | blocks.Add(new Block(blockStartIdx, lines.Count - 1)); |
87 | 66 |
|
88 | | - Blocks.AddRange(blocks); |
| 67 | + _blocks.AddRange(blocks); |
89 | 68 | } |
90 | 69 |
|
91 | 70 | public Block GetCurrentBlock() |
92 | 71 | { |
93 | | - if (_current >= 0 && _current < Blocks.Count) |
94 | | - return Blocks[_current]; |
| 72 | + if (_current >= 0 && _current < _blocks.Count) |
| 73 | + return _blocks[_current]; |
95 | 74 |
|
96 | 75 | return null; |
97 | 76 | } |
98 | 77 |
|
99 | 78 | public Block GotoFirst() |
100 | 79 | { |
101 | | - if (Blocks.Count == 0) |
| 80 | + if (_blocks.Count == 0) |
102 | 81 | return null; |
103 | 82 |
|
104 | | - Current = 0; |
| 83 | + _current = 0; |
105 | 84 | OnPropertyChanged(nameof(Indicator)); |
106 | | - return Blocks[_current]; |
| 85 | + return _blocks[_current]; |
107 | 86 | } |
108 | 87 |
|
109 | 88 | public Block GotoPrev() |
110 | 89 | { |
111 | | - if (Blocks.Count == 0) |
| 90 | + if (_blocks.Count == 0) |
112 | 91 | return null; |
113 | 92 |
|
114 | 93 | if (_current == -1) |
115 | | - Current = 0; |
| 94 | + _current = 0; |
116 | 95 | else if (_current > 0) |
117 | | - Current = _current - 1; |
| 96 | + _current--; |
118 | 97 |
|
119 | 98 | OnPropertyChanged(nameof(Indicator)); |
120 | | - return Blocks[_current]; |
| 99 | + return _blocks[_current]; |
121 | 100 | } |
122 | 101 |
|
123 | 102 | public Block GotoNext() |
124 | 103 | { |
125 | | - if (Blocks.Count == 0) |
| 104 | + if (_blocks.Count == 0) |
126 | 105 | return null; |
127 | 106 |
|
128 | | - if (_current < Blocks.Count - 1) |
129 | | - Current = _current + 1; |
| 107 | + if (_current < _blocks.Count - 1) |
| 108 | + _current++; |
130 | 109 |
|
131 | 110 | OnPropertyChanged(nameof(Indicator)); |
132 | | - return Blocks[_current]; |
| 111 | + return _blocks[_current]; |
133 | 112 | } |
134 | 113 |
|
135 | 114 | public Block GotoLast() |
136 | 115 | { |
137 | | - if (Blocks.Count == 0) |
| 116 | + if (_blocks.Count == 0) |
138 | 117 | return null; |
139 | 118 |
|
140 | | - Current = Blocks.Count - 1; |
| 119 | + _current = _blocks.Count - 1; |
141 | 120 | OnPropertyChanged(nameof(Indicator)); |
142 | | - return Blocks[_current]; |
| 121 | + return _blocks[_current]; |
143 | 122 | } |
144 | 123 |
|
145 | | - public bool AutoUpdate(int start, int end) |
| 124 | + public void UpdateByCaretPosition(int caretLine) |
146 | 125 | { |
147 | | - if (_current >= 0 && _current < Blocks.Count) |
| 126 | + if (_current >= 0 && _current < _blocks.Count) |
148 | 127 | { |
149 | | - var block = Blocks[_current]; |
150 | | - if ((block.Start >= start && block.Start <= end) || |
151 | | - (block.End >= start && block.End <= end) || |
152 | | - (block.Start <= start && block.End >= end)) |
153 | | - return false; |
| 128 | + var block = _blocks[_current]; |
| 129 | + if (block.IsInRange(caretLine)) |
| 130 | + return; |
154 | 131 | } |
155 | 132 |
|
156 | | - for (var i = 0; i < Blocks.Count; i++) |
| 133 | + for (var i = 0; i < _blocks.Count; i++) |
157 | 134 | { |
158 | | - var block = Blocks[i]; |
159 | | - if ((block.Start >= start && block.Start <= end) || |
160 | | - (block.End >= start && block.End <= end) || |
161 | | - (block.Start <= start && block.End >= end)) |
162 | | - { |
163 | | - Current = i; |
164 | | - OnPropertyChanged(nameof(Indicator)); |
165 | | - return true; |
166 | | - } |
167 | | - } |
| 135 | + var block = _blocks[i]; |
| 136 | + if (block.End < caretLine) |
| 137 | + continue; |
168 | 138 |
|
169 | | - return false; |
| 139 | + if (block.Start > caretLine) |
| 140 | + _current = i - 1; |
| 141 | + else |
| 142 | + _current = i; |
| 143 | + |
| 144 | + OnPropertyChanged(nameof(Indicator)); |
| 145 | + break; |
| 146 | + } |
170 | 147 | } |
171 | 148 |
|
172 | | - private int _current = -1; |
| 149 | + private int _current; |
| 150 | + private List<Block> _blocks = []; |
173 | 151 | } |
174 | 152 | } |
0 commit comments