1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-14 05:29:32 +00:00

Add "find previous"

The Find box now has forward/backward radio buttons.  Find Next
searches forward, and Find Previous searches backward, regardless
of the direction of the initial search.

The standard key sequence for "find previous" is Shift+F3.  The WPF
ListView has some weird logic that does something like: if you hit
a key, and the selection changes, and the shift key was held down,
then you must have meant to select a range.  So Shift+F3 often (but
not always) selects a range.  I think this might be fixable if I can
figure out how ListView keeps track of the current keyboard
navigation position (which is not the same as the selection).  For
now I'm working around the problem by using Ctrl+F3 to search.
Yay WPF.
This commit is contained in:
Andy McFadden 2019-10-09 17:41:44 -07:00
parent dfd5bcab1b
commit 3a67c14247
7 changed files with 88 additions and 14 deletions

View File

@ -151,6 +151,12 @@ namespace SourceGen {
/// </summary>
private int mFindStartIndex = -1;
/// <summary>
/// True if previous search was backward, so we can tell if we changed direction
/// (otherwise we think we immediately wrapped around and the search stops).
/// </summary>
private bool mFindBackward = false;
/// <summary>
/// Used to highlight the line that is the target of the selected line.
/// </summary>
@ -2077,30 +2083,45 @@ namespace SourceGen {
if (dlg.ShowDialog() == true) {
mFindString = dlg.TextToFind;
mFindStartIndex = -1;
FindText();
FindText(dlg.IsBackward);
}
}
public void FindNext() {
FindText();
FindText(false);
}
private void FindText() {
public void FindPrevious() {
FindText(true);
}
private void FindText(bool goBackward) {
if (string.IsNullOrEmpty(mFindString)) {
return;
}
int incr = goBackward ? -1 : 1;
// If we reversed direction, reset the "start index" so we don't tell the user
// we've wrapped around.
if (mFindBackward != goBackward) {
mFindStartIndex = -1;
mFindBackward = goBackward;
}
// Start from the topmost selected line, or the start of the file if nothing
// is selected.
// TODO(maybe): if multiple lines are selected, search only within the selected set.
int index = mMainWin.CodeListView_GetFirstSelectedIndex();
if (index < 0) {
index = 0;
}
// Start one past the selected item.
index++;
index += incr;
if (index == CodeLineList.Count) {
index = 0;
} else if (index == -1) {
index = CodeLineList.Count - 1;
}
//Debug.WriteLine("FindText index=" + index + " start=" + mFindStartIndex +
// " str=" + mFindString);
@ -2118,12 +2139,19 @@ namespace SourceGen {
mMainWin.CodeListView_EnsureVisible(index);
mMainWin.CodeListView_DeselectAll();
mMainWin.CodeListView_SelectRange(index, 1);
// TODO(someday): I think we need to do something with the ListView
// keyboard nav state here. Otherwise Shift+F3 is regarded as selection
// movement with shift held down, and it does a range select. Currently
// working around this by using Ctrl+F3 instead. See also maybe the
// ItemContainerGenerator stuff in MainWindow.
return;
}
index++;
index += incr;
if (index == CodeLineList.Count) {
index = 0;
} else if (index == -1) {
index = CodeLineList.Count - 1;
}
}

View File

@ -329,7 +329,10 @@ can also use PgUp/PgDn and the arrow keys.</p>
<p>Use Edit &gt; Find to search for text. This performs a case-insensitive
text search on the label, opcode, operand, and comment fields.
Use Edit &gt; Find Next to find the next match.</p>
Use Edit &gt; Find Next to find the next match, and
Edit &gt; Find Previous to find the previous match. Note "next" is
always downward, and "previous" is always upward, regardless of the
direction of the initial search chosen in the Find dialog.</p>
<p>Use Edit &gt; Go To to jump to an offset, address, or label. Remember
that offsets and addresses are always hexadecimal, and offsets start

View File

@ -223,6 +223,8 @@ not part of the chip specification, but most of them have consistent
behavior and can be used. If the box is not checked, the instructions
are treated as invalid and cause the code analyzer to assume that it
has run into a data area. This option has no effect on the 65816.</p>
<p>The "treat BRK as two-byte instruction" checkbox determines whether
BRK instructions should be handled as if they have an operand.</p>
<p>The entry flags determine the initial value for the processor status
flag register. Code that is unreachable internally (requiring a code

View File

@ -26,9 +26,15 @@ limitations under the License.
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
ContentRendered="Window_ContentRendered"
PreviewKeyDown="Window_KeyEventHandler">
<StackPanel Margin="8" Orientation="Horizontal">
<TextBox Name="findTextBox" Width="200" Text="{Binding TextToFind}"/>
<Button Content="Find" Width="70" IsDefault="True" Margin="16,0,0,0"
Click="OkButton_Click"/>
<StackPanel Margin="8">
<StackPanel Orientation="Horizontal">
<TextBox Name="findTextBox" Width="200" Text="{Binding TextToFind}"/>
<Button Content="Find" Width="70" IsDefault="True" Margin="16,0,0,0"
Click="OkButton_Click"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<RadioButton Content="_Forward" IsChecked="{Binding IsForward}"/>
<RadioButton Content="_Backward" Margin="16,0,0,0" IsChecked="{Binding IsBackward}"/>
</StackPanel>
</StackPanel>
</Window>

View File

@ -25,19 +25,29 @@ namespace SourceGen.WpfGui {
/// Find text dialog.
/// </summary>
public partial class FindBox : Window, INotifyPropertyChanged {
static bool sLastSearchBackward = false;
/// <summary>
/// Text to find. On success, holds the string searched for. This is bound to the
/// text field.
/// </summary>
public string TextToFind {
get { return mTextToFind; }
set {
mTextToFind = value;
OnPropertyChanged();
}
set { mTextToFind = value; OnPropertyChanged(); }
}
private string mTextToFind;
private bool mIsForward;
public bool IsForward {
get { return mIsForward; }
set { mIsForward = value; OnPropertyChanged(); }
}
private bool mIsBackward;
public bool IsBackward {
get { return mIsBackward; }
set { mIsBackward = value; OnPropertyChanged(); }
}
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
@ -55,6 +65,12 @@ namespace SourceGen.WpfGui {
Debug.Assert(findStr != null);
TextToFind = findStr;
if (sLastSearchBackward) {
IsBackward = true;
} else {
IsForward = true;
}
}
private void Window_ContentRendered(object sender, EventArgs e) {
@ -77,6 +93,7 @@ namespace SourceGen.WpfGui {
private void OkButton_Click(object sender, RoutedEventArgs e) {
DialogResult = true;
sLastSearchBackward = IsBackward;
}
}
}

View File

@ -101,6 +101,12 @@ limitations under the License.
<KeyGesture>F3</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
<RoutedUICommand x:Key="FindPreviousCmd" Text="Find Previous">
<RoutedUICommand.InputGestures>
<!-- should be Shift+F3, but that causes ListView to do range selection -->
<KeyGesture>Ctrl+F3</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
<RoutedUICommand x:Key="FormatAsWordCmd" Text="Format As Word">
<RoutedUICommand.InputGestures>
<KeyGesture>Ctrl+W</KeyGesture>
@ -218,6 +224,8 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="FindCmd_Executed"/>
<CommandBinding Command="{StaticResource FindNextCmd}"
CanExecute="IsProjectOpen" Executed="FindNextCmd_Executed"/>
<CommandBinding Command="{StaticResource FindPreviousCmd}"
CanExecute="IsProjectOpen" Executed="FindPreviousCmd_Executed"/>
<CommandBinding Command="{StaticResource FormatAsWordCmd}"
CanExecute="CanFormatAsWord" Executed="FormatAsWordCmd_Executed"/>
<CommandBinding Command="{StaticResource FormatAddressTableCmd}"
@ -318,6 +326,7 @@ limitations under the License.
<MenuItem Command="{StaticResource SelectAllCmd}"/>
<MenuItem Command="Find"/>
<MenuItem Command="{StaticResource FindNextCmd}"/>
<MenuItem Command="{StaticResource FindPreviousCmd}"/>
<MenuItem Command="{StaticResource GotoCmd}"/>
<Separator/>
<MenuItem Command="{StaticResource EditHeaderCommentCmd}"/>

View File

@ -718,6 +718,11 @@ namespace SourceGen.WpfGui {
Debug.Assert(start >= 0 && start < CodeDisplayList.Count);
Debug.Assert(count > 0 && start + count <= CodeDisplayList.Count);
if (count == 1) {
codeListView.SelectedItems.Add(CodeDisplayList[start]);
return;
}
DisplayList.FormattedParts[] tmpArray = new DisplayList.FormattedParts[count];
for (int index = 0; index < count; index++) {
tmpArray[index] = CodeDisplayList[start + index];
@ -1139,6 +1144,10 @@ namespace SourceGen.WpfGui {
mMainCtrl.FindNext();
}
private void FindPreviousCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.FindPrevious();
}
private void FormatAsWordCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.FormatAsWord();
}