3131import android .os .Looper ;
3232import android .os .Message ;
3333import android .util .AttributeSet ;
34+ import android .view .Gravity ;
3435import android .view .MotionEvent ;
3536import android .view .View ;
37+ import android .widget .LinearLayout ;
38+ import android .widget .PopupWindow ;
3639import android .widget .Toast ;
3740
3841import androidx .core .graphics .ColorUtils ;
3942
43+ import io .github .yawnoc .utilities .Valuey ;
44+
4045/*
4146 A container that holds:
4247 - Candidates bar
@@ -58,13 +63,13 @@ public class InputContainer
5863
5964 private static final int SWIPE_ACTIVATION_DISTANCE = 40 ;
6065
61- private static final int SHIFT_DISABLED = 0 ;
66+ public static final int SHIFT_DISABLED = 0 ;
6267 private static final int SHIFT_SINGLE = 1 ;
6368 private static final int SHIFT_PERSISTENT = 2 ;
6469 private static final int SHIFT_INITIATED = 3 ;
6570 private static final int SHIFT_HELD = 4 ;
6671
67- private static final String KEYBOARD_FONT = "stroke_input_keyboard.ttf" ;
72+ public static final String KEYBOARD_FONT = "stroke_input_keyboard.ttf" ;
6873
6974 private static final float COLOUR_LIGHTNESS_CUTOFF = 0.7f ;
7075
@@ -97,11 +102,17 @@ public class InputContainer
97102 // Keyboard drawing
98103 private final Rect keyboardRectangle ;
99104 private final Paint keyboardFillPaint ;
105+
106+ // Key drawing
100107 private final Rect keyRectangle ;
101108 private final Paint keyFillPaint ;
102109 private final Paint keyBorderPaint ;
103110 private final Paint keyTextPaint ;
104111
112+ // Key preview
113+ private final KeyPreview keyPreview ;
114+ private final PopupWindow keyPreviewPopup ;
115+
105116 // Debugging
106117 private final Paint debugPaint ;
107118 private final Toast debugToast ;
@@ -129,6 +140,7 @@ public void handleMessage(Message message) {
129140 inputListener .onLongPress (activeKey .valueText );
130141 activeKey = null ;
131142 activePointerId = NONEXISTENT_POINTER_ID ;
143+ updateKeyPreview ();
132144 invalidate ();
133145 break ;
134146 }
@@ -155,6 +167,13 @@ public void handleMessage(Message message) {
155167 );
156168 keyTextPaint .setTextAlign (Paint .Align .CENTER );
157169
170+ final int popup_size = LinearLayout .LayoutParams .WRAP_CONTENT ;
171+
172+ keyPreview = new KeyPreview (context );
173+ keyPreviewPopup = new PopupWindow (keyPreview , popup_size , popup_size );
174+ keyPreviewPopup .setTouchable (false );
175+ keyPreviewPopup .setClippingEnabled (false );
176+
158177 debugPaint = new Paint (Paint .ANTI_ALIAS_FLAG );
159178 debugPaint .setStyle (Paint .Style .STROKE );
160179
@@ -245,7 +264,7 @@ public void onDraw(final Canvas canvas) {
245264
246265 keyRectangle .set (0 , 0 , key .width , key .height );
247266
248- int keyFillColour = key .keyFillColour ;
267+ int keyFillColour = key .fillColour ;
249268 if (
250269 key == activeKey
251270 ||
@@ -260,22 +279,22 @@ public void onDraw(final Canvas canvas) {
260279 )
261280 )
262281 {
263- keyFillColour = getContrastingColour (keyFillColour );
282+ keyFillColour = toPressedColour (keyFillColour );
264283 }
265284
266285 keyFillPaint .setColor (keyFillColour );
267- keyBorderPaint .setColor (key .keyBorderColour );
268- keyBorderPaint .setStrokeWidth (key .keyBorderThickness );
286+ keyBorderPaint .setColor (key .borderColour );
287+ keyBorderPaint .setStrokeWidth (key .borderThickness );
269288
270289 final int keyTextColour ;
271290 if (key == activeKey && swipeModeIsActivated ) {
272- keyTextColour = key .keyTextSwipeColour ;
291+ keyTextColour = key .textSwipeColour ;
273292 }
274293 else {
275- keyTextColour = key .keyTextColour ;
294+ keyTextColour = key .textColour ;
276295 }
277296 keyTextPaint .setColor (keyTextColour );
278- keyTextPaint .setTextSize (key .keyTextSize );
297+ keyTextPaint .setTextSize (key .textSize );
279298
280299 final String keyDisplayText ;
281300 if (debugModeIsActivated && key .valueText .equals ("SPACE" )) {
@@ -285,32 +304,24 @@ public void onDraw(final Canvas canvas) {
285304 : activeKey .valueText
286305 );
287306 }
288- else if (shiftMode == SHIFT_DISABLED ) {
289- keyDisplayText = key .displayText ;
290- }
291307 else {
292- keyDisplayText = key .valueTextShifted ;
308+ keyDisplayText = key .shiftAwareDisplayText ( shiftMode ) ;
293309 }
294310
295311 final float keyTextX = (
296312 key .width / 2f
297- + key .keyTextOffsetX
313+ + key .textOffsetX
298314 );
299315 final float keyTextY = (
300316 (key .height - keyTextPaint .ascent () - keyTextPaint .descent ()) / 2f
301- + key .keyTextOffsetY
317+ + key .textOffsetY
302318 );
303319
304320 canvas .translate (key .x , key .y );
305321
306322 canvas .drawRect (keyRectangle , keyFillPaint );
307323 canvas .drawRect (keyRectangle , keyBorderPaint );
308- canvas .drawText (
309- keyDisplayText ,
310- keyTextX ,
311- keyTextY ,
312- keyTextPaint
313- );
324+ canvas .drawText (keyDisplayText , keyTextX , keyTextY , keyTextPaint );
314325
315326 canvas .translate (-key .x , -key .y );
316327 }
@@ -330,7 +341,7 @@ else if (shiftMode == SHIFT_DISABLED) {
330341 Lighten a dark colour and darken a light colour.
331342 Used for key press colour changes.
332343 */
333- private static int getContrastingColour (final int colour ) {
344+ public static int toPressedColour (final int colour ) {
334345
335346 final float [] colourHSL = new float [3 ];
336347 ColorUtils .colorToHSL (colour , colourHSL );
@@ -365,6 +376,7 @@ public boolean onTouchEvent(final MotionEvent event) {
365376 shiftPointerId = NONEXISTENT_POINTER_ID ;
366377 activeKey = null ;
367378 activePointerId = NONEXISTENT_POINTER_ID ;
379+ updateKeyPreview ();
368380 invalidate ();
369381 return true ;
370382 }
@@ -490,6 +502,7 @@ private void sendDownEvent(
490502 activePointerY = y ;
491503
492504 sendAppropriateExtendedPressHandlerMessage (key );
505+ updateKeyPreview ();
493506 invalidate ();
494507 }
495508
@@ -520,6 +533,7 @@ else if (key == activeKey && isSwipeableKey(key)) {
520533 removeAllExtendedPressHandlerMessages ();
521534 sendAppropriateExtendedPressHandlerMessage (key );
522535 resetKeyRepeatIntervalMilliseconds ();
536+ updateKeyPreview ();
523537 shouldRedrawKeyboard = true ;
524538 }
525539
@@ -560,6 +574,7 @@ else if (key != null) {
560574 removeAllExtendedPressHandlerMessages ();
561575 resetKeyRepeatIntervalMilliseconds ();
562576 if (shouldRedrawKeyboard ) {
577+ updateKeyPreview ();
563578 invalidate ();
564579 }
565580 }
@@ -575,6 +590,7 @@ private void sendShiftDownEvent(final int pointerId) {
575590 }
576591 shiftPointerId = pointerId ;
577592
593+ updateKeyPreview ();
578594 invalidate ();
579595 }
580596
@@ -587,6 +603,7 @@ private void sendShiftMoveToEvent(final int pointerId) {
587603 activePointerId = NONEXISTENT_POINTER_ID ;
588604
589605 removeAllExtendedPressHandlerMessages ();
606+ updateKeyPreview ();
590607 invalidate ();
591608 }
592609
@@ -607,6 +624,7 @@ private void sendShiftMoveFromEvent(
607624 removeAllExtendedPressHandlerMessages ();
608625 sendAppropriateExtendedPressHandlerMessage (key );
609626 resetKeyRepeatIntervalMilliseconds ();
627+ updateKeyPreview ();
610628 invalidate ();
611629 }
612630
@@ -627,6 +645,7 @@ private void sendShiftUpEvent(boolean shouldRedrawKeyboard) {
627645 shiftPointerId = NONEXISTENT_POINTER_ID ;
628646
629647 if (shouldRedrawKeyboard ) {
648+ updateKeyPreview ();
630649 invalidate ();
631650 }
632651 }
@@ -650,6 +669,46 @@ private boolean isSwipeableKey(final Key key) {
650669 return key != null && key .isSwipeable ;
651670 }
652671
672+ private void updateKeyPreview () {
673+
674+ if (activeKey == null || !activeKey .isPreviewable ) {
675+ if (keyPreviewPopup .isShowing ()) {
676+ keyPreviewPopup .dismiss ();
677+ }
678+ return ;
679+ }
680+
681+ keyPreview .update (activeKey , shiftMode );
682+
683+ final int previewWidth = keyPreview .width ;
684+ final int previewHeight = keyPreview .height ;
685+ final int previewMargin = activeKey .previewMargin ;
686+
687+ final int keyboardLeftX = 0 ;
688+ final int keyboardRightX = keyboard .getWidth () - previewWidth ;
689+ final int previewX =
690+ (int ) Valuey .clipValueToRange (
691+ activeKey .x - (previewWidth - activeKey .width ) / 2f ,
692+ keyboardLeftX ,
693+ keyboardRightX
694+ );
695+ final int previewY = activeKey .y - previewHeight - previewMargin ;
696+
697+ if (keyPreviewPopup .isShowing ()) {
698+ keyPreviewPopup .update (previewX , previewY , previewWidth , previewHeight );
699+ }
700+ else {
701+ keyPreviewPopup .setWidth (previewWidth );
702+ keyPreviewPopup .setHeight (previewHeight );
703+ keyPreviewPopup .showAtLocation (
704+ this ,
705+ Gravity .NO_GRAVITY ,
706+ previewX ,
707+ previewY
708+ );
709+ }
710+ }
711+
653712 private void sendAppropriateExtendedPressHandlerMessage (
654713 final Key key
655714 )
0 commit comments