-
Notifications
You must be signed in to change notification settings - Fork 30
Add UI elements for textual filtering of tests #1166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // *********************************************************************** | ||
| // Copyright (c) Charlie Poole and TestCentric contributors. | ||
| // Licensed under the MIT License. See LICENSE file in root directory. | ||
| // *********************************************************************** | ||
|
|
||
| using System.Drawing; | ||
| using System.Windows.Forms; | ||
| using System; | ||
|
|
||
| namespace TestCentric.Gui.Controls | ||
| { | ||
| /// <summary> | ||
| /// This class is required to stretch a ToolStripTextBox control within a ToolStrip to fill the available space and to resize when the control resizes. | ||
| /// The implementation is from the Microsoft Windows Forms documentation, but simplified to the current use case. | ||
| /// "How to: Stretch a ToolStripTextBox to Fill the Remaining Width of a ToolStrip" | ||
| /// https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/stretch-a-toolstriptextbox-to-fill-the-remaining-width-of-a-toolstrip-wf?view=netframeworkdesktop-4.8 | ||
| /// </summary> | ||
| internal class StretchToolStripTextBox : ToolStripTextBox | ||
| { | ||
| public override Size GetPreferredSize(Size constrainingSize) | ||
| { | ||
| // Get width of the owning ToolStrip | ||
| int textBoxMargin = 2; | ||
| Int32 width = Owner.DisplayRectangle.Width - textBoxMargin; | ||
|
|
||
| // If the available width is less than the default width, use the default width | ||
| if (width < DefaultSize.Width) width = DefaultSize.Width; | ||
|
|
||
| // Retrieve the preferred size from the base class, but change the width to the calculated width. | ||
| Size size = base.GetPreferredSize(constrainingSize); | ||
| size.Width = width; | ||
| return size; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| // *********************************************************************** | ||
| // Copyright (c) Charlie Poole and TestCentric contributors. | ||
| // Licensed under the MIT License. See LICENSE file in root directory. | ||
| // *********************************************************************** | ||
|
|
||
|
|
||
| using System; | ||
| using System.Windows.Forms; | ||
|
|
||
| namespace TestCentric.Gui.Elements | ||
| { | ||
| /// <summary> | ||
| /// This class implements the ISelection interface for a TextBox control. It provides this additional functionality: | ||
| /// - show a PlaceHoder text if there's no text input | ||
| /// - Invoke the SelectionChanged event as soon as no further input is made within a short period of time. | ||
| /// </summary> | ||
| public class TextBoxElement : ISelection | ||
| { | ||
| private Timer _typingTimer; | ||
|
|
||
| public event CommandHandler SelectionChanged; | ||
|
|
||
| public TextBoxElement(Control textBox, string placeHolderText) | ||
| { | ||
| TextBox = textBox; | ||
| PlaceHolderText = placeHolderText; | ||
| TextBox.TextChanged += OnTextChanged; | ||
|
|
||
| TextBox.LostFocus += OnTextBoxLostFocus; | ||
| TextBox.GotFocus += OnTextBoxGotFocus; | ||
|
|
||
| // Call LostFocus to set initial text and color | ||
| OnTextBoxLostFocus(null, EventArgs.Empty); | ||
| } | ||
|
|
||
| public string SelectedItem | ||
| { | ||
| get => TextBox.Text; | ||
| set => TextBox.Text = value; | ||
| } | ||
|
|
||
| public int SelectedIndex | ||
| { | ||
| get => 0; | ||
| set => throw new NotImplementedException(); | ||
| } | ||
|
|
||
| public bool Enabled | ||
| { | ||
| get => TextBox.Enabled; | ||
| set => TextBox.Enabled = value; | ||
| } | ||
|
|
||
| public bool Visible | ||
| { | ||
| get => TextBox.Visible; | ||
| set => TextBox.Visible = value; | ||
| } | ||
|
|
||
| public string Text | ||
| { | ||
| get => TextBox.Text; | ||
| set => TextBox.Text = value; | ||
| } | ||
|
|
||
| private string PlaceHolderText { get; set; } | ||
|
|
||
| private Control TextBox { get; } | ||
|
|
||
| private bool IsPlaceHolderTextShown { get; set; } | ||
|
|
||
| public void InvokeIfRequired(MethodInvoker _delegate) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| public void Refresh() | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| private void OnTextBoxGotFocus(object sender, EventArgs e) | ||
| { | ||
| // If the PlaceHolderText is shown, replace it with an empty text | ||
| if (IsPlaceHolderTextShown) | ||
| { | ||
| TextBox.Text = ""; | ||
| TextBox.ForeColor = System.Drawing.Color.Black; | ||
| IsPlaceHolderTextShown = false; | ||
| } | ||
| } | ||
|
|
||
| private void OnTextBoxLostFocus(object sender, EventArgs e) | ||
| { | ||
| // If there's no text input, show the PlaceHolderText instead | ||
| string searchText = TextBox.Text; | ||
| if (string.IsNullOrEmpty(searchText) && !string.IsNullOrEmpty(PlaceHolderText)) | ||
| { | ||
| IsPlaceHolderTextShown = true; | ||
| TextBox.Text = PlaceHolderText; | ||
| TextBox.ForeColor = System.Drawing.Color.LightGray; | ||
| } | ||
| } | ||
|
|
||
| private void OnTextChanged(object sender, EventArgs e) | ||
| { | ||
| if (IsPlaceHolderTextShown) | ||
| return; | ||
|
|
||
| if (_typingTimer == null) | ||
| { | ||
| _typingTimer = new Timer(); | ||
| _typingTimer.Interval = 600; | ||
| _typingTimer.Tick += TypingTimerTimeout; | ||
| } | ||
|
|
||
| _typingTimer.Stop(); | ||
| _typingTimer.Start(); | ||
| } | ||
|
|
||
| private void TypingTimerTimeout(object sender, EventArgs e) | ||
| { | ||
| var timer = sender as Timer; | ||
| if (timer == null) | ||
| return; | ||
|
|
||
| // The timer must be stopped! | ||
| timer.Stop(); | ||
| if (SelectionChanged != null) | ||
| SelectionChanged(); | ||
|
|
||
| TextBox.Focus(); | ||
| } | ||
| } | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the timeout strictly necessary? I'm fairly accustomed to controls that do nothing until I tab away or otherwise change focus.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This 'timeout' feature is definitely just a gimmick and not absolutely necessary. |
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISelection seems like an odd interface to use here, since there are no choices from which to select. Do we need an IChanged interface? Also, why not inherit from ToolStripElement, the base class for such elements?