2015年4月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
無料ブログはココログ

« Wiki を作ってみました | トップページ | コピペシール、その(1) »

2013年11月17日 (日)

微妙に便利になり切れなかった「可変タグ」シール

MOONPhase ver 2.7.0 で新設された "タグブロック" の出番がなくなってしまうほど便利なシールを作るつもりだったのですが、後述の理由で、今一つ中途半端なものになってしまいました。開発環境を整えられている人には便利に使ってもらえるかもしれませんが。ちょっと改造すれば各人の需要に合うと思うので。

使い方

  • 貼りつけると複数のタグ候補が表示された GUI が立ち上がります。上下の選択ボタン [▲] [▼] で候補を選んで [OK] ボタンをタップすると、その文字列でタグシールが作成されます。
  • シールのタップで検索、不要になったら剥がすだけです。

ダウンロード : 「可変タグ」シール もし、使いたい方がおられたら。

開発前の目標

実は、当初の目論見では、以下のような機能も実現したかったのですが。

  • [Edit] ボタンで Edit モードに入る
  • 上下の swap ボタンでタグ候補の順序を変更
  • [Delete] ボタンで不要なタグ候補を削除
    • 但し、最低一つの候補は残さなければならなく、全候補を削除することはできない
  • [Add] ボタンで任意の文字列をタグ候補として追加
    • 但し、入力できる文字列は全角で10文字以内、文字列中に、半角 ';' (セミコロン)は含められない
  • タグ候補を編集してシールを貼りつけたうえで、そのシールをシール台帳に再登録すると、編集したタグ候補が反映されている

以上のように、ダウンロード後にそれぞれのユーザーごとに都合よくカスタマイズできるシールを目指していました。

できなかったこと

上記のような機能を実現するために

  • 元のコードにタグ候補の初期値を用意しておく
    • TAGS = [ "タグ1",  "タグ2",  "タグ3",   "タグ4",   "タグ5" ] ;
    • INDEX = 0;
  • シールを貼った時に、初期値に対して編集を加えた結果を、シールID/info.json に以下のフォーマットで保存する
    • stickerProper: { AppName: 'variableTag', tags:  [ "タグ1",  "タグ7",  "タグ3",   "タグ2" ], index: 2, selected:   "タグ3" }
  • ユーザーが編集した情報は info.json に保存されているので、台帳に登録して別のページに貼りこんだ時には、タグ候補を info.json から読み込んで使えば、カスタマイズが反映される

という設計だったのですが、どうやら info.json にはシステムに規定の情報以外は保存できないようなのです。(詳細は Issue Tracker #148 に書きましたので、そちらを参照ください)

仕方がないので、カスタマイズの反映はあきらめて、とりあえず動くように、情報を localStroage に保存するように書き換えました。

info.json 以外にわかったこと

今回のシールでは、簡単な GUI の作成にチャレンジしました。(シールを動作させてみれば一目瞭然ですが、@k_ohga さんの「まとめて設定シール」を参考にさせていただきました。

enchant.js も(不要なのかもしれませんが)使ってみたかったので、enchant.js の Sprite でボタンを実装して 'touchstart' イベントを拾っているのですが、当初ボタンにイベントが全く届きませんでした。

と、言うのが、当初はシールを Hack してできる、MOONBlock ベースの hack.js に書き加えていったので、StickerPuppet.create(...) のパターンを使ったのですが、これを、Sticker.create()...sticker.register(); のパターンに書き換えると動きました。どうも、StickerPuppet.create(...) でやると、画面タッチをすべて scene が(?) 拾ってしまうようです。わかるまで随分かかってしまいましたので、もし、同じようなものを作りたい場合は、ご注意を。

それでは最後にコードを載せます

コードを組むのには、上述の @k_ohga さんの「まとめて設定シール」以外にも@paraches さんの 「ぷよMOON」、更には、その元となっている @otat_in さんの「とことんぷよぷよ」を参考にさせていただきました。

全体として、「なんでこんな変なことをしているのか」「どうしてこんな無駄なギミックになっているのか」という箇所があふれていると思います。一部は意識的に、javascript でできることを試してみたかったのもありますが、残りは思っていたことが思っていたようにできなくて、とにかくわかる範囲で動くことを目指したからです。

もう一年くらいしてから書き直せば、ずっとシンプルなものにできる(ようになっているといいな)と思います。あんまりよい参考資料にはならないかも。

GUI 部分 : view.js

enchant();
(function(global) {
    var CONST = {
         color: {
             bg: "black", rim: "white", highlight: "white", btn: "rgb(48,64,96)"
            ,font: { highlight: "black", normal: "white" }
         }
        ,rim: { box: 3, btn: 1 }
        ,margin:    5
        ,padding: { x:5, y:5 }
        ,font: { tag: 'bold 20px', btn: 'bold 24px' }
        ,height: { tagFont: 16, btnFont: 14, tag: 16 + 5 * 2 }
                                // height.tag = height.tagFont + padding.y * 2
        ,tagNGcharDefault: ';'
        ,maxTagLength: 20       // 半角単位で指定する
    }

    function binaryLength(str) {
        var r = 0;
        for (var i = 0; i < str.length; i++) {
            var c = str.charCodeAt(i);
            // Unicode : 0x0 - 0x80, 0xf8f0, 0xff61 - 0xff9f, 0xf8f1 - 0xf8f3
            if ( (0x0 <= c && c < 0x81) || (c == 0xf8f0) ||
            (0xff61 <= c && c < 0xffa0) || (0xf8f1 <= c && c < 0xf8f4) ) {
                r += 1;
            } else {
                r += 2;
            }
        }
        return r;
    }

    function cropStr( str, max ) {
        while ( binaryLength( str ) > max ) str = str.slice( 0, -1 );
        return str;
    }

    var TagBox = function( x, y, width, height, tags, index ) {
        this.width = width;     this.height = height;

        this.tags = tags;
        for ( var i = 0, len = tags.length; i < len; i++ ) tags[ i ] = cropStr( tags[ i ], CONST.maxTagLength );
        this.index = ( index < 0 ) ? 0 : index;
        this.index = ( this.index >= tags.length ) ? tags.length - 1 : this.index;

        // tag 名には含めてはいけない文字。呼び出し元から、new TagBox().tagNGchar = ... で設定する
        this.tagNGchar = CONST.tagNGcharDefault;

        var bg = new Sprite( width, height );
        this.node = bg;    this.node.x = x;    this.node.y = y;
        bg.image = new Surface( width, height );
        this.ctx = bg.image.context;
        this.ctx.fillStyle = CONST.color.rim;
        this.ctx.fillRect( 0, 0, this.width, this.height );
        this.ctx.fillStyle = CONST.color.bg;
        this.ctx.fillRect( CONST.rim.box, CONST.rim.box,
            this.width - CONST.rim.box * 2, this.height - CONST.rim.box * 2
        );

        var spaceForViewArea = CONST.rim.box + CONST.margin;
        var viewTagCount = Math.floor( ( this.height - spaceForViewArea * 2 ) / CONST.height.tag );
        this.viewTagPositions = {
             strX: spaceForViewArea + CONST.padding.x
            ,rectX: spaceForViewArea
            ,strY: [],              bgY: []
            ,maxStrWidth: this.width - (spaceForViewArea + CONST.padding.x) * 2
            ,rectWidth: this.width - spaceForViewArea * 2
        };
        for ( var i = 0; i < viewTagCount; i++ ) {
            this.viewTagPositions.strY[ i ] = spaceForViewArea + CONST.height.tag * (i + 1) - CONST.padding.y;
            this.viewTagPositions.bgY[ i ] = spaceForViewArea + CONST.height.tag * i;
        }
        this.indexOffset = ( this.index >= viewTagCount ) ? this.index - ( viewTagCount - 1 ) : 0;

        drawViewArea( this );
        highlightSelection( this, true );
    }

    function drawTag( that, viewIndex, tagStr, isHighlight ) {
        that.ctx.fillStyle = isHighlight ? CONST.color.highlight : CONST.color.bg;
        that.ctx.fillRect( that.viewTagPositions.rectX, that.viewTagPositions.bgY[ viewIndex ],
            that.viewTagPositions.rectWidth, CONST.height.tag
        );

        that.ctx.fillStyle = ( !isHighlight ) ? CONST.color.highlight : CONST.color.bg;
        that.ctx.font = CONST.font.tag;

        var textWidth = that.ctx.measureText( tagStr ).width;
        if ( textWidth > that.viewTagPositions.maxStrWidth ) {
            that.ctx.fillText( tagStr,
                that.viewTagPositions.strX, that.viewTagPositions.strY[ viewIndex ],
            that.viewTagPositions.maxStrWidth );
        } else {
            that.ctx.fillText( tagStr,
                that.viewTagPositions.strX, that.viewTagPositions.strY[ viewIndex ]
            );
        }
    }

    function drawViewArea( that ) {
        var tagsLength = that.tags.length;
        for ( var i = 0, len = that.viewTagPositions.strY.length; i < len; i++ ) {
            if ( that.indexOffset + i < tagsLength ) {
                drawTag( that, i, that.tags[ that.indexOffset + i ], false );
            } else {
                drawTag( that, i, '', false );
            }
        }
    }

    function highlightSelection( that, isOn ) {
        var viewIndex = that.index - that.indexOffset;
        var tag = that.tags[ that.index ];
        drawTag( that, viewIndex, tag, isOn );
    }

    TagBox.prototype.upTagSelection = function() {
        if ( this.index > 0 ) {
            highlightSelection( this, false );
            this.index -= 1;
            if ( this.indexOffset > this.index ) {
                this.indexOffset = this.index;
                drawViewArea( this );
            }
            highlightSelection( this, true );
        }
    }

    TagBox.prototype.downTagSelection = function() {
        if ( this.index < this.tags.length - 1 ) {
            highlightSelection( this, false );
            this.index += 1;
            var len = this.viewTagPositions.strY.length;
            if ( this.indexOffset + len - 1 < this.index ) {
                this.indexOffset = this.index - len + 1;
                drawViewArea( this );
            }
            highlightSelection( this, true );
        }
    }

    TagBox.prototype.swapTag = function( isUp ) {
        var idx = this.index;
        var tmp = this.tags[ idx ];
        if ( isUp && idx > 0 ) {
            this.tags[ idx ] = this.tags[ idx - 1 ];
            this.tags[ idx - 1 ] = tmp;
            drawViewArea( this );
            this.upTagSelection();
        } else if ( !isUp && idx < this.tags.length -1 ) {
            this.tags[ idx ] = this.tags[ idx + 1 ];
            this.tags[ idx + 1 ] = tmp;
            drawViewArea( this );
            this.downTagSelection();
        }
    }

    TagBox.prototype.removeTag = function() {
        var len = this.tags.length
        if ( len < 2 ) return { status: false
            ,message: "タグ がひとつしかない時は削除できません" };

        highlightSelection( this, false );
        this.tags = this.tags.slice( 0, this.index ).
            concat( this.tags.slice( this.index + 1, len ) );
        if ( this.index >= this.tags.length ) this.index = this.tags.length - 1;
        drawViewArea( this );
        highlightSelection( this, true );

        return {status: true, message: ""};
    }

    TagBox.prototype.addTag = function( newTag ) {
       if ( newTag.indexOf( this.tagNGchar ) >= 0 ) return { status: false
            ,message: "tag 名に \'" + this.tagNGchar + "\' を含めることはできません" };
        newTag = cropStr( newTag, CONST.maxTagLength );
        highlightSelection( this, false );
        this.tags.push( newTag );
        this.index = this.tags.length - 1;
        var len = this.viewTagPositions.strY.length;
        this.indexOffset = ( this.index >= len ) ? this.index - ( len - 1 ) : 0;
        drawViewArea( this );
        highlightSelection( this, true );

        return {status: true, message: ""};
    }

    var LabeledButton = function( x, y, width, height, text ) {
        this.bg = new Sprite( width, height );
        this.bg.image = new Surface( width, height );
        var ctx = this.bg.image.context;
        ctx.fillStyle = CONST.color.rim;
        ctx.fillRect( 0, 0, width, height );
        ctx.fillStyle = CONST.color.btn;
        ctx.fillRect( CONST.rim.btn, CONST.rim.btn, width - CONST.rim.btn * 2, height - CONST.rim.btn * 2 );

        ctx.fillStyle = CONST.color.font.normal;
        ctx.font = CONST.font.btn;
        var maxWidth = width - ( CONST.rim.btn + CONST.padding.x ) * 2;
        var textWidth = ctx.measureText( text ).width;
        if ( textWidth > maxWidth ) {
            ctx.fillText( text,
                CONST.rim.btn + CONST.padding.x, (height + CONST.height.btnFont)/2,
            maxWidth );
        } else {
            ctx.fillText( text,
                (width - textWidth)/2, (height + CONST.height.btnFont)/2
            );
        }
        this.node = this.bg;    this.node.x = x;    this.node.y = y;
    }

    global.TagBox = TagBox;
    global.LabeledButton = LabeledButton;

})(this);

(function(global) {
    var CONST = {
         screenX: 768, screenY: 1024
        ,guiX: 415, guiY: 370
        ,colorBG: "black"
    }

    function compileButtons( set, offsetX, offsetY ) {
        var btn, src;
        for ( var k in set ) {
            src = set[ k ];
            btn = new LabeledButton( offsetX + src[0], offsetY + src[1], src[2], src[3], src[4] ).node;
            btn.addEventListener( "touchstart", src[5] );
            set[ k ] = btn
        }
    }

    var GUI = function( tags, index, tagNGchar, callback ) {
        var _callback = callback;
        var offsetX = (CONST.screenX - CONST.guiX)/2;
        var offsetY = (CONST.screenY - CONST.guiY)/2;
        var gui = new Game( CONST.screenX, CONST.screenY );
        gui.fps = 10;
        gui.scale = 1;

    gui.onload = function() {
            var scene = gui.rootScene;

            var bg = new Sprite( CONST.guiX, CONST.guiY );
            bg.x = offsetX;    bg.y = offsetY;
            bg.image = new Surface( CONST.guiX, CONST.guiY );
            var ctx = bg.image.context;
            ctx.fillStyle = CONST.colorBG;
            ctx.fillRect( 0, 0, CONST.guiX, CONST.guiY );
            scene.addChild( bg );

            var box = new TagBox( offsetX + 150, offsetY + 60, 250  , 250, tags, index );
            box.tagNGchar = tagNGchar;
            var boxView = box.node;

            var buttonsSelect = {
                 upSelection:   [ 160, 10, 230, 35, '▲',  function(){ box.upTagSelection(); } ]
                ,downSelection: [ 160, 323, 230, 35, '▼', function(){ box.downTagSelection(); } ]
                ,startEdit:     [ 25, 218, 100, 100, 'Edit',  function(){
                    MOON.alert( "現在の実装では、Edit モードの操作にほとんど意味はありません。デモとしてご理解下さい。", function() {
                        for ( var k in buttonsSelect ) scene.removeChild( buttonsSelect[ k ] );
                        for ( var k in buttonsEdit ) scene.addChild( buttonsEdit[ k ] );
                    });
                }]
                ,finishSelection:   [ 15, 55, 120, 120, 'OK',  function(){
                    gui.stop();
                    _callback( box.tags, box.index );
                }]

            };
            var buttonsEdit = {
                 upSelection:   [ 290, 10,  100, 35, '▲',  function(){ box.upTagSelection(); } ]
                ,downSelection: [ 290, 323, 100, 35, '▼', function(){ box.downTagSelection(); } ]
                ,upSwap:        [ 165, 10,  100, 35, 'swap',   function(){ box.swapTag( true ); } ]
                ,downSwap:      [ 165, 323, 100, 35, 'swap',   function(){ box.swapTag( false ); } ]
                ,removeTag:     [ 25, 180, 100, 60, 'Delete',  function(){
                    MOON.alert( 'タグ : \'' + box.tags[ box.index ] + '\' を削除してよろしいですか?', function() {
                        var result = box.removeTag();
                        if ( !result.status ) MOON.alert( result.message, function(){} );
                    });
                }]
                ,addTag:        [ 25, 270, 100, 60, 'Add',  function(){
                    var inStr = window.prompt( '追加するタグを入力してください(全角10文字以内)', '' );
                    if ( inStr ) {
                        var result = box.addTag( inStr );
                        if ( !result.status ) MOON.alert( result.message, function(){} );
                    }
                }]
                ,finishEditing: [ 20, 40, 110, 100, 'Finish', function(){
                    for ( var k in buttonsEdit ) scene.removeChild( buttonsEdit[ k ] );
                    for ( var k in buttonsSelect ) scene.addChild( buttonsSelect[ k ] );
                }]
            };
            compileButtons( buttonsSelect, offsetX, offsetY );
            compileButtons( buttonsEdit, offsetX, offsetY );

            scene.addChild( boxView );
            for ( var k in buttonsSelect ) scene.addChild( buttonsSelect[ k ] );
        }
        gui.start();
    }


    global.GUI = GUI;
})(this);

info.json と localStorage へのアクセス : accessjson.js

(function(global) {
    var InfoUtil = {
         PROPER_TAG: 'stickerProper'
        ,getStickerID: function() {
            var relURL = window.location.getAbsoluteURL("").split("/Data/")[1];
            return relURL.split( "/" )[2];
        }
        ,getPageID: function() {
            var relURL = window.location.getAbsoluteURL("").split("/Data/")[1];
            return relURL.split( "/" )[1];
        }
        // JSON から、tag で指定した値を読み込む。
        // tag が存在しなかった場合の戻り値を指定できる。
        //
        ,getObjFromJSON: function( json, tag, nullDefault ) {
            var obj = json[ tag ];
            if ( nullDefault == null ) {
                return obj;
            } else {
                return ( obj == null ) ? nullDefault : obj;
            }
        }
        // JSON に、値 obj を 名 tag で登録する。
        // 但し、値が null, {}, [] の場合は削除する。
        //
        ,setObjToJSON: function( json, tag, obj ) {
            if ( (obj == null)
              || ( (typeof obj).match( /object/i ) && Object.keys( obj ).length <= 0 )
            ) {
                if ( json[ tag ] ) delete json[ tag ];
            } else {
                    json[ tag ] = obj;
            }
            return json;
        }
    };


    var StorageUtil = {
        // localStorage から、tag で指定した値を読み込む。
        // tag が存在しなかった場合の戻り値を指定できる。
        //
         get: function( tag, nullDefault ) {
            var obj = localStorage[ tag ];
            if ( nullDefault == null ) {
                return obj;
            } else {
                return ( obj == null ) ? nullDefault : obj;
            }
        }
        // localStorage に、値 obj を 名 tag で登録する。
        // 但し、値が null, {}, [] の場合は削除する。
        //
        ,set: function( tag, obj ) {
            if ( (obj == null)
              || ( (typeof obj).match( /object/i ) && Object.keys( obj ).length <= 0 )
            ) {
                if ( localStorage[ tag ] ) localStorage.removeItem( tag );
            } else {
                localStorage[ tag ] = obj;
            }
        }
    };

    global.InfoUtil = InfoUtil;
    global.StorageUtil = StorageUtil;
})(this);

hack.js

シールを剥がしたときのデータ削除は、意識的にくどく書いています。OS が落ちて localStorage にゴミデータが残ってしまっても、そのあとシールを貼り/剥がししているうちに、ゴミを削除できることを目指しているからです。

var TAGS = [ "お気に入り", "アイディアメモ", "仕事", "記録", "日記", "落書き", "プログラム", "イラスト" ];
var INDEX = 0;

/*--------------------------------------------------------------------------//
// 可変タグシール
//
// 上記の TAGS の内容が選択肢として表示される。文字列長は全角 10 文字以内。
// 貼り付け時に INDEX 番目が初期選択された状態で GUI が立ち上がる
// 例えば、上記の例なら INDEX = 2; であれば、"仕事" が選択されているので、
// 直ぐに [OK] で張り付けられる。
//
// シールの表示まで変えたいようなら、まず、TAGS と INDEX を希望の
// 組み合わせで定義し、初期選択のまま選択肢を変えずに張り付ければ
// シールの表示が初期選択文字に変わる。
// そのシールを改めて台帳に登録すれば、頻用するタグを直ぐに貼れる
// シールになります。
//                                                2013/11/16  くるの はるみ
//--------------------------------------------------------------------------*/

importJS(["lib/MOON.js", "lib/enchant.js", "lib/accessjson.js", "lib/view.js"], function() {
    enchant();

    var TAG_DELIMITER = ';';
    var SEARCH_INFO_NAME = 'vTagSearch';
    var INACTIVE_TAG = '<未設定>';  // tag を選択する前の表示文字
    var TAG_LIST = 'activeVtags';
    //
    // 文字列 str を埋め込んだ画像を file の名で save する。
    // 返り値として、save した画像の x, y size を返す。
    //
    function saveStickerImage( str, file ) {
        var canvas = window.document.createElement("canvas");
        var width = 18 * 7 + ( 5+3+5 ) *2;
        var height = 14 + ( 5+3+5+5 ) *2 - 3;
        var maxWidth = 18 * 7 + 2;
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = "white";
        ctx.fillRect(0,0,width,height);
        ctx.fillStyle = "black";
        ctx.fillRect(5,5,width - 10,height - 10 + 3);
        ctx.fillStyle = "white";
        ctx.fillRect(8,8,width - 16,height - 16 + 3);

        ctx.fillStyle = "white";
        ctx.fillRect(0,0,26,13);
        ctx.fillStyle = "black";
        ctx.font = "12px";
        ctx.fillText( "tag", 4, 10 );

        ctx.fillStyle = "blue";
        ctx.font = "18px";
        if ( ctx.measureText( str ).width > maxWidth ) {
            ctx.fillText( str, 12, 14+18, maxWidth );
        } else {
            ctx.fillText( str, 12, 14+18 );
        }

        MOON.saveImage( file, canvas );
        return { x: width, y: height };
    }

    //
    // MOON.searchStorage() に渡す、文字列化した query を返す。
    // myTag に対する link 情報の存在する page が検索にかかる。
    //
    function getVtagQuery( myTag ) {
        return 'function matches(s){var vt = s[\"' + SEARCH_INFO_NAME + '\"]; return ((vt != null) && (vt.indexOf(\"' + TAG_DELIMITER + myTag + '\") >= 0));}';
    }

    //
    // { myStikerID => linkToID } から成る object を scan.
    // 自ページのシール以外からの link 情報が紛れていたら
    // ゴミとして削除する。
    //
    function collectOtherVtags() {
        var OtherVtags = [];
/*
// info.json に 固有データが保存できれば
        var myStickerID = InfoUtil.getStickerID();
        var stickerJSON, properData, vtag;
        var stickers = MOON.getCurrentPage().papers;
        for ( var i = 0, len = stickers.length; i < len; i++ ) {
            if ( stickers[ i ] == myStickerID ) continue;
            stickerJSON = MOON.getPaperJSON( stickers[ i ] );
            properData = InfoUtil.getObjFromJSON( stikcerJSON, InfoUtil.PROPER_TAG, {} );
            vtag = propeData[ 'seledted' ];
            if ( vtag ) OtherVtags.push( vtag );
        }
*/
// info.json に 固有データが保存できなければ
        var flag;
        var myStickerID = InfoUtil.getStickerID();
        var stickers = MOON.getCurrentPage().papers;
        var vtagList = StorageUtil.get( TAG_LIST, {} );
        for ( var id in vtagList ) {
            if ( id == myStickerID ) continue;
            flag = false;
            for ( var i = 0; i < stickers.length; i++ ) {
                if ( id == stickers[ i ] ) {
                    flag = true;
                    break;
                 }
            }
            if ( flag ) OtherVtags.push( vtagList[ id ] );
        }
// ここまで
        return OtherVtags;
    }

    function getMyTag() {
/*
// info.json に 固有データが保存できれば
        var myStickerID = InfoUtil.getStickerID();
        var stickerJSON = MOON.getPaperJSON( myStickerID );
        var properData = InfoUtil.getObjFromJSON( stikcerJSON, InfoUtil.PROPER_TAG, {} );
        var myTag = InfoUtil.getObjFromJSON( properData, 'selected', null );
*/
// info.json に 固有データが保存できなければ
        var myStickerID = InfoUtil.getStickerID();
        var vtagList = StorageUtil.get( TAG_LIST, {} );
        var myTag = InfoUtil.getObjFromJSON( vtagList, myStickerID, null );
// ここまで
        return myTag;
    }

// info.json に 固有データが保存できないときに使用
    function saveMyTagInfoToLocalStrage( myTagInfo ) {
        StorageUtil.set( InfoUtil.PROPER_TAG, myTagInfo );
        var myStickerID = InfoUtil.getStickerID();
        var vtagList = StorageUtil.get( TAG_LIST, {} );
        InfoUtil.setObjToJSON( vtagList, myStickerID, myTagInfo.selected );
        StorageUtil.set( TAG_LIST, vtagList );
    }

// info.json に 固有データが保存できないときに使用
    function removeMyTagInfoFromLocalStorage() {
        var myStickerID = InfoUtil.getStickerID();
        var vtagList = StorageUtil.get( TAG_LIST, {} );
        InfoUtil.setObjToJSON( vtagList, myStickerID, null );
        StorageUtil.set( TAG_LIST, vtagList );
        if ( Object.keys( vtagList ).length <= 0 ) StorageUtil.set( InfoUtil.PROPER_TAG, null );
    }

    var sticker = Sticker.create();

    sticker.ontap = function(event) {
        var myTag = getMyTag();
        if ( myTag ) {
            var query = getVtagQuery( myTag );
            MOON.searchStorage( query );
            MOON.finish();
        } else {
            MOON.alert( "シールのデータが壊れています、一度剥がして張り直してください",
                function(){ MOON.finish(); }
            );
            MOON.finish();
        }
        MOON.finish();
    };

    sticker.onattach = function(event) {
        var myStickerID = InfoUtil.getStickerID();
        var stickerJSON = MOON.getPaperJSON( myStickerID );

        var stickerSize = saveStickerImage( INACTIVE_TAG, myStickerID + "/background.png" );
        stickerJSON.image = "background.png";
        stickerJSON.clip = {"width":0.01,"color":-16777216,"type":"pen","data":[0.0,0.0,0.05,stickerSize.x-1,0.0,0.05,stickerSize.x-1,stickerSize.y-1,0.05,0,stickerSize.y-1,0.05,0.0,0.0,0.05]};
        stickerJSON.width = stickerSize.x;
        stickerJSON.height = stickerSize.y;

        MOON.setPaperJSON( myStickerID, stickerJSON );
/*
// info.json に 固有データが保存できれば
        var properData = InfoUtil.getObjFromJSON( stickerJSON, InfoUtil.PROPER_TAG, {} );
        var initialTags = InfoUtil.getObjFromJSON( properData, 'tags', TAGS );
        var initialIndex = InfoUtil.getObjFromJSON( properData, 'index', INDEX );
*/
// info.json に 固有データが保存できなければ
        var properData = StorageUtil.get( InfoUtil.PROPER_TAG, {} );
        var initialTags = InfoUtil.getObjFromJSON( properData, 'tags', TAGS );
        var initialIndex = InfoUtil.getObjFromJSON( properData, 'index', INDEX );
// ここまで

        GUI( initialTags, initialIndex, TAG_DELIMITER, function( returnTags, returnIndex ) {
            var selectedTag = returnTags[ returnIndex ];
            // 検索用文字列の末尾に ':selectedTag' を追加して保存しなおす
            //
            var searchData = StorageUtil.get( SEARCH_INFO_NAME, "" );
            searchData = searchData + TAG_DELIMITER + selectedTag;
            StorageUtil.set( SEARCH_INFO_NAME, searchData );

            var myTagInfo = {
                 AppName: 'variableTag'
                ,tags: returnTags
                ,index: returnIndex
                ,selected: selectedTag
            };
// info.json に 固有データが保存できれば
//            stickerJSON[ InfoUtil.PROPER_TAG ] = myTagInfo;
// info.json に 固有データが保存できなければ
            saveMyTagInfoToLocalStrage( myTagInfo );
// ここまで

            var stickerSize = saveStickerImage( selectedTag, myStickerID + "/background.png" );
            stickerJSON.image = "background.png";

            MOON.setPaperJSON( myStickerID, stickerJSON );
            MOON.finish();
        });
    };

    sticker.ondetach = function(event) {
        var vtags = collectOtherVtags();
// info.json に 固有データが保存できないときに使用
        removeMyTagInfoFromLocalStorage();
// ここまで
        var searchData = ( vtags.length > 0 )? (TAG_DELIMITER + vtags.join( TAG_DELIMITER )) : null;
        StorageUtil.set( SEARCH_INFO_NAME, searchData );
// info.json に 固有データが保存できないときに使用
        if ( searchData == null ) {
            StorageUtil.set( InfoUtil.PROPER_TAG, null );
            StorageUtil.set( TAG_LIST, null );
        }
// ここまで
        MOON.finish();
    };

    sticker.register();
});

« Wiki を作ってみました | トップページ | コピペシール、その(1) »

enchantMOON」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1527616/53956620

この記事へのトラックバック一覧です: 微妙に便利になり切れなかった「可変タグ」シール:

« Wiki を作ってみました | トップページ | コピペシール、その(1) »