C++
button
example
imgui
tag-cloud

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

More than 1 year has passed since last update.


概要

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