@designliquido/delegua-interface-grafica 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ {
2
+ "git": {
3
+ "commitMessage": "Lançamento da versão v${version}"
4
+ },
5
+ "github": {
6
+ "release": true
7
+ },
8
+ "npm": {
9
+ "publishPath": "./dist"
10
+ },
11
+ "hooks": {
12
+ "before:init": ["yarn empacotar"],
13
+ "after:bump": "yarn copyfiles -V ./package.json ./dist"
14
+ }
15
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Design Líquido
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # delegua-interface-grafica
2
+
3
+ Biblioteca de interface gráfica para a linguagem [Delégua](https://github.com/DesignLiquido/delegua).
4
+
5
+ Permite criar janelas, botões, rótulos, caixas de texto e contêineres de layout diretamente em código Delégua, com suporte a eventos como cliques e alterações de texto.
6
+
7
+ ## Instalação
8
+
9
+ ```bash
10
+ npm install @designliquido/delegua-interface-grafica
11
+ ```
12
+
13
+ ## Uso em código Delégua
14
+
15
+ ```
16
+ var ig = importar("interfaceGrafica")
17
+
18
+ var janela = ig.janela(800, 600, "Meu Programa")
19
+ var rotulo = ig.rotulo(janela, "Digite seu nome:")
20
+ var caixa = ig.caixaTexto(janela, "")
21
+ var botao = ig.botao(janela, "Confirmar")
22
+
23
+ funcao aoClicar() {
24
+ var nome = ig.obterTexto(caixa)
25
+ ig.definirTexto(rotulo, "Olá, " + nome + "!")
26
+ }
27
+
28
+ ig.aoClicar(botao, aoClicar)
29
+ ig.iniciar()
30
+ ```
31
+
32
+ ## Métodos disponíveis
33
+
34
+ | Método | Descrição |
35
+ |--------|-----------|
36
+ | `janela(largura, altura, titulo)` | Cria a janela principal do programa. |
37
+ | `botao(pai, rotulo)` | Cria um botão dentro do componente pai. |
38
+ | `rotulo(pai, texto)` | Cria um rótulo de texto dentro do componente pai. |
39
+ | `caixaTexto(pai, textoInicial?)` | Cria uma caixa de texto editável. |
40
+ | `caixaVertical(pai)` | Cria um contêiner com layout vertical (de cima para baixo). |
41
+ | `caixaHorizontal(pai)` | Cria um contêiner com layout horizontal (da esquerda para direita). |
42
+ | `definirTexto(componente, texto)` | Altera o texto de um rótulo ou caixa de texto. |
43
+ | `obterTexto(componente)` | Lê o texto atual de um rótulo ou caixa de texto. |
44
+ | `aoClicar(componente, funcao)` | Registra uma função a ser chamada ao clicar no componente. |
45
+ | `aoAlterar(componente, funcao)` | Registra uma função a ser chamada quando o texto do componente mudar. A função recebe o novo texto como argumento. |
46
+ | `iniciar()` | Inicia o laço de eventos. Bloqueia até a janela ser fechada. |
47
+ | `encerrar()` | Encerra a interface gráfica e fecha todas as janelas. |
48
+
49
+ ## Arquitetura
50
+
51
+ A biblioteca é dividida em duas camadas:
52
+
53
+ - **`InterfaceGrafica`** — classe exposta ao código Delégua. Recebe o interpretador automaticamente como primeiro argumento de cada método (comportamento padrão de `FuncaoPadrao`) e repassa callbacks simples para a infraestrutura.
54
+ - **`InfraestruturaGraficaInterface`** — contrato que toda infraestrutura deve implementar. A infraestrutura não conhece o interpretador nem tipos internos de Delégua; apenas recebe e invoca callbacks nativos.
55
+
56
+ ### Infraestruturas disponíveis
57
+
58
+ | Classe | Pacote | Descrição |
59
+ |--------|--------|-----------|
60
+ | `InfraestruturaElectron` | este pacote | Cria elementos DOM no processo de renderização do Electron. É a infraestrutura padrão usada por `delegua-node`. |
61
+ | `InfraestruturaVazia` | este pacote | Infraestrutura sem operações visuais, usada em testes unitários e ambientes sem DOM. |
62
+
63
+ Para usar uma infraestrutura diferente (ou criar a sua própria), implemente `InfraestruturaGraficaInterface` e passe a instância ao construtor de `InterfaceGrafica`:
64
+
65
+ ```typescript
66
+ import { InterfaceGrafica, InfraestruturaGraficaInterface } from '@designliquido/delegua-interface-grafica';
67
+
68
+ class MinhaInfraestrutura implements InfraestruturaGraficaInterface {
69
+ // implementar os métodos da interface
70
+ }
71
+
72
+ const ig = new InterfaceGrafica(new MinhaInfraestrutura());
73
+ ```
74
+
75
+ ## Desenvolvimento
76
+
77
+ ```bash
78
+ # Instalar dependências
79
+ yarn
80
+
81
+ # Executar os testes
82
+ yarn testes-unitarios
83
+
84
+ # Compilar
85
+ yarn empacotar
86
+ ```
87
+
88
+ ## Licença
89
+
90
+ MIT
@@ -0,0 +1,238 @@
1
+ import { InfraestruturaElectron } from './infraestruturas/electron/infraestrutura-electron';
2
+ import { InterfaceGrafica } from './interface-grafica';
3
+
4
+ const _infraestrutura = new InfraestruturaElectron();
5
+ const _ig = new InterfaceGrafica(_infraestrutura);
6
+
7
+ export const DeleguaModuloInterfaceGrafica = {
8
+ janela: {
9
+ tipoRetorno: 'objeto',
10
+ funcao: _ig.janela.bind(_ig),
11
+ argumentos: [
12
+ { nome: 'largura', tipo: 'número' },
13
+ { nome: 'altura', tipo: 'número' },
14
+ { nome: 'titulo', tipo: 'texto' },
15
+ ],
16
+ documentacao:
17
+ `# \`InterfaceGrafica.janela(largura, altura, titulo)\`\n\n` +
18
+ 'Cria a janela principal do programa.\n\n' +
19
+ '## Exemplo de Código\n\n' +
20
+ '```delegua\n' +
21
+ 'var ig = importar("InterfaceGrafica")\n' +
22
+ 'var janela = ig.janela(800, 600, "Meu Programa")\n' +
23
+ '```\n',
24
+ exemploCodigo: 'ig.janela(800, 600, "Meu Programa")',
25
+ },
26
+ botao: {
27
+ tipoRetorno: 'objeto',
28
+ funcao: _ig.botao.bind(_ig),
29
+ argumentos: [
30
+ { nome: 'pai', tipo: 'objeto' },
31
+ { nome: 'rotulo', tipo: 'texto' },
32
+ ],
33
+ documentacao:
34
+ `# \`InterfaceGrafica.botao(pai, rotulo)\`\n\n` +
35
+ 'Cria um botão dentro do componente pai.\n\n' +
36
+ '## Exemplo de Código\n\n' +
37
+ '```delegua\n' +
38
+ 'var ig = importar("InterfaceGrafica")\n' +
39
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
40
+ 'var botao = ig.botao(janela, "Clique aqui")\n' +
41
+ '```\n',
42
+ exemploCodigo: 'ig.botao(janela, "Clique aqui")',
43
+ },
44
+ rotulo: {
45
+ tipoRetorno: 'objeto',
46
+ funcao: _ig.rotulo.bind(_ig),
47
+ argumentos: [
48
+ { nome: 'pai', tipo: 'objeto' },
49
+ { nome: 'texto', tipo: 'texto' },
50
+ ],
51
+ documentacao:
52
+ `# \`InterfaceGrafica.rotulo(pai, texto)\`\n\n` +
53
+ 'Cria um rótulo de texto dentro do componente pai.\n\n' +
54
+ '## Exemplo de Código\n\n' +
55
+ '```delegua\n' +
56
+ 'var ig = importar("InterfaceGrafica")\n' +
57
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
58
+ 'var rotulo = ig.rotulo(janela, "Olá, mundo!")\n' +
59
+ '```\n',
60
+ exemploCodigo: 'ig.rotulo(janela, "Olá, mundo!")',
61
+ },
62
+ caixaTexto: {
63
+ tipoRetorno: 'objeto',
64
+ funcao: _ig.caixaTexto.bind(_ig),
65
+ argumentos: [
66
+ { nome: 'pai', tipo: 'objeto' },
67
+ { nome: 'textoInicial', tipo: 'texto', opcional: true, valorPadrao: '' },
68
+ ],
69
+ documentacao:
70
+ `# \`InterfaceGrafica.caixaTexto(pai, textoInicial?)\`\n\n` +
71
+ 'Cria uma caixa de texto editável dentro do componente pai.\n\n' +
72
+ '## Exemplo de Código\n\n' +
73
+ '```delegua\n' +
74
+ 'var ig = importar("InterfaceGrafica")\n' +
75
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
76
+ 'var caixa = ig.caixaTexto(janela, "valor inicial")\n' +
77
+ '```\n',
78
+ exemploCodigo: 'ig.caixaTexto(janela, "valor inicial")',
79
+ },
80
+ caixaVertical: {
81
+ tipoRetorno: 'objeto',
82
+ funcao: _ig.caixaVertical.bind(_ig),
83
+ argumentos: [
84
+ { nome: 'pai', tipo: 'objeto' },
85
+ ],
86
+ documentacao:
87
+ `# \`InterfaceGrafica.caixaVertical(pai)\`\n\n` +
88
+ 'Cria um contêiner com layout vertical (empilhamento de cima para baixo).\n\n' +
89
+ '## Exemplo de Código\n\n' +
90
+ '```delegua\n' +
91
+ 'var ig = importar("InterfaceGrafica")\n' +
92
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
93
+ 'var coluna = ig.caixaVertical(janela)\n' +
94
+ 'var botao1 = ig.botao(coluna, "Primeiro")\n' +
95
+ 'var botao2 = ig.botao(coluna, "Segundo")\n' +
96
+ '```\n',
97
+ exemploCodigo: 'ig.caixaVertical(janela)',
98
+ },
99
+ caixaHorizontal: {
100
+ tipoRetorno: 'objeto',
101
+ funcao: _ig.caixaHorizontal.bind(_ig),
102
+ argumentos: [
103
+ { nome: 'pai', tipo: 'objeto' },
104
+ ],
105
+ documentacao:
106
+ `# \`InterfaceGrafica.caixaHorizontal(pai)\`\n\n` +
107
+ 'Cria um contêiner com layout horizontal (empilhamento da esquerda para direita).\n\n' +
108
+ '## Exemplo de Código\n\n' +
109
+ '```delegua\n' +
110
+ 'var ig = importar("InterfaceGrafica")\n' +
111
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
112
+ 'var linha = ig.caixaHorizontal(janela)\n' +
113
+ 'var rotulo = ig.rotulo(linha, "Nome:")\n' +
114
+ 'var caixa = ig.caixaTexto(linha, "")\n' +
115
+ '```\n',
116
+ exemploCodigo: 'ig.caixaHorizontal(janela)',
117
+ },
118
+ definirTexto: {
119
+ tipoRetorno: 'nulo',
120
+ funcao: _ig.definirTexto.bind(_ig),
121
+ argumentos: [
122
+ { nome: 'componente', tipo: 'objeto' },
123
+ { nome: 'texto', tipo: 'texto' },
124
+ ],
125
+ documentacao:
126
+ `# \`InterfaceGrafica.definirTexto(componente, texto)\`\n\n` +
127
+ 'Altera o texto de um componente (rótulo ou caixa de texto).\n\n' +
128
+ '## Exemplo de Código\n\n' +
129
+ '```delegua\n' +
130
+ 'var ig = importar("InterfaceGrafica")\n' +
131
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
132
+ 'var rotulo = ig.rotulo(janela, "antes")\n' +
133
+ 'ig.definirTexto(rotulo, "depois")\n' +
134
+ '```\n',
135
+ exemploCodigo: 'ig.definirTexto(rotulo, "depois")',
136
+ },
137
+ obterTexto: {
138
+ tipoRetorno: 'texto',
139
+ funcao: _ig.obterTexto.bind(_ig),
140
+ argumentos: [
141
+ { nome: 'componente', tipo: 'objeto' },
142
+ ],
143
+ documentacao:
144
+ `# \`InterfaceGrafica.obterTexto(componente)\`\n\n` +
145
+ 'Lê o texto atual de um componente (rótulo ou caixa de texto).\n\n' +
146
+ '## Exemplo de Código\n\n' +
147
+ '```delegua\n' +
148
+ 'var ig = importar("InterfaceGrafica")\n' +
149
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
150
+ 'var caixa = ig.caixaTexto(janela, "inicial")\n' +
151
+ 'escreva(ig.obterTexto(caixa))\n' +
152
+ '```\n',
153
+ exemploCodigo: 'ig.obterTexto(caixa)',
154
+ },
155
+ aoClicar: {
156
+ tipoRetorno: 'nulo',
157
+ funcao: _ig.aoClicar.bind(_ig),
158
+ argumentos: [
159
+ { nome: 'componente', tipo: 'objeto' },
160
+ { nome: 'funcao', tipo: 'função' },
161
+ ],
162
+ documentacao:
163
+ `# \`InterfaceGrafica.aoClicar(componente, funcao)\`\n\n` +
164
+ 'Registra uma função Delégua para ser chamada ao clicar no componente.\n\n' +
165
+ '## Exemplo de Código\n\n' +
166
+ '```delegua\n' +
167
+ 'var ig = importar("InterfaceGrafica")\n' +
168
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
169
+ 'var botao = ig.botao(janela, "Clique")\n' +
170
+ 'funcao aoClicar() {\n' +
171
+ ' escreva("Clicado!")\n' +
172
+ '}\n' +
173
+ 'ig.aoClicar(botao, aoClicar)\n' +
174
+ '```\n',
175
+ exemploCodigo: 'ig.aoClicar(botao, aoClicar)',
176
+ },
177
+ aoAlterar: {
178
+ tipoRetorno: 'nulo',
179
+ funcao: _ig.aoAlterar.bind(_ig),
180
+ argumentos: [
181
+ { nome: 'componente', tipo: 'objeto' },
182
+ { nome: 'funcao', tipo: 'função' },
183
+ ],
184
+ documentacao:
185
+ `# \`InterfaceGrafica.aoAlterar(componente, funcao)\`\n\n` +
186
+ 'Registra uma função Delégua para ser chamada quando o texto do componente mudar.\n' +
187
+ 'A função recebe o novo texto como argumento.\n\n' +
188
+ '## Exemplo de Código\n\n' +
189
+ '```delegua\n' +
190
+ 'var ig = importar("InterfaceGrafica")\n' +
191
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
192
+ 'var caixa = ig.caixaTexto(janela, "")\n' +
193
+ 'funcao aoAlterar(novoTexto) {\n' +
194
+ ' escreva(novoTexto)\n' +
195
+ '}\n' +
196
+ 'ig.aoAlterar(caixa, aoAlterar)\n' +
197
+ '```\n',
198
+ exemploCodigo: 'ig.aoAlterar(caixa, aoAlterar)',
199
+ },
200
+ iniciar: {
201
+ tipoRetorno: 'nulo',
202
+ funcao: _ig.iniciar.bind(_ig),
203
+ argumentos: [],
204
+ documentacao:
205
+ `# \`InterfaceGrafica.iniciar()\`\n\n` +
206
+ 'Inicia o laço de eventos da interface gráfica. Bloqueia a execução do programa ' +
207
+ 'até que a janela seja fechada.\n' +
208
+ 'Deve ser chamado após criar e configurar todos os componentes.\n\n' +
209
+ '## Exemplo de Código\n\n' +
210
+ '```delegua\n' +
211
+ 'var ig = importar("InterfaceGrafica")\n' +
212
+ 'var janela = ig.janela(800, 600, "Meu Programa")\n' +
213
+ '// ... criar componentes e registrar eventos ...\n' +
214
+ 'ig.iniciar()\n' +
215
+ '```\n',
216
+ exemploCodigo: 'ig.iniciar()',
217
+ },
218
+ encerrar: {
219
+ tipoRetorno: 'nulo',
220
+ funcao: _ig.encerrar.bind(_ig),
221
+ argumentos: [],
222
+ documentacao:
223
+ `# \`InterfaceGrafica.encerrar()\`\n\n` +
224
+ 'Encerra a interface gráfica e fecha todas as janelas.\n\n' +
225
+ '## Exemplo de Código\n\n' +
226
+ '```delegua\n' +
227
+ 'var ig = importar("InterfaceGrafica")\n' +
228
+ 'var janela = ig.janela(800, 600, "Exemplo")\n' +
229
+ 'var botao = ig.botao(janela, "Fechar")\n' +
230
+ 'funcao fechar() {\n' +
231
+ ' ig.encerrar()\n' +
232
+ '}\n' +
233
+ 'ig.aoClicar(botao, fechar)\n' +
234
+ 'ig.iniciar()\n' +
235
+ '```\n',
236
+ exemploCodigo: 'ig.encerrar()',
237
+ },
238
+ };
@@ -0,0 +1,3 @@
1
+ export * from './infraestruturas';
2
+ export * from './interface-grafica';
3
+ export * from './interfaces';
@@ -0,0 +1,92 @@
1
+ # InfraestruturaElectron
2
+
3
+ Implementação de `InfraestruturaGraficaInterface` para o processo de renderização do
4
+ [Electron](https://www.electronjs.org/). Cria e gerencia elementos DOM reais no
5
+ `document.body` da janela Electron em que o código Delégua está sendo executado.
6
+
7
+ ## Como funciona
8
+
9
+ ### Sobreposição de janela
10
+
11
+ Ao chamar `criarJanela`, a infraestrutura monta a seguinte hierarquia de elementos no
12
+ `document.body`:
13
+
14
+ ```
15
+ div.sobreposicao (position: fixed; cobre toda a viewport com fundo semitransparente)
16
+ └─ div.moldura (largura × altura fornecidos; borda e sombra de janela)
17
+ ├─ div.barraTitulo (barra escura com título e botão "×")
18
+ └─ div.areaConteudo (flex-column; recebe os filhos do código Delégua)
19
+ ```
20
+
21
+ O **handle** retornado pelo método (o `ComponenteInterfaceGraficaInterface`) aponta
22
+ internamente para `areaConteudo`, de modo que todos os filhos criados depois são
23
+ inseridos diretamente nessa área.
24
+
25
+ ### Mapa de componentes
26
+
27
+ Cada elemento DOM recebe um ID interno (e.g. `delegua-gui-1`, `delegua-gui-2`, …) gerado
28
+ por um contador de instância. O mapa `elementosPorId: Map<string, HTMLElement>` faz a
29
+ tradução entre o ID opaco exposto ao código Delégua e o `HTMLElement` real.
30
+
31
+ ### Elementos DOM por widget
32
+
33
+ | Método | Tag HTML | Notas |
34
+ |-----------------------|----------|-----------------------------------------------------|
35
+ | `criarJanela` | `div` | aponta para `areaConteudo`; sobreposição não exposta |
36
+ | `criarBotao` | `button` | `textContent` = rótulo |
37
+ | `criarRotulo` | `label` | `textContent` = texto |
38
+ | `criarCaixaTexto` | `input` | `type="text"`; `value` = texto inicial |
39
+ | `criarCaixaVertical` | `div` | `flex-direction: column` |
40
+ | `criarCaixaHorizontal`| `div` | `flex-direction: row` |
41
+
42
+ ### Leitura e escrita de texto
43
+
44
+ - Para `HTMLInputElement` / `HTMLTextAreaElement`: usa `element.value`.
45
+ - Para todos os outros elementos: usa `element.textContent`.
46
+
47
+ ### Mapeamento de eventos
48
+
49
+ O método `conectarEvento` traduz os nomes de eventos do Delégua para eventos DOM:
50
+
51
+ | Evento Delégua | Evento DOM |
52
+ |----------------|------------|
53
+ | `clique` | `click` |
54
+ | `alterado` | `input` |
55
+ | `tecla` | `keydown` |
56
+ | `foco` | `focus` |
57
+ | `desfoco` | `blur` |
58
+
59
+ Para o evento `alterado` em campos de texto, o valor atual de `element.value` é passado
60
+ automaticamente como primeiro argumento ao callback. Para os demais eventos, o callback
61
+ é invocado sem argumentos.
62
+
63
+ ### Ciclo de vida
64
+
65
+ | Método | Comportamento |
66
+ |---------------|-----------------------------------------------------------------------------------|
67
+ | `iniciarLaco` | Retorna uma `Promise` que fica pendente até `encerrar()` ser chamado. |
68
+ | `encerrar` | Remove a sobreposição do DOM, limpa `elementosPorId` e resolve a Promise do laço. |
69
+
70
+ O botão "×" da barra de título também chama `encerrar()` internamente.
71
+
72
+ ## Requisitos de ambiente
73
+
74
+ - Deve ser executada no **processo de renderização** do Electron, onde `document` está
75
+ disponível.
76
+ - Não funciona no processo principal (`main process`) nem em ambientes Node.js puros.
77
+
78
+ ## Exemplo de uso (código Delégua)
79
+
80
+ ```
81
+ importe InterfaceGrafica
82
+
83
+ var janela = InterfaceGrafica.janela(800, 600, 'Meu Programa')
84
+ var botao = InterfaceGrafica.botao(janela, 'Clique aqui')
85
+
86
+ funcao aoClicar() {
87
+ escreva('Clicado!')
88
+ }
89
+
90
+ InterfaceGrafica.aoClicar(botao, aoClicar)
91
+ InterfaceGrafica.iniciar()
92
+ ```