公開ソフトのアップデート

1年半くらい前に公開した ブロック配置ツール、この子に酷いバグがあったのを修正しました。

Block Placer Ver1.00 → Ver1.10修正内容

  • 2層目以降にブロックを配置できない不具合を修正
  • 右クリック時に、毎回ライブラリをスキャンしていたのを修正。1度だけスキャンされるようにした。

また、公開ツールを1つのページにまとめました。

公開ツールのダウンロードページ

 

3 thoughts on “公開ソフトのアップデート”

  1. はじめまして、いつも参考にさせて頂いています。

    R2012b以降ではcallbackInfo.mouseClickPositionは
    廃止されてしまっているようです。
    今手元にR2013aのデモ版しかないのですが、sl_customization.mに
    ブレークポイントを設定してcallbackInfoの構造を確認したところ、
    mouseClickPositionがないためエラーが発生します。
    会社のR2012bでも同様だった気がするのですが確認できていません。

    なお、R2013aではuiObjectはワークスペース変数のビューに
    表示されないのですが、ブレーク中のコマンドプロンプトで確認すると
    ちゃんと存在しています。

    回避方法をWEB上で検索したところ、下記WEBページにあるように
    クリック位置を取得するにはget(0, ‘PointerLocation’)を
    使用すればよいことが分かりました。
    http://www.mathworks.com/matlabcentral/fileexchange/30248-add-simulink-blocks-from-a-given-model-file-with-context-menu/content/sl_customization.m

    ただしPointerLocationはスクリーン座標上の値のため、
    これをモデルウィンドウ上の座標に変換する処理を追加する必要が
    あります。
    上記WEBページの例ではズームに対応していないため、
    ZoomFactorを取得して倍率変換してやる処理を追加した上で、
    吉武様のスクリプト(sl_customization.m)を変更して
    R2013a対応したもののdiffを下記に記載します。

    お役に立つか分かりませんが、ご参考にして頂ければ幸いです。


    36a37,40
    >
    > clickPosition = get(0, ‘PointerLocation’); % 右クリック時のマウスクリック位置(X,Y:左下が原点)を保存しておく
    > accKeys = ‘0123456789+-*/][}{> MAX_BLOCKS = length(accKeys); % 最大ブロック数をショートカットキーの個数に仮設定する
    39,78d42
    < schemaFcns = { @placeBlock0, @placeBlock1, @placeBlock2, @placeBlock3, @placeBlock4, @placeBlock5, @placeBlock6, @placeBlock7, @placeBlock8, @placeBlock9 };
    < % schemaFcnsをいったん10用意したが、block_placer_library_blocks(ライブラリ上のブロックリスト)よりも少ない場合には、余分なぶんを削る
    length( block_placer_library_blocks )
    < schemaFcns = schemaFcns( 1:length( block_placer_library_blocks ) );
    < end
    <
    < end
    <
    < %%
    < function schema = placeBlock0(~)
    < schema = registerPlaceOneBlockMenu( 0 );
    < end
    <
    < function schema = placeBlock1(~)
    < schema = registerPlaceOneBlockMenu( 1 );
    < end
    <
    < function schema = placeBlock2(~)
    < schema = registerPlaceOneBlockMenu( 2 );
    < end
    <
    < function schema = placeBlock3(~)
    < schema = registerPlaceOneBlockMenu( 3 );
    < end
    <
    < function schema = placeBlock4(~)
    < schema = registerPlaceOneBlockMenu( 4 );
    < end
    <
    < function schema = placeBlock5(~)
    < schema = registerPlaceOneBlockMenu( 5 );
    < end
    <
    < function schema = placeBlock6(~)
    < schema = registerPlaceOneBlockMenu( 6 );
    < end
    <
    < function schema = placeBlock7(~)
    < schema = registerPlaceOneBlockMenu( 7 );
    < end
    80,81c44,48
    < function schema = placeBlock8(~)
    schemaFcns = {};
    > for iBlocks =1:min(length(block_placer_library_blocks), MAX_BLOCKS)
    > idx = iBlocks-1;
    > akey = accKeys(iBlocks);
    > schemaFcns{iBlocks} = { @registerPlaceOneBlockMenu, {idx, akey, clickPosition} }; % {}内のデータはcallbackInfoのuserdataとして渡される
    84,85d50
    < function schema = placeBlock9(~)
    < schema = registerPlaceOneBlockMenu( 9 );
    89c54
    function schema = registerPlaceOneBlockMenu(callbackInfo)
    94a60,64
    > %callbackInfoに登録したユーザデータを取り出す
    > index = callbackInfo.userdata{1};
    > akey = callbackInfo.userdata{2}; % ショートカットキー
    > clickPosition = callbackInfo.userdata{3}; % クリック位置
    >
    101,102c71,72
    < schema.label = sprintf( '%s を配置する(&%d)', blockName, index );
    schema.label = sprintf( ‘%s を配置する(&%s)’, blockName, akey );
    > schema.userdata = { blockPath, clickPosition };
    107d76
    < % 上から(最大)10のブロックを認識します。
    130,134d98
    < % 10より多ければ、削除する
    10
    < sortedIndex = sortedIndex( 1:10 );
    < end
    <
    137c101
    % そこで、sortedIndexでblockOnLibraryを取り出すことで、上から順にブロックを取り出すことができる。
    153c117
    clickPosition = callbackInfo.userdata{2};
    156c120
    blockPath = callbackInfo.userdata{1};
    164c128,133
    position = get_param( placed, ‘Position’ ); % モデル内での位置
    > locationBase = get_param( subsystemName, ‘Location’); % モデル表示ウィンドウ(Simulink Editor)の[left, top, right, bottom]
    > scrollOffset = get_param( subsystemName, ‘ScrollbarOffset’); % スクロールバーのオフセット(モデルブラウザやツールバーの幅・高さを含む)
    > zoomFactor = str2num(get_param( subsystemName, ‘ZoomFactor’)); % モデル表示の拡大率
    > screenSize = get(0, ‘ScreenSize’);
    >
    172c141,152
    xpos = 1; % クリック位置XはPointerLocationパラメータの1番目
    > ypos = 2; % クリック位置YはPointerLocationパラメータの2番目
    > xofs = 1; % スクロールバーオフセット位置XはScrollbarOffsetパラメータの1番目
    > yofs = 2; % スクロールバーオフセット位置YはScrollbarOffsetパラメータの2番目
    >
    > p_X = clickPosition(1) – locationBase(left) + scrollOffset(xofs);
    > p_Y = screenSize(bottom) – clickPosition(ypos) – locationBase(top) + scrollOffset(yofs);
    > % ズーム対応
    > p_X = p_X/zoomFactor*100;
    > p_Y = p_Y/zoomFactor*100;
    >
    > newPosition = [ p_X p_Y p_X+width, p_Y+height ];

  2. コメントありがとうございます。

    いただいたパッチをまるまる当てて、R2010b、R2012b、R2013aどれでも動作する事を確認しました。ズーム対応もバッチリ動作していて、素晴らしいです。

    また、マウス位置に関するロジックとは別に、コールバックの構造もスッキリさせていただいていますね。あれは、汚いなー、なんとかならないかなー、と思っていた部分なので、とてもありがたいです。まさか、schemaFcnsに引数を指定できるとは・・・!

    これは、そのまま最新版として公開させていただきます。ありがとうございました。

Comments are closed.