-
Notifications
You must be signed in to change notification settings - Fork 735
Closed
Description
Describe the bug
Since I'm suing last version of v2_develop (commit: 7490ac9), my revisited version of combobox are no more working on my project ... I'm stuck :(
To Reproduce
Using the example provide below:
- Click on "Forwarding Immediate" menu
- Select any option using mouse => event SelectedItemChanged of ListView is NOT triggered 😑
to be more precise OnMouseEvent() method of ListView is not called - Use Mouse Up / or Mouse Down => event SelectedItemChanged of ListView is triggered 👍
Expected behavior
Event SelectedItemChanged of ListView must be triggered
Screenshots
Desktop (please complete the following information):
- OS: [Windows 11]
Code to reproduce:
using System.Collections.ObjectModel;
using System.Drawing;
using Terminal.Gui.Drawing;
using Terminal.Gui.Input;
using Terminal.Gui.ViewBase;
using Terminal.Gui.Views;
using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment;
public class Item
{
public String Id { get; set; }
public string Text { get; set; }
public Item()
{
Id = Text = "";
}
public Item(String id, String text)
{
Id = id;
Text = text;
}
public override string ToString()
{
if (String.IsNullOrEmpty(Text))
return Id;
return Text;
}
}
public class ContextMenuSelector : PopoverMenu
{
protected override void OnAccepted(CommandEventArgs args)
{
args.Handled = true;
}
}
public class ItemSelector : View
{
private Label lbl;
private Label lblSelector;
private Label lblArrow;
private ContextMenuSelector contextMenu;
private ListViewSelector categoryList;
private int maxItemLength = 0;
List<Item>? items;
Item? itemSelected;
public event EventHandler<Item>? SelectedItemUpdated;
public Item? ItemSelected
{
get => itemSelected;
}
public ItemSelector(String? label = null, List<Item>? items = null, Item? itemSelected = null)
{
lbl = new()
{
X = 0,
Y = 0,
Height = 1,
Width = (label is null) ? 0 : label.Length + 1,
Text = $"{label}:",
CanFocus = true,
//SchemeName = "BlackOnGray"
};
lblSelector = new()
{
X = Pos.Right(lbl) + 1,
Y = 0,
Height = 1,
Width = Dim.Func(() =>
{
var textLength = (lblSelector is null) ? 0 : lblSelector.Text.Length;
var spaceAvailable = Frame.Width - lbl.Frame.Width - ((lblArrow is null) ? 0 : lblArrow.Frame.Width) - 2;
if (spaceAvailable < 0) spaceAvailable = 0;
return Math.Min(textLength, spaceAvailable);
}),
CanFocus = true
//SchemeName = "BlueOnGray"
};
lblSelector.MouseClick += View_MouseClick;
lblArrow = new()
{
X = Pos.Right(lblSelector) + 1,
Y = 0,
Height = 1,
Width = 2,
Text = Emojis.TRIANGLE_DOWN,
//SchemeName = "BlueOnGray"
};
lblArrow.MouseClick += View_MouseClick;
Add(lbl, lblSelector, lblArrow);
Height = 1;
Width = Dim.Fill();
// Create categoryList
categoryList = new()
{
X = Pos.Func(() => lblSelector.FrameToScreen().X),
Y = Pos.Func(() => lblSelector.FrameToScreen().Y + 1),
Width = Dim.Fill(
Dim.Func(() =>
{
var delta = (categoryList?.VerticalScrollBar.Visible == true) ? 4 : 3;
var nbElements = maxItemLength + delta;
var spaceAvailable = Terminal.Gui.App.Application.Screen.Width - lblSelector.FrameToScreen().X;
return spaceAvailable - Math.Min(nbElements, spaceAvailable);
})),
Height = Dim.Fill(
Dim.Func(() =>
{
var delta = (categoryList?.HorizontalScrollBar.Visible == true) ? 4 : 3;
var nbElements = ((this.items is null) ? 0 : this.items.Count) + delta;
var spaceAvailable = Terminal.Gui.App.Application.Screen.Height - lblSelector.FrameToScreen().Y;
return spaceAvailable - Math.Min(nbElements, spaceAvailable);
})),
AllowsMarking = false,
CanFocus = true,
BorderStyle = LineStyle.Rounded,
SuperViewRendersLineCanvas = false,
//Source = new ListWrapper<Item>(null),
//SchemeName = "BlueOnGray" // /!\ Need to be set !!!
};
categoryList.VerticalScrollBar.AutoShow = true;
categoryList.HorizontalScrollBar.AutoShow = true;
categoryList.SelectedItemChanged += CategoryList_SelectedItemChanged;
categoryList.SameItemSelected += CategoryList_SameItemSelected;
// Create contextMenu
contextMenu = new()
{
CanFocus = true,
//SchemeName = "BlueOnGray"
};
contextMenu.Add(categoryList);
this.itemSelected = itemSelected;
SetItems(items);
CanFocus = true;
//SchemeName = "BlueOnGray";
}
protected override void OnViewportChanged(DrawEventArgs e)
{
HideViewSelection();
}
public void HideViewSelection()
{
Terminal.Gui.App.Application.Popover?.Hide(contextMenu);
}
public void ShowViewSelection()
{
if (items?.Count > 0)
{
Point position = new Point(lblSelector.FrameToScreen().X, lblSelector.FrameToScreen().Y + 1);
contextMenu.MakeVisible(position);
contextMenu.MouseClick += ContextMenu_MouseClick;
}
}
private void ContextMenu_MouseClick(object? sender, MouseEventArgs e)
{
e.Handled = false;
}
private void View_MouseClick(object? sender, MouseEventArgs e)
{
e.Handled = true;
ShowViewSelection();
}
private void CategoryList_SelectedItemChanged(object? sender, ListViewItemEventArgs e)
{
HideViewSelection();
itemSelected = (Item)e.Value;
Terminal.Gui.App.Application.Invoke(() =>
{
UpdateDisplay();
});
SelectedItemUpdated?.Invoke(this, (Item)e.Value);
}
private void CategoryList_SameItemSelected(object? sender, EventArgs e)
{
HideViewSelection();
}
private void UpdateDisplay()
{
if (itemSelected is null)
{
lblSelector.Text = "NONE";
lblSelector.Enabled = false;
lblArrow.Width = 0;
}
else
{
lblSelector.Text = itemSelected.Text;
lblSelector.Enabled = true;
lblArrow.Width = 2;
}
HideViewSelection();
}
public void SetItems(List<Item>? items)
{
this.items = items;
var previousItemSelected = itemSelected;
// Check itemSelected value
if (items?.Count > 0)
{
if ((itemSelected is null)
|| (items.FirstOrDefault(i => i.Id == itemSelected.Id) is null))
itemSelected = items[0];
}
else
{
itemSelected = null;
}
if (items?.Count > 0)
{
var strings = items.Select(i => i.ToString());
maxItemLength = strings.Aggregate("", (max, cur) => max.Length > cur.Length ? max : cur).Length;
categoryList.SetSource(new ObservableCollection<Item>(items));
categoryList.SelectedItem = 0;
}
else
{
maxItemLength = 0;
categoryList.SetSource(new ObservableCollection<Item>());
}
// Do we need to update the display ?
if (previousItemSelected?.Id == itemSelected?.Id)
return;
Terminal.Gui.App.Application.Invoke(() =>
{
UpdateDisplay();
});
}
public void SetItems(List<String>? elements)
{
List<Item>? items = null;
if (elements?.Count > 0)
{
items = [];
int count = 0;
foreach (var elm in elements)
{
var item = new Item()
{
Id = $"{count++}",
Text = elm,
};
items.Add(item);
}
}
SetItems(items);
}
public Boolean SetItemSelected(Item? item)
{
if ((item is not null) && (items is not null))
{
var index = items.FindIndex(x => x.Id == item.Id);
if (index > 0)
return SetItemSelected(index);
}
return false;
}
public Boolean SetItemSelected(int index)
{
if ((index >= 0) && (items?.Count > index))
{
var item = items[index];
if (item.Id != itemSelected?.Id)
{
itemSelected = items[index];
Terminal.Gui.App.Application.Invoke(() =>
{
categoryList.SelectedItem = index;
UpdateDisplay();
});
return true;
}
}
return false;
}
}
public class ListViewSelector : ListView
{
public event EventHandler<EventArgs> SameItemSelected;
public override bool OnSelectedChanged()
{
var result = base.OnSelectedChanged();
if (!result)
SameItemSelected?.Invoke(this, EventArgs.Empty);
return result;
}
}
public class TestWindow: Window
{
readonly List<string> listFwdType = ["Forwarding Immediate", "Forward on busy", "Forward on no reply", "Forward on busy/no reply"];
private Shortcut ShVersion;
public TestWindow()
{
BorderStyle = LineStyle.None;
var callForwardSelector = new ItemSelector("Call forward")
{
X = 0,
Y = 0,
Width = 80,
CanFocus = true
};
callForwardSelector.SetItems(listFwdType);
callForwardSelector.SelectedItemUpdated += CallForwardSelector_SelectedItemUpdated; ;
Add(callForwardSelector);
// Create StatusBar
StatusBar statusBar = new()
{
Visible = true,
AlignmentModes = AlignmentModes.IgnoreFirstOrLast,
CanFocus = false
};
ShVersion = new()
{
Title = "Version Info",
CanFocus = false
};
statusBar.Add(ShVersion); // always add it as the last one
Add(statusBar);
Height = Dim.Fill();
Width = Dim.Fill();
// Need to manage Loaded event
Loaded += LoadedHandler;
}
private void CallForwardSelector_SelectedItemUpdated(object? sender, Item e)
{
var id = (int.Parse(e.Id));
}
private void LoadedHandler(object? sender, EventArgs? args)
{
if (ShVersion is { })
{
ShVersion.Title = $"{RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}, {Terminal.Gui.App.Application.Driver.GetVersionInfo()}";
}
}
}
Metadata
Metadata
Assignees
Labels
No labels
