「
ポップアップメニューを「n*十件ずつ」のサブメニューに自動分割する
」を編集中
2019年4月21日 (日) 22:12時点における
Sukemaru
(
トーク
|
投稿記録
)
による版
(
→
サンプルコード
)
(
差分
)
← 古い版
|
最新版
(
差分
) |
新しい版 →
(
差分
)
ナビゲーションに移動
検索に移動
警告: このページの古い版を編集しています。
公開すると、この版以降になされた変更がすべて失われます。
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
== 分割サブメニュー == ポップアップメニューの'''アイテム数が非常に多いとき'''、メニューの上下に配置されたスピンハンドル ▲ ▼ でスクロールさせるのは効率が悪いので、「1 - 20 件目 ▸」「21 - 40 件目 ▸」のかたちでサブメニュー項目に分割して表示するためのサンプルコードです。 アイテム数にあわせて「1 - 20 件目 ▸」「21 - 40 件目 ▸」の'''分割サブメニュー項目を自動的に生成'''しますので、ポップアップメニューのアイテム数が増減する「検索」「抽出」系のマクロに仕込むと便利かも。 *「1 - 20 件目 ▸」「21 - 40 件目 ▸」の項目は、サブメニュー項目「20 件ずつ表示 ▸」配下の "孫" メニュー項目にすることもでき、分割サブメニュー内の行数「'''20''' 件目」の部分は設定項目で任意の数値に変更できます(10 件ごとにセパレータを挿入するので、10 の倍数を推奨)。 *「分割サブメニュー」を使用するかしないかは設定項目で選択できますが、「使用する」に設定した場合でもアイテム数が「分割する単位」の 2 倍以下のときは「分割サブメニュー」で表示せず、メインメニューの直下にアイテムを列挙します。 '''ポップアップメニューに列挙するアイテムは'''<br> ''PopupMenu.Add( "文字列", id [, flags ] )'' メソッドの記法にあわせて '''''[ ["アイテム1",id_1], ["アイテム2",id_2], ["アイテム3",id_3], ["アイテム4",id_4] ... ]''''' の形式の'''配列で用意してください。'''任意で ''flags'' を配列に入れてもよいでしょう。<br> for() 文のループ処理でポップアップメニュー項目に変換します。 ;サンプルコードのポップアップメニュー画像 [[ファイル:Mery_分割サブメニュー_SS(1).png|frameless|362px|thumb|left|subMenuEnable = 1]] [[ファイル:Mery_分割サブメニュー_SS(2).png|frameless|254px|thumb|subMenuEnable = 2]] <br clear=all> == 組み込み関数 DevidedSubMenu() == ポップアップメニューに列挙するアイテムとして用意した配列から「分割サブメニュー」を生成する関数コードです。 * 設定項目の変数 '''''subMenuHeight''''' で、分割サブメニュー内の行数の指定。<br> ※ 10 の倍数で指定してください。 * 設定項目の変数 '''''subMenuEnable''''' で、<br> ・分割サブメニュー「1 - 20 件目 ▸」「21 - 40 件目 ▸」... の項目を表示する/表示しない <br> ・メニュー項目「20 件ずつ表示 ▸」の配下に置く /メインのメニュー直下に置く <br> を指定する。 ::'''0''': 分割サブメニューを使用しない(全アイテムを列挙) ::'''1''': 「20 件ずつ表示 ▸」の配下に分割サブメニュー「1 - 20 件目 ▸」... を表示する(画像:左) ::'''2''': 分割サブメニュー「1 - 20 件目 ▸」「21 - 40 件目 ▸」... だけを表示する(画像:右) ※設定変数や、ポップアップメニューに列挙するアイテムの配列は、関数から参照できる階層のスコープにおいてください(または、引数として関数に渡す)。 おまけ関数コード * '''AddCancelLines() 関数''': 「セパレータ」「キャンセル」行の自動挿入 * '''Pad() 関数''': 連番の「ケタ埋め」(右揃え) ※ケタ埋めの空白文字は EN SPACE「 」(U+2002) にしてありますが、PCのコントロールパネル設定で指定した「メニュー」用のフォント種によっては半角数字との幅が合わないことがあります。 == サンプルコード == '''アイテム数が多い/アイテム数が変動するサンプル'''として、アクティブなタブのすべての論理行をポップアップメニューに表示する【仮】マクロです。<br> 「キャンセル」行の表示や、行番号の「ケタ埋め」するためのコードも入れているで読みづらいかも知れませんが、 '''''/* ... */''''' で説明をつけた部分が「分割サブメニュー」用のコードです。 配列の中身や、menu.Track(); 以降の動作コード'''【仮】'''の部分を、任意のコードに差し替えてお使いください。 :「分割サブメニュー」に表示される「キャンセル」のアイテムは Space キーをアクセラレータにしてあるので、Escape キーで多階層のメニューを繰り上がりをせずにポップアップメニューを一発キャンセルできます。<br> メインメニュー直下に全アイテムを列挙しているときは、Space キーで「キャンセル」アイテムをトグル移動しながらメニュー全体をスクロールできます(Escape キーでポップアップメニューをキャンセル)。 <source lang="javascript"> #title = "論理行をポップアップメニューにリストアップ" // ( function() { var start = new Date(); // 所要時間計測(開始) // ---------- ▼ 設定項目 ▼ ---------- /* ■「分割サブメニュー」を使用するか? */ var subMenuEnable = 1; // 0: 使用しない(メインメニュー直下に全アイテムを列挙する) // 1: メインメニュー直下には「20 件ずつ表示」と全アイテムの列挙 // 「20 件ずつ表示」の配下に「1-20 件目」「21-40 件目」の"孫"メニューを置く // 2: メインメニュー直下に「1-20 件目」「21-40 件目」のサブメニューを置く /* ■ 分割する単位 (初期値: 20 >> 20件ずつに分割) */ // ※ subMenuHeight の 2 倍より多いアイテムがあれば分割サブメニューを適用する var subMenuHeight = 20; // ---------- ▼ メインのコード ▼ ---------- // ポップアップメニューに表示する「アイテム」の配列 var itemArray = new Array(); // 【仮】 論理行数の連番アイテム(文字列と行番号)を生成する var d = editor.ActiveDocument; var lineText, lines = d.GetLines( 0 ); for ( var y = 1; y <= lines; y++ ) { // 空白文字を詰め、「&」記号を保守する lineText = d.GetLine( y, 0 ) .replace( /\t+|[ ]{4,}|[ ]{2,}/g, " › " ) .replace( /&/g, "&&" ).slice( 0, 30 ); itemArray.push( [ ": " + lineText, y ] ); } // 「アイテム」数 var len = itemArray.length; // 「アイテム数」のケタ数(※ケタ埋めに使用する) var lenWidth = len.toString().length; if ( len > 0 ) { // ポップアップメニューの準備 var menu = CreatePopupMenu(); /** * 「アイテム数」が「分割単位」の 2 倍より多いなら * 「分割サブメニュー」を生成する */ if ( subMenuEnable && len > subMenuHeight * 2 ) { DevidedSubMenu(); } // subMenuEnable = 1 またはアイテム数が「分割単位」の 2 倍以下なら // メインメニュー直下に全アイテムを列挙する if ( subMenuEnable < 2 || len <= subMenuHeight * 2 ) { for ( var i = 0; i < len; i++ ) { // 10 件ごとにセパレータ、20* 件ごとに「キャンセル」行を追加する AddCancelLines( menu, i, subMenuHeight ); // 配列の「アイテム」をメインメニュー直下に追加する menu.Add( Pad( itemArray[i][1], 2 ) + itemArray[i][0] , itemArray[i][1] ); } // 最下行に「キャンセル」をピン止めする(Space キーでスクロール可) menu.Add( "", 0, meMenuSeparator ); menu.Add( Pad() + "キャンセル\t& ", 0 ); } // ステータスバーにメニューの件数と処理時間を表示する var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 ); Status = " メニューのアイテム: " + len + " 件 " + " [ " + elapsedSec + " 秒 ]"; // ポップアップメニューを表示する var yy = menu.Track( mePosMouse ); // 【仮】 メニューの連番の論理行にジャンプする if ( yy > 0 ) { d.selection.SetActivePoint( mePosLogical, 1, yy ); } } // if( len > 0 ) 閉じ // ---------- ▼ 関数 ▼ ---------- // 関数は呼び出し元のスコープに配置する // ※ 呼び出し元のスコープが閉じていると変数を参照できなくなる /** * 関数 DevidedSubMenu() * サブメニュー「※ 20* 件ずつ表示 ※ ▶」/「1 - 20* 件目 ▶」に * 配列の「アイテム」を分割表示する * ※「20*」の部分の数値は設定用変数 subMenuHeight で指定 * * ※呼び出し元のスコープが閉じている場合は * ふたつの設定変数と menu , itemArray オブジェクトを引き渡すこと * e.g. DevidedSubMenu( objPopupMenu, items, mode, height ) * len = itemArray.length と lenWith = len.toString().length は * 関数のなかで再定義できる */ function DevidedSubMenu() { var subMenu = CreatePopupMenu(); var popupMenu = ( subMenuEnable == 1 ) ? subMenu : menu; if ( subMenuEnable == 1 ) { // 「※ 20* 件ずつ表示 ※ ▶」をピン止め menu.AddPopup( " ※ " + subMenuHeight + " 行ずつ表示(&D) ※" , subMenu ); } // 「キャンセル」をピン止め popupMenu.Add( Pad() + "キャンセル", 0 ); popupMenu.Add( "", 0, meMenuSeparator ); // 配列のアイテムをポップアップメニューに追加していく var smArray = []; // SubMenu Array var smId , _from , _to; for ( var i = 0; i < len; i++ ) { if ( i % subMenuHeight == 0 ) { // 配列にメニュー項目「_from - _to 件目 ▶」を生成する smArray.push( CreatePopupMenu() ); // 「_from - _to 件目」メニューの index smId = smArray.length - 1; // _from と _to の値 _from = smId * subMenuHeight + 1; _to = Math.min( smArray.length * subMenuHeight, len ); // 「_from - _to 件目」メニュー項目 popupMenu.AddPopup( Pad( _from, 1 ) + " - " + Pad( _to ) + " 件目" , smArray[smId] ); } // 「_from - _to 件目」メニュー配下の 10件 ごとにセパレータと // 先頭に「キャンセル」行(Space キーでキャンセル可) AddCancelLines( smArray[smId], i, subMenuHeight ); // 「アイテム」の配列から「_from - _to 件目」メニュー配下に追加する // ※ smArray[smId] は CreatePopupMenu オブジェクト smArray[smId].Add( Pad( itemArray[i][1], 2 ) + itemArray[i][0] , itemArray[i][1] ); // 「_from - _to 件目」のさいごに「キャセル」行を追加する if ( i == len - 1 ) { popupMenu.Add( "", 0, meMenuSeparator ); // (Space キーでキャンセル可) popupMenu.Add( Pad() + "キャンセル\t& ", 0 ); } } } /** * 関数 AddCancelLines( objPopupMenu, id, distance ) * 10 件ごとにセパレータと * 20* 件ごとに「キャンセル」行を追加する * ※Space キーでキャンセル可(またはスクロール) * * 第1引数は ポップアップメニューオブジェクト * 第2引数は 呼び出し元の for() 文の「 i 」 * 第3引数は 「キャンセル」行を表示する間隔* * (省略した場合は設定項目の変数 subMenuHeight) */ function AddCancelLines( objPopupMenu, id, distance ) { var distance = distance || subMenuHeight || 30; // 10 件ごとにセパレータを追加 && id % distance != 0 if ( id % 10 == 0 ) { objPopupMenu.Add( "", 0, meMenuSeparator ); } // 30* 件(distance)ごとに「キャンセル」行を追加 if ( id % distance == 0 ) { objPopupMenu.Add( Pad() + "キャンセル\t& ", 0 ); objPopupMenu.Add( "", 0, meMenuSeparator ); } } /** * 関数 Pad( num, amp ) * EN SPACE (U+2002)「 」でケタ埋めして右揃えにする * ※ケタ数にはグローバルスコープの変数 lenWidth を使用する * * 第1引数は ケタ埋め対象の数字 * 第2引数は アクセラレータ用の「&」の指定 * (1 なら先頭の数字、2 なら末尾の数字をアクセラレータにする) */ function Pad( num, amp ) { num = num || ""; var pad = ( amp == 1 ) ? ( " &" + num ) : ( amp == 2 ) ? ( " " + num ).replace( /(\d)$/, "&$1" ) : ( " " + num ); amp = amp ? "&" : ""; return pad.slice( - lenWidth - amp.length ); } // }() ); </source>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク