--- a/ui/winui/table.cpp Thu Oct 12 16:03:35 2023 +0200 +++ b/ui/winui/table.cpp Fri Oct 13 11:26:47 2023 +0200 @@ -38,6 +38,7 @@ #include <winrt/Microsoft.UI.Xaml.Data.h> #include <winrt/Microsoft.UI.Xaml.Media.h> #include <winrt/Microsoft.UI.Xaml.Input.h> +#include <winrt/Windows.UI.Core.h> using namespace winrt; using namespace Microsoft::UI::Xaml; @@ -120,6 +121,13 @@ winrt::Windows::UI::Color selectedFg = { 255, 0, 90, 158 }; // test color selectedBorderBrush = SolidColorBrush(selectedFg); + + grid.KeyDown( + winrt::Microsoft::UI::Xaml::Input::KeyEventHandler( + [=](IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const& args) { + // key event for hanling the table cursor or enter + }) + ); } void UiTable::add_header(UiModel* model) { @@ -190,6 +198,8 @@ } for (int col = 0; col < header.size(); col++) { + // create ui elements with the correct cell border + // dependeing on the column Border cellBorder = Border(); cellBorder.Background(defaultBrush); TextBlock cell = TextBlock(); @@ -204,26 +214,60 @@ else { cellBorder.BorderThickness(b2); } + Thickness padding = { 10,0,4,0 }; + cell.Padding(padding); + cell.VerticalAlignment(VerticalAlignment::Stretch); + // set cell value char* value = (char*)getvalue(elm, col); if (value) { wchar_t* wstr = str2wstr(value, nullptr); cell.Text(winrt::hstring(wstr)); free(wstr); } - Thickness padding = { 10,0,4,0 }; - cell.Padding(padding); - cell.VerticalAlignment(VerticalAlignment::Stretch); // event handler cellBorder.PointerPressed( winrt::Microsoft::UI::Xaml::Input::PointerEventHandler( [=](IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& args) { - if (selection > 0) { - row_background(selection, defaultBrush, defaultBrush); + winrt::Windows::System::VirtualKeyModifiers modifiers = args.KeyModifiers(); + + if (modifiers == winrt::Windows::System::VirtualKeyModifiers::Control) { + // add/remove current row + if (!is_row_selected(row)) { + row_background(row, selectedBrush, selectedBorderBrush); + selection.push_back(row); + } + else { + row_background(row, highlightBrush, highlightBrush); + remove_from_selection(row); + } } - row_background(row, selectedBrush, selectedBorderBrush); - selection = row; + else if (modifiers == winrt::Windows::System::VirtualKeyModifiers::None || selection.size() == 0) { + // no modifier or shift is pressed but there is no selection + if (selection.size() > 0) { + change_rows_bg(selection, defaultBrush, defaultBrush); + } + + row_background(row, selectedBrush, selectedBorderBrush); + selection = { row }; + } + else if (modifiers == winrt::Windows::System::VirtualKeyModifiers::Shift) { + // select everything between the first selection and the current row + std::sort(selection.begin(), selection.end()); + int first = selection.front(); + + // clear previous selection + change_rows_bg(selection, defaultBrush, defaultBrush); + + // create new selection + std::vector<int> newselection; + for (int s = first; s <= row; s++) { + newselection.push_back(s); + } + selection = newselection; + change_rows_bg(selection, selectedBrush, selectedBorderBrush); + } }) ); cellBorder.PointerReleased( @@ -235,7 +279,7 @@ cellBorder.PointerEntered( winrt::Microsoft::UI::Xaml::Input::PointerEventHandler( [=](IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& args) { - if (selection != row) { + if (!is_row_selected(row)) { row_background(row, highlightBrush, highlightBrush); } }) @@ -243,7 +287,7 @@ cellBorder.PointerExited( winrt::Microsoft::UI::Xaml::Input::PointerEventHandler( [=](IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& args) { - if (selection != row) { + if (!is_row_selected(row)) { row_background(row, defaultBrush, defaultBrush); } }) @@ -284,3 +328,16 @@ } } } + +void UiTable::change_rows_bg(std::vector<int> rows, winrt::Microsoft::UI::Xaml::Media::Brush brush, winrt::Microsoft::UI::Xaml::Media::Brush borderBrush) { + std::for_each(rows.cbegin(), rows.cend(), [&](const int& row) {row_background(row, brush, borderBrush); }); +} + +bool UiTable::is_row_selected(int row) { + return std::find(selection.begin(), selection.end(), row) != selection.end() ? true : false; +} + +void UiTable::remove_from_selection(int row) { + selection.erase(std::remove(selection.begin(), selection.end(), row), selection.end()); + selection.shrink_to_fit(); +}