コンボボックスをより深く使いこなせるようになりそうです。
テキスト入力での色指定は意外と面白そうだね〜
引き続き、JUCEチュートリアル、「Interface Design」の「The ComboBox class」です。今回は、「Text entry」の項目から進めていきます。16進数のカラーコードで色指定ができるようにアプリを改良し、コンボボックス内の要素無効化する実装していきます。前回の記事の続きとなります。
公式のチュートリアルページはこちらになります。
https://docs.juce.com/master/tutorial_combo_box.html
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEチュートリアル「The ComboBox class」をやっている人
・JUCEのコンボボックスの使い方について知りたい人
テキスト入力で色指定
16進数のカラーコード、(ARGBと、アルファが最初にくる点に注意)を次のようにコンボボックスに入力して、ウィンドウ上部のテキスト色が変更されるようにしていきます。
例えば、上の「ff8800dd」の場合は「8800dd」が紫で、「ff」が透明度アルファを表していますので、不透明な紫色にテキストの色が変更されています。
Webとかでよく使う16進数のカラーコードは透明度が最後なので、微妙に混乱しました。
MainComponent.h
MainComponent.hのprivateなメンバに次のようにhandleColourText関数を追加しました。
private:
//...略...
//追加
juce::Colour handleColourText();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
MainComponent.cpp
handleColourText関数
cppファイルの一番下に、次のようにhandleColourText関数を追加しました。
//以下の関数を追加しました。
juce::Colour MainComponent::handleColourText()
{
auto menuText = coloursMenu.getText();//[1]
auto valueFromHex = (juce::uint32) menuText.getHexValue32();//[2]
coloursMenu.setText(juce::String::toHexString((int)valueFromHex));//[3]
return juce::Colour(valueFromHex);//[4]
}
handleColourText関数は、呼び出すと戻り値としてColourクラスのオブジェクトが返るような関数です。[1]で、menuText変数にgetText関数でcoloursMenuコンボボックスのテキストを取得します。次に、[2]でStringクラスの関数、getHexValue32関数で32ビットの16進数へと変換します。16進数の場合、0~FFで8ビットで表現します。なので、ARGBを表現するためにはそれぞれ8ビット×4色の32ビットで表現できますので、32ビットの関数を利用しています。
この関数で、16進数(HEX)を表現する以外の文字が無視されたり、32ビットを越える長さの文字列の場合長さ調整が行われます。HEX入力のエラーをつぶすような役割も担います。
そして、その値をuint32にキャストしています。これは、この後のColorクラスに与える際、uint32(32ビットの符号なしの整数)として渡さなければいけないからキャストします。その値がvalueFromHexとなります。
[3]では、不要な文字などが修正されたHEXをテキスト表示するために、コンボボックスcoloursMenu内の文字を上書きします。toHexStringは引数の数値を16進数の文字列に変換する関数です。
[4]では、juce::Colourに先ほど作成した数値(32ビットの数値)を入れることでcolourオブジェクトを返しています。
coloursMenuChanged関数の変更
coloursMenuChanged関数で、項目以外の文字列が入力されている場合の条件を追加します。
void MainComponent::coloursMenuChanged()
{
juce::Colour textColour;
switch (coloursMenu.getSelectedId())
{
//...略...
case lightblue: textColour = juce::Colours::lightblue; break;
default: textColour = handleColourText(); break;//追加しました。
}
textLabel.setColour(juce::Label::textColourId, textColour);
}
switch文のdefaultの条件として、先ほど定義したhandleColourTextを呼び出して色を取得しています。
コンボボックス内項目の無効化
上段のコンボボックスでBoldを選択すると、下段の色選択のコンボボックスで、「white」をはじめとする明るい色がグレーアウトされて項目が制限されるような実装を行います。
MainComponent.h
以下のように、追加の処理を行うための関数を定義します。
private:
//...略...
void MainComponent::setLightColoursEnabled(const bool shouldBeEnabled);
void MainComponent::setStylePlain();
void MainComponent::setStyleBold();
void MainComponent::setStyleItalic();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
MainComponent.cpp
setLightColoursEnabled関数など
先ほどヘッダに定義したprivateな関数の実装をcppファイルに以下のように追加しました。
まずは、、setLightColoursEnabled関数です。引数にtrueまたはfalseを取ることで、「white」、「indianred」、「lightgreen」、「lightblue」を一括で有効無効化する関数です。setItemEnabled関数は、コンボボックス内の項目の有効化無効化を制御できます。
//コンボボックスの指定の項目を有効化、無効化する関数です。
void MainComponent::setLightColoursEnabled(const bool shouldBeEnabled)
{
coloursMenu.setItemEnabled(white, shouldBeEnabled);
coloursMenu.setItemEnabled(indianred, shouldBeEnabled);
coloursMenu.setItemEnabled(lightgreen, shouldBeEnabled);
coloursMenu.setItemEnabled(lightblue, shouldBeEnabled);
}
次に、上段のコンボボックスの選択時にそれぞれの項目を選択した際に実行する(styleMenuChanged関数から呼び出すように後程書き換えます。)「setStyle〇〇」という関数を定義します。処理として、先ほど定義したsetLightColoursEnabledで項目の有効、無効化をする処理を一行追加しました。boldのとき(setStyleBold)のみsetLightColoursEnabledにfalseを渡しています。
void MainComponent::setStylePlain()
{
setLightColoursEnabled(true);
textFont.setStyleFlags(juce::Font::plain);
}
void MainComponent::setStyleBold()
{
setLightColoursEnabled(false);
textFont.setStyleFlags(juce::Font::bold);
}
void MainComponent::setStyleItalic()
{
setLightColoursEnabled(true);
textFont.setStyleFlags(juce::Font::italic);
}
styleMenuChanged関数の変更
先ほど定義した「setstyle〇〇」系の関数をstyleMenuChanged関数内から呼び出すように変更しました。
void MainComponent::styleMenuChanged()
{
switch (styleMenu.getSelectedId())
{
/*case stylePlain: textFont.setStyleFlags(juce::Font::plain); break;
case styleBold: textFont.setStyleFlags(juce::Font::bold); break;
case styleItalic: textFont.setStyleFlags(juce::Font::italic); break;*/
//↑を↓に変更しました。
case stylePlain: setStylePlain(); break;
case styleBold: setStyleBold(); break;
case styleItalic: setStyleItalic(); break;
default: break;
}
textLabel.setFont(textFont);
}
注意点
コンボボックスの項目を有効無効化する関数、setItemEnabledは、あらかじめ指定されている項目を変更することはありません。例えば、上段「Plain」選択状態で下段whiteを選び、上段を「bold」に変更しても、boldで選択できないwhiteが選択されたままになってしまいます。そのため、この動作がアプリとして不都合であれば、この点も考慮したプログラムにする必要があります。