|
1 | | -# Virtual Keyboard (keyboard.ts) — Summary & API |
| 1 | +# Virtual Keyboard (`Keyboard.ts`) |
2 | 2 |
|
3 | | -This file implements an on-screen keyboard component for xrblocks with a few small helper classes and a fixed layout. |
| 3 | +A 3D on-screen virtual keyboard component for **xrblocks**. It allows users to type text using a customizable spatial interface in virtual or augmented reality. |
4 | 4 |
|
5 | | -## Exports |
| 5 | +--- |
6 | 6 |
|
7 | | -- `Keyboard` — main keyboard component (exported). |
8 | | -- `KeyboardButton` — internal button class (extends `xb.TextButton`). |
| 7 | +## Overview |
9 | 8 |
|
10 | | -## Key classes & interfaces |
| 9 | +The `Keyboard` component is a spatial UI panel that displays a full virtual QWERTY keyboard. It supports standard typing, shifted characters, caps lock, and special operations like backspace, tab, and enter. |
11 | 10 |
|
12 | | -- `SpecialKey` |
13 | | - - position: 'left' | 'right' | 'center' |
14 | | - - type: 'tab' | 'backspace' | 'shift_lock' | 'enter' | 'shift' | 'space' |
15 | | - - iconName: string |
16 | | - - weight?: number |
17 | | - - backgroundColor?: string |
| 11 | +--- |
18 | 12 |
|
19 | | -- `LayoutRow` |
20 | | - - textKeys?: string (sequence of non-special keys) |
21 | | - - shiftKeys?: string (shift variants aligned with textKeys) |
22 | | - - specialKeys: SpecialKey[] |
| 13 | +## Keyboard Layout |
23 | 14 |
|
24 | | -- `KeyboardButtonOptions` |
25 | | - - text: string |
26 | | - - fontSize: number |
27 | | - - backgroundColor: string |
28 | | - - originalKey: string |
29 | | - - shiftKey?: string | null |
| 15 | +The keyboard has **6 rows** structured using a grid layout: |
30 | 16 |
|
31 | | -- `KeyboardButton` extends `xb.TextButton` |
32 | | - - properties: `originalKey`, `shiftKey` |
| 17 | +- **Row 1:** Symbols (`~!@#$%^&*()_+`) |
| 18 | +- **Row 2:** Numbers and brackets (`` `1234567890<> ``) |
| 19 | +- **Row 3:** Top letter row (`qwertyuiop`) with a **Tab** key on the left and a **Backspace** key on the right. |
| 20 | +- **Row 4:** Middle letter row (`asdfghjkl`) with a **Caps Lock** key on the left and an **Enter** key on the right. |
| 21 | +- **Row 5:** Bottom letter row (`zxcvbnm,.`) with **Shift** keys on both the left and right. |
| 22 | +- **Row 6:** A centered **Space** bar. |
33 | 23 |
|
34 | | -## Key constants (defaults) |
| 24 | +--- |
35 | 25 |
|
36 | | -- KEY_WIDTH = 0.068 |
37 | | -- KEY_HEIGHT = 0.10 |
38 | | -- FONT_SIZE = 0.45 |
39 | | -- KEYBOARD_COLOR = '#5149ae' |
40 | | -- DEFAULT_KEY_COLOR = '#aa3939' |
41 | | -- SPECIAL_KEY_COLOR = '#3cb436' |
42 | | -- COL_SPACER = 0.01 |
43 | | -- ROW_SPACER = 0.015 |
44 | | -- TOTAL_KEYBOARD_WIDTH = 1.0 |
45 | | -- TOTAL_KEYBOARD_HEIGHT = computed from number of rows, key height and ROW_SPACER |
| 26 | +## How It Works |
46 | 27 |
|
47 | | -## Default layout (KEY_LAYOUT) |
| 28 | +### 1. UI Structure |
48 | 29 |
|
49 | | -- Row 1: number row with textKeys "`1234567890-+" and shiftKeys "~!@#$%^&\*()\_+" |
50 | | -- Row 2: `qwertyuiop` with left `tab` key and right `backspace` |
51 | | -- Row 3: `asdfghjkl` with left `shift_lock` and right `enter` |
52 | | -- Row 4: `zxcvbnm,.` with left and right `shift` keys |
53 | | -- Row 5: center `space` key (wide, weighted) |
| 30 | +- **Root Panel:** The entire keyboard is contained within a `SpatialPanel` (called `subspace`), which has a dark background and optional borders. |
| 31 | +- **Grid Layout:** The keys are organized using a `Grid` component. Columns and rows are sized dynamically using relative layout weights. |
| 32 | +- **Buttons:** |
| 33 | + - **Regular keys** are created as `KeyboardButton` (a custom class extending `TextButton`). |
| 34 | + - **Special keys** (like Tab, Enter, Space, Backspace, Caps Lock, Shift) use `IconButton` to display descriptive icons. |
54 | 35 |
|
55 | | -Special keys may set `weight` to span multiple columns; space is centered using side padding. |
| 36 | +### 2. Typing and State Management |
56 | 37 |
|
57 | | -## Behavior & state |
| 38 | +- **Transient Shift:** Pressing a **Shift** key toggles a temporary shifted state. After you type any character, the shifted state automatically turns off. |
| 39 | +- **Caps Lock:** Pressing the **Caps Lock** key toggles permanent uppercase. |
| 40 | +- **Upper/Lower Case Logic:** Letter buttons automatically switch between uppercase and lowercase based on an XOR logic: they display uppercase when `Shift` is active **or** `Caps Lock` is active, but not both. |
| 41 | +- **Buffer Updates:** Every key press updates an internal text buffer (`keyText`). |
58 | 42 |
|
59 | | -- Internal state: |
60 | | - - `keyText: string` — current buffer |
61 | | - - `isShifted: boolean` — transient shift state |
62 | | - - `isCapsLockOn: boolean` — caps lock state |
63 | | - - `textButtons: KeyboardButton[]` — all text buttons for updates |
| 43 | +--- |
64 | 44 |
|
65 | | -- Shift vs CapsLock: |
66 | | - - `produceUpper = isShifted !== isCapsLockOn` (XOR) |
67 | | - - Pressing a character while `isShifted` will reset `isShifted` (transient shift). |
68 | | - - `shift_lock` toggles `isCapsLockOn`. |
| 45 | +## Public API |
69 | 46 |
|
70 | | -- Special key handling: |
71 | | - - `backspace` removes last char |
72 | | - - `space` inserts `' '` |
73 | | - - `tab` inserts `'\t'` |
74 | | - - `enter` triggers enter callback |
75 | | - - `shift` toggles transient shift |
76 | | - - `shift_lock` toggles caps lock |
| 47 | +### Properties & Callbacks |
77 | 48 |
|
78 | | -- `refreshKeyboard()` updates visible labels for all text buttons (letters and shifted symbols). |
| 49 | +| Property | Type | Description | |
| 50 | +| :--------------- | :--------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | |
| 51 | +| `onTextChanged` | `((text: string) => void) \| null` | Triggered every time the typed text changes (e.g., on character addition, backspace, space, or tab). Passes the updated string. | |
| 52 | +| `onEnterPressed` | `((text: string) => void) \| null` | Triggered when the user presses the **Enter** key. Passes the current typed text buffer. | |
79 | 53 |
|
80 | | -## UI construction |
| 54 | +### Methods |
81 | 55 |
|
82 | | -- Uses `xb.SpatialPanel` as a root `subspace` with background color and size. |
83 | | -- Uses `xb.Grid` to build rows and columns for keys. |
84 | | -- Text keys are created as `KeyboardButton` instances; special keys use `xb.IconButton`. |
85 | | -- Buttons are added into panel cells; layout weights control key widths. |
| 56 | +#### `setText(text: string): void` |
86 | 57 |
|
87 | | -## Callbacks / Public API |
| 58 | +Manually updates the internal text buffer and triggers the `onTextChanged` callback. |
88 | 59 |
|
89 | | -- Properties: |
90 | | - - `onTextChanged: ((text: string) => void) | null` — called whenever the buffer changes |
91 | | - - `onEnterPressed: ((text: string) => void) | null` — called when Enter is pressed |
| 60 | +#### `init(): void` |
92 | 61 |
|
93 | | -- Methods: |
94 | | - - `setText(text: string): void` — externally set the buffer (and emits onTextChanged) |
95 | | - - Component lifecycle: `init()` positions the keyboard (sets `subspace.position`) |
| 62 | +Positions the keyboard in the 3D scene (by default, placed at `(0, 1.2, -1)`). |
96 | 63 |
|
97 | | -## Notes / implementation details |
| 64 | +--- |
98 | 65 |
|
99 | | -- Each key stores `originalKey` and optional `shiftKey` used to compute displayed text when shift/caps are toggled. |
100 | | -- Special keys may supply `backgroundColor` and `weight` to control appearance/size. |
101 | | -- The keyboard logs state changes to console (`console.log`) for key presses and enter/backspace events. |
102 | | -- `subspace.updateLayouts()` is called after construction so the grid layout is applied. |
| 66 | +## Visual Options & Constants |
103 | 67 |
|
104 | | -If you want the full file contents pasted instead of this summary, let me know and I will paste the keyboard.ts source. |
| 68 | +Below are the default sizes and colors defined in the component: |
| 69 | + |
| 70 | +- **Dimensions:** |
| 71 | + - `KEY_WIDTH` = `0.07` |
| 72 | + - `KEY_HEIGHT` = `0.08` |
| 73 | + - `TOTAL_KEYBOARD_WIDTH` = `1.0` |
| 74 | + - `TOTAL_KEYBOARD_HEIGHT` = `0.555` (calculated dynamically) |
| 75 | +- **Colors:** |
| 76 | + - Keyboard Panel Background: Dark Charcoal (`#1a1a1b`) |
| 77 | + - Regular Keys: Dark Gray (`#333334`) |
| 78 | + - Special Keys: Slate Gray (`#3e4a59`) |
| 79 | + - Action Key (Enter): Blue-Teal (`#449eb9`) |
| 80 | +- **Typography:** |
| 81 | + - `FONT_SIZE` = `0.45` |
0 commit comments