ペインウィンドウマネージャは、Webのブラウザ上で画面分割型のウィンドウを表示するためのJavaScriptのライブラリです。
Windowsなどデスクトップパソコンの広い画面では、任意の形状のウィンドウを重ねることができるウィンドウマネージャが一般的ですが、スマートフォンなどの狭い画面では、ペインウィンドウなどの画面分割型のウィンドウマネージャの方が使いやすくなります。
また、スマートフォンでは、画面を回転して縦横を切り替えて利用することがあります。
そのため、縦横を切り替えた場合に、長手方向で自動分割する機能が付いています。
この機能により、どちらのウィンドウも正方形に近い形となり使いやすくなります。
サンプル画面イメージとして、最も一般的な縦横比である16:9の画面で、メイン画面1に対して、サブ画面0.3の比率で表示してみましたので、ご確認ください。
参考までに、縦分割で固定の場合、横画面にすると細長い画面となってしまい、無駄な領域も多く使いにくくなります。 ウィンドウ内の処理は同じですので、いかに、正方形に近いウィンドウにできるかが、ポイントです。
ウィンドウの構成は、ユーザが利用する<w-win>タグの外側に、閉じるボタンやサイズ変更バーなどの部品をまとめた、<w-win-area>タグがあり、この<w-win-area>タグがペインウィンドウとして動作します。 これらのペインウィンドウの外側にある、<w-pane-area>タグがウィンドウ領域全体となります。 APIは、メインウィンドウとサブウィンドウで分かれていますが、内部的には同じ構造です。 メインウィンドウとサブウィンドウの階層構造は管理していますので、メインウィンドウを削除するとサブウィンドウも削除されます。
ウィンドウマネージャで管理しているのは、メインウィンドウとサブウィンドウの構造だけです。ウィンドウはクラス化されていますので、<w-win>タグ内のデータとして、<w-pane-area>タグを設置することは可能です。ただし、階層構造の管理はしていませんので、削除するときには、それぞれのウィンドウを個別に削除する必要があります。
ウィンドウマネージャは、APIの指示により下記のようなHTMLファイルを生成します。 ウィンドウには、IDが必要となっています。 親の領域もウィンドウIDを含むIDが付加されますので、このIDを指定して画面をカスタマイズすることができます。 ID指定の他にも、classを指定することで、デザインをカスタマイズすることもできます。
<w-pane-area id="w-pane-指定id">
<w-win-area id="w-win-指定id">
<w-win id="指定id"></w-win>
<w-btn></w-btn>
<w-toolbox></w-toolbox>
</w-win-area>
<w-win-area id="w-pane-指定id">
<w-win id="指定id"></w-win>
<w-btn></w-btn>
<w-toolbox></w-toolbox>
<w-close></w-close>
<w-slide></w-slide>
</w-win-area>
</w-pane-area>
<w-dialog>
<w-win-area id="w-pane-wDialog">
<w-win id="wDialog"></w-win>
<w-title-area>
<w-title></w-title>
<w-title-btn></w-title-btn>
</w-title-area>
</w-win-area>
</w-dialog>
<w-overlay></w-overlay>
ウィンドウ以外のボタンなどの要素には、IDやclassは必須ではありません。 ボタンなどを作成時には、その要素が返却されますので、必要に応じて、IDやclassを追加してください。 要素がウィンドウ内に1つしかない場合は、HTML構造の階層を利用して、スタイルを設定することもできます。
#w-win-area-指定ID > w-btn {}
ボタンの表示位置の設定
#w-win-area-指定ID > w-toolbox {}
ツールボックスの表示位置の設定
ウィンドウ部品には、メインウィンドウとサブウィンドウがあります。
どちらも同じウィンドウ部品を継承していますので、同じように扱えます。
サブウィンドウには、ウィンドウを閉じるためのボタンと、ウィンドウサイズを変更するためのスライダが付加することができます。
サブウィンドウは、画面の縦横によりflex-directionのrowとcolumnを切り替えて表示しているため、左と上、右と下が自動で切り替わります。
また、左上か右下かは、orderによって決まりますので、これらのスタイルを変更することでサブウィンドウの表示位置を変更できます。
メインウィンドウとサブウィンドウは、親子関係を持っていますので、メインウィンドウを削除すると、すべてのサブウィンドウが削除されます。
var wMain = W.mainWin('wMain', 'root');
wMain.win.innerHTML = 'メイン'; /* メインウィンドウの表示内容 */
wMain.removeCB = function() { /* メインウィンドウ削除時の処理 */ }
wMain.resizeCB = function(entry) { /* メインウィンドウサイズ変更時の処理 */ }
var wSub = W.subWin('wSub', wMain, {order: -1});
wSub.win.innerHTML = 'サブ'; /* サブウィンドウの表示内容 */
wSub.removeCB = function() { /* サブウィンドウ削除時の処理 */ }
wSub.resizeCB = function(entry) { /* サブウィンドウサイズ変更時の処理 */ }
ボタン部品は、36x36のCSSを使ったボタンとして提供しています。
スタイルを変更することで、いろいろカスタマイズできます。
このボタンの特徴は、ボタンの表示文字列を任意の文字が指定できることです。
日本語の漢字は、象形文字ですから、意味が統一されたアイコンと言っても良いと思います。
また、文字はフォントとして登録されていますので、デザインを定義する必要もありません。
ハンバーガーメニューアイコンのように、良く利用するアイコンは、必要に応じて追加しています。
各ボタンに対して、押された時の処理が登録できるようになっています。
var wBtn = wMain.addBtn({ // ボタンを登録
icon: 'menu', // メニューアイコンを定義
func: function(e) { /* ボタンクリック時の処理 */ }
});
wBtn.classList.add('wBtn');
作成したボタンオブジェクトに対して、クラスを登録することで、ボタン毎のスタイル設定を行うことができます。
.wBtn {
position: absolute;
bottom: 12px; left: 12px;
}
ツールボックス部品は、ボタン部品を縦方向や横方向に並べただけの部品です。 画面に常時表示するような場合でも、あまり場所を取らないというメリットがあります。 ツールボックスは、CSSのFlexBoxを利用していますので、ボタンを並べる方向などは、スタイルシートで設定します。
var toolMenu = [{ // ツールボックスメニュー処理
icon: 'str2', str: '左上', // 左上アイコンを定義
func: function(e) { /* 左上サブウィンドウ表示処理 */ }
},{
icon: 'str2', str: '右下', // 右下アイコンを定義
func: function(e) { /* 右下サブウィンドウ表示処理 */ }
},{
icon: 'str2', str: 'DLG', // DLGアイコンを定義
func: function(e) { /* ダイアログ表示処理 */ }
},{
icon: 'str2', str: '初期', // 初期アイコンを定義
func: function(e) { /* 初期化処理 */ }
}];
var wTool = wMain.addToolbox(toolMenu); // ツールボックスを登録
wTool.classList.add('wTool');
作成したボタンオブジェクトに対して、クラスを登録することで、ボタン毎のスタイル設定を行うことができます。
.wTool { /* ツールボックス */
position: absolute;
top: 12px; right: 12px;
flex-direction: row;
}
メニューボタンは、階層メニューを表示する部品です。
階層レベルは、表示可能な画面の大きさがあれば、特に制限はありません。
各メニューボタンから呼ばれる関数は、1つだけです。
ですから、各メニュー項目に対して、コマンド(cmd)とオプション(opt)という2つのパラメータを設定し、メニュー処理では、このパラメータで処理を切り分けます。
メニューは、任意の文字列が指定可能ですし、メニューの幅も文字列の長さに合わせて自動で設定されますので、簡単に利用することができます。
プルダウンメニューは、左上への設置のみ対応していますので、それ以外の場所に設置する場合は、プルダウンメニューのスタイルを変更する必要があります。
var menu3 = [ // サブメニュー3定義
{txt: '項目311', cmd: 'cmd311', opt: 'opt311'},
{txt: '項目312', cmd: 'cmd312', opt: 'opt312'}
];
var menu2 = [ // サブメニュー2定義
{txt: '項目21 >', menu: menu3},
{txt: '項目22', cmd: 'cmd22', opt: 'opt22'},
{txt: '項目23', cmd: 'cmd23', opt: 'opt23'}
];
var menu = [ // メニュー定義
{txt: '項目1', cmd: 'cmd1', opt: 'opt1'},
{txt: '項目2 >', menu: menu2},
{txt: '項目3', cmd: 'cmd3', opt: 'opt3'}
];
var wMenu = wMain.addMenu({menu: menu, func: function() { // メニューを登録
if (cmd == 'cmd1') { /* メニュー項目1の処理 */
} else if (cmd == 'cmdXXX') { /* メニュー項目XXXの処理 */
}
}});
wMenu.classList.add('wMenu');
作成したボタンオブジェクトに対して、クラスを登録することで、ボタン毎のスタイル設定を行うことができます。
.wMenu { /* プルダウンメニュー */
position: absolute;
top: 12px; left: 12px;
}
ダイアログ部品は、全ウィンドウに対して1つだけ表示可能なモーダルウィンドウです。 ダイアログ表示中は、背景が薄暗くなり、ダイアログの入力以外できなくなります。 閉じるボタンが付いていて、閉じるボタンを押すと、ダイアログは閉じます。 ESCキーでも閉じることができます。
var wDlg = W.dialog('ダイアログ');
wDlg.win.innerHTML = 'ダイアログの表示メッセージ';
ウィンドウマネージャで作成しているウィンドウは、単なるタグですので、Javascriptのwindowのような、リサイズメソッドなどは発生しません。 そこで、ウィンドウマネージャでは、下記の3つのコールバックをサポートしています。 これらのコールバック関数は、ウィンドウのプロパティとして定義すれば、それぞれのタイミングで呼ぼ出されます。 コールバック関数は、各ウィンドウ毎に登録できます。 コールバック関数内では、thisで対象となるウィンドウクラスを参照することができます。
ウィンドウのコールバック関数以外でも、DOM要素に対してイベントリスナーを登録してイベント処理を行うことはできます。 ただし、この場合のthisは、イベントリスナーを登録したDOM要素となります。 そこで、下記の3つの方法でウィンドウクラスを取得するメソッドを提供しています。
ウィンドウマネージャは、名前空間は「W」を利用していますので、W.XXXで利用できます。
アンダーバーの付き(_XXX)で定義されているメソッドや変数は、内部メソッドや内部変数ですので、参照しないでください。
クラス名は大文字、クラス名を小文字にするとインスタンスを作成できます。
これは、Leaflet準拠の仕様で、「win = W.win()」は「win = new W.Win()」と同じ意味です。
ウィンドウマネージャは、DOM要素の作成機能中心で、デザインは、CSSで直接指定することが基本です。
ですから、デザインに関するオプションは、少ないです。
要素作成時には、その要素を返却していますので、プログラムでカスタマイズすることは可能です。
DOM要素のカスタム属性として、ユーザデータを保存することもできます。
また、ウィンドウはクラス化されていますので、クラスを継承(entends)して、拡張することもできます。
MainWinクラスとSubWinクラスは、Winクラスを継承しています。 ですから、作成時の処理は異なりますが、ほぼ同じメソッドとプロパティが利用できます。
// MainWinクラス
// id: メインウィンドウのID
// pid: 親となるブロック要素のID
// opt: オプション
// rc: 分割方法 '':自動分割、'row':横分割、'column':縦分割
mainWin = W.mainWin(id, pid, opt); // メインウィンドウ(領域)作成
// subWinクラス(サブウィンドウクラス)
// id: サブウィンドウのID
// main: メインウィンドウクラス
// opt: オプション
// flex: w-win-areaのflexスタイルの設定(比率 1 最低ピクセル数)
// order: w-win-areaのorderスタイルの設定(負:左上、正:右下)
// closeBtn: 閉じるボタン有無 on:有、off:無
// slideBar: サイズ変更ボタン有無 on:有、off:無
subWin = W.subWin(id, mainWin, opt); // サブウィンドウ(ペイン)作成
// ウィンドウ削除メソッド
win.remove();
// ボタン<w-btn>を追加する
// inf: ボタン情報
// icon: アイコンの種類
// str: アイコン文字列
// str1: アイコン文字列1
// str2: アイコン文字列2
// func: ボタンクリック時の処理
elem = win.addBtn(inf)
// ツールボックス<w-toolbox>を追加する
// inf[]: ボタン情報の配列
elem = win.addToolbox(inf)
// プルダウンメニューボタン<w-btn class="pdmenu"><ul>を追加する
// inf: ボタン情報
// menu[]: メニュー情報の配列
// txt: メニュー表示文字列
// cmd メニューコマンド文字列
// opt: メニューパラメータ文字列
// func: メニュー選択時の処理
elem = win.addMenu(inf);
// ウィンドウプロパティ
win.id // ウィンドウID
win.opt // ウィンドウオプション
win.win // ウィンドウ要素<w-win>
win.area // ウィンドウ領域要素<w-win-area>
win.pane // ウィンドウ全体要素<w-pane-area>
// ウィンドウのコールバック関数
win.removeCB // ウィンドウ削除時に呼ばれるCB処理
win.resizeCB // ウィンドウサイズ変更時に呼ばれるCB処理
win.keydownCB // キーボード入力時に呼ばれるCB処理
// ウィンドウIDからウィンドウクラスを取得
win = W.getWin(id);
// クリック要素情報からウィンドウクラスを取得
// elem: <w-win-area>の子孫要素
win = W.getElemWin(elem);
// カレントウィンドウクラスを取得
// マウスカーソルのある位置の画面を取得
win = getCrntWin();
// ダイアログを表示する
// opt: オプション
// id: DialogのID
dialog = W.dialog(id, opt);
細かな設定は、DOMで行うことを前提で作成していますので、DOMの仕様を産雇にしてください。 以下に、良く使うメソッドを紹介しておきます。
・DOM要素にIDを追加し、IDからDOM要素を取得
elem.id = 'id'; // DOM要素にIDを設定
elem = document.getElementById(id); // IDからDOM要素を取得
・DOM要素を作成して登録
elem = document.createElement('タグ名'); // DOM要素を作成
parentElem.appendChild(elem); // DOM要素を登録
・DOM要素を削除
elem.remove();
・DOM要素にクラスを追加(デザインは、CSSで設定)
elem.className = 'クラス名'; // クラス名を設定
elem.classList.add('クラス名'); // クラス名を追加
・DOM要素のスタイルを直接変更
elem.style.スタイル名 = スタイル値; // 要素のスタイルを変更
// スタイル名に「-」が含まれる場合は、「-」を削除し次の文字を大文字にする
win.cssには、メニューアイコンや文字アイコンなど、いくつかのアイコンが設定されています。 文字アイコンは、w-iconタグの属性で、任意の文字を表示できる汎用アイコンです。 Unicodeの絵文字を指定するだけで、Unicodeの絵文字をアイコンとして表示できます。
下記のリンクから、ウィンドウマネージャとサンプルプログラムをダウンロードできます。 ウィンドウマネージャ(win.jsとwin.css)とサンプルプログラムが入っています。 ドキュメントは、このページを参照してください。