ラベルクラスは、テキストの入力もできるんですね
ラベルクラスの使い方を学んでいこう〜
JUCE、「Interface Design」の「The Label class」チュートリアルを勉強していきます。ラベルクラスの特徴やその使い方をでもアプリを通して学んでいきます。
公式のチュートリアルページはこちらになります。
https://docs.juce.com/master/tutorial_label.html
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEチュートリアル「The Label class」をやっている人
・JUCEのラベルクラスについて知りたい人
デモアプリの概要
このチュートリアルで実装するアプリは、次のようなUIのアプリとなります。上の「Text input」のテキストボックスに半角英数を入力してエンターを押すと、下の「Uppercase」テキストボックスに全て大文字として変換された文字列が表示されるようなアプリです。
小文字を、大文字に変換します。
このアプリには、全部で5つのラベルコンポーネントが使用されています。それぞれ、3つの用法で利用しています。
①緑色の文字のように、「見出し」のように利用します。
②オレンジのように、固定された文字列を表示します。
③青背景のテキストのように、変化する文字列を表示します。(下側はユーザー入力を受け付けない設定です)
ラベルクラスの特徴
ラベルクラスは、フォントやイタリックなど、ワードのような文字の表現を提供してくれます。また、コンポーネントのサイズに合わせて、文字の表示間隔を自動で調整してくれます。
でもアプリに、十分に猶予のある文字列(左)を入力した場合、文字間は詰められませんが、少し長めの文字列を入力すると、右のように文字間が詰められます。また、文字を詰めても表示しきれない場合は、「…」と省略表示が利用されることになります。
Labelクラスは、いい感じに優秀ですね。
デモアプリの実装とその内容
Projucerの「GUI」テンプレートから作成していきます。
MainComponent.h
「GUI」テンプレートが準備できたら、MainComponent.hのMainComponentクラスに次のようにprivateなメンバを追加します。
class MainComponent : public juce::Component
{
//...略...
private:
//以下のコンポーネントを追加します。
juce::Label titleLabel;
juce::Label inputLabel;
juce::Label inputText;
juce::Label uppercaseLabel;
juce::Label uppercaseText;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
MainComponent.cpp
コンストラクタ
コンストラクタでは、それぞれのラベルの初期化を行います。コンストラクタの内容を次のように変更します。
MainComponent::MainComponent()
{
//[1]緑色のタイトルラベルを初期化します。
addAndMakeVisible(titleLabel);
titleLabel.setFont(juce::Font(16.0f, juce::Font::bold));
titleLabel.setText("Click in the white box to enter some text...", juce::dontSendNotification);
titleLabel.setColour(juce::Label::textColourId, juce::Colours::lightgreen);
titleLabel.setJustificationType(juce::Justification::centred);
//[2]オレンジの文字のラベルを初期化します。
addAndMakeVisible(inputLabel);
inputLabel.setText("Text input:", juce::dontSendNotification);
inputLabel.attachToComponent(&inputText, true);
inputLabel.setColour(juce::Label::textColourId, juce::Colours::orange);
inputLabel.setJustificationType(juce::Justification::right);
addAndMakeVisible(uppercaseLabel);
uppercaseLabel.setText("Uppercase:", juce::dontSendNotification);
uppercaseLabel.attachToComponent(&uppercaseText, true);
uppercaseLabel.setColour(juce::Label::textColourId, juce::Colours::orange);
uppercaseLabel.setJustificationType(juce::Justification::right);
//[3]青背景のテキストラベルを初期化します。
//[3-1]下側の大文字を表示する部分です。
addAndMakeVisible(uppercaseText);
uppercaseText.setColour(juce::Label::backgroundColourId, juce::Colours::darkblue);
//[3-2]上側の文字を入力するテキストラベルです。
addAndMakeVisible(inputText);
inputText.setEditable(true);
inputText.setColour(juce::Label::backgroundColourId, juce::Colours::darkblue);
inputText.onTextChange = [this] { uppercaseText.setText(inputText.getText().toUpperCase(), juce::dontSendNotification); };
setSize(320, 200);
}
[1]では、オレンジ色の文字のタイトルに利用しているラベルコンポーネントを初期化します。addAndMakeVisible関数で可視化します。次に、setFont関数で文字のフォント設定を行います。setFont関数には、「juce::Font」クラスのオブジェクトを渡すことで設定ができますので、引数として、「サイズが16.0の太字」のFontオブジェクトを生成して渡しています。setText関数では、ラベルに表示する文字列を設定します。setColor関数では、「lightgreen」を設定しました。最後に、setJustification関数で、コンポーネントサイズの中の中央に位置するように「centred」を設定しています。
[2]のオレンジ色のラベルも基本的に、先のラベルと設定は同様ですが、attachToComponent関数で、特定のコンポーネントに隣接(左または上)する設定をしています。今回は、それぞれの右側の青色のラベルコンポーネントを指定しています。justificationは、rightなので、コンポーネント内の文字を右寄りに設定しています。
[3]は、青背景のラベルを設定しています。
[3-1]は、通常の入力不可能なラベルで、背景を「darkblue」としています。[3-2]でこのラベルを利用するので、先に定義をしています。
[3-2]が入力可能なラベルで、setEditable関数でtrueを与えることで、ユーザーからのテキスト入力を受け付けることができます。ラベルクラスのonTextChange関数は、ラムダ式を与えることで、テキスト入力に変化があった場合(エンターまたは、カーソルが他に移った場合)に実行する処理を定義することができます。
変化があった時に実行する処理としては、
getText関数でinputText自身の文字列を取得、toUpperCase関数で全てを大文字に変換して、uppercaseTextにsetTextで文字列を設定するという処理です。
paint関数とresized関数
paint関数では、背景を黒に塗りつぶすため、graphicsクラスのfillAll関数で黒を指定します。
また、それぞれのラベルコンポーネントをGUIに配置するため、resized関数を次のように変更しておきます。inputLabelとuppercaseLabelは、attachToComponent関数で、それぞれinputTextとuppercaseTextの左に隣接しているので、ここで配置する必要はないみたいです。
void MainComponent::paint (juce::Graphics& g)
{
g.fillAll(juce::Colours::black);
}
void MainComponent::resized()
{
titleLabel.setBounds(10, 10, getWidth() - 20, 30);
inputText.setBounds(100, 50, getWidth() - 110, 20);
uppercaseText.setBounds(100, 80, getWidth() - 110, 20);
}