From 3935699262f15faeee9dccb74a926a1600fecf81 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 19 Oct 2020 16:31:08 +1100 Subject: [PATCH 1/2] fix(windows): tweak scrolling in keyboard menu Fixes #3694. The keyboard menu would sometimes scroll too far, which could be confusing for the end user. This fix stops the scroll once the last item is in view; it also tweaks the down arrow key handler to ensure that the current item is correctly scrolled into view. --- windows/src/engine/keyman/UfrmKeymanMenu.pas | 45 +++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/windows/src/engine/keyman/UfrmKeymanMenu.pas b/windows/src/engine/keyman/UfrmKeymanMenu.pas index 28bcecddc7..1548f32e0f 100644 --- a/windows/src/engine/keyman/UfrmKeymanMenu.pas +++ b/windows/src/engine/keyman/UfrmKeymanMenu.pas @@ -362,11 +362,12 @@ end; procedure TfrmKeymanMenu.PopupEx(mnu: TPopupMenu; X, Y: Integer; IconRect: TRect); // I3990 var kmi: TKeymanMenuItem; - i, ItemWidth, ItemHeight: Integer; + i, ItemWidth, ItemHeight, TempItemHeight: Integer; v: Integer; begin Fmnu := mnu; + MaxScrollPosition := 0; MaxKeyboardWidth := 0; MaxItemWidth := 0; TotalKeyboardHeight := 0; @@ -411,7 +412,6 @@ begin MaxKeyboardWidth := ItemWidth; Inc(TotalKeyboardHeight, ItemHeight); - Inc(MaxScrollPosition); end else begin @@ -426,16 +426,34 @@ begin end; end; - Dec(MaxScrollPosition); // Don't allow scroll off the end of the list - // // Do we need scrollable keyboard list? Only if it's greater than 75% of screen height // - ScrollableView := TotalKeyboardHeight > (Screen.Height * 3 div 4); + ScrollableView := TotalKeyboardHeight > (Screen.Height * 1 div 5); if ScrollableView then begin - TotalKeyboardHeight := Screen.Height * 3 div 4; + TotalKeyboardHeight := Screen.Height * 1 div 5; + + // Calculate the maximum scroll + TempItemHeight := 0; + for i := Fmnu.Items.Count - 1 downto 0 do + begin + if Fmnu.Items[i] is TKeymanMenuItem then + begin + kmi := Fmnu.Items[i] as TKeymanMenuItem; + kmi.OnMeasureItem(kmi, Canvas, ItemWidth, ItemHeight); + if (kmi.CMIItemType = _mitKeyboardsList) then + begin + Inc(TempItemHeight, ItemHeight); + if TempItemHeight > TotalKeyboardHeight - ScrollBoxHeight*2 then + begin + MaxScrollPosition := i + 1; + Break; + end; + end; + end; + end; end; if not FIsKeyboardMenu then @@ -726,18 +744,6 @@ begin if not Assigned(Fmnu) or not Assigned(Fmnu.Items) then Exit; // I2884 case Key of - {VK_NEXT: - begin - Key := 0; - if ScrollableView and (ScrollPosition < MaxScrollPosition) then - Inc(ScrollPosition); - end; - VK_PRIOR: - begin - Key := 0; - if ScrollableView and (ScrollPosition > 0) then - Dec(ScrollPosition); - end;} VK_UP: begin Key := 0; @@ -819,7 +825,8 @@ begin if FSelectedItemIndex < ScrollPosition then ScrollPosition := FSelectedItemIndex else - while FItemRects[FSelectedItemIndex].Top + FItemOffsets[FSelectedItemIndex] < 0 do + while (FItemRects[FSelectedItemIndex].Top + FItemOffsets[FSelectedItemIndex] < 0) or + (FItemRects[FSelectedItemIndex].Bottom + FItemOffsets[FSelectedItemIndex] > ScrollRects[1].Top) do begin Inc(ScrollPosition); RecalculateScrollPositions; From 929e32601ce9266c04564efa5632c7a195ab5beb Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 19 Oct 2020 16:33:59 +1100 Subject: [PATCH 2/2] chore(windows): remove debug code --- windows/src/engine/keyman/UfrmKeymanMenu.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/windows/src/engine/keyman/UfrmKeymanMenu.pas b/windows/src/engine/keyman/UfrmKeymanMenu.pas index 1548f32e0f..10c54a1628 100644 --- a/windows/src/engine/keyman/UfrmKeymanMenu.pas +++ b/windows/src/engine/keyman/UfrmKeymanMenu.pas @@ -430,10 +430,10 @@ begin // Do we need scrollable keyboard list? Only if it's greater than 75% of screen height // - ScrollableView := TotalKeyboardHeight > (Screen.Height * 1 div 5); + ScrollableView := TotalKeyboardHeight > (Screen.Height * 3 div 4); if ScrollableView then begin - TotalKeyboardHeight := Screen.Height * 1 div 5; + TotalKeyboardHeight := Screen.Height * 3 div 4; // Calculate the maximum scroll TempItemHeight := 0;