見出し画像

GUI-WindowのデザインScript(InDesign用)

概要

InDesignのScript開発を行なっていて面倒臭いことの1つに「GUI-Windowのデザイン」があると思います。
どこが面倒臭いかというと、Window内の各パーツは位置を座標(数値)で指定しなければならないところだと思います。
この面倒臭さを解消したいと思い、このScriptを開発してみました。
同業者で同じような悩みを抱えている方がいらっしゃいましたらお使いいただければと思います。

使用方法

手順1 InDesignで「GUI-Window」のデザインを作成します。


画像のように作成したいデザインをテキストフレームで作成して下さい。
作成したフレームはサブレイヤー名を「GUI-Window」の「種類名※」に設定して下さい。
※種類名とはbutton、checkbox、などです。詳細は下記を参照下さい。
フレーム内に入力した文字はオブジェクトに反映されます。
なお、色やフォントは反映されません。
右の「名称」をオブジェクトのサブレイヤー名に設定することにより、スクリプトが認識し、サンプルウィンドウを作成します。

ダイアログ       dialog  ※1  
パレット        palette  ※1
ウィンドウ       window  ※1
静的テキスト      statictext  ※1
通常のボタン      button  ※1
チェックボックス    checkbox  ※1
ラジオボタン      radiobutton  ※1
編集可能なテキスト   edittext  ※1
パネル         panel  ※1
ドロップダウンリスト  dropdownlist  ※2
リストボックス     listbox  ※2
アイコンボタン     iconbutton  ※3
画像          image  ※3
タブパネル       tabbedpanel  ※3
ツリー表示       treeview  ※3
プログレスバー     progressbar  ※4
スクロールバー     scrollbar  ※4
スライダー       slider  ※4
グループ        なし  ※5
※1:フレーム内に入力した文字が反映されます。
※2:フレーム内に入力した文字を改行でスプリットして反映されます。
※3:リンクファイルが反映されます。
※4:文字は反映されません。
※5:グループ化したオブジェクトがグループとなります。

手順2 Scriptで「GUI-Window」のデザインの確認

 作成したデザインを選択し、スクリプトを起動すると、「GUI-Window」のサンプルが表示されます。デザインを確認して下さい。

 サンプルを閉じると、「GUI-Window source code」ウィンドウが開きコードが表示されます。

手順3 ソースをコピペして「GUI-Window」を作成
 デザインが確定したら、「GUI-Window source code」をコピーしてScript開発を行なって下さい。
下記コードは例です。

var winObj = new Window ( 'dialog' , 'ダイアログタイトル' , [0,0,220.36220472455,219.417322833575] );
winObj.add ( 'statictext' , [18,27.4173228335746,194.7244094491,53.4173228335746] , '静的テキスト' );
var btn1 = winObj.add ( 'button' , [18,81.1961364746093,92.7244094491,125.708661416787] , 'ボタン1' );
var btn2 = winObj.add ( 'button' , [120,81.1961364746093,194.7244094491,125.708661416787] , 'ボタン2' );
var btn3 = winObj.add ( 'button' , [18,151.417322833575,92.7244094491,195.929847775753] , 'ボタン3' );
var btn4 = winObj.add ( 'button' , [120,151.417322833575,194.7244094491,195.929847775753] , 'ボタン4' );
btn1.onClick = function() {
    alert( btn1.text );
}
btn2.onClick = function() {
    alert( btn1.text );
}
btn3.onClick = function() {
    alert( btn1.text );
}
btn4.onClick = function() {
    alert( btn1.text );
}
winObj.center();
winObj.show();

検証はCC2019とCS6で試しました。
色も設定できるようにしようかなと思ったのですが、CC以降は設定できないのでやめました。

サンプルデータとScriptのDL

スクリプトのコード

#targetengine "session"

var errarTx = "【 errar 】";
message = "";

//ドキュメントチェック
var alertBool = true;
if ( app.documents.length == 0 ){
    alertBool = false;
    errarTx = errarTx + "\rドキュメントが開かれていません。"
    alert( errarTx );
}

//処理開始
if ( alertBool == true ){
    alertBool = false;
    var sel = app.activeDocument.selection;

    //オブジェクトを選択しているかをチェックしてとりあえず取得
    if ( sel == "" ){
        alertBool = true;
        errarTx = errarTx + "\r何も選択されていません。";
    }
    else {
        var getArr = new Array();
        var sortArr = new Array();
        var resltArr = new Array();

        //ドキュメントの単位設定
        //ルーラー(定規ガイド)の原点取得
        var docZP = app.activeDocument.zeroPoint;

        //環境設定(単位と測定値)取得
        with( app.activeDocument.viewPreferences ){
            var get_h1 = horizontalMeasurementUnits;
            var get_v1 = verticalMeasurementUnits;
            var get_ty1 = typographicMeasurementUnits;
            var get_tx1 = textSizeMeasurementUnits;
            var get_st1 = strokeMeasurementUnits;
            var get_rO1 = rulerOrigin;
        }

        //定規の単位 開始位置 ページ
        app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;

        //単位を設定
        docTani( "PIXELS" , "PIXELS" , get_ty1 , get_tx1 , get_st1 );

        //オブジェクトを取得する
        for ( var i = 0 ; i < sel.length ; i ++ ){
            //サブレイヤーに名前が付いている
            if ( sel[i].name != "" ){
                getArr.push( sel[i] );
            }
            //グループ
            else if( sel[i] == "[object Group]" ){
                sel[i].name = "group";
                getArr.push( sel[i] );
            }
        }
    }

    //まず、「dialog」か「palette」を取得。そして、それ以外を取得しソートするために座標の値を取得する。
    for ( var i in getArr ){
        if ( ( getArr[i].name == "dialog" ) || ( getArr[i].name == "palette" ) || ( getArr[i].name == "window" ) ) {
            resltArr.push(getArr[i]);
        }
        else{
            var objVB = getArr[i].visibleBounds;
            var y1 = ( '000' + objVB[0] ).slice( -3 );
            var x1 = ( '000' + objVB[1] ).slice( -3 );
            sortArr.push( [ [ y1 , x1 ] , getArr[i] ] );
        }
    }

    //「dialog」か「palette」が無ければアラート。
    if ( resltArr.length == 0 ){
        alertBool = true;
        errarTx = errarTx + "\r「dialog」または「palette」が選択されていません。";
    }

    //座標でソートする。
    if ( sortArr.length >= 1 ){
        sortArr.sort();
        //panelを先にresltArrに入れる
        for ( var i in sortArr ){
            if ( sortArr[i][1].name == "panel" ){
                resltArr.push( sortArr[i][1] );
            }
        }
        //panel以外をresltArrに入れる
        for ( var i in sortArr ){
            if ( sortArr[i][1].name != "panel" ){
                resltArr.push( sortArr[i][1] );
            }
        }
    }

    //アラート、または処理開始
    if ( alertBool == true ){
        alert( errarTx );
    }
    else {
        var addWIndow = "";

        //ルーラー(定規ガイド)の原点設定
        app.activeDocument.zeroPoint = [ 0 , 0 ];
        app.activeDocument.zeroPoint = [ resltArr[0].visibleBounds[1] , resltArr[0].visibleBounds[0] ];

        //サンプルウィンドウ作成
        for ( var i = 0 ; i < resltArr.length ; i ++ ){
            var variable = "";
            var arrObj = resltArr[i];
            var addWIndow = windowTxAdd( arrObj , addWIndow , variable );
        }

        //ルーラー(定規ガイド)の原点を元に戻す
        app.activeDocument.zeroPoint = docZP;

        //定規の単位 開始位置
        app.activeDocument.viewPreferences.rulerOrigin = get_rO1;

        //ドキュメントの単位設定を元に戻す
        docTani( get_h1 , get_v1 , get_ty1 , get_tx1 , get_st1 );

        //サンプルウィンドウ作成
        eval( addWIndow );

        //サンプルウィンドウが閉じたらテキスト出力ウィンドウ
        winObj.onClose = function(){ textOutWindow( addWIndow , message ) }

        //サンプルウィンドウ表示
        winObj.center();
        winObj.show();

    }
}

//サンプルウィンドウ用文字作成
function windowTxAdd( arrObj , addWIndow , variable ){
    //引数
    if ( variable == "" ){ variable = "winObj" }

    //サブレイヤー名取得
    var objName = arrObj.name;

    //座標取得
    var objGetVB = arrObj.visibleBounds;
    var objVB = [ objGetVB[1] , objGetVB[0] , objGetVB[3] , objGetVB[2] ];
    
    //テキフレ内の文字取得
    if ( arrObj.toString() == "[object TextFrame]" ){ var objText = arrObj.contents }
    else { var objText = "" }

    //クループ内のオブジェクト格納用配列
    var grArr = new Array();
    switch ( objName ){
        case "dialog":
            message = "  ※[esc]で閉じます。";
            addWIndow = winAdd( objName , objText + message , objVB );
            break;
        case "palette": 
            addWIndow = winAdd( objName , objText , objVB );
            break;
        case "window": 
            addWIndow = winAdd( objName , objText , objVB );
            break;
        case "button": 
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "checkbox": 
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "edittext": 
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "panel": 
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "statictext": 
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "edittext":
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "radiobutton":
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "dropdownlist":
            addWIndow = winListAdd( objName , objText , objVB , variable );
            break;            
        case "listbox":
            addWIndow = winListAdd( objName , objText , objVB , variable );
            break;
        case "image":
            objText = new File( arrObj.allGraphics[0].itemLink.filePath );
            addWIndow = winObjAdd( objName , objText , objVB , variable );
            break;
        case "iconbutton":
            objText = new File( arrObj.allGraphics[0].itemLink.filePath );
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '" + objText + "' , { button:true,toolbutton:true } );\r";
            break;
        case "progressbar":
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '0' , '100' );\r";
            break;
        case "scrollbar":
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '0' , '0' , '100' );\r";
            break;
        case "slider":
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '0' , '0' , '100' );\r";
            break;
        case "tabbedpanel":
            //テキストを配列化
            reObjText = textSplit( objText );

            //変数追加
            variable = "var winTab = " + variable;

            //テキスト作成
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '' );\r";

            //タブ作成
            for ( var j = 0 ; j < reObjText.length ; j ++ ){
                addWIndow = addWIndow + "winTab.add ( 'tab' , [" + objVB + "] , " + reObjText[j] + " );\r";
            }
            break;
        case "treeview":
            //テキストを配列化
            reObjText = textSplit( objText );

            //変数追加
            variable = "var winTree = " + variable;
            
            //テキスト作成
            addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , [" + reObjText + "] );\r";

            //ツリーのサンプルを1つ作成
            if ( reObjText.length >= 1 ){
                for ( var j = 0 ; j < reObjText.length ; j ++ ){
                    addWIndow = addWIndow + "winTree.items[" + j + "].add ( 'node' , 'treeSample' );\r";
                }
            }
            break;
        case "group":
            //グループ内のオブジェクトを取得
            for ( var j = 0 ; j < arrObj.allPageItems.length ; j ++ ){
                var grItem = arrObj.allPageItems[j];
                //親のidでマッチさせ、グループの直下のオブジェクトを取得
                if ( grItem.parent.id == arrObj.id ){
                    grArr.push( grItem );
                    //変数取得 オブジェクトのidを変数名にする
                    reVariable = "winGr" + grItem.parent.id;
                }
            }

            //親がグループなら、親を変数を取得
            if ( arrObj.parent == "[object Group]" ){
                variable = "winGr" + arrObj.parent.id;
            }

            //テキスト作成
            addWIndow = addWIndow + "var " + reVariable + " = " + variable + ".add ( '" + objName + "' , [" + objVB + "] );\r";

            //グループ内のオブジェクトを処理
            if ( grArr.length >= 1 ){
                //ルーラー(定規ガイド)の原点取得
                var reGetZeroPnt = app.activeDocument.zeroPoint;

                //ルーラー(定規ガイド)の原点設定 グループに原点を合わせる
                app.activeDocument.zeroPoint = [ 0 , 0 ];
                app.activeDocument.zeroPoint = [ arrObj.visibleBounds[1] , arrObj.visibleBounds[0] ];

                //グループ内のオブジェクトを処理
                for ( var j = 0 ; j < grArr.length ; j ++ ){
                    if ( grArr[j] == "[object Group]" ){
                        grArr[j].name = "group";
                    }
                    var addWIndow = windowTxAdd( grArr[j] , addWIndow , reVariable );
                }
                
                //引数なし
                reVariable = "";
                
                //ルーラー(定規ガイド)の原点設定
                app.activeDocument.zeroPoint = [ 0 , 0 ];
                app.activeDocument.zeroPoint = reGetZeroPnt;
            }
            //groupを<グループ>に戻す
            arrObj.name = "";
            break;
    }
    return addWIndow;

    function textSplit( objText ){
        var reObjText = new Array();
        //テキフレ内の文字を改行でスプリット
        var sp = objText.split("\r");
        //シングルクォーテーションをつけて配列
        if ( sp.length >= 1 ){
            for ( var j in sp ){
                reObjText.push( "'" + sp[j] + "'" );
            }
        }
        return reObjText;
    }

    function winAdd( objName , objText , objVB ){
        //テキスト作成
        addWIndow = addWIndow + "var winObj = new Window ( '" + objName + "' , '" + objText + "' , [" + objVB + "] );\r";
        return addWIndow;
    }

    function winObjAdd( objName , objText , objVB , variable ){
        //テキスト作成
        addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , '" + objText + "' );\r";
        return addWIndow;
    }

    function winListAdd( objName , objText , objVB , variable ){
        //テキフレ内の文字を改行でスプリット
        var sp = objText.split("\r");
        var reObjText = new Array();
        //シングルクォーテーションをつけて配列
        if ( sp.length >= 1 ){
            for ( var j in sp ){
                reObjText.push( "'" + sp[j] + "'" );
            }
        }
        //変数追加
        variable = "var winList = " + variable;
        //テキスト作成
        addWIndow = addWIndow + variable + ".add ( '" + objName + "' , [" + objVB + "] , [" + reObjText + "] );\r";
        //リストの1つめを選択状態にする。
        addWIndow = addWIndow + "winList.items[0].selected = true;\r";
        return addWIndow;
    }

}

//テキスト出力ウィンドウ
function textOutWindow( addWIndow , message ){
    var winSize = [ 0 , 0 , 1000 , 500 ];
    var prop1 = {
        resizeable: false,
        closeButton: true,
        maximizeButton: true,
        minimizeButton: true,
        borderless: false
    }
    winObjTx = new Window ( 'dialog' , 'GUI-Window source code  ※[esc]で閉じます。' , winSize , prop1 );
    var prop2 = {
        multiline: true,
        readonly: false,
        noecho: false,
        enterKeySignalOnChange: false,
        borderless: true,
        scrollable: true
    }
    var winObjTxEt = winObjTx.add( "edittext" , winSize ,"", prop2 );
    //メッセージ削除 (dialogの場合に表示される閉じ方)
    var Regexp = new RegExp( message , "g" );
    result = addWIndow.toString().replace( Regexp , "" );
    winObjTxEt.text = result;
    winObjTx.center();
    winObjTx.show();
}

//ドキュメントの単位設定
function docTani( h , v , ty , tx , st ){
    // h:水平方向
    // v:垂直方向
    // ty:組版
    // tx:テキストサイズ
    // st:線

    // AGATES:アゲート                        
    // AMERICAN_POINTS:アメリカ式ポイント        
    // BAI:Bai
    // CENTIMETERS:センチメートル
    // CICEROS:シセロ
    // CUSTOM:カスタム
    // HA:歯
    // INCHES:インチ
    // INCHES_DECIMAL:デシマルインチ
    // MILLIMETERS:ミリメートル
    // MILS:Mils
    // PICAS:パイカ
    // PIXELS:ピクセル
    // POINTS:ポイント
    // Q:級
    // U:U
    
    //選ドキュの環境設
    with( app.activeDocument.viewPreferences ){
        horizontalMeasurementUnits = Taniswitch( h ); //水平方向
        verticalMeasurementUnits = Taniswitch( v ); //垂直方向
        typographicMeasurementUnits = Taniswitch( ty ); //組版
        textSizeMeasurementUnits = Taniswitch( tx ); //テキストサイズ
        strokeMeasurementUnits = Taniswitch( st ); //線
    }
    
    function Taniswitch( get ){
        switch ( get.toString() ){
            case "AGATES": set = MeasurementUnits.AGATES; break;
            case "AMERICAN_POINTS": set = MeasurementUnits.AMERICAN_POINTS; break;
            case "BAI": set = MeasurementUnits.BAI; break;
            case "CENTIMETERS": set = MeasurementUnits.CENTIMETERS; break;
            case "CICEROS": set = MeasurementUnits.CICEROS; break;
            case "CUSTOM": set = MeasurementUnits.CUSTOM; break;
            case "HA": set = MeasurementUnits.HA; break;
            case "INCHES": set = MeasurementUnits.INCHES; break;
            case "INCHES_DECIMAL": set = MeasurementUnits.INCHES_DECIMAL; break;
            case "MILLIMETERS": set = MeasurementUnits.MILLIMETERS; break;
            case "MILS": set = MeasurementUnits.MILS; break;
            case "PICAS": set = MeasurementUnits.PICAS; break;
            case "PIXELS": set = MeasurementUnits.PIXELS; break;
            case "POINTS": set = MeasurementUnits.POINTS; break;
            case "Q": set = MeasurementUnits.Q; break;
            case "U": set = MeasurementUnits.U; break;
        }
        return set;
    }
}

いいなと思ったら応援しよう!