JUCEで作るSVGボタン
できたもの
https://i.gyazo.com/f07438cff7651dcf6e9cf41fb7f71974.gif
見慣れたアイコンを使ったボタンをJUCEで作っていきます。
何をするためのボタンかが(文字情報に依らずとも)明確になります。
ライセンスも寛容で、多くの人にとって見慣れたアイコンが一通り揃っています。
SVGを変換
SVGをJUCEで扱いやすい形(具体的にはunsigned charの配列)へ変換しソースコードに埋め込みます。
変換はProjucerのSVG Path Converterを使用します。Projucerのメニュー Tools>SVG Path Converterを開きます。
ここに先ほどのSVGファイルをドラッグ&ドロップしてみると...
https://i.gyazo.com/ddc9382e1ffb86c67280097170680952.gif
本来であれば右下にアイコンが表示されるはずが、真っ白の四角になってしまいました。
https://gyazo.com/ca5eac48dc2f796bbbe953fcff0ce20e 思ってたんと違う四角
なぜうまく変換されないのか
SVGファイルをテキストエディタで確認します(適宜改行を追加しています)
code: create_new_folder-24px.svg
<path d="M0 0h24v24H0V0z" fill="none"/>
<path d="M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm0 12H4V6h5.17l2 2H20v10zm-8-4h2v2h2v-2h2v-2h-2v-2h-2v2h-2z"/>
</svg>
SVGファイルをドラッグ&ドロップした際は最初のpathタグのデータ(上でいうところの M0 0h24v24H0V0z)のみ取得するようになっています。
Material iconsはなぜか最初のパスに四角のみ書かれています。
それだけを変換した結果が先ほどの四角でした。
アイコンのパスのみ変換する
実際のアイコンのパスは2つ目の長い方のpathです。
テキストエディタから長い方のパスをコピペすると、意図した通りのアイコンに変換できます。
https://gyazo.com/9decbb55e70f0c5d424b7576e6563832 正しく変換されたアイコン
画面下のテキストボックスに変換された配列とJUCEのPathクラスとして読み込んだ例が表示されます。 code: 変換済パス.cpp
static const unsigned char pathData[] = { 110,109,0,0,160,65,0,0,192,64,108,0,0,64,65,0,0,192,64,108,0,0,32,65,0,0,128,64,108,0,0,128,64,0,0,128,64,98,194,245,56,64,0,0,128,64,215,163,0,64,225,122,156,64,215,163,0,64,0,0,192,64,108,0,0,0,64,0,0,144,65,98,0,0,0,64,72,225,152,65,194,245,56,64,
0,0,160,65,0,0,128,64,0,0,160,65,108,0,0,160,65,0,0,160,65,98,72,225,168,65,0,0,160,65,0,0,176,65,72,225,152,65,0,0,176,65,0,0,144,65,108,0,0,176,65,0,0,0,65,98,0,0,176,65,225,122,220,64,72,225,168,65,0,0,192,64,0,0,160,65,0,0,192,64,99,109,0,0,160,65,
0,0,144,65,108,0,0,128,64,0,0,144,65,108,0,0,128,64,0,0,192,64,108,82,184,18,65,0,0,192,64,108,82,184,50,65,0,0,0,65,108,0,0,160,65,0,0,0,65,108,0,0,160,65,0,0,144,65,99,109,0,0,64,65,0,0,96,65,108,0,0,96,65,0,0,96,65,108,0,0,96,65,0,0,128,65,108,0,0,
128,65,0,0,128,65,108,0,0,128,65,0,0,96,65,108,0,0,144,65,0,0,96,65,108,0,0,144,65,0,0,64,65,108,0,0,128,65,0,0,64,65,108,0,0,128,65,0,0,32,65,108,0,0,96,65,0,0,32,65,108,0,0,96,65,0,0,64,65,108,0,0,64,65,0,0,64,65,99,101,0,0 };
Path path;
path.loadPathFromData (pathData, sizeof (pathData));
juce::ShapeButton
JUCEにはほかにもDrawableButtonクラスがあり、そちらはSVGファイルをSVG Path Converterで変換せずにボタンにすることもできますが、今回は扱いません。 ShapeButtonクラスを使う最小限のコードを示します。
code: pushButtonExample.cpp
/*
SVG Path Converterで変換したパス
Google Material icon create_new_folder
*/
static const unsigned char pathData[] = {110, 109, 0, 0, (中略) 99, 101, 0, 0};
juce::ShapeButton pushButton{
"PushButton", // ボタンの名前(なんでもよい)
juce::Colours::grey, // 通常時の色
juce::Colours::white, // マウスオーバー時の色
juce::Colours::lawngreen // クリック時の色
};
//==============================================================================
MainComponent::MainComponent()
{
juce::Path path;
path.loadPathFromData(pathData, sizeof(pathData)); // SVG Path Converterで変換したパスを読み込む
// Push button
addAndMakeVisible(pushButton);
pushButton.setBounds(50, 100, 200, 200); //ボタンの表示領域 x, y, width, height
pushButton.setShape(path,
false, //ShapeButtonをPathのサイズにリサイズするか
true, //元素材のアスペクト比をキープするか
false); //ドロップシャドウ効果をつけるか
}
トグルスイッチ化
ShapeButtonクラスはデフォルトの挙動はプッシュボタンです(冒頭デモの左側)。
クリックごとにONとOFFが切り替わるトグルボタンにするには先の例に数行追加する必要があります。
トグルスイッチの最小限の例を示します。
code: toggleButtonExample.cpp
/*
SVG Path Converterで変換したパス
Google Material icon create_new_folder
*/
static const unsigned char pathData[] = {110, 109, 0, 0, (中略) 99, 101, 0, 0};
juce::ShapeButton toggleButton{
"ToggleButton", // ボタンの名前(なんでもよい)
juce::Colours::grey, // OFF状態の通常時の色
juce::Colours::white, // OFF状態のマウスオーバー時の色
juce::Colours::lawngreen // OFF状態のクリック時の色
};
//==============================================================================
MainComponent::MainComponent()
{
juce::Path path;
path.loadPathFromData(pathData, sizeof(pathData)); // SVG Path Converterで変換したパスを読み込む
// Toggle button
addAndMakeVisible(toggleButton);
toggleButton.setBounds(350, 100, 200, 200); //ボタンの表示領域 x, y, width, height
toggleButton.setShape(path,
false, //ShapeButtonをPathのサイズにリサイズするか
true, //元素材のアスペクト比をキープするか
false); //ドロップシャドウ効果をつけるか
toggleButton.setOnColours(juce::Colours::lawngreen, //ON状態の通常時の色
juce::Colours::lawngreen, //ON状態のマウスオーバー時の色
juce::Colours::lawngreen); //ON状態のクリック時の色
toggleButton.shouldUseOnColours(true); //ON状態の色を使用する
toggleButton.setClickingTogglesState(true); //トグルボタン化
}
まとめ
煩雑な手順のようですが、一度やってしまえば大したことありません。
何をするのか分かりづらいボタンは開発者が想像する以上にユーザーに押してもらえません。
Google Material iconsのような見慣れたアイコンを使うことで、ユーザーに親切かつデザイン性にも優れたGUIを作成することができます。