Skip to content
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

ComboBox multiple fixes #710

Merged
merged 42 commits into from
Jul 6, 2020
Merged

ComboBox multiple fixes #710

merged 42 commits into from
Jul 6, 2020

Conversation

fergusonr
Copy link
Contributor

@fergusonr fergusonr commented Jun 20, 2020

FIxes for #709

  • Dim.Fill() incorrectly calculated
  • List height not resizing
  • SetSource() not immediately updating list.
  • Double click not selecting item

…ht not resizing. SetSource() not immeadiately updating list. Double click not selecting item. Example now demo resizes with view
@fergusonr fergusonr changed the title ComboBox multiple fixes #709 ComboBox multiple fixes Jun 20, 2020
@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

@fergusonr, provide a functional constructor for the AllViewsTester.cs. Now there is an error on the searchset variable is null in this method.


		private int CalculatetHeight ()
		{
			var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height;
			return Math.Min (Math.Max (0, h - 1), searchset.Count);
		}

In the Demo.cs the ListView is not closing on exit.

@fergusonr
Copy link
Contributor Author

Thanks. Fixed AllViewsTester.cs. Investigating Demo.cs issue....

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

Thanks. Is possible you have the default constructor to accept a ustring and using that to have a search and source filled with that information making visible? It's the way that AllViewsTester.cs work. See the CheckBox example.

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

Thanks. It's possible to have that text also into the source? May be this? Not tested.


		public ComboBox () : this (string.Empty) { }

		/// <summary>
		/// Public constructor
		/// </summary>
		/// <param name="text"></param>
		public ComboBox (ustring text) : base ()
		{
			var source = new List<string> () { text.ToString () };
			search = new TextField (text.ToString ());
			listview = new ListView (source) { LayoutStyle = LayoutStyle.Computed, CanFocus = true };

			Initialize ();
			Text = text;
			SetSource (source);
		}

@fergusonr
Copy link
Contributor Author

The text (what your searching for) is independent to the source (your searching in)

I think this, added to AllViewTesters.cs CreateClass() would be better for the IUCatalog, but it does not seem to initialize a ListView or ComboBox. Even though I can breakpoint in SetSource() and see its being set.

if(view.GetType().GetMethod("SetSource") != null) {
	IList<string> list = new List<string>() { "Test Text1", "Test Text2", "Test Text3" };
	view?.GetType ().GetMethod ("SetSource")?.Invoke (view, new object [] { list });
}

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

I think you are wright. It seems it's not initializing in the ListView which must be fixed first. I also think that adding a Text property in the ListView with the default string selected would do (may be) the trick.

@fergusonr
Copy link
Contributor Author

I can now get ListView and ComboBox scenario lists to initialize with this code change in addition to the one mentioned above in AllViewTesters.cs CreateClass

Need @tig to comment on the validity of making this change

	// Instantiate view
	var view = (View)Activator.CreateInstance (type);

	view.Width = Dim.Fill (); // <-- Added
	view.Height = Dim.Fill (); // <-- Added

InitializeLists

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

I will submit a PR to the ListView related and then with that please try if it could have a default search with the default source based on that search.

@fergusonr
Copy link
Contributor Author

fergusonr commented Jun 20, 2020

Not sure why you need the constructor your asking for? It has no use outside of testing. The same can be achieved with this:-

var combo = new ComboBox ("Test Text");
combo.SetSource(new List<string>() { "Test Text" });

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

I understand your point of view but when @tig insisted on default builders I didn't immediately understand his intention. Check my PR #712 and you will see that even having only one default driver with a simple text it fills the ListView with the generic application AllViewTesters.cs. For now it only works with the Text and Title properties but @tig has already mentioned that it intends to implement other features.

@tig
Copy link
Collaborator

tig commented Jun 20, 2020

Need @tig to comment on the validity of making this change

	// Instantiate view
	var view = (View)Activator.CreateInstance (type);

	view.Width = Dim.Fill (); // <-- Added
	view.Height = Dim.Fill (); // <-- Added

I'd rather not add code like this to AllViewsTester, because one of the values of this Scenario is to illustrate the default behavior of views (to expose bugs).

@tig
Copy link
Collaborator

tig commented Jun 20, 2020

IMO, given the code I just pushed in #713, when ComboBox is selected, it should show "Test Text" in the TextField and List Item #1 (2 & 3) in the List. It does not do that now.

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

Of course it is just a record but it follows the same principle as the others. Now reading a Source property as @tig intends to implement and not a method as you suggested (although it was also a good idea, don't misinterpret) is more appropriate for the purpose of this class that intends to test its properties.

listview-text

@BDisp
Copy link
Collaborator

BDisp commented Jun 20, 2020

I am checking in the image I sent that the ListView does not keep the focus on the current selected item. @tig could fix this, please :-)

@fergusonr
Copy link
Contributor Author

IMO, given the code I just pushed in #713, when ComboBox is selected, it should show "Test Text" in the TextField and List Item #1 (2 & 3) in the List. It does not do that now.

Thanks @tig Your not seeing the list for three reasons:-

  • 1 There's a fix in this PR required
  • 2 The "Test Text" does not match anything in the source list items

Change the list items to this:-

var source = new ListWrapper (new List<ustring> () { 
  ustring.Make("Test Text #1"), ustring.Make("Test Text #2"), ustring.Make("Test Text #3") });
  • 3 The scenario environment is not fully emulating the real environment. Application.Loaded is not getting fired. Need this at the end of AllViewsTester.CreateClass()
View CreateClass (Type type) {
    ....
    ....
    ....
    Application.Loaded?.Invoke (new Application.ResizedEventArgs () { 
        Rows = Application.Driver.Rows, Cols = Application.Driver.Cols });

    return view;
}

UICatalog ComboBox

There is an issue in that the list does not appear until you give / remove focus on the Combo. Not clear where the problem lies at the moment.

@tig
Copy link
Collaborator

tig commented Jun 21, 2020 via email

@BDisp
Copy link
Collaborator

BDisp commented Jun 21, 2020

@fergusonr can you add a down arrow that will open or close the list items of the ComboBox, please? In that case both the TextField and the ListView will be with the same width, that is Width - 1. Something like this.

		public override void Redraw (Rect bounds)
		{
			base.Redraw (bounds);
			Move (Bounds.Right - 1, 0);
			Driver.AddRune (Driver.DownArrow);
		}

		public override bool MouseEvent (MouseEvent me)
		{
			if (me.X == Bounds.Right - 1 && me.Y == Bounds.Top && me.Flags == MouseFlags.Button1Clicked) {
				// Process the drop-down.
				return true;
			}
			return base.MouseEvent (me);
		}

Terminal.Gui/Views/ComboBox.cs Outdated Show resolved Hide resolved
Copy link
Collaborator

@tig tig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great progress. Thanks a ton for all your hard work on this.

See my notes on using brackets for nested statements.

Also, ApplicationLoaded is not the right event. Use LayoutComplete.

@BDisp
Copy link
Collaborator

BDisp commented Jun 22, 2020

I am checking in the image I sent that the ListView does not keep the focus on the current selected item. @tig could fix this, please :-)

I already fixed this in the PR #719.

@BDisp
Copy link
Collaborator

BDisp commented Jul 2, 2020

@fergusonr I inserted a ScrollView in the ComboBox. I hope you like it.

@tig
Copy link
Collaborator

tig commented Jul 2, 2020

Can one of you articulate a plan for finalizing this PR and ensuring all of the feedback has been incorporated? It's not clear to me how this will all come together.

Also, I'm not sure if this is addressed here yet or not, but it should be:

In Unicode.cs I had to comment out Combobox because of a crash due to Unicode handling:
image

@BDisp
Copy link
Collaborator

BDisp commented Jul 2, 2020

You can test my branch here (https://github.com/BDisp/gui.cs/tree/combobox-multiple-fixes) but @fergusonr will make your final decision as the author of the control. I just insisted that it is a ComboBox with AutoComplete features when typing but it will also have to work like a real ComboBox. But @fergusonr has every right to give his opinion and I am willing to collaborate with him to achieve common goals. Unicode already works because @fergusonr presented resolution in this PR.

Test dir more robust "\Windows"
Use ListViewItemEventArgs
@fergusonr
Copy link
Contributor Author

fergusonr commented Jul 3, 2020

Yes, the Unicode issue was fixed a good while back in this PR.

unicode

var comboBox = new ComboBox ("gui.cs") {
	X = 20,
	Y = Pos.Y (label),
	Width = Dim.Percent (50),
	Height = Dim.Percent(20)
};

I believe this PR is ready to go. I've hand picked two of @BDisp changes. Any wider changes can be done in a new PR post v0.90 / v1.00. AutoHide for example should be made a public property so it can be overwritten

Note that PR #724 is in this branch

Thankyou both for all your help and patience

@fergusonr fergusonr requested a review from tig July 3, 2020 04:56
Copy link
Collaborator

@tig tig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really great work. You've simplified things greatly.

I appreciate your taking the feedback!

Terminal.Gui/Views/ComboBox.cs Outdated Show resolved Hide resolved
@@ -596,6 +607,7 @@ public virtual void Remove (View view)
if (view == null || subviews == null)
return;

OnRemoving (view);
Copy link
Collaborator

@tig tig Jul 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove Removing from this PR. I have serious concerns about how it will interact with IDisposable and we don't have a clear use case where it's needed. I wish I could explain those concerns in detail, but I'm not confident I understand well enough yet. But I've learned to trust my instincts on things like this. There's no danger in removing the API for now. But there is danger in putting it in and having to change it later. Thanks.

Also, I am arguing for renaming Adding to Added. I made a comment that argues my point I think pretty clearly. I'll add to that argument that by using Adding (current tense) there's an implication that the operation can be cancelled. However, if we name it Added (past tense) it is very clear that the deal is done and there's no going back.

If you disagree, please explain. If you don't disagree, please rename to Added.

@BDisp
Copy link
Collaborator

BDisp commented Jul 3, 2020

I think there is no harm in maintaining OnRemoving. If it is to be removed then OnAdded must also be removed.

@tig
Copy link
Collaborator

tig commented Jul 3, 2020

I think there is no harm in maintaining OnRemoving. If it is to be removed then OnAdded must also be removed.

I think I've made my argument pretty clear. Beyond my concerns that the semantics around Removing will cause conflict with IDisposable, in framework/API design a key tenet to be followed is "Do not expose APIs that have no use cases." It just creates complexity and adds more code. History has shown that un-needed APIs just create bad legacy that has to be maintained in the future. We should strive to REMOVE code from the framework, not just add more and more.

If you feel strongly that Removing should be part of the API I would appreciate it if you explain why.

@BDisp
Copy link
Collaborator

BDisp commented Jul 3, 2020

If you feel strongly that Removing should be part of the API I would appreciate it if you explain why.

@tig if you prove it will create conflicts with the IDisposable implementation, I wouldn't think twice about supporting you. In this specific case of Removing I will tell you use cases in which they are very beneficial in implementing them. For example, ScrollView has two properties, namely ShowVerticalScrollIndicator and ShowHorizontalScrollIndicator, where they dynamically add or remove views from his control, which are the cases of the vertical and horizontal ``ScrollBarView. Now imagine that you create a control that includes the ScrollView as a subview and you want, for example, to resize any subview or other control as AutoHideScrollBars adds or removes the ScrollBarViews. If you had an event that notifies the subscribers of this occurrence, it becomes easier to react according to the needs.

@BDisp
Copy link
Collaborator

BDisp commented Jul 3, 2020

@fergusonr can you take a look for this small adjustments I have made to improve the ComboBox, please? Is more to hide the list if the ComboBox loses focus. Thanks.

https://github.com/BDisp/gui.cs/tree/pr%23710-combobox-multiple-fixes

@fergusonr fergusonr mentioned this pull request Jul 6, 2020
@BDisp
Copy link
Collaborator

BDisp commented Jul 6, 2020

@fergusonr, please merge my PR #723 again because I changed the Removing event to Removed to take action when the view no longer exists in the collection.

After selecting an item, the ComboBox closes but no longer opens either by clicking on the down arrow or with the cursor down.

@BDisp
Copy link
Collaborator

BDisp commented Jul 6, 2020

When autohide is true the ComboBox should close the list when it loses focus.

@BDisp
Copy link
Collaborator

BDisp commented Jul 6, 2020

With the mouse, the ComboBox should only get the focus with a click and not just passing the mouse over it.

@tig tig merged commit 98e224a into gui-cs:master Jul 6, 2020
@tig tig mentioned this pull request Jul 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants