ImGui で std::vector<std::string> で Combo を作る


背景

ImGui 素晴らしいですよね.
Combo UI も便利ですよね.

でも, ImGui::Combo では, C interface なのでちょっと使いづらい... (nullで区切った一つの文字列を作る必要があるなど)

std::vector<std::string> とかから, 毎回 ImGui 用にデータ変換してもいいけど, 処理時間が無駄ですよね.

std::vector<std::string> や, std::map<std::string, int> みたいな変数を直接扱って, お手軽ぺろっと Combo 作りたい.

方法

BeginCombo, EndCombo 使います.

こんな感じになります.

//
// Combo with std::vector<std::string>
//
static bool ImGuiComboUI(const std::string &caption, std::string &current_item,
                         const std::vector<std::string> &items) {
  bool changed = false;

  if (ImGui::BeginCombo(caption.c_str(), current_item.c_str())) {
    for (int n = 0; n < items.size(); n++) {
      bool is_selected = (current_item == items[n]);
      if (ImGui::Selectable(items[n].c_str(), is_selected)) {
        current_item = items[n];
        changed = true;
      }
      if (is_selected) {
        // Set the initial focus when opening the combo (scrolling + for
        // keyboard navigation support in the upcoming navigation branch)
        ImGui::SetItemDefaultFocus();
      }
    }
    ImGui::EndCombo();
  }

  return changed;
}

あとはお好みで配列インデックスを返すようにしたり, std::map<std::string, int>std::map<std::string, std::string> にしてみたりして.