From 2f124d6ef10b02e01bb2727066061607eb68e8ec Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Wed, 8 Dec 2021 12:46:51 +0100
Subject: [PATCH] Add virtual keyboard for comparison operators only

---
 docs/release-notes-player.txt                 |  1 +
 .../text-area/text-area-element.ts            |  2 +-
 .../text-field/text-field-element.ts          |  2 +-
 .../element-model-properties.component.html   |  2 +-
 projects/editor/src/assets/i18n/de.json       |  1 +
 .../element-container.component.ts            |  2 +-
 .../keyboard/keyboard.component.html          | 10 ++++--
 .../components/keyboard/keyboard.component.ts |  2 +-
 .../numbers-keyboard.component.css            |  4 +++
 .../numbers-keyboard.component.html           | 36 ++++++++++++++-----
 .../numbers-keyboard.component.ts             | 31 ++++++++++------
 11 files changed, 68 insertions(+), 25 deletions(-)

diff --git a/docs/release-notes-player.txt b/docs/release-notes-player.txt
index e7fc05851..3350edb39 100644
--- a/docs/release-notes-player.txt
+++ b/docs/release-notes-player.txt
@@ -1,6 +1,7 @@
 Player
 ======
 1.10.0
+ - Add virtual keyboard for comparison operators only
  - Fix volume setting of audios and videos
  - Fix page turning
 
diff --git a/projects/common/ui-elements/text-area/text-area-element.ts b/projects/common/ui-elements/text-area/text-area-element.ts
index 3b8d8436b..f08c649d2 100644
--- a/projects/common/ui-elements/text-area/text-area-element.ts
+++ b/projects/common/ui-elements/text-area/text-area-element.ts
@@ -13,7 +13,7 @@ export class TextAreaElement extends InputElement implements PositionedElement,
   appearance: 'standard' | 'legacy' | 'fill' | 'outline' = 'outline';
   resizeEnabled: boolean = false;
   rowCount: number = 3;
-  inputAssistancePreset: 'none' | 'french' | 'numbers' | 'numbersAndOperators' = 'none';
+  inputAssistancePreset: 'none' | 'french' | 'numbers' | 'numbersAndOperators' | 'comparisonOperators' = 'none';
   inputAssistancePosition: 'floating' | 'right' = 'floating';
 
   positionProps: PositionProperties;
diff --git a/projects/common/ui-elements/text-field/text-field-element.ts b/projects/common/ui-elements/text-field/text-field-element.ts
index 54dcfbaf3..890a55379 100644
--- a/projects/common/ui-elements/text-field/text-field-element.ts
+++ b/projects/common/ui-elements/text-field/text-field-element.ts
@@ -17,7 +17,7 @@ export class TextFieldElement extends InputElement implements PositionedElement,
   maxLengthWarnMessage: string = 'Eingabe zu lang';
   pattern: string = '';
   patternWarnMessage: string = 'Eingabe entspricht nicht der Vorgabe';
-  inputAssistancePreset: 'none' | 'french' | 'numbers' | 'numbersAndOperators' = 'none';
+  inputAssistancePreset: 'none' | 'french' | 'numbers' | 'numbersAndOperators' | 'comparisonOperators' = 'none';
   inputAssistancePosition: 'floating' | 'right' = 'floating';
   clearable: boolean = false;
 
diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html
index fcd3fe997..6c85a6a3a 100644
--- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html
+++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html
@@ -342,7 +342,7 @@
     <mat-label>{{'propertiesPanel.inputAssistance' | translate }}</mat-label>
     <mat-select [value]="combinedProperties.inputAssistancePreset"
                 (selectionChange)="updateModel.emit({ property: 'inputAssistancePreset', value: $event.value })">
-      <mat-option *ngFor="let option of ['none', 'french', 'numbers', 'numbersAndOperators']"
+      <mat-option *ngFor="let option of ['none', 'french', 'numbers', 'numbersAndOperators', 'comparisonOperators']"
                   [value]="option">
         {{ 'propertiesPanel.' + option | translate }}
       </mat-option>
diff --git a/projects/editor/src/assets/i18n/de.json b/projects/editor/src/assets/i18n/de.json
index 113fc1c08..56b73ee5a 100644
--- a/projects/editor/src/assets/i18n/de.json
+++ b/projects/editor/src/assets/i18n/de.json
@@ -109,6 +109,7 @@
     "french": "Französische Sonderzeichen",
     "numbers": "Zahlen",
     "numbersAndOperators": "Zahlen & Operatoren",
+    "comparisonOperators": "Vergleichsoperatoren",
     "inputAssistancePosition": "Eingabehilfeposition",
     "floating": "schwebend",
     "lineColoring": "Zeilenfärbung",
diff --git a/projects/player/src/app/components/element-container/element-container.component.ts b/projects/player/src/app/components/element-container/element-container.component.ts
index c5452bfce..f1c2fd053 100644
--- a/projects/player/src/app/components/element-container/element-container.component.ts
+++ b/projects/player/src/app/components/element-container/element-container.component.ts
@@ -40,7 +40,7 @@ export class ElementContainerComponent implements OnInit {
   @Input() pageIndex!: number;
 
   isKeyboardOpen!: boolean;
-  keyboardLayout!: 'french' | 'numbers' | 'numbersAndOperators' | 'none';
+  keyboardLayout!: 'french' | 'numbers' | 'numbersAndOperators' | 'comparisonOperators' | 'none';
   focussedInputElement!: HTMLTextAreaElement | HTMLInputElement;
 
   private ngUnsubscribe = new Subject<void>();
diff --git a/projects/player/src/app/components/keyboard/keyboard.component.html b/projects/player/src/app/components/keyboard/keyboard.component.html
index 4612d420b..182c78456 100644
--- a/projects/player/src/app/components/keyboard/keyboard.component.html
+++ b/projects/player/src/app/components/keyboard/keyboard.component.html
@@ -6,10 +6,16 @@
     <app-french-keyboard *ngIf="preset === 'french'"></app-french-keyboard>
     <app-numbers-keyboard *ngIf="preset === 'numbers'"
                           [inputComponent]="inputComponent"
-                          [showOperators]="false"></app-numbers-keyboard>
+                          [useComparisonOperators]="false"
+                          [showNumbersWithOperators]="false"></app-numbers-keyboard>
     <app-numbers-keyboard *ngIf="preset === 'numbersAndOperators'"
                           [inputComponent]="inputComponent"
-                          [showOperators]="true"></app-numbers-keyboard>
+                          [useComparisonOperators]="false"
+                          [showNumbersWithOperators]="true"></app-numbers-keyboard>
+    <app-numbers-keyboard *ngIf="preset === 'comparisonOperators'"
+                          [inputComponent]="inputComponent"
+                          [useComparisonOperators]="true"
+                          [showNumbersWithOperators]="false"></app-numbers-keyboard>
   </div>
 </div>
 
diff --git a/projects/player/src/app/components/keyboard/keyboard.component.ts b/projects/player/src/app/components/keyboard/keyboard.component.ts
index d57f0c7b5..6a2f05f56 100644
--- a/projects/player/src/app/components/keyboard/keyboard.component.ts
+++ b/projects/player/src/app/components/keyboard/keyboard.component.ts
@@ -6,7 +6,7 @@ import { Component, Input } from '@angular/core';
   styleUrls: ['./keyboard.component.css']
 })
 export class KeyboardComponent {
-  @Input() preset!: 'french' | 'numbers' | 'numbersAndOperators' | 'none';
+  @Input() preset!: 'french' | 'numbers' | 'numbersAndOperators' | 'comparisonOperators' | 'none';
   @Input() inputComponent!: HTMLTextAreaElement | HTMLInputElement;
 
   onMouseDown = (event: MouseEvent, stopPropagation: boolean): void => {
diff --git a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.css b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.css
index 78dad79e6..54bc9d454 100644
--- a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.css
+++ b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.css
@@ -7,6 +7,10 @@
   color: #fff;
 }
 
+.clear-button-container{
+  margin-left: 45px;
+}
+
 .grid-layout {
   margin-top: 15px;
   display: grid;
diff --git a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.html b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.html
index 32c55f0af..7327dd9ac 100644
--- a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.html
+++ b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.html
@@ -1,17 +1,37 @@
-<div *ngFor="let row of numbers">
-  <ng-container *ngFor="let key of row">
-    <app-key [key]="key"></app-key>
-    <button *ngIf="key === '0'"
-            type="button"
+<ng-container *ngTemplateOutlet="useComparisonOperators ? comparisonOperatorsTemplate : numbersTemplate"></ng-container>
+
+<ng-template #comparisonOperatorsTemplate>
+  <div *ngFor="let row of comparisonOperators">
+    <ng-container *ngFor="let key of row">
+      <app-key [key]="key"></app-key>
+    </ng-container>
+  </div>
+  <div class="clear-button-container">
+    <button type="button"
             mat-mini-fab
             class="delete-characters"
             (click)="keyboardService.deleterCharacters()">
       <mat-icon>keyboard_backspace</mat-icon>
     </button>
-  </ng-container>
-</div>
+  </div>
+</ng-template>
+
+<ng-template #numbersTemplate>
+  <div *ngFor="let row of numbers; let last = last">
+    <ng-container *ngFor="let key of row">
+      <app-key [key]="key"></app-key>
+      <button *ngIf="last"
+              type="button"
+              mat-mini-fab
+              class="delete-characters"
+              (click)="keyboardService.deleterCharacters()">
+        <mat-icon>keyboard_backspace</mat-icon>
+      </button>
+    </ng-container>
+  </div>
+</ng-template>
 
-<div *ngIf="showOperators" class="grid-layout">
+<div *ngIf="showNumbersWithOperators" class="grid-layout">
   <ng-container *ngFor="let row of operators; let rowIndex = index ">
     <ng-container *ngFor="let key of row; let columnIndex = index">
       <app-key *ngIf="key !== '='"
diff --git a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.ts b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.ts
index 7d24927b7..4bfe98b0b 100644
--- a/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.ts
+++ b/projects/player/src/app/components/numbers-keyboard/numbers-keyboard.component.ts
@@ -7,9 +7,15 @@ import { KeyboardService } from '../../services/keyboard.service';
   styleUrls: ['./numbers-keyboard.component.css']
 })
 export class NumbersKeyboardComponent implements AfterViewInit {
-  @Input() showOperators!: boolean;
+  @Input() useComparisonOperators!: boolean;
+  @Input() showNumbersWithOperators!: boolean;
   @Input() inputComponent!: HTMLTextAreaElement | HTMLInputElement;
   allowedKeys!: string[];
+
+  readonly comparisonOperators: string[][] = [
+    ['<', '=', '>']
+  ];
+
   readonly numbers: string[][] = [
     ['7', '8', '9'],
     ['4', '5', '6'],
@@ -27,16 +33,21 @@ export class NumbersKeyboardComponent implements AfterViewInit {
   }
 
   ngAfterViewInit(): void {
-    this.allowedKeys = this.showOperators ?
-      this.operators
-        .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue)).concat(
-          this.numbers
-            .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue))
-        ) :
-      this.numbers
+    if (this.useComparisonOperators) {
+      this.allowedKeys = this.comparisonOperators
         .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue));
-    if (this.inputComponent) {
-      this.inputComponent.addEventListener('keydown', this.restrict.bind(this));
+    } else {
+      this.allowedKeys = this.showNumbersWithOperators ?
+        this.operators
+          .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue)).concat(
+            this.numbers
+              .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue))
+          ) :
+        this.numbers
+          .reduce((accumulator: string[], currentValue: string[]): string[] => accumulator.concat(currentValue));
+      if (this.inputComponent) {
+        this.inputComponent.addEventListener('keydown', this.restrict.bind(this));
+      }
     }
   }
 
-- 
GitLab