kmk_firmware/docs/ptBR/keys.md

169 lines
9.1 KiB
Markdown
Raw Normal View History

2021-08-21 21:54:32 +02:00
# Teclas
> NOTE: Isto não é uma tabela de busca de objetos fornecidos pelo KMK. Esta
> listagem pode ser encontrada em `keycodes.md`. Possivelmente vale a pena
> observar o código-fonte bruto se você estiver travado: `kmk/keys.py`.
Este é um montante de documentação sobre como teclas físicas são mapeada para
eventos (e o ciclo-de-vida destes eventos) no KMK. É um tanto técnico, mas se
você cogita estender a funcionalidade so seu teclado com código extra, você
precisará de pelo menos uma fração deste conhecimento técnico.
Os primeiros passos neste processo não são tão interessantes para a maior parte
dos fluxos de trabalho, razão pela qual eles estão tão soterrados no KMK:
varremos um monte de faixas de GPIO (o quão rápido o CircuitPython nos permitir)
para ver onde, numa matriz de teclas, uma delas foi pressionada. Os detalhes
técnicos deste processo estão melhor descritos na
[Wikipedia](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit). Então,
varremos o mapa de teclas definido, encontrando a primeira tecla válida neste
índice baseado na pilha de camadas ativas (esta lógica, se você quer ler o
código, está em `kmk/internal_state.py`, método `_find_key_in_map`).
Os próximos passos são a parte interessante, mas para compreendê-los precisamos
entender um pouco do objeto `Key` (encontrado em `kmk/keys.py`). Objetos `Key`
têm algumas peças fundamentais de informação:
* O `code`, que pode ser qualquer inteiro. Inteiros menores que
`FIRST_KMK_INTERNAL_KEY` são enviados pela pilha de HID (e portanto para o
computador, que traduzirá aquele inteiro para algo útil - por exemplo,
`code=4` torna-se `a` em um teclado US QWERTY/Dvorak)
* Os modificadores anexados (para implementar coisas como Shift ou `KC.HYPR` que
são pressionamentos de teclas singulares enviadas juntamente a mais de uma
tecla em um único reporte HID. Este é um conceito diferente de Sequências, que
são uma característica do KMK documentada em `sequences.md`). Para todos os
propósitos fora do núcleo do KMK, este campo deve ser ignorado - ele pode ser
seguramente populado mediante meios bem mais sãos que perder tempo fazendo
isso na mão.
2021-08-21 21:55:16 +02:00
2021-08-21 21:54:32 +02:00
* Alguns dados sobre se a tecla deveria ter sido pressionada ou liberada - isto
é majoritariamente um detalhe de implementação sobre como Sequências
funcionam, onde, por exemplo, `KC.RALT` pode precisar ser segurada por toda a
duração da sequência, em vez de ser liberada imediatamente antes de mover para
o próximo catactere. Geralmente usuários finais não precisam se preocupar com
isso, mas os campos são denominados `no_press` e `no_release` e são
referenciados em alguns lugares da base de código se você precisar de
exemplos.
2021-08-21 21:55:16 +02:00
2021-08-21 21:54:32 +02:00
* Manipuladores (*handler*) para o pressionamento (algumas vezes chamado de
"keydown" ou "press") e liberação (algumas vezes chamado de "keyup" ou
"release"). KMK fornece manipuladores para funções padrão do yteclado e
algumas teclas especiais de sobrescrita (como `KC.GESC`, que é uma forma
aprimorada de teclas ANSI já existentes) em `kmk/handlers/stock.py`, para
troca de camadas em `kmk/handlers.layers.py`, e para tudo relacionado a
sequências (veja de novo `sequences.md`) em
`kmk/handlers/sequences.py`. Discutiremos mais estes em breve.
2021-08-21 21:55:16 +02:00
2021-08-21 21:54:32 +02:00
* Chamadas de retorno (*callback*) opcionais a serem executadas antes e/ou
depois dos handlers acima. Mais sobre isso em breve.
2021-08-21 21:55:16 +02:00
2021-08-21 21:54:32 +02:00
* Um campo `meta` genérico, que é mais comumente utilizado para teclas "com
argumentos" - objetos no objeto `KC` que na realidade são funções que retornam
instâncias de `Key`, que geralmente precisam acessar os argumentos passados
para a "função mais externa". Muitos destes exemplos são relacionados com
trocas de camadas - por exemplo, `KC.MO` é implementada como uma tecla com
argumentos - quando o usuário acrescenta `KC.MO(1)` ao teclado, a chamada de
função retorna um objeto `Key` com `meta` contendo um objeto contendo as
propriedades `layer` e `kc`. Existem outros usos para o campo `meta`, e
exemplos podem ser encontrados em `kmk/types.py`.
2021-08-21 21:55:16 +02:00
2021-08-21 21:54:32 +02:00
Objetos `Key` também podem ser encadeados chamando eles! Para criar uma tecla
que segura Ctrl e Shift simultaneamente, simplesmente fazemos:
```python
CTRLSHFT = KC.LCTL(KC.LSFT)
keyboard.keymap = [ ... CTRLSHFT ... ]
```
Quando uma tecla é pressionada e tiramos um objeto `Key` do keymap, acontecerá o
seguinte:
- Callbacks pré-pressionamento serão executados na ordem em que foram
atribuídos, com seus valores de retorno descartados (a não ser que o usuário
os anexe, eles quase nunca existem).
- O handler de pressionamento correspondente será executado (mais comumente este
é fornecido pelo KMK).
- Calllbacks pós-pressionamento serão executados na ordem em que foram
atribuídos, com seus valores de retorno descartados (a não ser que o usuário
os anexe, eles quase nunca existem).
Os mesmos passos são executados quando uma tecla é liberada.
_OK, então... Mas o que é um handler, e o que são esses callbacks?!_
Grosso modo, todos eles servem a um mesmo propósiti: fazer algo com os dados da
tecla, ou executar efeitos colaterais. A maioria dos handlers são fornecidos
pelo KMK internamente e modificam o `InternalState` de alguma forma -
adicionando a tecla à fila HID, modificando camadas, etc. Os handlers
pré/pós-pressionamento são projetados para permitir que a funcionalidade seja
embutida nestes pontos no fluxo de eventos sem ter que reimplementar (ou
importar e chamar internamente) os handlers internos.
Todos esses métodos recebem os mesmos argumentos, e por isso eu vou copiar a
docstring direto do código-fonte:
> Recebe o seguinte:
2021-08-21 21:55:16 +02:00
>
2021-08-21 21:54:32 +02:00
> - self (Esta instância Key)
> - state (InternalState corrente)
> - KC (A tabela de busca KC, para conveniência)
> - `coord_int` (Um inteiro, representação interna da coordenada da matriz para
> a tecla pressionada - costumeiramente isto não é útil para usuários finais,
> mas é fornecida por consistência com os manipuladores internos)
> - `coord_raw` (Uma tupla X,Y de coordenadas da matrix - costumeiramente não é
> útil, também)
2021-08-21 21:55:16 +02:00
>
2021-08-21 21:54:32 +02:00
> O valor de retorno do callback fornecido é descartado. _Exceções não são
> capturadas_, e provavelmente quebrarão o KMK se não forem tratadas dentro da
> tua função.
2021-08-21 21:55:16 +02:00
>
2021-08-21 21:54:32 +02:00
> Estes handlers são executados na ordem de anexação: handlers fornecidos por
> chamadas anteriores deste método são executados antes daqueles fornecidos por
> chamadas posteriores.
Isto significa que se você quer adicionar coisas como suporte a LED/brilho, ou
um botão que aciona seu modem GSM para falar com alguém, ou seja lá o que você
puder fazer em CircuitPython, que também retenha as capacidades de troca de
camadas ou seja lá qual for o handler de suporte, você está coberto. Isto também
significa que você pode adicionar funcionalidades completamente novas ao KMK
escrevendo seu próprio handler.
Eis um exemplo de gancho de ciclo de vida (*lifecycle hook*) que imprime um
Shrek gigante em Arte ASCII. Ele não utiliza os argumentos que recebe, porque
não tem intenção de modificar o estado interno. Ele é puramente um efeito
colateral ([side
effect](https://en.wikipedia.org/wiki/Side_effect_(computer_science))) executado
sempre que se pressiona o Alt esquerdo:
```python
def shrek(*args, **kwargs):
print('⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀')
print('⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆')
print('⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿')
print('⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀')
print('⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀')
print('⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀')
print('⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉')
KC.LALT.before_press_handler(shrek)
```
Você também pode copiar uma tecla sem quaisquer handlers pré ou pós nela
mediante `.clone()`, tal que por exemplo, se eu já adicionei Shrek ao meu `LALT`
mas quero um `LALT` sem Shrek em algum lugar do keymap, eu posso simplesmente
clonar a tecla, e a nova tecla não terá meus handlers atrelados a ela:
```python
SHREKLESS_ALT = KC.LALT.clone()
```