2P by GN⁺ | ★ favorite | 댓글 1개
  • ImRAD는 ImGui용 GUI 빌더로, 애플리케이션에서 바로 사용할 수 있는 C++ 코드를 생성하고 다시 파싱해 생성 UI를 계속 수정할 수 있게 함
  • 데이터 바인딩, 이벤트, 수동 UI 코드 추가를 지원하며, 생성 코드는 주석 마커로 구분되어 사용자가 코드를 넣어도 디자이너 사용을 계속할 수 있음
  • Windows, Linux, MacOS에서 실행되며, 생성된 코드는 Windows, Linux, MacOS, Android에서 동작함
  • 레이아웃은 절대 위치 대신 SameLine, Spacing, NextColumn박스 레이아웃을 사용하고, 위젯 간 부모-자식 관계와 순서를 유지함
  • ImRAD 소스는 GPL이지만, 도구가 생성한 코드와 생성 코드가 사용하는 imrad.h는 GPL에서 제외되어 오픈소스·상용 프로젝트에 포함할 수 있음

ImRAD의 역할과 코드 생성 방식

  • ImRAD는 ImGui 라이브러리용 GUI 빌더임
  • 애플리케이션에서 직접 사용할 수 있는 C++ 코드를 생성하고 파싱함
  • 다른 도구와 달리 생성된 UI를 계속 수정하는 흐름을 지원함
    • 데이터 바인딩

      • 이벤트
      • 수동 UI 코드 추가
      • 생성된 코드는 .h.cpp 파일로 저장되며, 코드 미리보기로 빠르게 확인할 수 있음

지원 플랫폼과 창 유형

  • ImRAD 자체는 Windows, Linux, MacOS에서 실행됨
  • 생성된 코드는 Windows, Linux, MacOS, Android에서 실행됨
  • 다양한 창 설계를 지원함
    • 플로팅 창, 팝업, 모달 팝업
    • GLFW 통합을 포함한 MainWindow
      • ImRAD가 GLFW 호출을 생성해 ImGui 창과 OS 창의 제목 표시줄, 크기 조절 플래그, 자동 크기 등을 동기화함
    • Activity
      • 전체 뷰포트 영역을 채우는 장식 없는 창
      • 한 번에 하나의 activity만 표시 가능
      • 주로 Android 앱에 사용됨
  • 템플릿도 포함함
    • GLFW 기반 일반 main.cpp
    • Android용 MainActivity.java, AndroidManifest.xml, main.cpp, CMakeLists.txt

위젯과 레이아웃 기능

  • 폭넓은 ImGui 위젯을 지원함
    • Text, Checkbox, Combo, Button, Slider, ColorEdit 같은 기본 위젯
    • Child, Table, CollapsingHeader, TreeNode, TabBar 같은 컨테이너 위젯
    • Splitter, DockSpace 같은 위젯
    • MenuBar와 컨텍스트 메뉴 편집
    • 외부 위젯 코드를 호출할 수 있는 CustomWidget
  • 레이아웃은 절대 위치 대신 SameLine, Spacing, NextColumn을 사용해 생성됨
    • 위젯이 item spacing과 frame padding을 일관되게 따르도록 함
    • Table 같은 컨테이너 위젯에 중요한 부모-자식 관계와 자식 순서가 명확함
    • 선택한 부모 코너로부터 상대 거리를 유지하는 대체 위치 지정도 가능해 오버레이 위젯에 사용할 수 있음
  • 박스 레이아웃을 지원함
    • ImGui 기능 위에 구현된 레이아웃 메커니즘
    • 크기 조절 가능한 위젯을 가로 또는 세로 방향으로 늘릴 수 있음
    • spacer를 넣어 정렬을 만들 수 있음
    • 보이지 않는 Table을 사용해 가로 레이아웃을 생성하는 Table Layout Helper도 사용할 수 있음

바인딩, 이벤트, 사용자 코드

  • ImGui는 즉시 모드 GUI 라이브러리이므로 입력 텍스트나 콤보박스 항목 같은 위젯 상태를 그리는 시점에 생성 코드 안에서 설정해야 하며, ImRAD는 이를 속성 바인딩으로 처리함
  • 클래스 변수는 간단한 class wizard 또는 바인딩 대화상자에서 관리할 수 있음
  • 속성 바인딩을 사용하면 생성 UI가 동적으로 동작하면서도 계속 디자인 가능함
  • 이벤트 핸들러와 지원 코드 생성을 지원함
    • 예를 들어 모달 대화상자는 닫힐 때 호출되는 람다 콜백을 가진 OpenPopup 멤버 함수를 자동 생성함
    • 이벤트 핸들러는 사용자 이벤트 처리 코드와 생성된 부분을 분리해 디자이너가 계속 동작할 수 있게 함
  • 생성 코드는 주석 마커로 구분됨
    • 사용자는 생성 코드 주변에 추가 코드를 넣을 수 있음
    • draw에 의존하는 팝업 호출이나 일부 변수 계산에 사용할 수 있음
    • CustomWidget을 사용해 사용자 콜백으로 위임할 수도 있음

설정, 스타일, 런타임 변형

  • Window configuration은 런타임에 활성화할 수 있는 UI 변형임
    • 서로 다른 플랫폼이나 화면 회전 등에 유용함
  • 스타일은 색상, 스타일 변수, 폰트를 묶은 설정임
    • ImGui 기본 스타일 외에 사용자가 새 스타일을 정의할 수 있음
    • 스타일은 style 폴더 아래 INI 파일로 저장 가능함
  • dialog unit은 장치 독립 픽셀로 설정할 수 있음
    • Android와 DPI 인식 앱에 유용함
  • ImRAD는 열린 파일 변경을 추적함
    • ImRAD에서 디자인하면서 사용자가 선택한 IDE에서도 같은 파일을 편집할 수 있음
    • INI 스타일 변경도 즉시 표시됨

생성 코드 의존성과 옵션

  • 생성 코드는 프로젝트에서 바로 사용할 수 있으며, 기본적으로 ImGui 라이브러리와 동반 헤더 imrad.h 에만 의존함
  • 현재 imrad.h는 인터페이스와 구현을 모두 포함함
    • main.cpp에서 구현을 만들려면 include 전에 IMRAD_H_IMPLEMENTATION을 정의함
  • 생성 코드는 ImRad::Format 포맷팅 루틴을 사용함
    • C++20에서는 기본적으로 std::format에 위임함
    • IMRAD_WITH_FMT를 정의하면 fmt 라이브러리를 사용할 수 있음
    • 둘 다 없으면 포맷팅 플래그를 건너뛰는 단순 포맷팅 루틴을 사용함
  • 일부 기능은 추가 의존성과 명시적 활성화가 필요함
    • MainWindow 또는 Image 위젯은 GLFW, STB 같은 추가 라이브러리가 필요함
    • IMRAD_WITH_LOAD_TEXTURE 정의가 필요함
  • imrad.hzlib 라이브러리를 사용해 zip 파일에서 에셋을 로드할 수 있음
    • IMRAD_WITH_MINIZIP으로 활성화함
  • 번역 문자열을 포함한 코드를 생성할 수 있음
    • IMRAD_WITH_GETTEXTimrad.h를 컴파일하면 gettext/libintl로 번역 가능함
    • 의존성이 없는 libintl-lite도 사용할 수 있음

라이선스와 배포

  • ImRAD 소스 코드는 GPL 라이선스
  • 도구가 생성한 코드는 GPL에서 제외됨
    • 오픈소스 또는 상용 프로젝트에 포함 가능함
    • 생성 코드의 라이선스는 사용자가 결정함
  • 생성 코드가 사용하는 imrad.h도 GPL에서 제외됨
  • 최신 버전은 저장소를 clone한 뒤 CMake로 빌드함
    • 3rdparty 디렉터리의 서브모듈도 가져와야 함
  • 다소 오래된 버전은 Releases에서 다운로드할 수 있음
  • 튜토리얼과 자세한 문서는 wiki에서 확인할 수 있음

댓글과 토론

Hacker News 의견들
  • 이 프로젝트에서 가장 놀라운 부분 중 하나는, 자신이 생성할 수 있는 C++ 부분집합을 읽기 위한 수제 파서를 갖고 있다는 점임
    전부 단일 헤더로 구현돼 있고, 인상적이면서도 미친 짓처럼 보임
    https://github.com/tpecholt/imrad/blob/main/src/cpp_parser.h

    • 이 말이 정확히 무슨 뜻인지 궁금함
      프로그래밍에 익숙하지 않아서, 이 프로젝트에 데이터를 읽을 수 있는 무언가가 있다는 정도만 이해했음
      C++을 읽을 수 있는 도구가 왜 대단한지 설명해주면 좋겠음
  • 정말 멋짐. Visual Basic 향수 때문일 수도 있지만, 내게는 imgui 케이크 위의 장식 같은 프로젝트임

    • 지금까지도 Visual Basic 6보다 빠른 RAD 경험은 없음
  • 브라우저에서 GUI를 빠르게 만들고 결과를 편집기에 복사해 붙여넣을 수 있게, wasm HTML5 앱으로 들어가면 멋질 것 같음
    “C++ 코드를 생성하고 파싱하며, 이 코드는 애플리케이션에서 바로 사용할 수 있다”고 되어 있는데, 여기서 파싱은 자기가 생성한 코드를 다시 읽기 위한 것인지 궁금함

    • 파서는 여기 있음: https://github.com/tpecholt/imrad/blob/main/src/cpp_parser.h
      자기가 생성한 코드를 읽기 위한 게 맞아 보임. 수제 파서는 언어 전체가 아니라 부분집합만 처리함
      예를 들어 STL 컨테이너 인식을 하드코딩하고 있고, 아마 생성 코드에서 나올 수 있는 것들만 처리하는 듯함
      이 단계에서는 추상 구문 트리(AST) 를 만들지 않음. 토큰화와 어휘 분석을 하고, 파싱 “상태 기계”를 어떻게 진행할지는 호출자가 이해해야 하는 구조로 보임
      AST 생성과 코드 생성은 9000줄이 넘는 이 파일에서 하는 듯함: https://github.com/tpecholt/imrad/blob/main/src/node.cpp
    • 네이티브 애플리케이션 설치하고 실행하는 법을 잊은 건가? :)
      “ImRAD는 Windows, Linux, MacOS에서 실행된다”고 되어 있음
    • wasm HTML5 앱은 여러 플랫폼에서 네이티브로 동작하고 의존성을 최소화하려는 imgui 라이브러리 방향과는 좀 맞지 않아 보임
  • 훌륭함. 지난 몇 년간 ImGui C++ 앱을 만들고 있었는데, 이게 있었다면 많은 시간을 아꼈을 것 같음

    • 이제 막 imGui를 시작하는 중인데, 이게 어떻게 시간을 아껴주는지 알고 싶음
  • dear-imgui 창시자가 이름이 “dear”라고 밝혔다면 “for the Dear library”라고 해야 하는 것 아닌가?
    IMGUI는 즉시 모드 GUI를 뜻하고, ocornut은 “simgui”라는 다른 IMGUI에서 영감을 받았다고 했음
    “약 15개월 뒤에 ‘dear imgui’로 이름을 바꿨다. ‘imgui’가 약어 전체를 독점하고 있었기 때문이다. 지금까지도 혼란을 일으킨 점은 미안하다.”
    https://github.com/ocornut/imgui/issues/7892

    • Dear ImGui가 공식 전체 이름이지만, 그냥 ImGui라고 부르는 것도 여전히 아주 흔함
      네임스페이스 이름도 ImGui이고, 단순히 “Dear”만은 절대 아님
  • 거기에 sudo가 너무 많이 들어가면 안 될 것 같음. 그 외에는 정말 멋져 보임

  • 생성된 C++ 코드를 pyimgui 바인딩을 쓸 때 Python 같은 곳에서도 사용할 수 있는지 궁금함

  • ImGui용 GUI 빌더가 왜 ImGui 자체로 구현되지 않았는지 궁금함

    • 왜 아니라고 생각하는지 모르겠음. 코드와 스크린샷을 보면 UI에 Dear ImGui를 쓰고 있음
  • 멋짐. ImGui로 프로젝트를 만들고 있는데 계속 이런 게 있으면 좋겠다고 생각했음. 한번 써볼 예정임

  • Steam은 인기 있는 크로스플랫폼 시스템인데, 게임이 아닌 애플리케이션에도 쓸 수 있을까? 심지어 엔터프라이즈 애플리케이션에도 가능할까?

    • 애플리케이션에는 보통 좋은 텍스트 렌더링과 레이아웃 지원이 필요함
      여러 줄, 글꼴, 경우에 따라 RTL 같은 기능인데, ImGUI에는 이런 부분이 부족함
    • 왜 Steam을 꺼낸 건지는 잘 모르겠지만, Steam에서도 소프트웨어를 판매하긴 함