LoginSignup
2
3

More than 5 years have passed since last update.

ImGui でタグクラウド風のボタンクラウドを実装する例

Posted at

概要

ImGui を採用する際にタグクラウド的なウィジェットパーツを実装したい場合の実装例を紹介する。

image

実装例

ソースコード

namespace usagi
{
  namespace imgui
  {
    class small_button_cloud
      : public std::multimap
        < std::string
        , std::function< auto () -> void >
        >
    {
      float _width = 0.0f;
    public:
      auto width() { return _width; }
      auto width( const decltype( _width ) in ) { return _width = in; }
      auto get_width_pointer() { return &_width; }
      auto operator()()
      {
        ImGui::BeginGroup();

        const auto s = ImGui::GetStyle();
        const auto iis2 = s.ItemInnerSpacing.x * 2;
        const auto is   = s.ItemSpacing.x;

        auto current_line_width = 0.0f;

        for ( const auto& p : *this )
        {
          const auto entity_width = ImGui::CalcTextSize( p.first.c_str() ).x;
          const auto tmp_line_width = current_line_width + is + iis2 + entity_width;

          if ( current_line_width > 0.0f and tmp_line_width < _width )
          {
            ImGui::SameLine();
            current_line_width = tmp_line_width;
          }
          else
            current_line_width = iis2 + entity_width;

          if ( ImGui::SmallButton( p.first.c_str() ) )
            p.second();
        }

        ImGui::EndGroup();
      }
    };
  }
}

使用する ImGui API 群

  1. ImGui::SmallButton
  2. ImGui::BeginGroup
  3. ImGui::EndGroup
  4. ImGui::CalcTextSize
  5. ImGui::GetStyle
  6. ImGui::SameLine

実装の tips

  1. 任意の width の領域に、ラベルとクリック時のファンクターのマルチマップから SmallButton でタグクラウド風のスモールボタンクラウドを実装する。
  2. SmallButton の横幅は CalcTextSize() + GetStyle().ItemInnerSpacing * 2 で SmallButton 定義前に計算できる。
  3. SmallButton を横に複数 SameLine する場合のアイテム間の間隔は GetStyle().ItemSpacing で取得できる。

各種サイズの図解

image

動作テスト

  using usagi::imgui::small_button_cloud;

  static small_button_cloud c;

  ImGui::SliderFloat( "width", c.get_width_pointer(), 0.0f, 1024.0f );

  if ( c.empty() )
    for ( auto n = 0; n < 32; ++n )
      c.emplace( "hoge-" + std::to_string( n ), [=]{ std::cerr << "hoge-" << n << '\n'; } );

  c();

image

image

image

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3