Dialogs - 다이얼로그 시스템

ImEDA의 모든 다이얼로그는 c_imgui_dialog를 기반으로 합니다. wxFrame 위에 ImGui로 UI를 렌더링하며, 모달리스 패턴, geometry 자동 저장/복원, 세션 유지 등의 공통 기능을 제공합니다.

c_imgui_dialog 기반 시스템

다이얼로그 구조

      c_imgui_dialog (base)
           |
           +-- wxFrame (OS 창 관리, geometry 저장/복원)
           +-- OpenGL Context (ImGui 렌더링, WM_IME, DPI)
           +-- renderImGui() (순수 가상 함수)
                 +-- 콘텐츠 영역
                 +-- Bottom Button Panel
    

필수 패턴

#규칙설명
1c_imgui_dialog 상속renderImGui() 구현
2setDialogId("id")geometry 자동 저장/복원
3모달리스 생성new + ShowDialog()
4부모 윈도우 필수nullptr 금지
5UI 문자열c_mlts::T() 사용
6CloseDialog()Close(true) 직접 호출 시 CRASH
7블로킹 모달CallAfter()로 지연
8세션 유지user_conf_dir()/<id>.json
9빈 공간 금지버튼 하단 고정, 콘텐츠 채움
10버튼 우측 정렬SetCursorPosX(availW - totalW)
11Close 버튼 금지X 버튼과 중복
12버튼 크기CalcButtonWidth(text)
13필드 그룹화SeparatorText()

다이얼로그 생성 패턴

기본 구현

class c_my_dialog : public c_imgui_dialog {
public:
    c_my_dialog(wxWindow* parent)
        : c_imgui_dialog(parent, c_mlts::T("dialog.my.title"),
                         wxDefaultPosition, wxSize(500, 400))
    {
        setDialogId("my_dialog");
        loadSession();
    }
protected:
    void renderImGui() override {
        float panelH = CalcBottomPanelHeight(false);
        float contentH = ImGui::GetContentRegionAvail().y - panelH;
        ImGui::BeginChild("##wnd.content", ImVec2(0, contentH));
        // ... content ...
        ImGui::EndChild();
        BeginBottomButtonPanel(panelH);
        float okW = CalcButtonWidth(c_mlts::T("dialog.ok"));
        ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - okW);
        if (ImGui::Button(c_mlts::T("dialog.ok"), ImVec2(okW, 0)))
            CloseDialog();
    }
};

세션 저장/복원

geometry merge 패턴

void saveSession() {
    auto path = c_paths::user_conf_dir() + "/my_dialog.json";
    json j = c_filesystem::ReadJson(path);
    if (j.is_null()) j = json::object();
    j["inputPath"] = m_inputPath;
    c_filesystem::WriteJson(path, j);
}

주요 다이얼로그 목록

AI AI Analysis Dialog

AI 데이터시트 분석. PDF에서 부품 정보 추출, 심볼 생성 자동화.

Converter Dialogs

외부 CAD 포맷(Altium, KiCad, Eagle, EasyEDA) 변환. 다이얼로그 내 상표명 금지.

Customize Dialog

Ribbon UI 커스터마이즈, 툴바 구성, 일반 설정.

Colortable Dialog

색상 테이블 편집. 변경 시 EVT_COLORTABLE_CHANGED 발행.

Shortcut Dialog

단축키 설정. 충돌 감지 및 기본값 복원.

AI Symbol-Footprint Mapper

AI 심볼-풋프린트 자동 매핑. TreeNode, FP 검증, 컨텍스트 메뉴.

UI 패턴

Bottom Button Panel

헬퍼 API

float panelH = CalcBottomPanelHeight(hasStatus);
float contentH = ImGui::GetContentRegionAvail().y - panelH;
BeginBottomButtonPanel(panelH);

컨텍스트 메뉴 - Pending Action

Pending Action 구조체

struct s_context_action {
    std::string action;
    std::string projectKey;
    std::string filePath;
    std::string param;
};
// 우클릭 -> OpenPopup -> MenuItem -> m_pendingAction 저장
// EndPopup 후 별도 함수에서 처리

MI 헬퍼 람다

메뉴 아이콘 열 패턴

float iconColW = c_ui_metrics::menu_icon_column_width();
float spaceW = ImGui::CalcTextSize(" ").x;
int numSpaces = (spaceW > 0.0f) ? static_cast<int>(iconColW / spaceW) + 1 : 3;
std::string sp(numSpaces, ' ');
auto MI = [&](const char* label, ...) -> bool {
    return ImGui::MenuItem((sp + label).c_str(), ...);
};

블로킹 모달 지연

wxFileDialog 안전 호출

if (ImGui::Button("Select File...")) {
    wxTheApp->CallAfter([this]() {
        wxFileDialog dlg(this, ...);
        if (dlg.ShowModal() == wxID_OK)
            m_filePath = dlg.GetPath().ToStdString();
    });
}

IME 한글 조합

OS IME 팝업 억제 + 인라인 IME 구현. c_imgui_input_text 사용 시 자동 처리.

다이얼로그 체크리스트

항목확인 사항
기본 클래스c_imgui_dialog 상속
ID 설정setDialogId() 호출
생성new + ShowDialog()
닫기CloseDialog()
문자열c_mlts::T()
버튼우측 정렬, CalcButtonWidth()
세션user_conf_dir()/<id>.json
IMEc_imgui_input_text
파일 선택CallAfter()