Skip to content
Open
7 changes: 6 additions & 1 deletion src/HASS.Agent.Staging/HASS.Agent/Forms/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,15 @@ private async void ShowMain()
/// </summary>
private async void ShowQuickActions()
{

// check if quickactions aren't already open, and if there are any actions
if (HelperFunctions.CheckIfFormIsOpen("QuickActions"))
{
await HelperFunctions.TryBringToFront("QuickActions");
var quickActionsForm = HelperFunctions.GetForm("QuickActions") as QuickActions.QuickActions;
var result = await HelperFunctions.TryBringToFront(quickActionsForm);
if (result)
quickActionsForm.SelectNextQuickActionItem();

return;
}

Expand Down
218 changes: 154 additions & 64 deletions src/HASS.Agent.Staging/HASS.Agent/Forms/QuickActions/QuickActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace HASS.Agent.Forms.QuickActions
public partial class QuickActions : MetroForm
{
public event EventHandler ClearFocus;

private readonly List<QuickAction> _quickActions = new();
private readonly List<QuickActionPanelControl> _quickActionPanelControls = new();

Expand All @@ -26,7 +26,10 @@ public partial class QuickActions : MetroForm

public QuickActions(List<QuickAction> quickActions)
{
foreach (var quickAction in quickActions) _quickActions.Add(quickAction);
foreach (var quickAction in quickActions)
{
_quickActions.Add(quickAction);
}

InitializeComponent();
}
Expand Down Expand Up @@ -55,7 +58,11 @@ private async void QuickActions_Load(object sender, EventArgs e)

// check hass status
var hass = await CheckHassManagerAsync();
if (!hass) CloseWindow();
if (!hass)
CloseWindow();

// select first item
SelectQuickActionItem(0, 0);
}

/// <summary>
Expand All @@ -73,24 +80,33 @@ private void BuildLayout()

_columns = columns;
_rows = rows;

// prepare our panel
PnlActions.AutoSize = true;

for (var c = 0; c <= _columns; c++) PnlActions.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 152));
PnlActions.ColumnCount = _columns;

for (var r = 0; r <= _columns; r++) PnlActions.RowStyles.Add(new RowStyle(SizeType.Absolute, 255));
PnlActions.RowCount = _rows;

PnlActions.CellBorderStyle = TableLayoutPanelCellBorderStyle.None;


for (var c = 0; c <= _columns; c++)
{
PnlActions.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 152));
}

for (var r = 0; r <= _columns; r++)
{
PnlActions.RowStyles.Add(new RowStyle(SizeType.Absolute, 255));
}

// resize window
Width = 152 * columns + 20;
Height = 255 * rows + 30;

if (columns > 1) Width += 5 * (columns - 1);
if (rows > 1) Height += 5 * (rows - 1);
if (columns > 1)
Width += 5 * (columns - 1);
if (rows > 1)
Height += 5 * (rows - 1);

// add the quickactions as controls
var currentColumn = 0;
Expand All @@ -105,34 +121,57 @@ private void BuildLayout()
Row = currentRow
};

// update position when item is selected by mouse cursor
panelControl.QuickActionControl.MouseEnter += QuickActionItemMouseEnter;

// add to list
_quickActionPanelControls.Add(panelControl);

// store position
if (!_rowColumnCounts.ContainsKey(currentRow)) _rowColumnCounts.Add(currentRow, currentColumn);
else _rowColumnCounts[currentRow] = currentColumn;

if (!_rowColumnCounts.ContainsKey(currentRow))
{
_rowColumnCounts.Add(currentRow, currentColumn);
}
else
{
_rowColumnCounts[currentRow] = currentColumn;
}

// add to the panel
PnlActions.Controls.Add(quickAction, currentColumn, currentRow);

// set next column & row
if (currentColumn < columns - 1) currentColumn++;
if (currentColumn < columns - 1)
{
currentColumn++;
}
else
{
// on to the next row (if there is one)
currentColumn = 0;
if (currentRow < rows - 1) currentRow++;
if (currentRow < rows - 1)
currentRow++;
}
}
}

private void QuickActionItemMouseEnter(object sender, EventArgs e)
{
var position = PnlActions.GetPositionFromControl(sender as QuickActionControl);
_selectedColumn = position.Column;
_selectedRow = position.Row;
return;
}

/// <summary>
/// Tries to close the window
/// </summary>
internal void CloseWindow()
{
if (!IsHandleCreated) return;
if (IsDisposed) return;
if (!IsHandleCreated)
return;
if (IsDisposed)
return;

Invoke(new MethodInvoker(delegate
{
Expand Down Expand Up @@ -184,8 +223,10 @@ private async Task<bool> CheckHassManagerAsync()
/// <param name="loading"></param>
private void SetGuiLoading(bool loading)
{
if (!IsHandleCreated) return;
if (IsDisposed) return;
if (!IsHandleCreated)
return;
if (IsDisposed)
return;

Invoke(new MethodInvoker(delegate
{
Expand Down Expand Up @@ -216,6 +257,25 @@ private void QuickActions_FormClosing(object sender, FormClosingEventArgs e)
}
}

/// <summary>
/// Selects QuickAction item at given position
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
private bool SelectQuickActionItem(int row, int column)
{
var control = _quickActionPanelControls.Find(x => x.Row == row && x.Column == column);
if (control == null)
return false;

control.QuickActionControl.OnFocus();
_selectedColumn = column;
_selectedRow = row;

return true;
}

/// <summary>
/// Intercepts and processes the arrow keys
/// </summary>
Expand All @@ -226,83 +286,89 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
try
{
// if never pressed before ..
// should not happen, but select first item if nothing is selected
if (_selectedColumn == -1)
{
// .. always select first one
var control = _quickActionPanelControls.Find(x => x.Row == 0 && x.Column == 0);
if (control == null) return true;
SelectQuickActionItem(0, 0);

control.QuickActionControl.OnFocus();
_selectedColumn = 0;
_selectedRow = 0;
return true;
}

if (keyData == Keys.Down)
{
// is there a next row?
if (_selectedRow == _rows - 1) return true;

// jep, select the control below (or the last)
_selectedRow++;
var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
if (control == null)
// wrap up if we're at the last row
if (_selectedRow == _rows - 1)
{
// none found with same column, get the last
_selectedColumn = _rowColumnCounts[_selectedRow];
control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
control?.QuickActionControl.OnFocus();
SelectQuickActionItem(0, _selectedColumn);

return true;
}

control.QuickActionControl.OnFocus();
var nextRow = _selectedRow + 1;
var selected = SelectQuickActionItem(nextRow, _selectedColumn);
if (!selected)
{
SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]);
}

return true;
}

if (keyData == Keys.Right)
{
// is there a next column?
var maxColumnsForRow = _rowColumnCounts[_selectedRow];
if (_selectedColumn == maxColumnsForRow) return true;

// jep, select the control to the right
_selectedColumn++;
var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
control?.QuickActionControl.OnFocus();
// wrap up to first row if there is nothing below
if (_selectedColumn == maxColumnsForRow)
{
var nextRow = _selectedRow == (_rows - 1) ? 0 : _selectedRow + 1;
SelectQuickActionItem(nextRow, 0);

return true;
}

SelectQuickActionItem(_selectedRow, _selectedColumn + 1);

return true;
}

if (keyData == Keys.Left)
{
// is there a previous column?
if (_selectedColumn == 0) return true;
// wrap up to last row if there is nothing above
if (_selectedColumn == 0)
{
var nextRow = _selectedRow == 0 ? _rows - 1 : _selectedRow - 1;
SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]);

return true;
}

SelectQuickActionItem(_selectedRow, _selectedColumn - 1);

// jep, select the control to the left
_selectedColumn--;
var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
control?.QuickActionControl.OnFocus();
return true;
}

if (keyData == Keys.Up)
{
// is there a previous row?
if (_selectedRow == 0) return true;
var nextRow = _selectedRow - 1;

// jep, select the control above (or the last)
_selectedRow--;
var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
if (control == null)
// wrap down if we're at the first row
if (_selectedRow == 0)
{
// none found with same column, get the first
_selectedColumn = 0;
control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn);
control?.QuickActionControl.OnFocus();
nextRow = _rows - 1;
var maxColumnsForNextRow = _rowColumnCounts[nextRow];
var nextColumn = maxColumnsForNextRow < _selectedColumn ? maxColumnsForNextRow : _selectedColumn;
SelectQuickActionItem(nextRow, nextColumn);

return true;
}

control.QuickActionControl.OnFocus();
var selected = SelectQuickActionItem(nextRow, _selectedColumn);
if (!selected)
{
SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]);
}

return true;
}
}
Expand All @@ -315,6 +381,27 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
return base.ProcessCmdKey(ref msg, keyData);
}

/// <summary>
/// Selects next Quick Action item following right->down->up pattern
/// </summary>
public void SelectNextQuickActionItem()
{
var maxColumnsForRow = _rowColumnCounts[_selectedRow];

// are we at the end of the row / wrap up to first row if there is nothing below
if (_selectedColumn == maxColumnsForRow)
{
var nextRow = _selectedRow == (_rows - 1) ? 0 : _selectedRow + 1;
SelectQuickActionItem(nextRow, 0);

return;
}

SelectQuickActionItem(_selectedRow, _selectedColumn + 1);

return;
}

/// <summary>
/// Triggers clearing the focus of all controls
/// </summary>
Expand All @@ -323,9 +410,12 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData)

private void QuickActions_ResizeEnd(object sender, EventArgs e)
{
if (Variables.ShuttingDown) return;
if (!IsHandleCreated) return;
if (IsDisposed) return;
if (Variables.ShuttingDown)
return;
if (!IsHandleCreated)
return;
if (IsDisposed)
return;

try
{
Expand Down
Loading