Skip to content

Commit f7a97b2

Browse files
committed
Add right-click (Button3) support across the framework
Plumb MouseRightClick events through all layers so controls can handle right-clicks and applications can build context menus on top. - Add MouseRightClick event to IMouseAwareControl interface - InputCoordinator: activate windows and propagate clicks on Button3 - WindowEventDispatcher: handle focus and UnhandledMouseClick for Button3 - Add MouseRightClick event + Button3Clicked handling to all 22 controls
1 parent 647aa25 commit f7a97b2

26 files changed

Lines changed: 259 additions & 4 deletions

SharpConsoleUI/Controls/ButtonControl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ public bool ProcessKey(ConsoleKeyInfo key)
184184
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
185185
#pragma warning restore CS0067
186186

187+
/// <summary>
188+
/// Occurs when the button is right-clicked with the mouse.
189+
/// </summary>
190+
public event EventHandler<MouseEventArgs>? MouseRightClick;
191+
187192
/// <inheritdoc/>
188193
public event EventHandler<MouseEventArgs>? MouseEnter;
189194

@@ -212,6 +217,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
212217
return true;
213218
}
214219

220+
// Handle right-click
221+
if (args.HasFlag(MouseFlags.Button3Clicked))
222+
{
223+
MouseRightClick?.Invoke(this, args);
224+
return true;
225+
}
226+
215227
// Handle mouse clicks
216228
if (args.HasFlag(MouseFlags.Button1Clicked))
217229
{

SharpConsoleUI/Controls/CheckboxControl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public CheckboxControl(string label = "Checkbox", bool isChecked = false)
8686
/// </summary>
8787
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
8888

89+
/// <summary>
90+
/// Occurs when the checkbox is right-clicked with the mouse.
91+
/// </summary>
92+
public event EventHandler<MouseEventArgs>? MouseRightClick;
93+
8994
/// <summary>
9095
/// Gets the actual rendered width of the control based on content.
9196
/// </summary>
@@ -349,6 +354,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
349354
return true;
350355
}
351356

357+
// Handle right-click
358+
if (args.HasFlag(MouseFlags.Button3Clicked))
359+
{
360+
MouseRightClick?.Invoke(this, args);
361+
return true;
362+
}
363+
352364
// Handle mouse click to toggle checkbox
353365
if (args.HasFlag(MouseFlags.Button1Clicked))
354366
{

SharpConsoleUI/Controls/ColumnContainer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,9 @@ public void PaintDOM(CharacterBuffer buffer, LayoutRect bounds, LayoutRect clipR
892892
/// <inheritdoc/>
893893
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
894894

895+
/// <inheritdoc/>
896+
public event EventHandler<MouseEventArgs>? MouseRightClick;
897+
895898
#pragma warning disable CS0067 // Event never raised (interface requirement)
896899
/// <inheritdoc/>
897900
public event EventHandler<MouseEventArgs>? MouseEnter;
@@ -957,6 +960,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
957960
var contentPosition = new Point(args.Position.X - _margin.Left, args.Position.Y - _margin.Top);
958961
var contentArgs = args.WithPosition(contentPosition);
959962

963+
// Handle right-click
964+
if (args.HasFlag(MouseFlags.Button3Clicked))
965+
{
966+
MouseRightClick?.Invoke(this, contentArgs);
967+
return true;
968+
}
969+
960970
// Handle double-click detection (two methods like ListControl)
961971

962972
// Method 1: Direct flag detection from driver (preferred method)

SharpConsoleUI/Controls/DropdownControl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ public DropdownControl(string prompt)
156156
/// <inheritdoc/>
157157
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
158158

159+
/// <summary>
160+
/// Occurs when the control is right-clicked with the mouse.
161+
/// </summary>
162+
public event EventHandler<MouseEventArgs>? MouseRightClick;
163+
159164
/// <inheritdoc/>
160165
public event EventHandler<MouseEventArgs>? MouseEnter;
161166

@@ -825,6 +830,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
825830
return true;
826831
}
827832

833+
// Handle right-click
834+
if (args.HasFlag(MouseFlags.Button3Clicked))
835+
{
836+
MouseRightClick?.Invoke(this, args);
837+
return true;
838+
}
839+
828840
// Handle mouse down
829841
if (args.HasAnyFlag(MouseFlags.Button1Pressed))
830842
{

SharpConsoleUI/Controls/HorizontalGridControl.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,9 @@ public void SetFocusWithDirection(bool focus, bool backward)
879879
/// <inheritdoc/>
880880
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
881881

882+
/// <inheritdoc/>
883+
public event EventHandler<MouseEventArgs>? MouseRightClick;
884+
882885
/// <inheritdoc/>
883886
public event EventHandler<MouseEventArgs>? MouseEnter;
884887

@@ -915,6 +918,12 @@ public bool ProcessMouseEvent(MouseEventArgs args)
915918
}
916919

917920
// No control was clicked, but we might want to handle grid-level events
921+
if (args.HasFlag(MouseFlags.Button3Clicked))
922+
{
923+
MouseRightClick?.Invoke(this, args);
924+
return true;
925+
}
926+
918927
if (args.HasFlag(MouseFlags.Button1Clicked))
919928
{
920929
MouseClick?.Invoke(this, args);

SharpConsoleUI/Controls/IMouseAwareControl.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public interface IMouseAwareControl : IWindowControl
4242
/// </summary>
4343
event EventHandler<MouseEventArgs>? MouseDoubleClick;
4444

45+
/// <summary>
46+
/// Event fired when the control is right-clicked (Button3)
47+
/// </summary>
48+
event EventHandler<MouseEventArgs>? MouseRightClick;
49+
4550
/// <summary>
4651
/// Event fired when the mouse enters the control area
4752
/// </summary>

SharpConsoleUI/Controls/ListControl/ListControl.Mouse.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
160160
}
161161
}
162162

163+
// Handle right-click
164+
if (args.HasFlag(MouseFlags.Button3Clicked))
165+
{
166+
MouseRightClick?.Invoke(this, args);
167+
return true;
168+
}
169+
163170
// Handle double-click event from driver (preferred method)
164171
if (args.HasFlag(MouseFlags.Button1DoubleClicked) && _doubleClickActivates)
165172
{

SharpConsoleUI/Controls/ListControl/ListControl.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ public ListControl(string title)
266266
/// </summary>
267267
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
268268

269+
/// <summary>
270+
/// Occurs when the control is right-clicked with the mouse.
271+
/// </summary>
272+
public event EventHandler<MouseEventArgs>? MouseRightClick;
273+
269274
#endregion
270275

271276
#region Properties
@@ -671,6 +676,7 @@ protected override void OnDisposing()
671676
MouseMove = null;
672677
ItemHovered = null;
673678
MouseDoubleClick = null;
679+
MouseRightClick = null;
674680
GotFocus = null;
675681
LostFocus = null;
676682
}

SharpConsoleUI/Controls/LogViewerControl.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using SharpConsoleUI.Logging;
1414
using Spectre.Console;
1515
using Color = Spectre.Console.Color;
16+
using SharpConsoleUI.Drivers;
1617
using SharpConsoleUI.Events;
1718
using System.Collections.Concurrent;
1819

@@ -95,6 +96,11 @@ public LogViewerControl(ILogService logService)
9596
/// </summary>
9697
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
9798

99+
/// <summary>
100+
/// Occurs when the control is right-clicked with the mouse.
101+
/// </summary>
102+
public event EventHandler<MouseEventArgs>? MouseRightClick;
103+
98104
/// <summary>
99105
/// Occurs when the mouse enters the control area.
100106
/// </summary>
@@ -290,6 +296,14 @@ public void SetFocus(bool focus, FocusReason reason = FocusReason.Programmatic)
290296
/// <inheritdoc/>
291297
public bool ProcessMouseEvent(MouseEventArgs args)
292298
{
299+
300+
// Handle right-click
301+
if (args.HasFlag(MouseFlags.Button3Clicked))
302+
{
303+
MouseRightClick?.Invoke(this, args);
304+
return true;
305+
}
306+
293307
// Delegate mouse handling to scroll panel
294308
return _scrollPanel.ProcessMouseEvent(args);
295309
}

SharpConsoleUI/Controls/MarkupControl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ public Color? ForegroundColor
154154
/// </summary>
155155
public event EventHandler<MouseEventArgs>? MouseDoubleClick;
156156

157+
/// <summary>
158+
/// Occurs when the control is right-clicked.
159+
/// </summary>
160+
public event EventHandler<MouseEventArgs>? MouseRightClick;
161+
157162
/// <summary>
158163
/// Occurs when the mouse enters the control area.
159164
/// </summary>
@@ -208,6 +213,13 @@ public bool ProcessMouseEvent(MouseEventArgs args)
208213
if (!WantsMouseEvents || args.Handled)
209214
return false;
210215

216+
// Handle right-click
217+
if (args.HasFlag(MouseFlags.Button3Clicked))
218+
{
219+
MouseRightClick?.Invoke(this, args);
220+
return true;
221+
}
222+
211223
// Handle double-click (driver-level detection - preferred method)
212224
if (args.HasFlag(MouseFlags.Button1DoubleClicked) && _doubleClickEnabled)
213225
{

0 commit comments

Comments
 (0)