いつも生成されるMainComponentのテンプレートに近づいてきました。
テンプレートを理解することも大事だね~
JUCEプログラミングの「Graphics」の「The main component」チュートリアルの続きです。「Implementing the paint function」の項目からすすめていきます。
公式のチュートリアルページはこちらになります。
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEチュートリアル「The main component」をやっている人
・JUCEアプリのMainComponentクラスについて知りたい人
paint関数の実装
前回作成したMainComponentクラスのPaint関数(MainComponent.cppファイル)を以下のように変更します。
void MainComponent::paint (juce::Graphics& g)
{
g.fillAll(juce::Colours::lightblue);
g.setColour(juce::Colours::darkblue);
g.setFont(20.0f);
g.drawText("Hello, World!", getLocalBounds(), juce::Justification::centred, true);
}
Paint関数はComponentの描画を担当する関数です。Juce::Componentクラスのpaint関数をoverrideしてComponent独自の描画処理を記述していきます。引数にJUCE::Graphicsクラスのオブジェクトgをとるので、gの各種関数を呼び出すことでMainComponentの領域に描画を行うことができます。
fillAllは背景を塗りつぶす処理です。
setColourはこのあとの描画の色を指定しています。そして、setFontでフォントサイズを20に指定して、最後のdrawTextでHelloWorldとテキストをウィンドウ中心に記載します。
graphicsクラスでの描画は、こちらの記事でも勉強しましたので、ご参照ください。
main.cppの変更
MainComponentクラスを追加しましたが、この状態ではまたMainComponentのpaintに記載したプログラム通り描画は反映されていません。
main.cppにMainComponentクラスを使えるように、次のようにMainComponentクラスをincludeします。
#include <JuceHeader.h>
//↓追加しました。
#include "MainComponent.h"
次に、MainWindowクラスのコンストラクタでMainComponentクラスのオブジェクトを生成するようなプログラムを追加します。
//...略...
class MainWindow : public juce::DocumentWindow
{
public:
MainWindow(juce::String name) : DocumentWindow(name,
juce::Colours::lightgrey,
DocumentWindow::allButtons)
{
setUsingNativeTitleBar(true);
setContentOwned(new MainComponent(), true);//[1]追加しました。
centreWithSize(getWidth(), getHeight());//[2]変更しました。
setVisible(true);
}
//...略...
[1]では、setContentOwned関数を利用して、ウィンドウの中心にComponentを配置します。第二引数がtrueなので、設定したコンポーネントのサイズにウィンドウサイズを合わせる設定です。
[2]では、centreWithSize関数の引数をgetWidthとgetHeight関数を利用して設定するようにしています。この関数で幅と高さを取得するには、一つ前のMainComponentの幅と高さが決まっていないとエラーになります。
そのため、次のようにして、MainComponentのコンストラクタでサイズを指定しておく必要があります。
※以下のプログラムは、MainComponent.cppに追記します。
MainComponent::MainComponent()
{
setSize(400, 300);//追加しました。
}
ここまでで、次のような実行結果となります。
resized関数の挙動
resized関数の挙動を確認するために、いくつかの実装を行います。ウィンドウサイズを反映したテキストをウィンドウの中心に描画します。
プログラムの変更
まずは、Main.cppに実装している、MainWindowクラスにウィンドウのリサイズを有効化する設定を追加します。
{
setUsingNativeTitleBar(true);
setContentOwned(new MainComponent(), true);
centreWithSize(getWidth(), getHeight());
setResizable(true, true);//ここを追加してリサイズ可能にします。
setVisible(true);
}
次に、MainComponentクラスの変更を行います。
MainComponent.hに以下のようにprivateなメンバ変数でjuce::tringsオブジェクトを追加します。
//...略...
private:
juce::String currentSizeAsString;//テキストを格納するためのメンバ変数です。
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
そして、MainComponent.cppに実装している、paint関数で描画するテキストをHelloWorldから先ほどのメンバ変数「currentSizeAsString」を表示するように変更しました。
void MainComponent::paint (juce::Graphics& g)
{
//...略...
g.drawText(currentSizeAsString, getLocalBounds(), juce::Justification::centred, true);//ここを変更です。
}
最後に、resized関数に次のプログラムを追加します。
void MainComponent::resized()
{
currentSizeAsString = juce::String(getWidth()) + " x " + juce::String(getHeight());
}
currentSizeAsStringオブジェクトに、juce::Stringクラスのテキストを格納しています。
動作の順番
resize関数で「currentSizeAsString」にテキストを設定しますので、その後にpaint関数が実行されていないと、描画されません。DBGで処理を確認したところ、resized関数の呼び出しの後にはpaint関数が実行されます。
今まで雰囲気で使ってきたMainComponentクラスも、MainWindowクラスから生成されたり、仕組みがあるんですね。