0
0

More than 3 years have passed since last update.

Autodesk Inventor API Hacking (ダークテーマへの対応~アイコン編~)

Posted at

0. はじめに

Freeradicalの中の人、yamarahです。
Inventor 2021に、プレビュー扱いですがダークテーマが実装されました。
AddInをダークテーマに対応するには、どうすれば良いかという話しです。
ダイアログを表示する場合は、その背景色を変える必要もあるでしょう。とりあえず今回は、リボンに表示されるアイコンを対応させます。

1. Autodesk社の対応を見る

まず、Autodesk社純正のアイコンが、どのような対応をしているのか確認しましょう。
純正LightDark.png
見ての通り、上がライトテーマで、下がダークテーマです。
単に背景の色が違うだけではなく、縁取りの線の色など、細かいデザインが変わっているのが見て取れます。
つまりは、背景色を変えさえすれば良い、という訳ではないということです。

2. 透過アイコンを使う

とはいえ、真面目に2種類のデザインをするのは大変なので、背景色のみを変えて乗り切れないか試してみましょう。
APIを調べた限りでは、テーマ別のアイコンを設定する個所はなさそうです。ですので、背景部を透明にした透過アイコンを試してみます。
テスト用に、以下のアイコン画像を作りました。
TestIcon1.png
アイコン作成にはジェネリック イラレと名高いAffinity Designerを使いました。
Inventorがアルファチャンネルを正しく認識してくれれば、これで大丈夫なはずです。
テスト用のAddInに組み込んで、実際に表示した結果です。
TestIcon1LightDark.png
ダークテーマにおいて、半透明部分のブレンドが正しく行われていないことが見て取れます。
どうやらInventorは、半透明部分には白をブレンドしてアルファー値を二値化処理しているようです。
つまり、この結果から導き出される結論は、アンチエイリアス処理で半透明ピクセルがあるアイコンは、ライトテーマ, ダークテーマ用に作り分けないと見栄えが悪いということです。

3. テーマの切り替えの検出

アイコンの差し替え自体は、ButtonDefinitionStandardIcon, LargeIconを上書きすれば可能です。
問題は、どのタイミングで行うかでして、今回はApplicationEvents.OnApplicationOptionChangeを使います。現在のテーマはApplication.ThemeManager.ActiveThemeで取得可能なので、OnApplicationOptionChangeで値が変化したかどうかを調べるわけです。
抜粋したコードを以下に示します。

private string? CurrentThemeName = null;
private string? GetApplicationThemeName()
{
    return InventorApplication.ThemeManager.ActiveTheme.Name;
}

private void UpdateDefinitionIcon()
{
    if (CurrentThemeName != "DarkTheme")
    {
        ThisDefinition.StandardIcon = Properties.Resources.LightIcon16x16.ToIPictureDisp();
        ThisDefinition.LargeIcon = Properties.Resources.LightIcon32x32.ToIPictureDisp();
    }
    else
    {
        ThisDefinition.StandardIcon = Properties.Resources.DarkIcon16x16.ToIPictureDisp();
        ThisDefinition.LargeIcon = Properties.Resources.DarkIcon32x32.ToIPictureDisp();
    }
}

public void Activate(ApplicationAddInSite addInSiteObject, bool firstTime)
{
    CurrentThemeName = GetApplicationThemeName();
    UpdateDefinitionIcon();
    InventorApplication.ApplicationEvents.OnApplicationOptionChange += ApplicationEvents_OnApplicationOptionChange;
}


private void ApplicationEvents_OnApplicationOptionChange(EventTimingEnum BeforeOrAfter, NameValueMap Context, out HandlingCodeEnum HandlingCode)
{
    if (BeforeOrAfter == EventTimingEnum.kAfter)
    {
        var themeName = GetApplicationThemeName();
        if (CurrentThemeName != themeName)
        {
            // Themeが変わった
            CurrentThemeName = themeName;
            UpdateDefinitionIcon();
        }
    }
    HandlingCode = HandlingCodeEnum.kEventNotHandled;
}

public void Deactivate()
{
    InventorApplication.ApplicationEvents.OnApplicationOptionChange -= ApplicationEvents_OnApplicationOptionChange;
}

これでテーマが変わるタイミングで、アイコンが差し替えられるはずです。

4. 背景焼きこみアイコンの差し替え

背景をライト、ダーク背景色にして、アンチエイリアスを焼き込こんだアイコンを作って、うまく切り替わるか試してみました。
TestIcon2LightDark.png
良い感じに馴染んでいます。これにて解決・・・となるはずだったのですが・・・

5. ハイライト時に背景色が変わらない

ボタンにマウスポインタがフライオーバーした時に、
TestIcon2Bad.png
何やら違和感が。ダークテーマの背景をアイコンに焼き込んだので、うまくハイライトせずに四角い枠が見えてしまっています。
ここまで来れば意地で、アイコン画像をジェネリック フォトショことAffinity Photoに取り込み、背景を透明にします。
Dark切り抜き.png
アンチエイリアス部のみ焼き込みを残して、他の背景は100%透過にしたわけです。
このアイコン画像と差し替えて再チャレンジ。
TestIcon3OK.png
今度はうまく行きました。

6. 旧バージョンへの対応

ThemeオブジェクトはInventor 2021で導入されたものであり、バージョン25以降のInteropを使わないとアクセスできません。しかし、そうすると、作成されたAddInはInventor2020以前では動作しなくなります。
悩ましい問題ですが、ここは泥臭くdynamicを使って逃げましょう。
先のコードのGetApplicationThemeName()を、以下の通り変更します。

private string? GetApplicationThemeName()
{
    try
    {
        return ((dynamic)InventorApplication).ThemeManager.ActiveTheme.Name;
    }
    catch
    {
        return null;
    }
}

例外が発生すればnullを返し、結果としてライトテーマのアイコンが設定されます。
dynamic並びに例外処理は重たい処理なので避けたいということならば、Application.SoftwareVersion.Majorで切り分けでも良いですし、例外検知でフラグを立てて2回目以降は常にnullを返しても良いと思います。

99. 親の記事に戻る

Autodesk Inventor API Hacking (概略)

0
0
0

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
0
0