|
|
「ダイアログ風のウインドウを表示する」のゴールはここにありました。画面内で自由に移動・リサイズ可能なミニウインドウが実現できれば、WebOSみたいなことが可能です。まずは中身の無い空のウインドウを生成し、他のプログラムから利用できるようにします。このプログラムの機能は
ウインドウは生成されると画面中央に配置される。
ウインドウのタイトルバーを掴んで画面内を自由に移動できる。
ウインドウの隅を掴んで画面内で自由にリサイズできる。
タイトルバー右端のwindow-closeアイコンをクリックするとウインドウは消滅する。
引数で指定されたオブジェクトから初期サイズやタイトルなどのプロパティを読み込み、コンテンツを表示する。
といったところです。利用例については、また別の機会に。
[ サンプルの実行]←クリックすると画面中央に小さなウインドウが表示されます。 var win = new @INCLUDE(window.js)({ title:'空のウインドウ' });
- window.js
/*
* window.js - ミニwindowを生成する
* 依存するライブラリ:geometry.js, style.js, event.js, pngdecode.js
* 影響を受けるプロパティ:
* - document.onmousemoveその他
* - window移動中にGoogleツールバーがエラーを吐く
*/
function(object) {
var ICONS = {
'window-close' :
'data:image/png;base64,' +
'iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAAAAABzHgM7AAAAAXNSR0IArs4c6QAA' +
'AAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sHFgQsNRv0lU4AAACnSURBVAgd' +
'AZwAY/8BWjoACPgACPgACPi+BDpj3ykAAAAAAOgQAAIA8Hy+AAAAAMdj8AAAlP/W' +
'Ur3//8ZKzv+UAJT//9ZKxr1Kzv//lAQAAAApjHQAjCkAAAACAAAAAOcIAPAAAAAA' +
'AJT//71K1s5Kxv//lACU/71K1v//zkrO/5QAlNZS1v/////OUv+UAJT37///////' +
'////lAS+AAAAAAAAAAAAAL4Dt0hRWmfrigAAAABJRU5ErkJggg=='
};
var self = this;
if (!object['width']) object['width'] = 400;
if (!object['height']) object['height'] = 300;
var bind = function(obj, fn) {
return function() { return fn.apply(obj, arguments); }
};
var fixEvent = @INCLUDE(event.js);
var geom = self.geom = new @INCLUDE(geometry.js);
var pngdecode = @INCLUDE(pngdecode.js);
self.style = (@INCLUDE(style.js))(
"div.window-frame {" +
" border:1px solid gray;" +
" position:absolute;" +
" font-size:10pt;" +
" color:black;" +
" text-align:left;" +
" line-height:1em;" +
" z-index:9999;" +
"}" +
"div.window-head {" +
" color:white;" +
" background-color:gray;" +
" height:1em;" +
" padding: 3px 3px;" +
" cursor:move;" +
"}" +
"div.window-body {" +
" clear:both;" +
" background-color:white;" +
" padding:0;" +
" margin:0;" +
" overflow:auto;" +
"}" +
"img.close-icon," +
"div.close-icon {" +
" float:right;" +
" vertical-align:baseline;" +
" width:12px; height:12px;" +
" cursor:default;" +
"}"
);
self.frame = document.body.appendChild(document.createElement('div'));
self.frame.className = self.frame.styleClass = 'window-frame';
self.frame.style.width = object['width'] + 'px';
self.frame.style.height = object['height'] + 'px';
self.frame.onclick = function(evt) {
if (typeof object.onfocus == 'function') object.onfocus();
};
self.head = self.frame.appendChild(document.createElement('div'));
self.head.className = self.frame.styleClass = 'window-head';
var closeIcon = self.head.appendChild(document.createElement('img'));
closeIcon.className = closeIcon.styleClass = 'close-icon';
closeIcon.onmousedown = function(evt) {
evt = fixEvent(evt).stop();
};
closeIcon.onclick = bind(self, function(evt) {
fixEvent(evt).stop();
this.exit();
});
closeIcon.onerror = function(evt) { //for data scheme unsupported browser
evt = fixEvent(evt);
var img = evt.target;
var png = new pngdecode(img.src.replace(/^.*,(.*)$/, "$1"));
var newimg = png.toDOM();
newimg.className = newimg.styleClass = 'close-icon';
newimg.onmousedown = img.onmousedown;
newimg.onclick = img.onclick;
newimg.style.cssFloat = newimg.style.styleFloat = 'right';
img.parentNode.insertBefore(newimg, img);
img.style.display = 'none';
};
closeIcon.src = ICONS['window-close'];
self.head.appendChild(document.createTextNode(object['title']));
self.body = self.frame.appendChild(document.createElement('div'));
self.body.className = self.frame.styleClass = 'window-body';
self.body.style.height = (self.frame.offsetHeight - self.body.offsetTop - self.frame.clientTop * 2) + 'px';
if (object.content) self.body.appendChild(object.content);
var size = geom.getWindowSize();
self.frame.style.left = ((size.width - self.frame.offsetWidth) / 2
+ document.documentElement.scrollLeft + document.body.scrollLeft) + 'px';
self.frame.style.top = ((size.height - self.frame.offsetHeight) / 2
+ document.documentElement.scrollTop + document.body.scrollTop) + 'px';
self.frame.onfit = function() {
var fg = geom.getGeometry(self.frame);
if (self.head.style.display)
self.head.style.display = '';
var hg = geom.getGeometry(self.head);
self.body.style.height = (fg.height - hg.height - fg.borderTop - fg.borderBottom) + 'px';
self.body.style.display = '';
return false;
};
self.head.onmousedown = bind(self, function(evt) {
evt = fixEvent(evt).stop();
document.onmousemove = this.move;
document.onmouseup = this.moveend;
document.onselectstart = function(evt){ evt = fixEvent(evt); evt.stop(); }
this.offset = { x:evt.offsetX, y:evt.offsetY };
});
self.move = bind(self, function(evt) {
evt = fixEvent(evt).stop();
self.frame.style.left = (evt.pageX - this.offset.x) + 'px';
self.frame.style.top = (evt.pageY - this.offset.y) + 'px';
});
self.moveend = function(evt) {
document.onmousemove = null;
document.onmouseup = null;
document.onselectstart = null;
};
self.exit = function(evt) {
self.frame.parentNode.removeChild(self.frame);
self.style.parentNode.removeChild(self.style);
geom.finalize();
if (typeof object.onunload == 'function') object.onunload();
};
//resizable
geom.resizable(self.frame);
}
|
|
|