2 pontos por GN⁺ 2024-08-17 | 1 comentários | Compartilhar no WhatsApp
  • ImRAD é um construtor de GUI para ImGui que gera código C++ pronto para uso direto no aplicativo e também faz o parse desse código novamente, permitindo continuar editando a UI gerada
  • Suporta data binding, eventos e adição manual de código de UI, e o código gerado é separado por marcadores de comentário para que o usuário possa inserir código e continuar usando o designer
  • Roda em Windows, Linux e MacOS, e o código gerado funciona em Windows, Linux, MacOS e Android
  • O layout usa box layout e SameLine, Spacing, NextColumn em vez de posicionamento absoluto, preservando a relação pai-filho e a ordem entre widgets
  • O código-fonte do ImRAD é GPL, mas o código gerado pela ferramenta e o imrad.h usado por esse código ficam fora da GPL, podendo ser incluídos em projetos open source ou comerciais

Papel do ImRAD e forma de geração de código

  • ImRAD é um construtor de GUI para a biblioteca ImGui
  • Gera e faz o parse de código C++ que pode ser usado diretamente no aplicativo
  • Diferente de outras ferramentas, dá suporte a um fluxo em que a UI gerada pode continuar sendo modificada
    • Data binding

      • Eventos
      • Adição manual de código de UI
      • O código gerado é salvo em arquivos .h e .cpp, e pode ser verificado rapidamente com a prévia de código

Plataformas compatíveis e tipos de janela

  • O próprio ImRAD roda em Windows, Linux e MacOS
  • O código gerado roda em Windows, Linux, MacOS e Android
  • Suporta vários tipos de projeto de janela
    • Janela flutuante, popup e popup modal
    • MainWindow, incluindo integração com GLFW
      • O ImRAD gera chamadas GLFW para sincronizar a barra de título, flags de redimensionamento, auto-size e outros aspectos entre a janela ImGui e a janela do sistema operacional
    • Activity
      • Janela sem decoração que preenche toda a área do viewport
      • Apenas uma activity pode ser exibida por vez
      • Usada principalmente em apps Android
  • Também inclui templates
    • main.cpp comum baseado em GLFW
    • MainActivity.java, AndroidManifest.xml, main.cpp e CMakeLists.txt para Android

Widgets e recursos de layout

  • Suporta uma ampla variedade de widgets do ImGui
    • Widgets básicos como Text, Checkbox, Combo, Button, Slider, ColorEdit
    • Widgets contêiner como Child, Table, CollapsingHeader, TreeNode, TabBar
    • Widgets como Splitter e DockSpace
    • Edição de MenuBar e menus de contexto
    • CustomWidget para chamar código de widget externo
  • O layout é gerado com SameLine, Spacing e NextColumn em vez de posicionamento absoluto
    • Isso faz com que os widgets sigam de forma consistente item spacing e frame padding
    • A relação pai-filho e a ordem dos filhos, importantes em widgets contêiner como Table, ficam claras
    • Também é possível usar posicionamento alternativo que mantém a distância relativa a partir do canto do pai selecionado, útil para widgets de overlay
  • Suporta box layout
    • Um mecanismo de layout implementado sobre os recursos do ImGui
    • Permite expandir widgets redimensionáveis na horizontal ou na vertical
    • É possível inserir spacers para criar alinhamento
    • Também pode ser usado o Table Layout Helper, que cria layouts horizontais com uma Table invisível

Bindings, eventos e código do usuário

  • Como o ImGui é uma biblioteca de GUI em modo imediato, o estado dos widgets, como texto de entrada ou itens de combobox, precisa ser configurado dentro do código gerado no momento do desenho, e o ImRAD trata isso por meio de property binding
  • Variáveis de classe podem ser gerenciadas com um simples class wizard ou pela caixa de diálogo de binding
  • Ao usar property binding, a UI gerada pode se comportar dinamicamente e ainda continuar editável no designer
  • Suporta geração de handlers de evento e código de apoio
    • Por exemplo, uma caixa de diálogo modal gera automaticamente uma função membro OpenPopup com um callback lambda chamado ao fechar
    • Os handlers de evento separam o código de tratamento de evento do usuário das partes geradas, permitindo que o designer continue funcionando
  • O código gerado é separado por marcadores de comentário
    • O usuário pode inserir código adicional ao redor do código gerado
    • Isso pode ser usado para chamadas de popup dependentes de draw ou para calcular algumas variáveis
    • Também é possível delegar para callbacks do usuário usando CustomWidget

Configuração, estilo e variações em tempo de execução

  • Window configuration é uma variação de UI que pode ser ativada em tempo de execução
    • Útil para plataformas diferentes ou rotação de tela, por exemplo
  • Estilo é uma configuração que agrupa cores, variáveis de estilo e fontes
    • Além do estilo padrão do ImGui, o usuário pode definir novos estilos
    • Os estilos podem ser salvos como arquivos INI na pasta style
  • Dialog unit pode ser configurado como pixels independentes de dispositivo
    • Útil para Android e apps com reconhecimento de DPI
  • O ImRAD acompanha alterações em arquivos abertos
    • Enquanto o usuário projeta no ImRAD, também pode editar os mesmos arquivos na IDE de sua escolha
    • Alterações no estilo INI também aparecem imediatamente

Dependências e opções do código gerado

  • O código gerado pode ser usado diretamente no projeto e, por padrão, depende apenas da biblioteca ImGui e do header complementar imrad.h
  • Atualmente, imrad.h inclui tanto a interface quanto a implementação
    • Para gerar a implementação em main.cpp, defina IMRAD_H_IMPLEMENTATION antes do include
  • O código gerado usa a rotina de formatação ImRad::Format
    • Em C++20, ela delega por padrão para std::format
    • Se IMRAD_WITH_FMT for definido, pode usar a biblioteca fmt
    • Se nenhum dos dois estiver disponível, usa uma rotina simples de formatação que ignora flags de formatação
  • Alguns recursos exigem dependências extras e ativação explícita
    • O widget MainWindow ou Image precisa de bibliotecas adicionais como GLFW e STB
    • É necessário definir IMRAD_WITH_LOAD_TEXTURE
  • imrad.h pode usar a biblioteca zlib para carregar assets de arquivos zip
    • Ative isso com IMRAD_WITH_MINIZIP
  • Também pode gerar código com strings traduzíveis
    • Ao compilar imrad.h com IMRAD_WITH_GETTEXT, é possível traduzir com gettext/libintl
    • Também é possível usar libintl-lite, que não tem dependências

Licença e distribuição

  • O código-fonte do ImRAD usa a licença GPL
  • O código gerado pela ferramenta fica fora da GPL
    • Pode ser incluído em projetos open source ou comerciais
    • A licença do código gerado é definida pelo usuário
  • O imrad.h usado pelo código gerado também fica fora da GPL
  • A versão mais recente pode ser compilada com CMake após clonar o repositório
    • Também é preciso trazer os submódulos no diretório 3rdparty
  • Versões um pouco mais antigas podem ser baixadas em Releases
  • Tutoriais e documentação detalhada estão disponíveis na wiki

1 comentários

 
GN⁺ 2024-08-17
Opiniões no Hacker News
  • Uma das partes mais surpreendentes deste projeto é que ele tem um parser feito à mão para ler o subconjunto de C++ que ele próprio consegue gerar
    Tudo é implementado em um único header, e parece ao mesmo tempo impressionante e coisa de maluco
    https://github.com/tpecholt/imrad/blob/main/src/cpp_parser.h

    • Fiquei curioso sobre o que exatamente isso quer dizer
      Não tenho muita familiaridade com programação, então só entendi que este projeto tem algo capaz de ler dados
      Gostaria que alguém explicasse por que uma ferramenta capaz de ler C++ é algo tão incrível
  • Muito legal. Talvez seja a nostalgia do Visual Basic, mas para mim este projeto é a cereja do bolo do imgui

    • Até hoje não existe uma experiência RAD mais rápida que o Visual Basic 6
  • Seria legal se virasse um app wasm HTML5, para criar GUIs rapidamente no navegador e copiar e colar o resultado no editor
    Diz que “gera e faz parsing de código C++, e esse código pode ser usado diretamente na aplicação”; fico curioso se esse parsing é para reler o código que ele mesmo gerou

    • O parser está aqui: https://github.com/tpecholt/imrad/blob/main/src/cpp_parser.h
      Parece mesmo ser para ler o código que ele próprio gera. O parser feito à mão não lida com a linguagem inteira, só com um subconjunto
      Por exemplo, o reconhecimento de contêineres da STL está hardcoded, e provavelmente só trata aquilo que pode aparecer no código gerado
      Nessa etapa, ele não cria uma árvore sintática abstrata (AST). Parece uma estrutura em que faz tokenização e análise léxica, e o chamador precisa entender como avançar a “máquina de estados” do parsing
      A geração da AST e a geração de código parecem acontecer neste arquivo com mais de 9000 linhas: https://github.com/tpecholt/imrad/blob/main/src/node.cpp
    • Você esqueceu como instalar e executar uma aplicação nativa? :)
      Está escrito que “o ImRAD roda em Windows, Linux e MacOS”
    • Um app wasm HTML5 não parece combinar muito com a direção da biblioteca imgui, que tenta funcionar nativamente em várias plataformas e minimizar dependências
  • Excelente. Nos últimos anos venho criando apps ImGui em C++, e acho que teria economizado muito tempo se isto existisse

    • Estou começando agora com imGui e gostaria de saber como isso economiza tempo
  • Se o criador do dear-imgui disse que o nome é “dear”, então não deveria ser “for the Dear library”?
    IMGUI significa GUI de modo imediato, e ocornut disse que se inspirou em outro IMGUI chamado “simgui”
    “Cerca de 15 meses depois, renomeei para ‘dear imgui’, porque ‘imgui’ estava monopolizando a sigla inteira. Peço desculpas pela confusão que isso ainda causa.”
    https://github.com/ocornut/imgui/issues/7892

    • Dear ImGui é o nome oficial completo, mas chamá-lo simplesmente de ImGui ainda é muito comum
      O nome do namespace também é ImGui, e definitivamente não é apenas “Dear”
  • Acho que não deveria ter sudo demais ali. Fora isso, parece muito legal

  • Fico curioso se o código C++ gerado também pode ser usado em algo como Python quando se usa os bindings pyimgui

  • Fico pensando por que um construtor de GUI para ImGui não foi implementado com o próprio ImGui

    • Não sei por que você acha que não foi. Pelo código e pelas capturas de tela, ele usa Dear ImGui na UI
  • Legal. Estou criando um projeto com ImGui e vivia pensando que seria bom existir algo assim. Pretendo experimentar

  • Steam é um sistema multiplataforma popular; será que poderia ser usado também para aplicações que não são jogos? Até mesmo para aplicações enterprise?

    • Aplicações normalmente precisam de bom suporte a renderização de texto e layout
      Coisas como várias linhas, fontes e, em alguns casos, RTL; o ImGUI é fraco nessa parte
    • Não sei bem por que você mencionou Steam, mas eles também vendem software no Steam