Carregar apresentação
A apresentação está carregando. Por favor, espere
PublicouAndré di Azevedo Moreira Alterado mais de 7 anos atrás
1
www.3layer.com.br - slide 1 de xx Geração Automática e Assistida de Interfaces de Usuário Marcelo Mrack www.3layer.com.br
2
Sumário PARTE 1 1.Introdução 2.Motivação 3.Interfaces de Usuário PARTE 2 4.MBUIDE PARTE 3 5.Merlin 6.Estudo de Caso PARTE 4 7.Conclusões
3
www.3layer.com.br PARTE 1 1.Introdução 2.Motivação 3.Interfaces de Usuário
4
www.3layer.com.br Introdução Contextualização Esta apresentação resume o trabalho de pesquisa realizado durante um curso de mestrado com ênfase sobre o software Merlin, o qual é o resultado de um trabalho que vem sendo desenvolvido desde 2001 O Merlin é um software para geração automatizada de Interfaces de Usuário (IU) que segue as premissas das MBUIDE, e que tem foco específico no mercado profissional de desenvolvimento de sistemas Objetivos Apresentar o conceito de geração de IU defendido pelas MBUIDE e um panorama geral dessa tecnologia na atualidade Detalhar as bases do projeto Merlin e sua relação com as demais MBUIDE, buscando evidenciar os seus diferenciais Apresentar um pequeno Estudo de Caso, onde o Merlin é utilizado para gerar uma IU de baixa complexidade Mostrar os resultados obtidos até o momento, os pontos em aberto e os direcionamentos da pesquisa
5
www.3layer.com.br Motivação Experiência Profissional A criação de UI, principalmente em sistemas de banco de dados, é uma tarefa repetitiva, cansativa em com baixos índices de reuso Custo Expressivo para a Criação das IU De forma geral, pesquisas comprovam que os custos de criação de IU são significativos, mesmo na atualidade Quanto custa a IU nos sistemas em geral Sistema Completo Interface do Usuário 100% 50% User Interface Software Tools; MEYERS (1994,2002)
6
www.3layer.com.br Interfaces de Usuário Cenário Atual na Criação de IU Escrita de código-fonte Programador escreve c ó digo-fonte usando API de um toolkit gr á fico Uso de ferramentas WYSIWYG 1 Programador usa o conceito de arrastar e soltar elementos de IU Uso de assistentes de criação Wizards coletam informa ç ões do meio do sistema e geram c ó digo-fonte Geração Automatizada Templates –Esqueletos de c ó digo substitu í veis otimizam a programa ç ão Model Driven Architecture (MDA) –Cartuchos de gera ç ão transformam modelos abstratos em c ó digo 1. ( WYSIWYG: /w ɪ ziw ɪ g/ ) What You See Is What You Get, ou seja o que você vê (ou o que você desenha no editor) é o que você tem quando o sistema estiver em execução.
7
www.3layer.com.br Interfaces de Usuário Problemas Recorrentes nas Abordagens Descritas Tempo elevado de construção de estruturas genéricas Quanto custa criar um template? Demora nas alterações Como refatorar classes j á geradas? E se o c ó digo j á foi alterado? Falta de reuso Posso reusar o label “ Nome do cliente ” em projetos diferentes? Gerência de código C ó digo template ou não? E a versão? Refatoração E se o template contiver erros?
8
www.3layer.com.br Interfaces de Usuário Tipos de Interfaces de Usuário Uso Geral São interfaces de usu á rio que não têm rela ç ão espec í fica com os dados do sistema, e são orientadas para satisfazer as mais variadas regras de neg ó cio Devido a sua generalidade, a automa ç ão de gera ç ão dessas IU é reduzida Interfaces CRUD Acrônimo do inglês Create, Retrieve, Update and Delete, são IU destinadas a visualizar e manipular os dados existentes nos sistemas Por possu í rem uma rela ç ão muito forte com os dados do sistema, tendem a ser beneficiadas por recursos de gera ç ão automatizada Presentes em 100% dos sistemas que operam sobre banco de dados Custo das CRUD nas IU em sistemas de operam sobre BD IU CRUD em geral 100% 60% Merlin: Um Novo Horizonte na Criação de Telas de Cadastro; MRACK (2007) CRUD elementar 36%
9
www.3layer.com.br Interfaces de Usuário Tipos de Interfaces CRUD Um-Para-Um São as IU mais simples, e todos os elementos da IU existem em fun ç ão de um objeto de dados com propriedades primitivas ou com associa ç ões de cardinalidade m á xima igual a 1 no destino EXEMPLO: Tela de cadastro de um produto Um-Para-Muitos (Mestre-Detalhes) De m é dia complexidade, os elementos da IU satisfazem objetos de dados com associa ç ões de cardinalidade maior que 1 no destino, e exatamente 1 na origem EXEMPLO: Tela de cadastro de uma nota fiscal e seus itens Muitos-Para-Muitos De alta complexidade, satisfazem dados relacionados por estruturas com cardinalidade maior que 1 em ambas extremidades Na pr á tica, durante a implementa ç ão, são transformadas em IU Um-Para- Muitos isom ó rficas EXEMPLO: Tela de cadastro de cursos e disciplinas
10
www.3layer.com.br Interfaces de Usuário Foco do Software Proposto 100% das interfaces CRUD elementares com custo zero de configuração 100% das interfaces CRUD com algum trabalho de configuração que tenha melhor custo-benefício do que as abordagens existentes Abrangência da ferramenta Merlin descrita no trabalho IU CRUD em geral 50% 30% CRUD elementar 18% Sistema completo 100%
11
www.3layer.com.br PARTE 2 4.MBUIDE
12
www.3layer.com.br MBUIDE Model-Based User Interface Development Environment (MBUIDE) São ferramentas que objetivam produzir IU através do uso de modelos declarativos de alto nível Os modelos são processados por um mecanismo de transformação que tem como resultado as IU do sistema São semelhantes à tecnologia MDA, porém: Dão grande ênfase para a geração de IU Valem-se de de processos, linguagens e mecanismos de transformação proprietários Dependem muito de uma metodologia exclusiva de trabalho
13
www.3layer.com.br MBUIDE Origens nas antigas UIMS User Interface Management System (UIMS) Início dos anos 80 Primeira alternativa utilizada para produzir IU sem escrever diretamente código-fonte Características das UIMS Focada no resultado final pela visão do desenvolvedor e sem processos ou metodologias claras de trabalho Sem grande preocupação com integrações ou refatoramento Utilização de linguagens ou sintaxes próprias Uso de diagramas de estados e transições para modelar o diálogo entre o usuário e o sistema Resultados das UIMS Geração dos principais menus do sistema, caixas de diálogo, mensagens simples e invocação de funções pré-determinadas
14
www.3layer.com.br MBUIDE Evolução Grande crescimento entre os anos 80 e 90 Evolução das linguagens e sintaxes de especificação mais ricas Separação de conceitos: Elementos de IU, Tarefas, Dados, etc. Modelos Formam a base das MBUIDE Estruturas declarativas que armazenam aspectos relevantes do sistema a ser gerado e que, em conjunto, podem detalhar todas as informações necessárias para geração de uma aplicação Definidos, os modelos servem como entrada para os mecanismos de geração da MBUIDE que, através de ciclos evolutivos e incrementais, produz as IU do sistema
15
www.3layer.com.br MBUIDE Tipos de Modelos 1.Modelo de Dados Semelhante a um modelo relacional, foca os dados persistentes da aplica ç ão 2.Modelo de Domínio Extende o Modelo de Dados, agregando conceitos semelhantes a OO 3.Modelo de Tarefas Foca as regras de neg ó cio da aplica ç ão e as opera ç ões e restri ç ões relacionadas 4.Modelo de Apresentação D á ênfase para os elementos gr á ficos da IU Abstract Interface Object (AIO) e Concrete Interface Object (CIO) são suportados 5.Modelo de Diálogo Correlato ao Modelo de Tarefas, focaliza a conversa ç ão do usu á rio com a IU 6.Modelo de Usuário Define aspectos de personaliza ç ão da IU para determinados usu á rios ou grupos 7.Modelo de Aplicação Efetua a liga ç ão das IU com o meio externo da aplica ç ão 8.Modelo de Plataforma Variante do Modelo de Aplica ç ão, foca mais detalhes do ambiente operacional 9.Modelo de Contexto Semelhante ao Modelo de Usu á rio, enfatiza aspectos dependentes do uso do sistema
16
www.3layer.com.br MBUIDE Exemplos de Modelos de MBUIDE BODART, LEHEUREUX e VANDERDONCKT (1994) e MRACK (2007) Modelos de ApresentaçãoModelo de Tarefas na TRIDENT DEFINE INTERACTION-OBJECT ID_Label; WORDING IS "Id."; MNEMONIC IS "I"; PROMPT IS ":"; IS INSTANCE OF Label; IS COMPONENT OF Customer_GroupBox; DEFINE INTERACTION-OBJECT Id_EditBox; MAX-LENGTH IS 6; LINEARITY SIMPLE; IS INSTANCE OF EditBox; IS COMPONENT OF Customer_GroupBox; IS ATTACHED TO Cust_id; @Properties(“mnemonic=I;”) @Group(“Customer”) @Length(max=6) String id; Merlin (2007) TRIDENT (1994) ||| >> ||| >> ||| >> ||| Acess and Manage Patient Information Manage Patiente Information Identification Insert Login Insert Password Request Patient File Visualize Pictures Visualize Text Add Information Delete Information Manage Patiente Medical File Visualize Patiente Medical File Modify Patiente Medical File Monitor Real Time Patient Information Close Session Adaptado de SOUCHON, LIMBOURG e VANDERDONCK (2002)
17
www.3layer.com.br MBUIDE Arquitetura Geral Adaptado de PINHEIRO (2001) (a) TEALLACH e TADEUS (b) TRIDENT e METAGEN (c) MERLIN e MECANO Conjunto de modelos Gerador de código- fonte Compilador Código principal da aplicação Código gerado para um toolkit gráfico específico Aplicação final Conjunto de modelos Gerador de código intermediário Compilador Código principal da aplicação Subconjunto otimizado dos modelos Aplicação final Conjunto de modelos Compilador Código principal da aplicação Aplicação final Interpretador de tempo de execução Biblioteca do toolkit gráfico específico Arquitetura geral das MBUIDE em relação ao processo de geração da IU
18
www.3layer.com.br MBUIDE Arquitetura Geral Geradores de código-fonte Aplicação final não possui dependência dos modelos da MBUIDE Menor suporte para refatoração, usando abordagem “uma via” Maior desempenho da aplicação final (devido compilação total) Geração de código intermediário Menor dependência dos modelos da MBUIDE Problemas de sincronização duplicados, devido 2 pontos de integração Possível melhor desempenho Geradores de tempo de execução (abordagem utilizada no trabalho) Total dependência dos modelos da MBUIDE Prototipação instantânea Praticamente não sofrem problemas de refatoração Possível pior desempenho
19
www.3layer.com.br MBUIDE Processo de Desenvolvimento Criação dos modelos Nova IU Adição de funcionalid ades Geração de versões preliminare s Detalhame ntos de mais baixo nível Geração da IU ou código- fonte final Ajustes e integração com o restante do sistema IU Completa Refatoração Processo geral de desenvolvimento de IU usando MBUIDE (notação BPMN) Abstração MaiorMenor
20
www.3layer.com.br MBUIDE Vantagens Padronização e centralização de atividades Trabalhos realizados em mais alto nível Respostas rápidas nos primeiros ciclos de desenvolvimento Problemas Recorrentes Sintaxes e notações complicadas Linguagens e metodologias fora dos padrões de mercado Desequilíbrio entre a pesquisa e a aplicação Busca pela generalidade, implicando em modelos demasiadamente complexos e instáveis Reuso de soluções não alcançado com praticidade Fraco suporte à refatoração e evolução dos modelos
21
www.3layer.com.br PARTE 3 5.Merlin 6.Estudo de Caso
22
www.3layer.com.br Merlin É uma MBUIDE com ênfase no cenário de desenvolvimento profissional que: 1.Tem foco específico em interfaces CRUD Na versão corrente suporta CRUD simples, do tipo Um-Para-Um 2.Utiliza uma estrutura única para o armazenamento dos seus modelos Na prática, os modelos são as próprias classes compiladas da aplicação 3.Não gera nenhum tipo de código-fonte A transformação dos modelos em IU ocorre em tempo de execução 4.Vale-se de heurísticas plugáveis para geração da IU Podendo serem definidas em linguagem nativa ou usando frameworks externos 5.Utiliza um mecanismo realimentado de configurações Inferência de comportamento com base em informações históricas e taxas de acerto 6.É neutro em relação a pacote gráfico e ambiente de uso Web, desktop ou dispositivos móveis podem ser alcançados 7.Possui uma arquitetura focada em reuso e integração de tecnologias
23
www.3layer.com.br Merlin Origens Projeto Metagen na UNISC Iniciado em 2001, era uma MBUIDE rudimentar Gerava interfaces CRUD Um-Para-Um e Um-Para-Muitos Foi utilizado com sucesso em sistemas profissionais Ênfase no Modelo de Dados Utilizava código intermediário para os modelos Carências do Metagen Linguagem VB, Delphi e Kylix Sem suporte Web, não era multi-plataforma e não permitia distribuição Sem definição clara de modelos Orientação a Objetos não era utilizada Pouca preocupação com padrões e tecnologias de mercado Reuso baseado em cópia de configuração Layout de IU sem grande flexibilidade
24
www.3layer.com.br Merlin Típica interface CRUD gerada pelo Metagen (2003) Interface CRUD Um-Para-Um de média complexidade gerada pelo Metagen Agrupamentos simples Layout essencialmente tabular Dependências de preenchimento Máscaras e tamanhos Ligação básica de funções de negócio Operações CRUD essenciais
25
www.3layer.com.br Merlin Iniciado em 2004, é a continuação do projeto Metagen Uso da linguagem Java Franco crescimento Suporte Web, Desktop, multi-plataforma Orientação a Objetos Separação de conceitos Modelos claros –Modelo de Domínio –Modelo de Tarefas –Modelo de Apresentação, com suporte AIO e CIO –Modelo de Diálogo –Modelo de Usuário Outros modelos sem utilidade devido uso da Java Flexibilidade total no layout da IU Foco em reuso de configurações e integração de tecnologias Geração totalmente em tempo de execução
26
www.3layer.com.br Merlin Características Modelos O Merlin utiliza 5 tipos de modelos para geração das IU, todos orbitando sobre o Modelo de Domínio Os modelos descritos através da própria linguagem Java, através do recurso conhecido como Metadata Facility, ou simplesmente Anotações (JSR 175) Os modelos fazem parte das classes da aplicação, e portando podem ser compilados juntos a elas, evitando estruturas externas para o seu armazenamento Os modelos nada mais são do que as classes de persistência da aplicação enriquecidos com Anotações, as quais: –São definidas pelo próprio Merlin –Podem ser reutilizadas de outros frameworks –Podem ser criadas pelo próprio programador
27
www.3layer.com.br Merlin Características Modelos no Merlin, um Exemplo @Caption(“Cadastro de Cliente Pessoa Física”) class Cliente extends Pessoa implements PessoaFisica { @Agent( event={“focusLost”}, action={“habilitarCartao”} condition={“length>0”}) float salario; @NotNull boolean cartaoCredito; @Email @Property(“foreground=Color.blue”) @Order(FIRST) String email; Estado uf; @RenderAs(Lookup.class) Cidade cidade; } 1 2 3 4 5 6 7 8 Uma classe de persistência utilizada como base de um conjunto de modelos 9 10 11 12 13 14 15 16 Dependências em grafos Cliente Cidade Estado Dependência transitiva
28
www.3layer.com.br PARTE 4 7.Conclusões
29
www.3layer.com.br Espaço comum Participe!
30
www.3layer.com.br - slide 30 de xx Fim Geração Automática e Assistida de Interfaces de Usuário Marcelo Mrack
31
www.3layer.com.br - slide 31 de xx Dicas sobre essa apresentação Use somente as cores padrões do esquema de cores Não altere o tipo e o tamanho das fontes Se o texto não couber no slide é porque é muito texto para um slide só! Note o uso de rodapés Edite-os, clicando em Exibir>Cabeçalho e Rodapé e também em Exibir>Slide Mestre Figura Rodapé Uma tela simples OKCancelar Cores do esquema. Não use outras
32
www.3layer.com.br - slide 32 de xx Dicas sobre essa apresentação O último slide dessa apresentação é oculto e contém modelos para criação de figuras, caixas de texto explicativas e elementos com preenchimento de cores padrões Ao criar a apresentação, sempre adicione Anotações explicativas para cada slide Uso de anotações Título da figura Cuide para a figura não sobrepor o rodapé
33
www.3layer.com.br - slide 33 de xx Sobre o autor Marcelo Mrack, mmrack@gmail.commmrack@gmail.com 29 anos, 8 em TI, 6 em Java Bacharel em C. Computação, UNISC – 2001 Mestrando em C. Computação, UFRGS – 2006 Atuação em projetos web e desktop n camadas Sócio e arquiteto na 3Layer Tecnologia Projetista na CWI Software Consultor e instrutor Hibernate, Java EE Especialidades: IHC, Patterns, geradores, PU Ágil e UML http://merlin.dev.java.net http://merlin.dev.java.net http://telasdecadastro.blogspot.com http://telasdecadastro.blogspot.com
34
www.3layer.com.br - slide 34 de xx Modelos Domain TaskPresentation Abstract Presentation Concrete Presentation Dados e regras de negócio Modelos integrados no código-fonte public final class Cliente extends Pessoa { @Agent( {event=“focusLost”,action=“load”}, {properties=“size=FULL,order=LAST}) ) private String nome; private String observacoes; } 1 2 3 4 5 6 7 8
35
www.3layer.com.br - slide 35 de xx Figuras Auxiliares A partir daqui, figuras auxiliares
36
www.3layer.com.br - slide 36 de xx Modelos de Apresentação Modelos de Apresentação em algumas MBUIDEs (a) TRIDENT DEFINE INTERACTION-OBJECT ID_Label; WORDING IS "Id."; MNEMONIC IS "I"; PROMPT IS ":"; IS INSTANCE OF Label; IS COMPONENT OF Customer_GroupBox; DEFINE INTERACTION-OBJECT Id_EditBox; MAX-LENGTH IS 6; LINEARITY SIMPLE; IS INSTANCE OF EditBox; IS COMPONENT OF Customer_GroupBox; IS ATTACHED TO Cust_id; (b) MERLIN @Properties(“mnemonic=I;”) @Group(“Customer”) @Length(max=6) String id; CIO AIO CIO (BODART, LEHEUREUX e VANDERDONCKT, 1994) e MERLIN (MRACK, 2007)
37
www.3layer.com.br - slide 37 de xx Modelos de Tarefa Modelo de Tarefas na ferramenta TRIDENT (SOUCHON, LIMBOURG e VANDERDONCK, 2002) - ORIGINAL
38
www.3layer.com.br - slide 38 de xx Modelos de Tarefa Modelo de Tarefas na ferramenta TRIDENT (SOUCHON, LIMBOURG e VANDERDONCK, 2002) ||| >> ||| >> ||| >> ||| Acess and Manage Patient Information Manage Patiente Information Identification Insert Login Insert Password Request Patient File Visualize Pictures Visualize Text Add Information Delete Information Manage Patiente Medical File Visualize Patiente Medical File Modify Patiente Medical File Monitor Real Time Patient Information Close Session
39
www.3layer.com.br Geração da IU - slide 39 de xx Arquitetura geral das MBUIDE em relação ao processo de geração da IU Conjunto de modelos (a) TEALLACH e TADEUS Gerador de código- fonte Compilador Código principal da aplicação Código gerado para um toolkit gráfico específico Aplicação final Conjunto de modelos (b) TRIDENT e METAGEN Gerador de código intermediário Compilador Código principal da aplicação Subconjunto otimizado dos modelos Aplicação final Conjunto de modelos (c) MERLIN e MECANO Compilador Código principal da aplicação Aplicação final Interpretador de tempo de execução Biblioteca do toolkit gráfico específico
40
www.3layer.com.br - slide 40 de xx Um Modelo de Dados e uma possível Interface CRUD resultante Modelo de Dados e a respectiva IU nome usuario logradouro Rua São Sepé numero 256 complemento cidade observacoes SalvarCancelar codigo
41
www.3layer.com.br - slide 41 de xx Modelo de Domínio e a respectiva IU Um Modelo de Domínio e uma possível Interface CRUD resultante Nome Cadastro de Usuário Dicas O campo nome é obrigatório. O campo logradouro é obrigatório O campo número é obrigatório Logradouro Rua São Sepé Número 256 Complemento Cidade Endereço Observações SalvarCancelar
42
www.3layer.com.br Mapeamento de um grafo de objetos para uma Interface de Usuário Mapeamento de IU - slide 42 de xx codigo = “RH0001” : String nome = “Marcelo Mrack” : String ativo = true : boolean : Funcionario dataDeNascimento = 02/10/1977 : Date observacoes = null : String : ComplementoDoFuncionario
43
www.3layer.com.br Ligação de elementos e Injeção de recursos Interligação de eventos e regras de negócio para controles de IU public class Funcionario { @Agent( event = { “lostFocus" }, action = { “fillEmail" } ) String nome; String email; } 1 2 3 4 5 6 7 8 (a) Classe do Modelo de Domínio(b) Classe com regras de negócio public class RegrasDeNegocio { @In Context ctx; void fillEmail() { ctx.eval( “$txtEmail.text = $txtNome.text.trim + ‘@3layer.com.br’”); } 1 2 3 4 5 6 7 8 9
44
www.3layer.com.br - slide 44 de xx Regras clássica de mapeamento Mapeamento clássico de modelos nas MBIDEs Modelo de DomínioModelo de Apresentação Classe ou InterfaceFormulárioAtributoControleAssociaçãoNavegação
45
www.3layer.com.br - slide 45 de xx Modelos de Apresentação Modelo de Domínio como elemento central no MERLIN public class Cliente extends Pessoa { @Agent( event = { "change" }, action = { "calcularLimiteDeCredito" } ) @Pattern(regex=“money") float salario; @Properties(“editable=false") float limiteDeCredito; } 1 2 3 4 5 6 7 8 9 10
46
www.3layer.com.br - slide 46 de xx Edição Textual Assistida (a) Início da edição(b) Assistente textual invocado (c) Resultado final, após adição do evento e ação de negócio
47
www.3layer.com.br - slide 47 de xx Suporte à correções Edição Textual Assistida Assistência na correção de erros The event focosLost cannot be recognized. Available events are: focusLost focusGain see others... focusLost
48
www.3layer.com.br Layout de IU via anotações Redefinindo a ordem de controles e a posição de textos descritivos na IU A classe de dados class Cliente { @Order(after=“observacoes”) String nome; float salario; @Caption(pos=Caption.TOP_LEFT) String observacoes; } 1 2 3 4 5 6 7 A tela gerada Cadastro de Cliente Salário Nome Observações 2 5
49
www.3layer.com.br Layout de IU via templates Um exemplo de layout manual (a) O template inicial AlgumaClasse extends JPanel Cadastro de Cliente (b) O template configurado Cadastro de Cliente AlgumaClasse extends JPanel lblSalario salario lblNome nome observacoes lblObservacoes (c) A IU gerada Cadastro de Cliente Salário Nome Observações (d) A chamada ao gerador, informando o template de IU a ser utilizado merlin.createIhc(Cliente.class, AlgumaClassse.class);
50
www.3layer.com.br Geração de mensagens de auxílio Email: obrigatório; mínimo 12 caracteres Data de nascimento: formato ‘dd/mm/aaaa’ CPF: obrigatório; formato ‘###.###.###.##’
51
www.3layer.com.br Geração de mensagens de auxílio
52
www.3layer.com.br Sinônimos e Similaridades Utilizando similaridades e sinônimos para a geração da IU Modelo de Domínio A class Cliente { @RenderAs(JTextArea.class) String observacao; } Modelo de Domínio B class Produto { String observacoes; } Modelo de Domínio C class NotaFiscal { String obs; } Observação Cliente Observações Produto Obs Nota Fiscal
53
www.3layer.com.br Processo de Desenvolvimento O processo de desenvolvimento utilizando o Merlin Tempo de projeto Tempo de execução 2 1 34 5 6 7 IDE Aplicação
54
www.3layer.com.br Processo de Desenvolvimento O processo de desenvolvimento utilizando o Merlin (a) Tempo de projeto(b) Tempo de execução Ambiente de desenvolvimento Aplicação Programador Classes Java Anotações [Enriquecer] Compilar Utilizar Criar Evoluir MERLIN IU Usuário Classes-base da IU compiladas com anotações Classes compiladas do restante da aplicação
55
www.3layer.com.br Estudo de Caso, geração 1 - slide 55 de xx 1 6 3 2 4 5 7
56
www.3layer.com.br Estudo de Caso, geração 2 - slide 56 de xx 1 2 3 4 5 6 7 8 9 10
57
www.3layer.com.br - slide 57 de xx Slide auxiliar (oculto) Figura Subfigura 2 Caixa pintada Caixa explicativa Demo
Apresentações semelhantes
© 2024 SlidePlayer.com.br Inc.
All rights reserved.