Telas, menus e atalhos
Navegar entre telas com parâmetros, a barra de menus, atalhos que viram Cmd no macOS, status, notificação e a tabela com seleção.
Telas e navegação#
Cada tela é uma ação que recebe t. A primeira registrada é a que abre. t.ir(nome, parametros) troca de tela e empilha; t.voltar() desempilha. Os dois acabam a tela ali — o que vem depois deles não roda.
adopt Arcane.Bigorna as B
adopt Arcane.OS as OS
clientes := [{"id": 1, "nome": "Ana"}, {"id": 2, "nome": "Bruno"}]
app := B.app("CRM", pasta_de_config := $"{OS.temp_dir()}/df-doc-{randint(100000, 999999)}")
action lista(t):
t.titulo("Clientes")
cycle c in clientes:
given t.botao(c["nome"]):
t.ir("cliente", {"id": c["id"]})
action cliente(t):
id := t.parametro("id")
t.titulo($"Cliente {id}")
given t.botao("Voltar"):
t.voltar()
app.tela("lista", lista)
app.tela("cliente", cliente)
s := B.testar(app)
s.clicar("Bruno")
assert s.tela_atual() is "cliente"
assert s.tem("Cliente 2")
s.clicar("Voltar")
assert s.tela_atual() is "lista"Menus e atalhos#
B.item(rótulo, comando, atalho) cria um item; t.comando("novo") é yes na execução em que ele foi escolhido — pelo menu ou pelo atalho, que são o mesmo evento.
adopt Arcane.Bigorna as B
adopt Arcane.OS as OS
app := B.app("Editor", pasta_de_config := $"{OS.temp_dir()}/df-doc-{randint(100000, 999999)}")
app.menu("Arquivo", [
B.item("Novo", "novo", atalho := "Ctrl+N"),
B.item("Salvar", "salvar", atalho := "Ctrl+S"),
B.separador(),
B.item("Exportar PDF", "pdf", atalho := "Ctrl+Shift+E"),
])
app.menu("Ajuda", [B.item("Sobre", "sobre")])
eventos := []
action tela(t):
t.titulo("Documento")
cycle c in ["novo", "salvar", "pdf", "sobre"]:
given t.comando(c):
eventos.append(c)
app.tela("doc", tela)
s := B.testar(app)
s.atalho("Cmd+S") // Cmd e Ctrl são o mesmo atalho
s.atalho("ctrl+shift+e") // a grafia é normalizada
s.menu("Ajuda", "Sobre")
assert eventos is ["salvar", "pdf", "sobre"]
out s.menus()| Escrito | No macOS | No Windows e no Linux |
|---|---|---|
Ctrl+N | ⌘N | Ctrl+N |
Ctrl+Shift+S | ⌘⇧S | Ctrl+Shift+S |
Alt+F4 | ⌥F4 | Alt+F4 |
O programa escreve Ctrl uma vez, e no macOS ele vira Cmd sozinho: um atalho que existisse num sistema só obrigaria a ramificar o código. Dois itens com o mesmo atalho são recusados — só um deles rodaria, e qual dependeria da ordem.
Status, notificação e atualizar#
adopt Arcane.Bigorna as B
adopt Arcane.OS as OS
tarefas := ["ler", "escrever", "revisar"]
app := B.app("Tarefas", pasta_de_config := $"{OS.temp_dir()}/df-doc-{randint(100000, 999999)}")
action tela(t):
t.lista(tarefas)
t.status($"{len(tarefas)} tarefa(s)")
given t.botao("Concluir a primeira"):
tarefas.remove(tarefas[0])
t.notificar("concluída")
t.atualizar() // o status acima já tinha sido calculado
app.tela("t", tela)
s := B.testar(app)
s.clicar("Concluir a primeira")
assert s.status() is "2 tarefa(s)"
assert s.notificacoes() is ["concluída"]Na janela, a notificação aparece no topo e some sozinha em três segundos; o status fica na barra de baixo.
Tabela com seleção#
adopt Arcane.Bigorna as B
adopt Arcane.OS as OS
pedidos := [{"n": 101, "total": 30}, {"n": 102, "total": 45}]
app := B.app("Pedidos", pasta_de_config := $"{OS.temp_dir()}/df-doc-{randint(100000, 999999)}")
action tela(t):
escolhido := t.tabela(["n", "total"], pedidos, selecionar := yes)
given escolhido is void:
t.texto("escolha um pedido")
otherwise:
t.texto($"pedido {escolhido["n"]}: R$ {escolhido["total"]}")
app.tela("t", tela)
s := B.testar(app)
assert s.tem("escolha um pedido")
s.selecionar(1)
assert s.tem("pedido 102: R$ 45")Ela devolve o que foi passado — o vault inteiro, e não o texto da célula —, ou void enquanto nada foi escolhido. Uma seleção que aponta para além da lista (ela encolheu) volta a void, em vez de devolver outra linha.