LoginSignup
3
4

More than 3 years have passed since last update.

JUCEのLocalisedStringsについての覚え書き

Last updated at Posted at 2019-12-07

1つのプログラムを多言語に対応させる「ローカライズ」は、ユーザーフレンドリーなアプリケーションを提供するにあたり重要な要素となっています。
JUCEでは翻訳リソースを準備、プログラムに反映するためのツールが備わっています。
本記事では、JUCEアプリケーションにおける翻訳リソースの準備とプログラムへの反映について解説します。

juce::LocalisedStringsクラス

JUCEではローカライズエンジンとも言える機能がjuce::LocalisedStringsクラスに実装されています。
公式リファレンス

1. プログラミング時、翻訳を反映したい文字列にTRANSマクロを付けておく

JUCEのローカライズエンジンではTRANSマクロの引数に渡された文字列が翻訳対象の文字列になります

image.png

2. Projucerから『Translation File Builder』を起動する

image.png

image.png

3. Translation File Builderでソースコード内に記述された"TRANS"マクロ付きの文字列リストを取得する

Translation File Builderの[Scan folder for TRANS macros]をクリックしてソースコードが置かれたフォルダを選択します。
選択されたフォルダ内に置かれたソースコードからTRANSマクロで囲まれた文字列を検索し、翻訳対象の文字列リストを生成します。この時、検索した文字列ごとに一意の識別記号と共に表示されます。次の図では "JCTRIDX0."と書かれた文字列が識別記号です。

image.png

4. Translation File Builderに翻訳後の文字列を入力する

Translation File Builderの2段目の欄に翻訳後の文字列を入力します。この時、ソースコード内の文字列ごとに設定された一意の識別記号を基準として翻訳対象の文字列が紐付けられることに気を付けましょう。

image.png

5. Translation File Builderの[Generate]を実行する

"翻訳前の文字列" - "翻訳後の文字列"の対応リストが生成されます

image.png

6. UTF-8エンコーディングのテキストファイルを作成し、テキストファイルに生成された翻訳データをペーストする

JUCEではUTF-8エンコーディングの文字列を扱います。UTF-8エンコーディングのテキストファイルを作成し、
テキストファイルのエンコーディングがShift-JISだった場合、翻訳結果が文字化けする可能性があります。

image.png

7. ペーストしたテキストファイルのヘッダにある"language"と"countries"の項目を修正する

"language"項目について:juce::LocalisedStringsクラスに翻訳リソースをロードした際にLocalisedStrings::getLanguageName()関数からこの値を取得します。
"countries"項目について:juce::LocalisedStringsクラスに翻訳リソースをロードした際にLocalisedStrings::getCountryCodes()関数からこの値を取得します。

image.png

8. 翻訳リソース(テキストファイル)をプログラムから読み込む

テキストファイルをプログラムに読み込む方法は任意で構いません。
本記事での事例では、英語用と日本語用の翻訳リソース(テキストファイル)を用意してProjucerでバイナリデータ化してプログラムに組み込むことにしました。

image.png

バイナリデータ化したテキストファイルは以下のJUCE APIでバイナリデータからString型のデータに変換することができます。

String::createStringFromData(BinaryData::jaJP_txt, BinaryData::jaJP_txtSize);

9. juce::LocalisedStringsのマッピングをセットする

juce::String型のデータからjuce::LocalisedStrings型のインスタンスを作成し、juce::LocalisedStrings::setCurrentMappings()に渡すことで、juce::LocalisedStringsにおけるマッピングデータを変更します。

juce::LocalisedStringsクラスはシングルトンパターンで実装されています。マッピングデータを変更して以降にTRANSマクロに文字列を渡す処理を通ることで翻訳処理(文字列の変換)が実行されます。

txt = String::createStringFromData(BinaryData::jaJP_txt, BinaryData::jaJP_txtSize);
LocalisedStrings::setCurrentMappings(new LocalisedStrings(txt, false));

本記事の実装例

■ MainComponent.h

#pragma once

#include "../JuceLibraryCode/JuceHeader.h"

class MainComponent   : public Component
{
public:
    MainComponent();
    ~MainComponent();

    void paint (Graphics&) override;
    void resized() override;

private:
    ComboBox localeSelector;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

■ MainComponent.cpp

#include "MainComponent.h"

MainComponent::MainComponent()
{
    setSize (600, 400);

    addAndMakeVisible(localeSelector);
    localeSelector.addItem("en", 1);
    localeSelector.addItem("ja", 2);
    localeSelector.onChange = [&] {
        String txt;
        if (localeSelector.getText() == "en"){
            getLookAndFeel().setDefaultSansSerifTypefaceName("Arial");
            txt = String::createStringFromData(BinaryData::enUS_txt, BinaryData::enUS_txtSize);
        }
        else if (localeSelector.getText() == "ja") {
            getLookAndFeel().setDefaultSansSerifTypefaceName("Meiryo UI");
            txt = String::createStringFromData(BinaryData::jaJP_txt, BinaryData::jaJP_txtSize);
        }
        LocalisedStrings::setCurrentMappings(new LocalisedStrings(txt, false));
        repaint();
    };
    localeSelector.setSelectedItemIndex(0);
}

MainComponent::~MainComponent()
{
}

void MainComponent::paint (Graphics& g)
{
    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
    g.setFont (Font (16.0f));
    g.setColour (Colours::white);
    g.drawText (TRANS("Hello World!"), getLocalBounds(), Justification::centred, true);
}

void MainComponent::resized()
{
    auto bounds = getLocalBounds();
    localeSelector.setBounds(bounds.removeFromTop(30));
}

■ スクリーンショット

image.png

3
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4