Windows + Adobe CC illustrator / CEP 5 でイラレのカスタム UI を作ってみる (6) ボタンを押して、次に描画する図形を決める

## Introduction
 
Adobe illustrator (イラレ) の仕事では線幅やカラーが厳格に指定されている図形を多用する場合があります。(例えば地図作成や誌面デザイン、手芸の手順書 etc.)
illustrator では既定で直線や円などの描画モードがワンボタンで選べるので、同様に所定の図形をワンボタン化できないか調べてまとめました。

この記事は CC 版 illustrator / Windows 環境が対象です。この章では、自作のボタンで図形の描画モードを指定する方法をまとめました。

## 今回やりたいことの流れ
ここまでの記事では、図形を選択した状態でボタンを押すと所定のプロパティが設定されるような機能を作ってきました。この機能を使う背景を考えると、例えばこんなシチュエーションが思い浮かびます。

* illustrator で地図を描いていた。建物は四角、道は黒線で書いていた。
* 途中まで書いたところで修正指示が入り、建物は灰色で塗り、道は緑色の破線にすることになった

さて、この指示を受けて既存のデータを修正した後にユーザーは残り作業に戻るかもしれません。つまり書き残していた建物や道を書き足していくわけですが、追加分についても一旦四角や線を引いた後、ボタンを押してプロパティ変更をしていたら面倒です。

ユーザーの使い勝手を考えると、何も図形を選択していない状態でボタンを押すと「そのモード」になったらうれしいですね。illustrator は既定で以下のような円モードや四角モードを備えており、何も選択せずボタンだけ押すと以降の図形がその設定で描かれます。

![SS29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/f126b1b5-968e-db1a-d9ad-9e26e41482e1.png)

同じように、建物モードや道モードを作るのが今回の目的です。
なお、これまでと異なり図形が選択されていない状態での処理を記述するので、作ってきた setProperty01 の以下の箇所を利用してしまいましょう。エラーハンドル用に `return  null;` とだけ書いていましたが、ここに処理を追加します。

```javascript:hostscript.js
    //もし図形が選択されていなかったらnullを返す
    if (selectedObject.length ==0){
        return null;
    }
```

## これから描く図形のモードをツールボックスから指定する
以下 3 つの方法を挙げて検討したり質問したりした結果、3 番目で行くことにしました。

####描きたい図形をスクリプトで出した後すぐ削除する : NG

例えばスクリプトで長方形を生成し、その直後に削除する。こうすると画面の見かけ上は変わらず、また現在のモードが四角になるはず…と思いましたが、試したところモードは変わりません。ツールの選択と PathItem は独立しているようです。

####キーボード ショートカットを利用する : NG

たとえば長方形ツールは [M] キーを押すと選択できるようショートカットが設定されています。Javascript で KeyboardEvent を発行することで、ボタンを押す --> M キーが押された扱いになる --> 長方形が選択される、という流れを期待しましたがうまくいきませんでした。Mキーはエクステンションパネルに発行されてしまい、illustrator で実行したことになりません。(これは、きちんと調べれば方法があるのかも…)

####図形のモードをプロパティで指定 : OK

お手上げだったのでフォーラムで聞きました。すぐに回答がいただけて大変ありがたい…
https://community.adobe.com/t5/illustrator/toolbox-menu-selection-by-cep-jsx-script/m-p/12109400

`app.selectTool('<ツール名>');` を JSX 側で実行することでツール選択ができるということでした。とりあえず入れてみましょう。こんな感じですね。

```javascript:hostscript.jsx
    //もし図形が選択されていなかったら、ツールボックスから長方形メニューを選択した状態にする
    if (selectedObject.length ==0){
        app.selectTool('Adobe Rectangle Shape Tool');
        return null;
    }
```
できました。素晴らしい。
![SS30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/964140a6-5182-8098-ddee-212369ecc1e2.png)

## これから描く図形の線や色を指定しておく

上と同じ理由で、これから描く四角形の線幅や点線、塗り色なども指定できたほうがよいでしょう。
これらの設定はツールボックスからはできないため別メニューを探ります。"既定の" 塗り色や線設定なので "default" ~ をキーワードにリファレンスを検索すると、どうやら document.defaultFillColor や document.defaultStroke~ あたりが怪しそうです。(以下 p35-36)
https://www.adobe.com/content/dam/acom/en/devnet/illustrator/pdf/Illustrator_JavaScript_Scripting_Reference_2017.pdf

これを現在のドキュメント 'app.activeDocument' に対して設定していけばよさそうです。
例えば以下のようにすると、これから塗る色は CMYK (10,20,40,0)、線の太さは 5pt、点 7pt、間隔 5pt の破線になります。
(コードの類似性からわかるように、前回やった "選択図形に対するプロパティ変更" と同じ設定をしています。)

```javascript:hostscript.jsx
    //もし図形が選択されていなかったら、ツールボックスから長方形メニューを選択した状態にし、線や塗り色を既定設定する
    if (selectedObject.length ==0){
        //長方形メニューの選択
        app.selectTool('Adobe Rectangle Shape Tool');

        //既定の塗り色設定
        var myCMYKColor = new CMYKColor();
        myCMYKColor.black = 10;
        myCMYKColor.cyan = 20;
        myCMYKColor.magenta = 40;
        myCMYKColor.yellow = 0;

        //設定した myCMYKColor を既定の塗り色に設定
        app.activeDocument.defaultFillColor = myCMYKColor;

        //既定の線の太さを 5pt に設定
        app.activeDocument.defaultStrokeWidth = 5;

        //既定の線を点7pt、間隔5pt の破線に設定
        app.activeDocument.defaultStrokeDashes = [7,5];

        return null;
    }
```
これで、何も選択していない状態でボタンを押すと以下のような四角がすぐ描けるようになりました。
![SS32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558908/a7abebe8-744b-b972-d186-d1afc3205a50.png)


## まとめ
(5) (6) を通じて、setProperty01() には

- 図形が選択されていない場合、すぐに所定のプロパティの長方形が書けるようになる
- 図形が選択されている場合、所定のプロパティを設定する

機能を一度に担ってもらう構成になりました。地図などで特定の役割を示す図形をたくさん描いて編集する場合には便利に使えると思います。

setProperty01() の全体像は以下のようになっています。

```javascript:hostscript.jsx
function setProperty01(){
    //選択中の図形を取り出す              
    var selectedObject = app.activeDocument.selection;

    //もし図形が選択されていなかったら、ツールボックスから長方形メニューを選択した状態にし、線や塗り色を既定設定する
    if (selectedObject.length ==0){
        //長方形メニューの選択
        app.selectTool('Adobe Rectangle Shape Tool');

        //既定の塗り色設定
        var myCMYKColor = new CMYKColor();
        myCMYKColor.black = 10;
        myCMYKColor.cyan = 20;
        myCMYKColor.magenta = 40;
        myCMYKColor.yellow = 0;

        //設定した myCMYKColor を既定の塗り色に設定
        app.activeDocument.defaultFillColor = myCMYKColor;

        //既定の線の太さを 5pt に設定
        app.activeDocument.defaultStrokeWidth = 5;

        //既定の線を点7pt、間隔5pt の破線に設定
        app.activeDocument.defaultStrokeDashes = [7,5];

        return null;
    }
    //図形が 1 つ以上選択されていれば for 文で要素のプロパティを設定していく
    else {
        
        for (var i=0; i < selectedObject.length; i++){
            //取り出した図形のプロパティを設定
            //myCMYKColorの宣言
            var myCMYKColor = new CMYKColor();
            myCMYKColor.black = 10;
            myCMYKColor.cyan = 20;
            myCMYKColor.magenta = 40;
            myCMYKColor.yellow = 0;

            //設定した myCMYKColor を、選択要素の i 番目に設定
            selectedObject[i].fillColor = myCMYKColor;

            //選択要素 1 番目の線の太さを 5pt に設定
            selectedObject[i].strokeWidth = 5;

            //選択要素 1 番目を、点7pt、間隔5pt の破線に設定
            selectedObject[i].strokeDashes = [7,5];
        };
        return null;
    }
}

```

次は地図記号のような、所定の図形をそのまま追加するようなスクリプトを考えていきましょう。