mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-19 21:41:15 +00:00
Teach the command palette to clamp its indices on page up/down (#8190)
This commit will teach CommandPalette to clamp the scroll page up and scroll page down navigation so as to not wrap. Closes #8189
This commit is contained in:
@@ -118,48 +118,87 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Scrolls the focus up or down the list of commands.
|
||||
// - Scroll the command palette to the specified index
|
||||
// Arguments:
|
||||
// - pageDown: if true, we're attempting to move to the last visible item in the
|
||||
// list. Otherwise, we're attempting to move to the first visible item.
|
||||
// - index within a list view of commands
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollDown(const bool pageDown)
|
||||
void CommandPalette::_scrollToIndex(uint32_t index)
|
||||
{
|
||||
auto numItems = _filteredActionsView().Items().Size();
|
||||
|
||||
if (numItems == 0)
|
||||
{
|
||||
// if the list is empty no need to scroll
|
||||
return;
|
||||
}
|
||||
|
||||
auto clampedIndex = std::clamp<int32_t>(index, 0, numItems - 1);
|
||||
_filteredActionsView().SelectedIndex(clampedIndex);
|
||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Computes the number of visible commands
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the approximate number of items visible in the list (in other words the size of the page)
|
||||
uint32_t CommandPalette::_getNumVisibleItems()
|
||||
{
|
||||
const auto container = _filteredActionsView().ContainerFromIndex(0);
|
||||
const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>();
|
||||
const auto itemHeight = ::base::saturated_cast<int>(item.ActualHeight());
|
||||
const auto listHeight = ::base::saturated_cast<int>(_filteredActionsView().ActualHeight());
|
||||
const int numVisibleItems = listHeight / itemHeight;
|
||||
|
||||
auto selected = _filteredActionsView().SelectedIndex();
|
||||
const int numItems = ::base::saturated_cast<int>(_filteredActionsView().Items().Size());
|
||||
|
||||
const auto newIndex = ((numItems + selected + (pageDown ? numVisibleItems : -numVisibleItems)) % numItems);
|
||||
_filteredActionsView().SelectedIndex(newIndex);
|
||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||
return listHeight / itemHeight;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the focus either to the top item or to the end item in the list of commands.
|
||||
// - Scrolls the focus one page up the list of commands.
|
||||
// Arguments:
|
||||
// - end: if true, we're attempting to move to the last item in the
|
||||
// list. Otherwise, we're attempting to move to the first item.
|
||||
// Depends on the pageUpDown argument.
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::GoEnd(const bool end)
|
||||
void CommandPalette::ScrollPageUp()
|
||||
{
|
||||
const auto lastIndex = ::base::saturated_cast<int>(_filteredActionsView().Items().Size() - 1);
|
||||
if (end)
|
||||
{
|
||||
_filteredActionsView().SelectedIndex(lastIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_filteredActionsView().SelectedIndex(0);
|
||||
}
|
||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||
auto selected = _filteredActionsView().SelectedIndex();
|
||||
auto numVisibleItems = _getNumVisibleItems();
|
||||
_scrollToIndex(selected - numVisibleItems);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Scrolls the focus one page down the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollPageDown()
|
||||
{
|
||||
auto selected = _filteredActionsView().SelectedIndex();
|
||||
auto numVisibleItems = _getNumVisibleItems();
|
||||
_scrollToIndex(selected + numVisibleItems);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the focus to the top item in the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollToTop()
|
||||
{
|
||||
_scrollToIndex(0);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the focus to the bottom item in the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollToBottom()
|
||||
{
|
||||
_scrollToIndex(_filteredActionsView().Items().Size() - 1);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -241,25 +280,25 @@ namespace winrt::TerminalApp::implementation
|
||||
else if (key == VirtualKey::PageUp)
|
||||
{
|
||||
// Action Mode: Move focus to the first visible item in the list.
|
||||
ScrollDown(false);
|
||||
ScrollPageUp();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::PageDown)
|
||||
{
|
||||
// Action Mode: Move focus to the last visible item in the list.
|
||||
ScrollDown(true);
|
||||
ScrollPageDown();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::Home)
|
||||
{
|
||||
// Action Mode: Move focus to the first item in the list.
|
||||
GoEnd(false);
|
||||
ScrollToTop();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::End)
|
||||
{
|
||||
// Action Mode: Move focus to the last item in the list.
|
||||
GoEnd(true);
|
||||
ScrollToBottom();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::Enter)
|
||||
|
||||
@@ -41,9 +41,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void SelectNextItem(const bool moveDown);
|
||||
|
||||
void ScrollDown(const bool pageDown);
|
||||
|
||||
void GoEnd(const bool end);
|
||||
void ScrollPageUp();
|
||||
void ScrollPageDown();
|
||||
void ScrollToTop();
|
||||
void ScrollToBottom();
|
||||
|
||||
// Tab Switcher
|
||||
void EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx);
|
||||
@@ -119,6 +120,9 @@ namespace winrt::TerminalApp::implementation
|
||||
void _dispatchCommandline();
|
||||
void _dismissPalette();
|
||||
|
||||
void _scrollToIndex(uint32_t index);
|
||||
uint32_t _getNumVisibleItems();
|
||||
|
||||
friend class TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user