11 ( function( pettanr, gOS, window, undefined ){
14 * PettanR service driver.
16 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
17 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
19 FileAPI = gOS.registerDriver( function(){
20 var self = Driver = this;
22 function onLoadJson( _file, _json ){
23 var _access = FileAPI.getFileDataAccess( _file ),
24 _data = _access !== null ? _access.DATA : null,
30 _data.state = Const.FILE.STATE.OK;
32 if( Type.isArray( _json ) === true ){
35 for( var i=0; i<l; ++i ){
36 buildFileData( _json[ i], _data);
40 buildFileData( _json, _data );
42 _file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, _file, 'children', null) );
44 function onErrorJson( _file ){
45 var _data = FileAPI.getFileData( _file);
47 _data.state = Const.FILE.STATE.ERROR;
50 function buildFileData( _data, _parent ){
53 if( _parent === FILE_DATA_PANELS_ROOT ){
54 _data.type = FILE_TYPE.PANEL;
58 if( _parent === FILE_DATA_COMICS_ROOT ){
59 _data.type = FILE_TYPE.COMIC;
62 if( _parent.type === FILE_TYPE.COMIC ){
66 if( _parent === FILE_DATA_LISENCE_ROOT ){
67 _data.type = FILE_TYPE.LICENSE;
68 _array = ORIGINAL_LICENSE_ARRAY;
71 if( _parent === FILE_DATA_AUTHOR_ROOT ){
72 _data.type = FILE_TYPE.AUTHOR;
73 _array = AUTHOR_ARRAY;
76 if( _parent === FILE_DATA_ARTIST_ROOT ){
77 _data.type = FILE_TYPE.ARTIST;
78 _array = ARTIST_ARRAY;
81 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
82 _data.type = FILE_TYPE.PICTURE;
83 _array = RESOURCE_PICTURE_ARRAY;
84 // original_license を含まなければ、license object を削除して ビットデータ で保持
85 // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
86 var _license = _data.license,
90 if( typeof _license === 'object'){
91 for( i=0, l=BASIC_LICENSES.length; i<l; ++i ){
92 _rule = _license[ BASIC_LICENSES[ i]];
93 if( typeof _rule === 'number' && _rule === 1 ){
94 _bits += _Math_pow( 2, i );
97 _data.license = _bits;
103 _data.driver = Driver;
105 // _array に _data を格納 または 上書き
106 if( typeof _data.id === 'number' && _data.id > 0 ){
107 var _id = _data.id - 1,
108 __data = _array[ _id ],
109 _reserved = Const.FILE.DATA_PROPERTY_RESERVED.join( ', ' );
111 for( var key in _data){
112 if( _reserved.indexOf( key ) === -1 ){
113 __data[ key ] = _data[ key ];
116 _data = __data; // このタイミングで参照が切れるので注意!!
118 _array[ _id ] = _data;
126 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
127 addChildData( _parent, _data );
130 if( _parent.type === FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
131 var _panels = _data.panels,
133 if( _panels && Type.isArray( _panels ) === true ){
135 for( i=0, l=_panels.length; i<l; ++i){
136 _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
140 addChildData( _data, _panel );
144 if( _data.json !== null ){
147 if( Type.isArray( _data.children ) === false ){
151 var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
153 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
154 addChildData( _author, _data );
155 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
157 if( _parent === FILE_DATA_COMICS_ROOT ){
158 addChildData( FILE_DATA_LATEST_COMICS, _data);
162 if( _parent === FILE_DATA_PANELS_ROOT ){
163 _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
164 _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
166 // picture data をファイルに取り出し
167 var _elements = _data.panel_elements,
169 if( Type.isArray( _elements ) === true ){
170 for( i=0, l=_elements.length; i<l; ++i){
171 _elm = _elements[ i];
172 if( _elm.resource_picture ){
173 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
175 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
181 if( _data.type == FILE_TYPE.PICTURE ){
182 var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
184 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
185 addChildData( _artist, _data );
186 if( _artist.id === MyArtistID ){
187 addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
188 //FILE_DATA_MY_PICTURES_ROOT.type = FILE_TYPE.ARTIST;
189 //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
195 function addChildData( _parent, _child ){
196 if( Type.isArray( _parent.children ) === false){
197 _parent.children = [];
199 Util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
201 function getResource( _array, _id ){
202 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
203 var _data = _array[ _id - 1 ];
205 _data = _array[ _id - 1 ] = {};
210 this.getSeqentialFiles = function( _file ){
211 var _data = FileAPI.getFileData( _file ),
212 _json = _data !== null ? _data.json : null;
213 if( _json === true && _data.type === FILE_TYPE.COMIC ){
214 if( pettanr.CONST.SERVER_SUPPORT === false ){
215 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
217 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
220 if( typeof _json === 'string' ){
221 FileAPI.getJson( _file, _json, onLoadJson, onErrorJson );
222 _data.state = Const.FILE.STATE.LOADING;
227 this.getName = function( _file ){
228 var _data = FileAPI.getFileData( _file ),
229 _type = _data !== null ? _data.type : null;
230 if( _type === FILE_TYPE.PICTURE ){
231 return [ _data.id, _data.ext ].join( '.' );
233 if( _type === FILE_TYPE.PANEL ){
234 return [ _data.t, ':', _data.comic.title ].join( '' );
236 if( _type === FILE_TYPE.COMIC ){
239 if( _type === FILE_TYPE.ARTIST ){
240 return [ _data.name, '画伯' ].join( '' );
242 if( _type === FILE_TYPE.AUTHOR ){
243 return [ _data.name, '先生' ].join( '' );
247 this.getThumbnail = function( _file ){
248 var _data = FileAPI.getFileData( _file ),
249 _type = _data !== null ? _data.type : null;
250 if( _type === FILE_TYPE.PICTURE ){
251 return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '' )};
253 if( _data === FILE_DATA_COMICS_ROOT ){
254 return { className: 'file-type-cabinet' };
256 if( _type === FILE_TYPE.COMIC ){
257 return { className: 'file-type-comic' };
259 if( _type === FILE_TYPE.PANEL ){
260 return { className: 'file-type-panel' };
262 if( _type === FILE_TYPE.AUTHOR ){
263 return { className: 'file-type-author' };
265 if( _type === FILE_TYPE.ARTIST ){
266 return { className: 'file-type-artist' };
268 if( _type === FILE_TYPE.FOLDER){
269 return { className: 'file-type-folder' };
271 return { className: 'file-type-broken' };
273 this.getSummary = function( _file ){
274 var _data = FileAPI.getFileData( _file ),
275 _type = _data !== null ? _data.type : null;
276 if( _type === FILE_TYPE.PICTURE ){
277 return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
279 if( _data === FILE_DATA_COMICS_ROOT ){
280 return 'cabinet file';
282 if( _type === FILE_TYPE.COMIC ){
283 return 'comic file, id:' + _data.id;
285 if( _type === FILE_TYPE.PANEL ){
286 return [ _data.width, 'x', _data.height ].join( '' );
288 if( _type === FILE_TYPE.AUTHOR ){
289 return 'author file, id:' + _data.id;
291 if( _type === FILE_TYPE.ARTIST ){
292 return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
294 if( _type === FILE_TYPE.FOLDER ){
295 return 'pettanR folder';
297 return 'pettanR unknown file';
299 this.read = function( _file ){
300 var _data = FileAPI.getFileData( _file ),
301 _type = _data !== null ? _data.type : null,
303 if( _type === FILE_TYPE.COMIC ){
304 // children を panels に deepcopy
306 for( var key in _data ){
307 ret[ key ] = _data[ key ]
309 ret.panels = _data.children;
312 if( _type === FILE_TYPE.PANEL ){
314 if( _type === FILE_TYPE.PANEL_PICTURE ){
317 if( _type === FILE_TYPE.BALLOON ){
319 if( _type === FILE_TYPE.PICTURE ){
322 this.write = function( _file, _newData, _onUpdate ){
323 var _data = FileAPI.getFileData( _file ),
324 _type = _data !== null ? _data.type : null;
325 if( _type === FILE_TYPE.COMIC ){
327 if( _type === FILE_TYPE.PANEL ){
329 if( _type === FILE_TYPE.PANEL_PICTURE ){
332 if( _type === FILE_TYPE.BALLOON ){
334 if( _type === FILE_TYPE.PICTURE ){
337 this.viewerApplicationList = function( _file ){
338 var _data = FileAPI.getFileData( _file ),
339 _type = _data !== null ? _data.type : null;
340 if( _type === FILE_TYPE.PANEL ){
343 if( _type === FILE_TYPE.COMIC ){
346 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
347 return [ PremiumSatge ];
349 if( _type === FILE_TYPE.ARTIST ){
350 return [ PremiumSatge ];
354 this.editorApplicationList = function( _file ){
355 var _data = FileAPI.getFileData( _file ),
356 _type = _data !== null ? _data.type : null;
357 if( _type === FILE_TYPE.PANEL ){
360 if( _type === FILE_TYPE.COMIC ){
361 return [Editor, ComicConsole ];
366 Const = FileAPI.getConst(),
367 FILE_TYPE = Util.extend(
370 COMIC: FileAPI.createFileTypeID(),
371 PANEL: FileAPI.createFileTypeID(),
372 PICTURE: FileAPI.createFileTypeID(),
373 PANEL_PICTURE: FileAPI.createFileTypeID(),
374 BALLOON: FileAPI.createFileTypeID(),
375 AUTHOR: FileAPI.createFileTypeID(),
376 ARTIST: FileAPI.createFileTypeID(),
377 LICENSE: FileAPI.createFileTypeID()
380 FILE_DATA_SERVICE_ROOT = {
381 name: 'PettanR root',
382 type: FILE_TYPE.FOLDER,
385 FILE_DATA_COMICS_ROOT = {
387 type: FILE_TYPE.FOLDER,
390 json: pettanr.CONST.URL_COMICS_JSON
392 FILE_DATA_PANELS_ROOT = {
394 type: FILE_TYPE.FOLDER,
397 json: pettanr.CONST.URL_PANELS_JSON
399 FILE_DATA_PICTURE_ROOT = {
401 type: FILE_TYPE.FOLDER,
404 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
406 FILE_DATA_MY_COMICS_ROOT = {
408 type: FILE_TYPE.FOLDER,
413 FILE_DATA_LATEST_COMICS = {
414 name: 'Latest Comics',
415 type: FILE_TYPE.FOLDER,
418 FILE_DATA_MY_PICTURES_ROOT = {
420 type: FILE_TYPE.FOLDER,
423 json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON,
426 FILE_DATA_AUTHOR_ROOT = {
428 type: FILE_TYPE.FOLDER,
431 FILE_DATA_ARTIST_ROOT = {
433 type: FILE_TYPE.FOLDER,
436 FILE_DATA_LISENCE_ROOT = {
437 name: 'Original Lisences',
438 type: FILE_TYPE.FOLDER,
441 FILE_DATA_BALLOON_ROOT = {
442 name: 'Balloon templetes',
443 type: FILE_TYPE.FOLDER,
450 RESOURCE_PICTURE_ARRAY = [],
451 BALLOON_TEMPLETE_ARRAY = [],
452 ORIGINAL_LICENSE_ARRAY = [],
453 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
454 FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_PICTURE_ROOT, FILE_DATA_PANELS_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT );
455 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT );
456 FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT );
458 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT );
460 Driver.isPettanrFileInstance = function( _file ){
461 if( FileAPI.isFileInstance( _file ) === true){
462 var _data = FileAPI.getFileData( _file);
463 return _data !== null && _data.driver === Driver;
468 var Cabinet = gOS.registerApplication( function(){
473 this.bgColor = '#FFFFFF';
474 this.MIN_WIDTH = 500;
475 this.MIN_HEIGHT = 300;
476 this.onInit = function(){
477 self.rootElement.id = 'cabinet-root';
478 self.rootElement.innerHTML = '<div id="cabinet-container" class="finder-container"></div>';
480 tree = FileAPI.createTree( FILE_DATA_SERVICE_ROOT );
482 this.onOpen = function( _w, _h ){
483 finder = self.createFinder( self.rootElement, tree );
484 self.onPaneResize( _w, _h );
486 this.onClose = function(){
489 finder = tree = null;
491 this.onPaneResize = function( _w, _h ){
492 finder.resize( _w, _h );
494 }, false, true, 'Cabinet', 'cabinet', null, '#1C1C1C' );
496 var Gallery = gOS.registerApplication( function(){
501 this.bgColor = '#FFFFFF';
502 this.MIN_WIDTH = 500;
503 this.MIN_HEIGHT = 300;
504 this.onInit = function(){
505 self.rootElement.id = 'gallery-root';
506 self.rootElement.innerHTML = '<div id="gallery-container" class="finder-container"></div>';
508 tree = FileAPI.createTree( FILE_DATA_PICTURE_ROOT );
509 var _root = tree.getRootFile(),
510 _myPic = _root.getChildFileByIndex( 0 ),
511 _pic = _root.getChildFileByIndex( 1 );
512 _myPic.getSeqentialFiles();
513 _pic.getSeqentialFiles();
517 this.onOpen = function( _w, _h ){
518 finder = self.createFinder( self.rootElement, tree );
519 self.onPaneResize( _w, _h );
521 this.onClose = function(){
524 finder = tree = null;
526 this.onPaneResize = function( _w, _h ){
527 finder.resize( _w, _h );
529 }, false, true, 'Gallery', 'gallery', null, '#01A31C' );
531 var Backyard = gOS.registerApplication( function(){
534 this.bgColor = '#FFFFFF';
535 this.MIN_WIDTH = 500;
536 this.MIN_HEIGHT = 300;
537 this.onInit = function(){
539 this.onOpen = function( _w, _h, _option ){
541 this.onClose = function(){
543 this.onPaneResize = function( _w, _h){
545 }, false, false, 'Settings', 'settings', null, '#DDDDDD' );
547 if( pettanr.DEBUG === true){
548 var Debug = gOS.registerApplication( function(){
553 pettanR: pettanr.version,
554 ua: navigator.userAgent,
555 platform: navigator.platform,
556 appVersion: navigator.appVersion,
557 appCodeName: navigator.appCodeName,
558 appName: navigator.appName,
559 language: navigator.browserLanguage || navigator.language,
561 RenderingMode: UA.isStanderdMode === true ? 'Standerd' : 'Quirks'
564 data.version = UA.IE;
565 if( UA.ieVersion >= 8 ) data.RenderingVersion = UA.ieRenderingVersion;
566 data.browserType = UA.STANDALONE === true ? 'Standalone' : 'bundle';
567 if( UA.ieVersion < 9 ) {
576 this.bgColor = '#FFFFFF';
577 this.MIN_WIDTH = 500;
578 this.MIN_HEIGHT = 300;
579 this.onInit = function(){
580 self.rootElement.id = 'debug-root';
581 self.rootElement.innerHTML = '<dl id="useragent" class="dl-table clearfix"></dl>';
583 this.onOpen = function( _w, _h, _option ){
584 elmDl = document.getElementById( 'useragent' );
586 for( var key in data ){
587 elmDt = document.createElement( 'dt' );
588 elmDt.innerHTML = key;
589 elmDd = document.createElement( 'dd' );
590 elmDd.innerHTML = '' + data[ key];
591 if( !data[ key ] ) elmDd.style.color = 'red';
592 elmDl.appendChild( elmDt );
593 elmDl.appendChild( elmDd );
596 this.onClose = function(){
599 this.onPaneResize = function( _w, _h ){
602 }, false, true, 'Debug', 'debug', null, '#01A31C' );
605 /* ----------------------------------------
606 * Image Group Exproler
609 var PremiumSatge = gOS.registerApplication( function(){
610 var BASE_PATH = pettanr.CONST.RESOURCE_PICTURE_PATH,
611 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
612 LIMIT_FILESIZE = 1024 * 10,
618 elmContainer, elmIconOrigin, elmName, elmButton,
619 containerW, containerH,
620 itemW, itemH, buttonW,
625 var ImageGroupIconClass = function( index, data ){
626 var elmIconWrap = elmIconOrigin.cloneNode( true ),
627 elmIconTitle = Util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
628 SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
629 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
630 reversibleImage = null,
634 elmContainer.appendChild( elmIconWrap );
635 elmIconWrap.style.left = ( index * itemW ) + 'px';
636 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
638 function onImageLoad( url, _imgW, _imgH ){
639 data.width = _imgW = _imgW || data.width || 64;
640 data.height = _imgH = _imgH || data.height || 64;
641 elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
642 var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
643 MATH_FLOOR = Math.floor,
644 h = MATH_FLOOR( _imgH * zoom ),
645 w = MATH_FLOOR( _imgW * zoom );
646 reversibleImage.elm.style.cssText = [
649 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
651 reversibleImage.resize( w, h );
652 self.addMouseEventListener( elmIconWrap, 'click', onClick );
657 PremiumSatge.shutdown();
660 function asyncDraw(){
661 reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
662 elmIconWrap.appendChild( reversibleImage.elm );
667 this.onEnter = function( delay ){
668 self.addTimer( asyncDraw, delay, true );
669 delete instance.onEnter;
671 this.destroy = function(){
672 delete instance.destroy;
673 // timer && window.clearTimeout( timer );
674 self.removeTimer( asyncDraw );
675 self.removeMouseEventListener( elmIconWrap );
676 reversibleImage !== null && reversibleImage.destroy();
677 // Util.removeAllChildren( elmIconWrap );
678 // elmContainer.removeChild( elmIconWrap );
679 reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
683 function onEnterShowImage(){
684 var l = ICON_ARRAY.length,
685 _start = -wrapX /itemW -1,
686 _end = _start + winW /itemW +1,
688 for( var i=0, c = 0; i<l; ++i){
689 _icon = ICON_ARRAY[ i ];
690 if( _start < i && i < _end && _icon.onEnter ){
691 _icon.onEnter( c * 100 );
695 //onEnterInterval !== null && window.clearTimeout( onEnterInterval );
696 //onEnterInterval = null;
697 self.removeTimer( onEnterShowImage );
699 function clickClose(){
700 PremiumSatge.shutdown();
702 function onMouseWheel( e ){
703 if( winW < containerW ){
704 wrapX += e.wheelDelta / 2;
705 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
706 elmContainer.style.left = wrapX + 'px';
708 self.removeTimer( onEnterShowImage );
709 self.addTimer( onEnterShowImage, 500 );
714 function drawIcons(){
715 while( ICON_ARRAY.length > 0 ){
716 ICON_ARRAY.shift().destroy();
718 var _index = rootFile.search( {
720 type: FILE_TYPE.ARTIST
722 _artistFile = rootFile.getChildFileByIndex( _index ),
724 if( _artistFile !== null ){
725 for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
726 _file = _artistFile.getChildFileByIndex( i );
727 ICON_ARRAY.push( new ImageGroupIconClass( i, FileAPI.getFileData( _file ) ));
730 elmName.firstChild.data = _artistFile.getName();
731 _artistFile.destroy();
735 function onFadeout(){
736 while( ICON_ARRAY.length > 0 ){
737 ICON_ARRAY.shift().destroy();
739 onUpdate !== null && onUpdateData !== null && onUpdate( onUpdateData );
740 onUpdate = onUpdateData = null;
741 PremiumSatge.shutdown();
745 this.MIN_WIDTH = 320;
746 this.MIN_HEIGHT = 320;
747 this.onInit = function(){
748 self.rootElement.id = 'image-group-wrapper';
750 self.rootElement.innerHTML = [
751 '<div id="image-group-icon-container"></div>',
752 '<div id="image-group-name">NO DATA...</div>',
753 '<div id="image-group-button" class="button">close</div>'
756 tree = FileAPI.createTree( FILE_DATA_ARTIST_ROOT );
757 rootFile = tree.getRootFile();
759 this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdate ){
760 elmContainer = document.getElementById( 'image-group-icon-container' );
761 containerH = Util.getElementSize( elmContainer ).height;
763 elmIconOrigin = ( function(){
764 var ret = document.createElement( 'div' ),
765 data = document.createElement( 'div' );
766 ret.appendChild( data );
767 ret.className = 'image-group-item';
768 data.className = 'image-group-item-title';
772 var size = Util.getElementSize( elmIconOrigin );
776 elmName = document.getElementById( 'image-group-name' );
777 elmButton = document.getElementById( 'image-group-button' );
779 buttonW = Util.getElementSize( elmButton ).width;
781 self.addMouseEventListener( elmContainer, 'mousewheel', onMouseWheel );
782 self.addMouseEventListener( elmButton, 'click', clickClose );
783 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, drawIcons );
785 if( Driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
786 var _data = FileAPI.getFileData( _ARTISTIDorFILE );
787 if( _ARTISTIDorFILE.getType() === FILE_TYPE.ARTIST || FILE_DATA_MY_PICTURES_ROOT === _data ){
788 artistID = _data.id || -1;
791 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
792 artistID = _ARTISTIDorFILE;
795 onUpdate = _onUpdate || null;
801 containerW = ICON_ARRAY.length * itemW;
805 var w = winW > containerW ? winW : containerW,
806 h = _windowH > containerH ? containerH : _windowH,
807 MATH_FLOOR = Math.floor;
809 $( elmContainer ).css( {
813 top: MATH_FLOOR( _windowH /2 )
816 top: MATH_FLOOR( _windowH /2 - h /2 )
817 }, onEnterShowImage );
819 elmButton.style.cssText = [
820 'left:', MATH_FLOOR( _windowW /2 - buttonW /2 ), 'px;',
821 'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10 ), 'px'
824 this.onPaneResize = function( _windowW, _windowH ){
825 var w = _windowW > containerW ? _windowW : containerW,
826 h = _windowH > containerH ? containerH : _windowH,
827 MATH_FLOOR = Math.floor,
828 offsetW = MATH_FLOOR( _windowW /2 -winW /2 );
832 if( offsetW <= 0 ){ // smaller
833 $( elmContainer ).stop().css( {
838 top: MATH_FLOOR( _windowH /2 -h /2 )
841 $( elmContainer ).stop().css( { // bigger
844 borderLeftWidth: offsetW
846 top: MATH_FLOOR( _windowH /2 -h /2 ),
850 elmButton.style.cssText = [
851 'left:', MATH_FLOOR( _windowW /2 -buttonW /2 ), 'px;',
852 'top:', MATH_FLOOR( _windowH /2 +containerH /2 + 10 ), 'px'
856 this.onClose = function(){
857 if( tree === null ) return true;
858 $( elmContainer ).stop().animate( {
860 top: Math.floor( winH /2 )
862 // onEnterInterval !== null && window.clearTimeout( onEnterInterval );
863 // onEnterInterval = null;
866 tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, drawIcons );
868 tree = rootFile = null;
872 }, true, true, 'Premium Stage', 'premiumStage', null, '#C3325F' );
875 /* ----------------------------------------
879 var TextEditor = gOS.registerApplication( function(){
880 var elmTextarea, elmButton,
881 textElement, onUpdate,
887 textElement && textElement.text( elmTextarea.val() );
888 self.addAsyncCall( asyncCallback );
891 function asyncCallback(){
892 onUpdate && onUpdate( textElement );
893 onUpdate = textElement = null;
894 TextEditor.shutdown();
898 function textareaFitHeight(){
900 while( elmTextarea.offsetHeight < textElement.h ){
902 elmTextarea.rows = rows;
904 if( rows > 1 ) elmTextarea.rows = --rows;
909 this.MIN_WIDTH = 320;
910 this.MIN_HEIGHT = 320;
911 this.onInit = function(){
912 self.rootElement.id = 'speach-editor-wrapper';
913 self.rootElement.innerHTML = '<textarea id="speach-editor"></textarea><div id="speach-edit-complete-button" class="button">OK</div>';
915 this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdate ){
916 elmTextarea = document.getElementById( 'speach-editor' );
917 elmButton = document.getElementById( 'speach-edit-complete-button' );
919 self.addKeyEventListener( 'keydown', new Function( 'return false' ), 69, false, true );
920 self.addMouseEventListener( elmButton, 'click', clickOK );
924 textElement = _textElement;
925 onUpdate = _onUpdate || null;
927 self.onPaneResize( _w, _h );
928 elmTextarea.value = _textElement.text()
932 * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
934 UA.isIE === true && UA.ieVersion <= 7 && self.addAsyncCall( textareaFitHeight );
936 this.onPaneResize = function( _w, _h ){
937 self.rootElement.style.cssText = [
938 'left:', textElement.x + panelX, 'px;',
939 'top:', textElement.y + panelY, 'px;',
940 'width:', textElement.w, 'px;',
941 'height:', textElement.h, 'px;'
944 this.onClose = function(){
945 self.removeKeyEventListener();
946 self.removeMouseEventListener( elmButton );
948 elmTextarea = elmButton = onUpdate = textElement = self = null;
950 }, true, false, 'Tetxt Editor', 'texteditor', null, '#DDDDDD' );
953 var Reader = gOS.registerApplication( function(){
954 var windowW, windowH,
958 elmContainer, elmTitle, elmAuthor, elmBackButton, elmNextButton,
967 function onBackClick(){
968 currentIndex -= ( currentIndex > 0 ? 1 : 0 );
972 function onNextClick(){
973 currentIndex += ( currentIndex < numPanel - 1 ? 1 : 0 );
978 var elm = elmContainer.childNodes[ currentIndex ],
979 h = windowH - headerH - consoleH,
982 top = headerH - elm.offsetTop + Math.floor( ( h - elm.offsetHeight ) / 2 );
985 $( elmContainer ).stop().animate( {
989 function getCurrentTopPosition(){
993 var fileData, title, author;
995 if( Driver.isPettanrFileInstance( currentFile ) === true ){
996 if( currentFile.getType() === FILE_TYPE.COMIC ){
997 fileData = currentFile.read();
998 title = fileData.title;
999 author = fileData.author.name;
1000 comicData = fileData;
1001 numPanel = currentFile.getChildFileLength();
1003 if( currentFile.getType() === FILE_TYPE.PANEL ){
1004 fileData = currentFile.read();
1005 title = fileData.comic.title;
1006 author = fileData.comic.author.name;
1007 comicData = fileData;
1014 if( comicData !== null ){
1015 elmTitle.data = title;
1016 elmAuthor.data = author;
1017 bindWorker.json( comicData );
1018 self.addAsyncCall( asyncResize );
1021 function asyncResize(){
1022 self.onPaneResize( windowW, windowH );
1027 this.MIN_WIDTH = 320;
1028 this.MIN_HEIGHT = 320;
1029 this.onInit = function(){
1030 self.rootElement.id = 'comic-reader-wrapper';
1031 self.rootElement.innerHTML = [
1032 '<div id="comic-reader-panel-container"></div>',
1033 '<div class="comic-reader-shadow" style="top:0;height:40px;"></div>',
1034 '<div id="comic-reader-header">',
1035 '<div id="comic-reader-header-content">',
1036 '<span id="comic-reader-title">NO DATA...</span>',
1037 '<span id="comic-reader-author">NO DATA...</span>',
1040 '<div class="comic-reader-shadow" style="bottom:0;height:100px;"></div>',
1041 '<div id="comic-reader-console">',
1042 '<div id="comic-reader-button-centering">',
1043 '<a href="#" id="comic-reader-back-button">▲</da>',
1044 '<a href="#" id="comic-reader-forward-button">▼</a>',
1049 this.onOpen = function( _w, _h, _file ){
1050 headerH = Util.getElementSize( document.getElementById( 'comic-reader-header' ) ).height;
1051 consoleH = Util.getElementSize( document.getElementById( 'comic-reader-console' ) ).height;
1052 elmContainer = document.getElementById( 'comic-reader-panel-container' );
1053 elmTitle = document.getElementById( 'comic-reader-title' ).firstChild;
1054 elmAuthor = document.getElementById( 'comic-reader-author' ).firstChild;
1055 elmBackButton = document.getElementById( 'comic-reader-back-button' );
1056 elmNextButton = document.getElementById( 'comic-reader-forward-button' );
1058 bindWorker = pettanr.bind.createBindWorker( elmContainer, null, false, false );
1060 self.addMouseEventListener( elmBackButton, 'click', onBackClick );
1061 self.addMouseEventListener( elmNextButton, 'click', onNextClick );
1063 numPanel = currentIndex = 0;
1065 elmContainer.style.cssText = 'left:' + ( _w / 2 ) + 'px;' + 'top:' + _h + 'px;';
1069 if( FileAPI.isFileInstance( _file ) === true ){
1070 currentFile = _file;
1071 _file.addEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw );
1072 _file.getSeqentialFiles();
1076 this.onPaneResize = function( _windowW, _windowH ){
1079 var panelH = elmContainer.offsetHeight,
1080 panelW = elmContainer.offsetWidth,
1081 h = _windowH - headerH - consoleH;
1082 $( elmContainer ).stop().animate(
1084 left: Math.floor( ( _windowW - panelW ) / 2 ),
1085 top: headerH + ( panelH < h ? Math.floor( ( h - panelH ) / 2 ) : 0 )
1089 this.onClose = function(){
1090 self.removeMouseEventListener( elmBackButton );
1091 self.removeMouseEventListener( elmNextButton );
1093 bindWorker.destroy();
1096 currentFile && currentFile.removeEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw );
1097 currentFile = comicData = currentPanel = null;
1099 elmContainer = elmTitle = elmAuthor = elmBackButton = elmNextButton = null;
1101 }, true, true, 'Comic Reader', 'comicreader', null, '#01A31C' );
1104 var Editor = gOS.registerApplication( function(){
1106 var PANEL_ELEMENT_TYPE_IMAGE = 0,
1107 PANEL_ELEMENT_TYPE_TEXT = 1,
1109 MOUSE_LISTENER_ARRAY = [],
1110 PANEL_ELEMENT_ARRAY = [],
1111 MIN_PANEL_HEIGHT = 20,
1112 MIN_ELEMENT_SIZE = 19,
1113 MOUSE_HIT_AREA = 10,
1114 elmMouseEventChatcher,
1115 jqMouseEventChacher,
1118 currentListener = null,
1129 var kill = function(){
1132 if( o.hasOwnProperty && !o.hasOwnProperty( p ) ) continue;
1149 destroy: function(){
1154 register: function( _class ){
1155 _class.prototype = TMP.abstractModule;
1157 MODULE_ARRAY.push( ret );
1161 /* ----------------------------------------
1163 * - mouseEventListener
1174 var MENU_BAR_CONTROL = ( function(){
1175 var ELM_ITEM_CLASSNAME = 'menu-bar-item',
1178 elmItemOrigin, elmSelectionOrigin,
1179 barH, itemW, selectionW;
1181 var MenubarOptionClass = function( callback, separateAfter ){
1182 this.callback = callback;
1183 this.separateAfter = separateAfter;
1185 MenubarOptionClass.prototype = {
1188 title: function( _title ){
1189 if( Type.isString( _title ) === true ){
1190 this.elmTitle.innerHTML = _title;
1192 return this.elmTitle.innerHTML;
1195 visible: function( _visible ){
1196 if( Type.isBoolean( _visible ) === true && this._visible !== _visible ){
1197 this._visible = _visible;
1198 this.elm.className = _visible === true ? '' : 'disabled';
1200 return this._visible;
1202 _init: function( elmParent, _title, _shortcut, _visible ){
1203 this.elm = elmSelectionOrigin.cloneNode( true );
1204 this.elmTitle = this.elm.getElementsByTagName( 'span' )[ 0 ];
1206 elmParent.appendChild( this.elm );
1208 this.title( _title );
1209 this.visible( !!_visible );
1211 var elmShortcut = this.elm.getElementsByTagName( 'kbd' )[ 0 ];
1213 elmShortcut.innerHTML = _shortcut;
1215 elmShortcut.parentNode.removeChild( elmShortcut );
1221 var MenuBarItemClass = function( title ){
1222 this.elm = elmItemOrigin.cloneNode( true );
1223 elmBar.appendChild( this.elm );
1224 this.elm.style.left = ( itemW * itemList.length ) + 'px';
1226 this.elm.getElementsByTagName( 'div' )[ 0 ].innerHTML = title;
1228 this.elmUl = this.elm.getElementsByTagName( 'ul' )[ 0 ];
1229 this.optionList = [];
1230 this.visible = false;
1232 var optionList = this.optionList;
1234 this.onClick = function( e ){
1235 var i = Util.getChildIndex( this.parentNode, this );
1236 i !== -1 && this.className !== 'disabled' && optionList[ i ].callback( i );
1239 this._onClose = function(){
1243 MenuBarItemClass.prototype = {
1245 if( this.visible === true ) return;
1246 elmRoot.appendChild( this.elm );
1247 this.elm.className = ELM_ITEM_CLASSNAME + '-focus';
1248 this.onShow && app.addAsyncCall( this.onShow );
1249 this.visible = true;
1252 if( this.visible === false ) return;
1253 elmBar.appendChild( this.elm );
1254 this.elm.className = ELM_ITEM_CLASSNAME;
1255 this.onHide && app.addAsyncCall( this.onHide );
1256 this.visible = false;
1258 createOption: function( title, shortcut, callback, visible, separateBefore, separateAfter ){
1259 var ret = new MenubarOptionClass( callback, separateAfter ),
1260 before = this.optionList[ this.optionList.length -1 ];
1261 ret._init( this.elmUl, title, shortcut, visible );
1263 this.optionList.push( ret );
1264 if( before && ( separateBefore === true || before.separateAfter === true )){
1265 ret.elm.style.borderTop = '1px solid #ccc';
1270 for( var lis = this.optionList, i = lis.length; i; ){
1271 app.addMouseEventListener( lis[ --i ].elm, 'click', this.onClick );
1277 while( o = this.optionList.shift() ) o._kill();
1283 function createMenubarItem( title ){
1284 itemList.push( new MenuBarItemClass( title ) );
1285 return itemList[ itemList.length - 1 ];
1289 elmRoot = app.rootElement;
1290 elmBar = document.getElementById( 'menu-bar' );
1291 elmItemOrigin = ( function(){
1292 var ret = document.createElement( 'div' ),
1293 div = document.createElement( 'div' ),
1294 ul = document.createElement( 'ul' );
1295 ret.className = ELM_ITEM_CLASSNAME;
1296 ret.appendChild( div );
1297 ret.appendChild( ul );
1300 elmSelectionOrigin = ( function(){
1301 var ret = document.createElement( 'li' ),
1302 a = document.createElement( 'a' ),
1303 span = document.createElement( 'span' ),
1304 key = document.createElement( 'kbd' );
1305 a.appendChild( span );
1306 a.appendChild( key );
1307 ret.appendChild( a );
1311 barH = Util.getElementSize( elmBar ).height;
1312 MENU_BAR_CONTROL.h = barH;
1313 itemW = Util.getElementSize( elmItemOrigin ).width;
1314 selectionW = Util.getElementSize( elmItemOrigin.getElementsByTagName( 'ul' )[ 0 ] ).width;
1316 MENU_BAR_CONTROL.QUIT = createMenubarItem( 'Quit' );
1317 MENU_BAR_CONTROL.EDIT = createMenubarItem( 'Edit' );
1318 MENU_BAR_CONTROL.WINDOW = createMenubarItem( 'Window' );
1319 MENU_BAR_CONTROL.HELP = Util.extend(
1320 createMenubarItem( 'Help' ),
1322 createAjaxSelection: function( callback ){
1323 var elmLoading = document.createElement( 'li' ),
1325 this.elmUl.appendChild( elmLoading );
1326 elmLoading.className = 'loading';
1327 elmLoading.style.height = '90px';
1329 this.onShow = callback;
1332 delete this.createAjaxSelection;
1334 that.elmUl.removeChild( elmLoading );
1337 elmLoading = that = null;
1344 elmBar.style.top = ( -barH ) + 'px';
1345 $( elmBar ).animate( { top: 0 });
1347 delete MENU_BAR_CONTROL.init;
1350 for( var i = itemList.length; i; ) itemList[ --i ]._open();
1351 delete MENU_BAR_CONTROL.open;
1355 while( s = itemList.shift() ) s._close();
1356 itemList = elmRoot = elmBar = elmItemOrigin = elmSelectionOrigin = null;
1357 MENU_BAR_CONTROL.kill = kill;
1358 MENU_BAR_CONTROL.kill();
1361 mousemove: function( _mouseX, _mouseY ){
1362 if( barH >= _mouseY ) return true;
1364 for( var i = itemList.length; i; ) itemList[ --i ].hide();
1367 mouseup: function( _mouseX, _mouseY ){
1370 mousedown: function( _mouseX, _mouseY ){
1371 var l = itemList.length;
1372 if( barH < _mouseY || itemW * l < _mouseX ) return false;
1375 itemList[ l ][ l * itemW <= _mouseX && _mouseX < ( l + 1 ) * itemW ? 'show' : 'hide' ]();
1379 busy: function( _busy ){
1382 onWindowResize: function( _windowW, _windowH ){
1393 /* ----------------------------------------
1397 var HISTORY_CONTROL = ( function() {
1405 * currentを控えてstackForward.push(current)
1406 * stackBack.pop()を実行してcurrentに
1408 if( stackBack.length === 0 ) return;
1410 var s = stackBack.pop();
1412 menubarBack.visible( stackBack.length !== 0 );
1413 SAVE_CONTROL.panelUpdated( stackBack.length !== 0 );
1415 stackForward.push( s );
1416 menubarForward.visible( true );
1419 if( stackForward.length === 0 ) return;
1421 var s = stackForward.pop();
1422 s.fn( s.argForword );
1423 menubarForward.visible( stackForward.length !== 0 );
1425 stackBack.push( s );
1426 menubarBack.visible( true );
1427 SAVE_CONTROL.panelUpdated( true );
1429 var StackClass = function( _function, _argBack, _argForword, _destroy ){
1430 this.fn = _function;
1431 this.argBack = _argBack;
1432 this.argForword = _argForword;
1433 this.destroy = _destroy;
1435 StackClass.prototype.kill = function( _callDestroy ){
1436 var _argBack = this.argBack,
1437 _argForword = this.argForword,
1442 if( _callDestroy !== true ) return;
1444 if( Type.isArray( _argBack ) === true ){ // isArray
1445 while( v = _argBack.shift() ){
1446 _callDestroy === true && Type.isFunction( v.destroy ) === true && v.destroy();
1449 if( Type.isArray( _argForword ) === true ){
1450 while( v = _argForword.shift() ){
1451 _callDestroy === true && Type.isFunction( v.destroy ) === true && v.destroy();
1457 app.addKeyEventListener( 'keydown', back, 90, false, true ); // ctrl + Z
1458 app.addKeyEventListener( 'keydown', forward, 90, true, true ); // ctrl + shift + Z
1459 app.addKeyEventListener( 'keydown', forward, 89, false, true ); // ctrl + Y
1461 delete HISTORY_CONTROL.init;
1464 menubarBack = MENU_BAR_CONTROL.EDIT.createOption( 'back', 'ctrl + z', back, false );
1465 menubarForward = MENU_BAR_CONTROL.EDIT.createOption( 'forward', 'ctrl + y', forward, false, false, true );
1467 delete HISTORY_CONTROL.open;
1471 while( s = stackBack.shift() ) s.kill( true );
1472 while( s = stackForward.shift() ) s.kill( true );
1473 menubarBack = menubarForward = stackBack = stackForward = null;
1475 saveState: function( _function, _argBack, _argForword, _destroy ){
1476 stackBack.push( new StackClass( _function, _argBack, _argForword, _destroy ));
1477 menubarBack.visible( true );
1478 SAVE_CONTROL.panelUpdated( true );
1481 while( s = stackForward.shift() ) s.kill( s.destroy );
1482 menubarForward.visible( false );
1487 /* ----------------------------------------
1491 var SAVE_CONTROL = ( function(){
1492 var save, saveQuit, eXport, quit,
1498 function onExport(){
1500 comicID, panelID, panelTimming,
1501 PANEL_CONTROL.w, PANEL_CONTROL.h,
1502 2, // border, BackgroundImage
1508 delete SAVE_CONTROL.init;
1511 save = MENU_BAR_CONTROL.QUIT.createOption( 'save', 'ctrl + S', quit, false );
1512 saveQuit = MENU_BAR_CONTROL.QUIT.createOption( 'save & quit', null, quit, false, false, true );
1513 eXport = MENU_BAR_CONTROL.QUIT.createOption( 'export', null, onExport, true, false, true );
1514 quit = MENU_BAR_CONTROL.QUIT.createOption( 'quit', null, quit, true, true );
1516 delete SAVE_CONTROL.open;
1519 save = saveQuit = eXport = quit = null;
1520 SAVE_CONTROL.kill = kill;
1521 SAVE_CONTROL.kill();
1524 panelUpdated: function( _updated ){
1525 if( Type.isBoolean( _updated ) === true ){
1526 save.visible( _updated );
1527 saveQuit.visible( _updated );
1538 /* ----------------------------------------
1541 * - mouseEventListener
1543 var WINDOWS_CONTROL = ( function(){
1545 * 表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。
1547 var DEFAULT_MIN_WINDOW_WIDTH = 200,
1548 DEFAULT_MIN_WINDOW_HEIGHT = 200,
1550 WINDOW_BODY_BODER_SIZE = 1,
1551 currentWindowIndex = -1,
1557 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH ){
1559 elmHeader, elmFooter = null,
1560 elmBody, elmBodyStyle,
1561 startX, startY, startW, startH,
1563 headerH, bodyH, footerH = 0,
1566 bodyIsTachable = false,
1569 function update( _x, _y, _w, _h ){
1570 _x = _x !== undefined ? _x : x;
1571 _y = _y !== undefined ? _y : y;
1572 _y = _y > MENU_BAR_CONTROL.h ? _y : MENU_BAR_CONTROL.h;
1573 _w = _w !== undefined ? _w : w;
1574 _h = _h !== undefined ? _h : h;
1575 self.elm.style.cssText = [
1578 'width:', _w, 'px;',
1579 'height:', _h, 'px;'
1581 bodyH = _h - headerH - footerH;
1582 elmBodyStyle.height = bodyH + 'px';
1583 ( w !== _w || h !== _h) && self.onResize && self.onResize( _w, bodyH );
1589 function bodyBackOrForward( isBack ){
1591 if( bodyIsTachable === !isBack) return;
1592 elmBodyStyle.position = isBack === true ? 'relative' : 'absolute';
1593 elmBodyStyle.left = isBack === true ? 0 : x +'px';
1594 elmBodyStyle.top = isBack === true ? 0 : y +headerH +'px';
1595 elmBodyStyle.width = isBack === true ? '' : ( w -WINDOW_BODY_BODER_SIZE *2) +'px';
1596 bodyIsTachable === isBack && isBack === true ? elmHeader.parentNode.insertBefore( elmBody, elmHeader.nextSibling ) : app.rootElement.appendChild( elmBody );
1597 bodyIsTachable = !isBack;
1600 this.init = function(){
1601 self.elm = elmWindowOrigin.cloneNode( true );
1602 menubarOption = MENU_BAR_CONTROL.WINDOW.createOption(
1603 ( visible !== true ? 'show ' : 'hide ' ) + title,
1604 null, function(){ visible === true ? self.close() : self.open(); }, true
1606 elmHeader = Util.getElementsByClassName( self.elm, 'window-header' )[ 0 ];
1607 elmHeader.innerHTML = title;
1608 headerH = Util.getElementSize( elmHeader ).height;
1609 elmBody = Util.getElementsByClassName( self.elm, 'window-body' )[ 0 ];
1610 elmBodyStyle = elmBody.style;
1612 self.onInit && self.onInit();
1615 this.x = function(){ return x;};
1616 this.y = function(){ return y;};
1617 this.w = function(){ return w;};
1618 this.h = function(){ return h;};
1619 this.title = function( _title ){
1620 if( Type.isString( _title ) === true ){
1621 jqHeader.html( _title );
1626 this.visible = visible;
1627 this.firstOpen = function(){
1628 var elmReplace = Util.getElementsByClassName( self.elm, 'window-body-insert-position' )[ 0 ];
1630 if( bodyTempleteID ){
1631 elmReplace.parentNode.replaceChild( document.getElementById( bodyTempleteID ), elmReplace );
1633 elmReplace.parentNode.removeChild( elmReplace );
1636 if( CLOSE_BUTTON_ENABLED !== true ){
1637 var elmClose = Util.getElementsByClassName( self.elm, 'window-close-button' )[ 0 ];
1638 elmClose.parentNode.removeChild( elmClose );
1642 var elmFooter = Util.getElementsByClassName( self.elm, 'window-footer' )[ 0 ];
1643 if( RESIZE_BUTTON_ENABLED === true ){
1644 footerH = Util.getElementSize( elmFooter ).height;
1646 elmFooter.parentNode.removeChild( elmFooter );
1648 self.onFirstOpen && self.onFirstOpen( w, h - headerH - footerH );
1650 update( x, y, w, h );
1652 delete self.firstOpen;
1654 this.open = function(){
1655 if( visible === true )return;
1656 self.visible = visible = true;
1658 menubarOption.title( 'hide ' + title );
1660 for( var i=0, l = WINDOW_ARRAY.length; i<l; ++i ){
1661 if( WINDOW_ARRAY[ i ] === self ){
1662 WINDOW_ARRAY.splice( i, 1 );
1663 WINDOW_ARRAY.unshift( self );
1664 currentWindow = null;
1665 currentWindowIndex = -1;
1669 this.onFadeIn = function(){
1670 self.firstOpen && self.firstOpen();
1671 self.onOpen && self.onOpen( w, bodyH );
1673 this.onFadeOut = function(){
1674 self.elm.parentNode.removeChild( self.elm );
1675 self.onClose && setTimeout( self.onClose, 0 );
1677 this.close = function(){
1678 if( visible === false) return;
1679 self.visible = visible = false;
1680 $( self.elm ).fadeOut( self.onFadeOut );
1681 menubarOption.title( 'show ' + title );
1683 this.bodyBackOrForward = bodyBackOrForward;
1684 this.mousedown = function( _mouseX, _mouseY ){
1685 if( RESIZE_BUTTON_ENABLED === true && x + w -20 <= _mouseX && _mouseX < x + w && y + headerH + bodyH < _mouseY && _mouseY <= y + h ){
1686 bodyBackOrForward( true);
1694 updateMouseCursor( 'nw-resize');
1698 if( x > _mouseX || y > _mouseY || x + w < _mouseX || y + headerH < _mouseY ) return;
1699 if( CLOSE_BUTTON_ENABLED === true && x + w - closeButtonWidth < _mouseX){
1705 updateMouseCursor( 'move');
1713 this.mouseup = function( _mouseX, _mouseY ){
1714 isDragging = isResizing = false;
1715 updateMouseCursor( '');
1717 this.mousemove = function( _mouseX, _mouseY ){
1718 var _updateX = _mouseX - offsetX,
1719 _updateY = _mouseY - offsetY;
1721 if( isResizing === true){
1722 var _w = startW +_updateX,
1723 _h = startH +_updateY;
1724 update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h );
1727 if( isDragging === true) {
1728 update( startX + _updateX, startY + _updateY);
1731 if( x > _mouseX || x + w < _mouseX ) return;
1733 ( y <= _mouseY && y +headerH >= _mouseY ) ?
1734 updateMouseCursor( 'pointer') : // hit to header
1735 updateMouseCursor( '');
1736 bodyBackOrForward( y + headerH > _mouseY || y + headerH + bodyH < _mouseY);
1738 this.onMouseOut = function( _mouseX, _mouseY ){
1739 bodyIsTachable === true && bodyBackOrForward( true );
1741 updateMouseCursor( '' );
1743 this.busy = function(){
1744 return isDragging === true || isResizing === true;
1748 function getCurrentIndex( _mouseX, _mouseY ){
1749 if( currentWindow && currentWindow.busy() === true ) return currentWindowIndex;
1750 var l = WINDOW_ARRAY.length,
1751 _currentWindow = null,
1753 currentWindowIndex = -1;
1754 for( var i=0; i<l; i++){
1755 _win = WINDOW_ARRAY[ i];
1756 if( _win.visible !== true ) continue;
1759 if( _x <= _mouseX && _y <= _mouseY && _x +_win.w() >= _mouseX && _y +_win.h() >= _mouseY){
1760 _currentWindow = _win;
1761 currentWindowIndex = i;
1765 currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY);
1766 currentWindow = _currentWindow;
1767 return currentWindowIndex;
1769 function openWindow( _window ){
1770 if( _window.visible !== true ) return;
1771 elmRoot.appendChild( _window.elm );// appendした後に fadeIn() しないと ie で filterが適用されない.
1772 $( _window.elm ).fadeIn( _window.onFadeIn );
1778 elmRoot = document.getElementById( 'window-container' );
1779 elmWindowOrigin = app.fetchHTMLElement( 'windowTemplete' );
1780 closeButtonWidth = Util.getElementSize( Util.getElementsByClassName( elmWindowOrigin, 'window-close-button' )[ 0 ] ).width;
1782 delete WINDOWS_CONTROL.init;
1785 for( var i = WINDOW_ARRAY.length, _window; i; ){
1786 _window = WINDOW_ARRAY[ --i ];
1787 _window.init && _window.init();
1788 _window.visible === true && openWindow( _window );
1791 delete WINDOWS_CONTROL.open;
1795 mousemove: function( _mouseX, _mouseY ){
1796 var _index = getCurrentIndex( _mouseX, _mouseY );
1798 currentWindow.mousemove( _mouseX, _mouseY );
1801 if( _index > 0 ){ // 先頭のクリックでない場合
1803 WINDOW_ARRAY.splice( currentWindowIndex, 1 );
1804 WINDOW_ARRAY.unshift( currentWindow );
1806 elmRoot.appendChild( currentWindow.elm );
1807 currentWindowIndex = 0;
1812 mouseup: function( _mouseX, _mouseY ){
1813 if( getCurrentIndex( _mouseX, _mouseY) === 0){
1814 currentWindow.mouseup( _mouseX, _mouseY);
1819 mousedown: function( _mouseX, _mouseY ){
1820 if( getCurrentIndex( _mouseX, _mouseY) === 0){
1821 currentWindow.mousedown( _mouseX, _mouseY);
1827 return currentWindow !== null;
1829 onWindowResize: function( _windowW, _windowH ){
1834 createWindow: function( EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH ){
1835 opt_visible = opt_visible !== false;
1836 opt_closeButtonEnabled = opt_closeButtonEnabled === true;
1837 opt_resizeButtonEnabled = opt_resizeButtonEnabled === true;
1838 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH ) ? w : DEFAULT_MIN_WINDOW_WIDTH;
1839 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT ) ? h : DEFAULT_MIN_WINDOW_HEIGHT;
1841 var _window = new WindowClass( bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH );
1842 for( var key in EXTENDS ){
1843 _window[ key ] = EXTENDS[ key ];
1845 WINDOW_ARRAY.unshift( _window );
1846 if( Type.isUndefined( WINDOWS_CONTROL.init ) === true ){
1848 openWindow( _window );
1855 /* ----------------------------------------
1859 var TOOL_BOX_WINDOW = ( function(){
1861 app.addKeyEventListener( 'keydown', addImage, 73, false, true );
1862 app.addKeyEventListener( 'keydown', addText, 84, false, true );
1863 app.addKeyEventListener( 'keydown', switchGrid, 71, false, true );
1865 function addImage(){
1866 IMAGE_EXPLORER_WINDOW.open();// setTimeout( IMAGE_EXPLORER_WINDOW.open, 0);
1867 TOOL_BOX_WINDOW.bodyBackOrForward( true );
1870 setTimeout( PANEL_ELEMENT_CONTROL.createTextElement, 0 );
1872 function switchGrid(){
1873 setTimeout( GRID_CONTROL.update, 0 );
1875 function popupHelp(){
1876 TOOL_BOX_WINDOW.bodyBackOrForward( true );
1877 setTimeout( HELP_DOCUMENTS_WINDOW.open, 0 );
1879 function editBG( e ){
1880 TOOL_BOX_WINDOW.bodyBackOrForward( true );
1881 setTimeout( INFOMATION_WINDOW.open, 0 );
1884 return WINDOWS_CONTROL.createWindow(
1887 MENU_BAR_CONTROL.EDIT.createOption( 'Add Image', 'ctrl + I', addImage, true, true, false);
1888 MENU_BAR_CONTROL.EDIT.createOption( 'Add Text', 'ctrl + T', addText, true, false, true);
1889 MENU_BAR_CONTROL.EDIT.createOption( 'show Grid', 'ctrl + G', switchGrid, true, true, true);
1891 delete TOOL_BOX_WINDOW.onInit;
1893 onFirstOpen: function(){
1894 app.addMouseEventListener( document.getElementById( 'toolbox-add-image-button'), 'click', addImage );
1895 app.addMouseEventListener( document.getElementById( 'toolbox-add-text-button'), 'click', addText );
1896 app.addMouseEventListener( document.getElementById( 'toolbox-edit-bg-button'), 'click', editBG );
1897 app.addMouseEventListener( document.getElementById( 'toolbox-switch-grid'), 'click', switchGrid );
1898 app.addMouseEventListener( document.getElementById( 'toolbox-popup-help-button'), 'click', popupHelp );
1900 // postButton = $( '#toolbox-post-button');
1902 delete TOOL_BOX_WINDOW.onFirstOpen;
1905 'toolbox-window', 'Tool box', 0, 215, 110, 290, true
1910 /* ----------------------------------------
1914 var IMAGE_EXPLORER_WINDOW = ( function(){
1917 function onFileSelect( _file ){
1918 // 他の image ファイルも許可する?
1919 if( Driver.isPettanrFileInstance( _file ) === true ){
1920 if( _file.getType() === FILE_TYPE.PICTURE ){
1921 PANEL_ELEMENT_CONTROL.onImageSelect( FileAPI.getFileData( _file ) );
1926 return WINDOWS_CONTROL.createWindow(
1929 delete IMAGE_EXPLORER_WINDOW.onInit;
1931 onFirstOpen: function( _w, _h ){
1932 tree = FileAPI.createTree( FILE_DATA_PICTURE_ROOT );
1933 var _root = tree.getRootFile(),
1934 _myPic = _root.getChildFileByIndex( 0 ),
1935 _pic = _root.getChildFileByIndex( 1 );
1936 _myPic.getSeqentialFiles();
1937 _pic.getSeqentialFiles();
1941 finder = app.createFinder(
1942 document.getElementById( 'image-exproler-container' ),
1946 PANEL_ELEMENT_CONTROL.onImageSelect
1949 delete IMAGE_EXPLORER_WINDOW.onFirstOpen;
1951 onOpen: function( _w, _h ){
1952 finder.resize( _w, _h );
1954 onResize: function( _w, _h ){
1955 finder.resize( _w, _h );
1958 'image-exproler', 'Album', 0, 215, 600, 350, false, true, true, 300, 300
1963 /* ----------------------------------------
1967 var INFOMATION_WINDOW = ( function(){
1968 var FADE_EFFECT_ENABLED = true, //UA.isIE === false || UA.ieVersion >= 8,
1969 FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show',
1970 FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide',
1971 backgroundInfomationElm,
1972 jqPanelElementInformation,
1973 ui, inputX, inputY, inputZ, inputA, inputW, inputH, inputAspectRatio,
1974 inputPercentW, inputPercentH,
1975 currentPanelElement = null,
1976 currentElementType = -1,
1977 currentLock = false;
1979 return WINDOWS_CONTROL.createWindow(
1981 onFirstOpen: function( _w, _h ){
1982 backgroundInfomationElm = $( '#panel-background-information');
1984 jqPanelElementInformation = $( '#comic-element-infomation').hide().css( {
1987 ui = app.createUIGroup();
1988 inputX = ui.createInputText( document.getElementById( 'comic-element-x' ), null );
1989 inputY = ui.createInputText( document.getElementById( 'comic-element-y' ), null );
1990 inputZ = ui.createInputText( document.getElementById( 'comic-element-z' ), null );
1991 inputA = ui.createInputText( document.getElementById( 'comic-element-a' ), null );
1992 inputW = ui.createInputText( document.getElementById( 'comic-element-w' ), null );
1993 inputH = ui.createInputText( document.getElementById( 'comic-element-h' ), null );
1994 inputPercentW = ui.createInputText( document.getElementById( 'comic-element-w-percent' ), null );
1995 inputPercentH = ui.createInputText( document.getElementById( 'comic-element-h-percent' ), null );
1996 inputAspectRatio = $( '#comic-element-keep-aspect' );
1997 delete INFOMATION_WINDOW.onFirstOpen;
1999 onResize: function( _w, _h ){
2000 jqPanelElementInformation.css( {
2004 update: function( currentElement ){
2006 if( currentLock === true && currentElement === null) return;
2008 var _elementType = currentElement === null ? -1 : currentElement.type,
2009 x = currentElement !== null ? currentElement.x : 0,
2010 y = currentElement !== null ? currentElement.y : 0,
2011 z = currentElement !== null ? currentElement.z : 0,
2012 a = _elementType === PANEL_ELEMENT_TYPE_TEXT ? Math.floor( currentElement.angle() ) : 0,
2013 w = currentElement !== null ? currentElement.w : 0,
2014 h = currentElement !== null ? currentElement.h : 0,
2015 actualW = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualW() : 1,
2016 actualH = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualH() : 1,
2017 wPercent = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( w / actualW *100 ) : 0,
2018 hPercent = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( h / actualH *100 ) : 0,
2019 keepAspect = currentElement !== null && currentElement.keepAspect === true;
2021 if( currentElementType !== _elementType ){
2022 if( _elementType !== -1 ){
2023 if( _elementType === 1 ){
2024 inputA.visible( true );
2025 inputPercentW.visible( false );
2026 inputPercentH.visible( false );
2027 inputAspectRatio.hide();
2029 inputA.visible( false );
2030 inputPercentW.visible( true );
2031 inputPercentH.visible( true );
2032 inputAspectRatio.show();
2034 currentElementType === -1 && jqPanelElementInformation.stop().css( {
2037 })[ FADE_IN_EFFECT ]();
2039 currentElementType !== -1 && jqPanelElementInformation.stop().css({
2042 })[ FADE_OUT_EFFECT ]();
2044 currentElementType = _elementType;
2046 if( currentElementType !== -1){
2050 _elementType === 1 && inputA.value( a );
2053 _elementType === 0 && inputPercentW.value( wPercent );
2054 _elementType === 0 && inputPercentH.value( hPercent );
2059 lock: function( _currentLock ){
2060 currentLock = !!_currentLock;
2061 INFOMATION_WINDOW.bodyBackOrForward( !currentLock );
2064 'infomation-window', 'Infomation', 0, 30, 200, 180, true
2068 /* ----------------------------------------
2072 var HELP_DOCUMENTS_WINDOW = ( function(){
2077 currentPageIndex = 0,
2080 onLoadFunction = null;
2082 function onAjaxStart( _pageIndex ){
2083 currentPageIndex = _pageIndex || currentPageIndex;
2084 if( onHelpLoad !== null ){
2092 onAjaxStart = new Function;
2094 var onHelpLoad = function( _xml ){
2095 var jqXML = $( _xml ),
2096 helpTitle = jqXML.find( 'pages' ).eq( 0 ).attr( 'title' ),
2097 elmNavi = document.createElement( 'div' ),
2098 elmItemOrigin = document.createElement( 'a' ),
2099 elmPages = document.createElement( 'div' ),
2100 elmPageOrigin = document.createElement( 'div' ),
2101 elmTitleOrigin = document.createElement( 'h2' ),
2103 elmNavi.className = 'sidenavi';
2104 elmItemOrigin.className = 'sidenavi-item';
2105 elmItemOrigin.href = '#';
2106 elmPages.className = 'page-contents';
2107 elmPageOrigin.className = 'page-content main';
2108 elmPageOrigin.appendChild( elmTitleOrigin);
2110 jqXML.find( 'page' ).each( function(){
2111 var xmlPage = $( this ),
2112 title = xmlPage.attr( 'title' ),
2113 content = xmlPage.text();
2115 elmItemOrigin.innerHTML = title;
2116 elmNavi.appendChild( elmItemOrigin.cloneNode( true ));
2118 elmTitleOrigin.innerHTML = title;
2120 elmPage = elmPageOrigin.cloneNode( true );
2121 elmPage.innerHTML = content;
2123 Util.cleanElement( elmPage);
2125 if( elmPage.childNodes.length > 0 ){
2126 elmPage.insertBefore( elmTitleOrigin.cloneNode( true ), elmPage.childNodes[0]);
2128 elmPage.appendChild( elmTitleOrigin.cloneNode( true ));
2130 elmPages.appendChild( elmPage );
2132 help.createOption( title, null, onSelectionClick, true );
2136 onLoadFunction = null;
2138 jqAjaxContents.removeClass( 'loading' ).append( elmNavi, elmPages );
2140 jqNaviItems = jqAjaxContents.find( 'a.' + elmItemOrigin.className ).click( onNaviClick );
2141 jqPages = jqAjaxContents.find( '.page-content' );
2142 jqPages.find( 'a' ).click( onInnerLinkClick );
2144 setTimeout( jumpPage, 0 );
2146 function onSelectionClick( _pageIndex ){
2147 HELP_DOCUMENTS_WINDOW.open();
2148 jumpPage( _pageIndex );
2150 function jumpPage( _index ){
2151 if( typeof _index === 'number' && 0 <= _index && _index < numPage && currentPageIndex !== _index ){
2152 currentPageIndex = _index;
2154 jqNaviItems.removeClass( 'current' ).eq( currentPageIndex).addClass( 'current' );
2155 jqPages.hide().eq( currentPageIndex ).show();
2157 function onNaviClick( e ){
2159 jumpPage( Util.getChildIndex( this.parentNode, this ));
2162 function onInnerLinkClick( e ){
2163 var jump = ( this.href || '' ).split( '#jump' ),
2166 jumpPage( '' + parseFloat( n ) === n ? parseFloat( n ) : -1 );
2169 return WINDOWS_CONTROL.createWindow(
2172 help = MENU_BAR_CONTROL.HELP;
2173 onLoadFunction = help.createAjaxSelection( onAjaxStart );
2174 jqAjaxContents = $( HELP_DOCUMENTS_WINDOW.elm ).find( '.window-body' ).addClass( 'loading' );
2175 delete HELP_DOCUMENTS_WINDOW.onInit;
2177 onFirstOpen: function( _w, _h ){
2178 jqAjaxContents.css( { height: _h } );
2180 delete HELP_DOCUMENTS_WINDOW.onFirstOpen;
2182 onResize: function( _w, _h ){
2183 jqAjaxContents && jqAjaxContents.css( { height: _h });
2186 null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300
2190 /* ----------------------------------------
2193 * - panelResizeListener
2195 var GRID_CONTROL = ( function(){
2197 urlBG = "url('images/grid.gif')",
2202 elmGrid = document.getElementById( 'grid' );
2203 delete GRID_CONTROL.init;
2206 delete GRID_CONTROL.open;
2211 onPanelResize: function( _panelX, _panelY ){
2212 elmGrid.style.backgroundPosition = [ _panelX % 10, 'px ', _panelY % 10, 'px' ].join( '' );
2213 elmGrid.style.height = windowH +'px';
2215 enabled: function(){
2219 $( elmGrid ).stop().css( {
2222 })[ visible === true ? 'fadeOut' : 'fadeIn' ]();
2226 if( visible === true && urlBG !== null ){
2227 elmGrid.style.backgroundImage = urlBG;
2235 /* ----------------------------------------
2236 * WHITE_GLASS_CONTROL
2237 * - panelResizeListener
2239 var WHITE_GLASS_CONTROL = ( function(){
2240 var styleTop, styleLeft, styleRight, styleBottom;
2244 styleTop = document.getElementById( 'whiteGlass-top' ).style;
2245 styleLeft = document.getElementById( 'whiteGlass-left' ).style;
2246 styleRight = document.getElementById( 'whiteGlass-right' ).style;
2247 styleBottom = document.getElementById( 'whiteGlass-bottom' ).style;
2248 delete WHITE_GLASS_CONTROL.init;
2250 onPanelResize: function( _panelX, _panelY, _panelW, _panelH ){
2253 marginTop = _panelY,
2254 marginBottom = windowH -_h -marginTop,
2256 rightWidth = windowW -_w -marginX;
2258 styleTop.height = ( marginTop < 0 ? 0 : marginTop ) + 'px';
2260 styleLeft.top = marginTop + 'px';
2261 styleLeft.width = ( marginX < 0 ? 0 : marginX ) + 'px';
2262 styleLeft.height = ( _h + marginBottom ) + 'px';
2264 styleRight.top = marginTop + 'px';
2265 styleRight.left = _w +marginX + 'px';
2266 styleRight.width = ( rightWidth < 0 ? 0 : rightWidth ) + 'px';
2267 styleRight.height = ( _h + marginBottom ) + 'px';
2269 styleBottom.top = ( _h +marginTop ) + 'px';
2270 styleBottom.left = marginX + 'px';
2271 styleBottom.width = _w + 'px';
2272 styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom ) + 'px';
2278 /* --------------------------------------------------------------------------------------------
2280 * - mouseEventListener
2282 var PanelResizerClass = function( id, isTop ){
2283 var style = document.getElementById( id ).style,
2285 RESIZER_HEIGHT = 30,
2286 x = -BORDER_WIDTH / 2,
2287 y = isTop === true ? ( -5 - RESIZER_HEIGHT - BORDER_WIDTH ) : 0,
2290 panelX, panelY, panelW, panelH,
2291 offsetY, startY, startH,
2294 function restoreState( arg ){
2295 if( arg && arg.length > 3){
2296 PANEL_CONTROL.resize( isTop, arg[ 0 ] || panelX, arg[ 1 ] || panelY, arg[ 2 ] || panelW, arg[ 3 ] || panelH );
2300 this.mousedown = function( _mouseX, _mouseY ){
2301 var _x = _mouseX -panelX,
2302 _y = _mouseY -panelY;
2303 if( _x < x || x + w < _x || _y < y || y + h < _y) return false;
2308 updateMouseCursor( 'n-resize' );
2311 this.mousemove = function( _mouseX, _mouseY ){
2312 var _x = _mouseX - panelX,
2313 _y = _mouseY - panelY;
2314 if( isDragging !== true ){
2315 if( _x < x || x + w < _x || _y < y || y + h < _y ) return false;
2316 PANEL_ELEMENT_OPERATION_MANAGER.hide();
2317 updateMouseCursor( 'pointer' );
2320 var move = _y -offsetY;
2321 if( isTop === true){
2322 if( panelH - move < MIN_PANEL_HEIGHT ){
2323 move = panelH -MIN_PANEL_HEIGHT;
2325 PANEL_CONTROL.resize( true, panelX, panelY + move, panelW, panelH - move );
2327 var _h = startH + move;
2328 if( 0 < _h && _h < windowH -panelY -RESIZER_HEIGHT -5 -BORDER_WIDTH ){
2329 PANEL_CONTROL.resize( false, panelX, panelY, panelW, _h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : _h );
2335 this.mouseup = function( _mouseX, _mouseY ){
2336 if( isDragging !== true ) return;
2337 ( startY !== panelY || startH !== panelH ) && HISTORY_CONTROL.saveState( restoreState, [ NaN, startY, NaN, startH], [ NaN, panelY, NaN, panelH ] );
2339 updateMouseCursor( '');
2341 this.busy = function(){
2344 this.onPanelResize = function( _x, _y, _w, _h ){
2347 if( panelW !== _w ){
2348 style.width = ( _w + 2 ) + 'px';
2352 y = isTop === true ? y : ( panelH + 5 + BORDER_WIDTH );
2356 var PANEL_RESIZER_TOP,
2357 PANEL_RESIZER_BOTTOM;
2359 /* ----------------------------------------
2362 * - mouseEventListener
2364 * panel-border の表示と onPanelResize の通知.
2368 var PANEL_CONTROL = ( function(){
2369 var elmPanel, stylePanel,
2370 DEFAULT_PANEL_WIDTH = 400,
2371 DEFAULT_PANEL_HEIGHT = 300,
2373 offsetX, offsetY, startX, startY,
2375 isDraggable = false;
2377 app.addKeyEventListener( 'keychange', onSpaceUpdate, 32, false, false );
2379 function onSpaceUpdate( e ){
2380 if( e.type === 'keyup' ){
2381 currentListener === null && updateMouseCursor( '' );
2382 isDraggable = false;
2384 currentListener === null && updateMouseCursor( 'move' );
2396 elmPanel = document.getElementById( 'panel-tools-container' );
2397 stylePanel = elmPanel.style;
2399 PANEL_RESIZER_TOP = new PanelResizerClass( 'panel-resizer-top', true );
2400 PANEL_RESIZER_BOTTOM = new PanelResizerClass( 'panel-resizer-bottom', false );
2401 PanelResizerClass = null;
2403 delete PANEL_CONTROL.init;
2405 open: function( _panelW, _panelH, _borderSize ){
2406 PANEL_CONTROL.w = Type.isFinite( _panelW ) === true ? _panelW : DEFAULT_PANEL_WIDTH;
2407 PANEL_CONTROL.h = Type.isFinite( _panelH ) === true ? _panelH : DEFAULT_PANEL_HEIGHT;
2408 borderSize = Type.isFinite( _borderSize ) === true ? _borderSize : borderSize;
2410 delete PANEL_CONTROL.open;
2415 resize: function( isResizerTopAction, _x, _y, _w, _h ){
2416 PANEL_CONTROL.x = _x = _x !== undefined ? _x : PANEL_CONTROL.x;
2417 PANEL_CONTROL.y = _y = _y !== undefined ? _y : PANEL_CONTROL.y;
2418 PANEL_CONTROL.w = _w = _w !== undefined ? _w : PANEL_CONTROL.w;
2419 PANEL_CONTROL.h = _h = _h !== undefined ? _h : PANEL_CONTROL.h;
2421 stylePanel.left = ( _x - borderSize ) + 'px';
2422 stylePanel.top = ( _y - borderSize ) + 'px';
2423 stylePanel.width = _w + 'px';
2424 stylePanel.height = _h + 'px';
2426 PANEL_RESIZER_TOP.onPanelResize( _x, _y, _w, _h );
2427 PANEL_RESIZER_BOTTOM.onPanelResize( _x, _y, _w, _h );
2428 GRID_CONTROL.onPanelResize( _x, _y );
2429 WHITE_GLASS_CONTROL.onPanelResize( _x, _y, _w, _h );
2430 PANEL_ELEMENT_CONTROL.onPanelResize( _x, _y, _w, _h, isResizerTopAction === true );
2432 onWindowResize: function( _windowW, _windowH ){
2433 PANEL_CONTROL.x = Math.floor( ( _windowW - PANEL_CONTROL.w ) / 2 );
2434 PANEL_CONTROL.y = Math.floor( ( _windowH - PANEL_CONTROL.h ) / 2 );
2435 PANEL_CONTROL.resize();
2437 mousemove: function( _mouseX, _mouseY ){
2438 if( isDraggable === true && isDragging === true ){
2439 PANEL_CONTROL.resize( false, startX + _mouseX - offsetX, startY + _mouseY - offsetY );
2442 mouseup: function( _mouseX, _mouseY ){
2443 if( isDraggable === true ){
2445 updateMouseCursor( '' );
2448 mousedown: function( _mouseX, _mouseY ){
2449 if( isDraggable === true ){
2452 startX = PANEL_CONTROL.x;
2453 startY = PANEL_CONTROL.y;
2455 updateMouseCursor( 'move' );
2460 return isDragging === true;
2466 /* --------------------------------------------------------------------------------------------
2469 var CONSOLE_CONTROLER = ( function(){
2470 var LAYER_BACK_BUTTON, LAYER_FORWARD_BUTTON, DELETE_BUTTON, EDIT_BUTTON, CHANGE_BUTTON,
2471 elmConsoleWrapper, styleConsoleWrapper,
2473 styleImgConsole, styleTextConsole,
2474 currentElement = null,
2477 imgConsoleWidth, imgConsoleHeight,
2478 textConsoleWidth, textConsoleHeight,
2480 buttonClickable = false;
2482 function buttonBackOrForward( isBack ){
2483 var offset = Util.getAbsolutePosition( elmConsoleWrapper );
2484 styleConsoleWrapper.position = isBack === true ? '' : 'absolute';
2485 styleConsoleWrapper.left = ( isBack === true ? CONSOLE_CONTROLER.x : offset.x ) + 'px';
2486 styleConsoleWrapper.top = ( isBack === true ? CONSOLE_CONTROLER.y : offset.y ) + 'px';
2487 buttonClickable === isBack && ( isBack === true ? elmConsoleParent : app.rootElement ).appendChild( elmConsoleWrapper );
2488 buttonClickable = !isBack;
2490 function layerBack(){
2491 if( currentElement === null) return;
2492 if( PANEL_ELEMENT_CONTROL.replace( currentElement, false) === false ) return;
2493 INFOMATION_WINDOW.update( currentElement );
2494 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restoreReplace, [ currentElement, true ], [ currentElement, false ]);
2495 var _z = currentElement.z;
2496 LAYER_BACK_BUTTON.visible( _z > 0 );
2497 LAYER_FORWARD_BUTTON.visible( _z < PANEL_ELEMENT_ARRAY.length -1 );
2499 function layerForward(){
2500 if( currentElement === null) return;
2501 if( PANEL_ELEMENT_CONTROL.replace( currentElement, true) === false) return;
2502 INFOMATION_WINDOW.update( currentElement);
2503 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restoreReplace, [ currentElement, false], [ currentElement, true]);
2504 var _z = currentElement.z;
2505 LAYER_BACK_BUTTON.visible( _z > 0);
2506 LAYER_FORWARD_BUTTON.visible( _z < PANEL_ELEMENT_ARRAY.length -1);
2509 if( currentElement === null) return;
2510 buttonBackOrForward( true);
2511 PANEL_ELEMENT_CONTROL.remove( currentElement);
2512 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ true, currentElement], [ false, currentElement], true);
2513 PANEL_ELEMENT_OPERATION_MANAGER.hide();
2516 if( currentElement === null || currentElement.type !== PANEL_ELEMENT_TYPE_TEXT) return;
2517 TextEditor.boot( PANEL_CONTROL.x, PANEL_CONTROL.y, currentElement );
2518 buttonBackOrForward( true );
2521 if( currentElement === null) return;
2522 buttonBackOrForward( true);
2523 PremiumSatge.boot( currentElement.getArtistID(), currentElement.resourcePicture );
2525 function onImageSelect( resourcePicture ){
2526 currentElement.resourcePicture( resourcePicture );
2534 app.addKeyEventListener( 'keydown', layerBack, 66, false, true );
2535 app.addKeyEventListener( 'keydown', layerForward, 70, false, true );
2536 app.addKeyEventListener( 'keydown', del, 68, false, true );
2537 app.addKeyEventListener( 'keydown', edit, 69, false, true );
2538 app.addKeyEventListener( 'keydown', change, 85, false, true );
2540 var elmImgConsole = document.getElementById( 'image-element-consol' ),
2541 imgConsoleSize = Util.getElementSize( elmImgConsole );
2542 imgConsoleWidth = imgConsoleSize.width;
2543 imgConsoleHeight = imgConsoleSize.height;
2544 styleImgConsole = elmImgConsole.style;
2545 elmImgConsole.style.display = 'none';
2547 var elmTextConsole = document.getElementById( 'text-element-consol' ),
2548 textConsoleSize = Util.getElementSize( elmTextConsole );
2549 textConsoleWidth = textConsoleSize.width;
2550 textConsoleHeight = textConsoleSize.height;
2551 styleTextConsole = elmTextConsole.style;
2552 styleTextConsole.display = 'none';
2554 elmConsoleWrapper = document.getElementById( 'comic-element-consol-wrapper' );
2555 styleConsoleWrapper = elmConsoleWrapper.style;
2556 elmConsoleParent = elmConsoleWrapper.parentNode;
2557 styleConsoleWrapper.display = 'none';
2559 app.addMouseEventListener( document.getElementById( 'edit-text-button' ), 'click', edit );
2560 app.addMouseEventListener( document.getElementById( 'delete-image-button' ), 'click', del );
2561 app.addMouseEventListener( document.getElementById( 'delete-text-button' ), 'click', del );
2562 app.addMouseEventListener( document.getElementById( 'change-image-button' ), 'click', change );
2563 app.addMouseEventListener( document.getElementById( 'layer-forward-button' ), 'click', layerForward );
2564 app.addMouseEventListener( document.getElementById( 'forward-text-button' ), 'click', layerForward );
2565 app.addMouseEventListener( document.getElementById( 'layer-back-button' ), 'click', layerBack );
2566 app.addMouseEventListener( document.getElementById( 'back-text-button' ), 'click', layerBack );
2568 delete CONSOLE_CONTROLER.init;
2571 LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'layer back', 'ctrl + B', layerBack, false, true, false );
2572 LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'layer forward', 'ctrl + F', layerForward, false, false, false );
2573 DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'delete', 'ctrl + D', del, false, true, true );
2574 EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'Edit Text', 'ctrl + E', edit, false, true, false );
2575 CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'change', 'ctrl + U', change, false, false, true );
2577 delete CONSOLE_CONTROLER.open;
2579 show: function( _currentElement, _w, _h ){
2580 if( visible === false ) styleConsoleWrapper.display = '';
2582 currentElement = _currentElement;
2583 var _currentType = _currentElement.type,
2584 _z = _currentElement.z;
2585 if( currentType !== _currentType ){
2586 currentType = _currentType;
2587 styleImgConsole.display = _currentType === PANEL_ELEMENT_TYPE_IMAGE ? '' : 'none';
2588 styleTextConsole.display = _currentType === PANEL_ELEMENT_TYPE_TEXT ? '' : 'none';
2589 CONSOLE_CONTROLER.w = _currentType === PANEL_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth;
2590 CONSOLE_CONTROLER.h = _currentType === PANEL_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight;
2592 CONSOLE_CONTROLER.x = Math.floor( ( _w - CONSOLE_CONTROLER.w ) / 2 );
2594 LAYER_BACK_BUTTON.visible( _z > 0 );
2595 LAYER_FORWARD_BUTTON.visible( _z < PANEL_ELEMENT_ARRAY.length - 1 );
2596 DELETE_BUTTON.visible( true);
2597 EDIT_BUTTON.visible( _currentType === PANEL_ELEMENT_TYPE_TEXT );
2598 CHANGE_BUTTON.visible( false);
2600 if( _w > CONSOLE_CONTROLER.w * 1.5 && _h > CONSOLE_CONTROLER.h * 1.5 ){
2601 CONSOLE_CONTROLER.y = Math.floor( ( _h - CONSOLE_CONTROLER.h ) / 2 );
2602 elmConsoleWrapper.className = '';
2604 CONSOLE_CONTROLER.y = _h + tailSize;
2605 elmConsoleWrapper.className = 'console-out';
2607 styleConsoleWrapper.left = CONSOLE_CONTROLER.x + 'px';
2608 styleConsoleWrapper.top = CONSOLE_CONTROLER.y + 'px';
2611 if( visible === true ) styleConsoleWrapper.display = 'none';
2613 currentElement = null;
2614 LAYER_BACK_BUTTON.visible( false);
2615 LAYER_FORWARD_BUTTON.visible( false);
2616 DELETE_BUTTON.visible( false);
2617 EDIT_BUTTON.visible( false);
2618 CHANGE_BUTTON.visible( false);
2620 mousemove: function( _mouseX, _mouseY ){
2621 if( CONSOLE_CONTROLER.x > _mouseX || CONSOLE_CONTROLER.y > _mouseY || CONSOLE_CONTROLER.x + CONSOLE_CONTROLER.w < _mouseX || CONSOLE_CONTROLER.y + CONSOLE_CONTROLER.h < _mouseY ){
2622 buttonClickable === true && buttonBackOrForward( true );
2625 buttonClickable === false && buttonBackOrForward( false );
2631 /* --------------------------------------------------------------------------------------------
2633 * - panelElementOperator
2635 var TAIL_OPERATOR = ( function(){
2642 DEG_TO_RAD = Math.PI / 180,
2643 RAD_TO_DEG = 1 / DEG_TO_RAD,
2647 balloonW, balloonH, balloonA, radA,
2653 var elm = document.getElementById( 'balloon-tail-mover' );
2654 SIZE = Util.getElementSize( elm ).width;
2655 styleMover = elm.style;
2656 delete TAIL_OPERATOR.init;
2658 update: function ( _w, _h, _a ){
2659 balloonW = _w !== undefined ? _w : balloonW;
2660 balloonH = _h !== undefined ? _h : balloonH;
2661 balloonA = _a !== undefined ? _a : balloonA;
2662 radA = ( balloonA - 90 ) * DEG_TO_RAD;
2663 tailX = FLOOR( ( ( COS( radA ) / 2 + 0.5 ) * ( balloonW + SIZE )) - SIZE / 2 );
2664 tailY = FLOOR( ( ( SIN( radA ) / 2 + 0.5 ) * ( balloonH + SIZE )) - SIZE / 2 );
2665 styleMover.left = tailX +'px';
2666 styleMover.top = tailY +'px';
2667 //log.html( [ balloonW, balloonH, balloonA].join());
2669 show: function( _currentText ){
2671 * visibilityのほうがいい, display:none だと ie で描画が狂う
2673 styleMover.visibility = '';
2674 TAIL_OPERATOR.update( _currentText.w, _currentText.h, _currentText.angle() );
2675 currentText = _currentText;
2677 hitTest: function( _mouseX, _mouseY ){
2678 var _x = tailX -SIZE / 2,
2679 _y = tailY -SIZE / 2;
2680 ret = _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY;
2681 ret === true && updateMouseCursor( 'move' );
2685 styleMover.visibility = 'hidden';
2688 onStart: function( _currentText, _mouseX, _mouseY ){
2689 if( _currentText.type !== PANEL_ELEMENT_TYPE_TEXT ) return false;
2692 if( TAIL_OPERATOR.hitTest( _mouseX -x, _mouseY -y ) === true){
2695 currentText = _currentText;
2696 startA = _currentText.angle();
2701 onDrag: function( _mouseX, _mouseY ){
2702 _mouseX = _mouseX - x - w / 2;
2703 _mouseY = _mouseY - y - h / 2; //Balloonの中心を0,0とする座標系に変換
2704 TAIL_OPERATOR.update( w, h,
2706 ATAN( _mouseY / _mouseX ) * RAD_TO_DEG + ( _mouseX > 0 ? 90 : 270 ) :
2707 _mouseY > 0 ? 180 : 0
2709 currentText && currentText.angle( FLOOR( balloonA + 0.5 ));
2710 INFOMATION_WINDOW.update( currentText );
2712 onFinish: function(){
2713 startA !== currentText.angle() && PANEL_ELEMENT_OPERATION_MANAGER.saveStatus( x, y, w, h, startA );
2714 startA !== currentText.angle() && PANEL_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, currentText.angle() );
2717 onCancel: function(){
2718 currentText.angle( startA);
2719 PANEL_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, startA );
2725 /* --------------------------------------------------------------------------------------------
2727 * - panelElementOperator
2729 var RESIZE_OPERATOR = ( function(){
2730 var HIT_AREA = MOUSE_HIT_AREA,
2731 POSITION_ARRAY = [],
2734 { cursor: 'n-resize', v: 3 },
2735 { cursor: 'e-resize', h: 2 },
2736 { cursor: 'e-resize', h: 1 },
2737 { cursor: 'n-resize', v: 0 },
2738 { cursor: 'nw-resize', h: 5, v: 6, vh: 7 },
2739 { cursor: 'ne-resize', h: 4, v: 7, vh: 6 },
2740 { cursor: 'ne-resize', h: 7, v: 4, vh: 5 },
2741 { cursor: 'nw-resize', h: 6, v: 5, vh: 4 }
2743 elmResizerContainer,
2744 elmResizerContainerStyle,
2746 elmResizerLeftStyle,
2747 elmResizerRightStyle,
2748 elmResizerBottomStyle,
2752 currentIsTextElement = false;
2754 var RESIZE_WORK_ARRAY = [
2755 { x: 0, w: 0, y: 1, h: -1}, //top
2756 { x: 1, w: -1, y: 0, h: 0}, //left
2757 { x: 0, w: 1, y: 0, h: 0}, //right
2758 { x: 0, w: 0, y: 0, h: 1}, //bottom
2759 { x: 1, w: -1, y: 1, h: -1}, //top-left
2760 { x: 0, w: 1, y: 1, h: -1}, //top-right
2761 { x: 1, w: -1, y: 0, h: 1}, //bottom-left
2762 { x: 0, w: 1, y: 0, h: 1} //bottom-right
2764 startX, startY, startW, startH, startFilpV, startFilpH, startAspect,
2765 baseX, baseY, baseW, baseH,
2766 currentX, currentY, currentW, currentH,
2771 function draw( _x, _y, _w, _h ){
2772 x = _x = _x !== undefined ? _x : x;
2773 y = _y = _y !== undefined ? _y : y;
2774 w = _w = _w !== undefined ? _w : w;
2775 h = _h = _h !== undefined ? _h : h;
2777 elmResizerContainerStyle.left = _x + 'px';
2778 elmResizerContainerStyle.top = _y + 'px';
2779 elmResizerContainerStyle.width = _w + 'px';
2780 elmResizerContainerStyle.height = _h + 'px';
2781 elmResizerTopStyle.left = elmResizerBottomStyle.left = FLOOR( _w / 2 - 5 ) + 'px';
2782 elmResizerLeftStyle.top = elmResizerRightStyle.top = FLOOR( _h / 2 - 5 ) + 'px';
2784 alert( [x, y, w, h].join( ','));
2788 POSITION_ARRAY.splice( 0, POSITION_ARRAY.length );
2789 POSITION_ARRAY.push(
2790 {x: _x +5, y: _y -HIT_AREA, w: _w -5 *2, h: HIT_AREA +5},
2791 {x: _x -HIT_AREA, y: _y +HIT_AREA +5, w: HIT_AREA +5, h: _h -5 *2},
2792 {x: _x + _w -5, y: _y +HIT_AREA +5, w: HIT_AREA +5, h: _h -5 *2},
2793 {x: _x +5, y: _y +_h -5, w: _w -5 *2, h: HIT_AREA +5},
2794 {x: _x -HIT_AREA, y: _y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5},
2795 {x: _x + _w -HIT_AREA, y: _y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5},
2796 {x: _x -HIT_AREA, y: _y +_h -5, w: HIT_AREA +5, h: HIT_AREA +5},
2797 {x: _x +_w -5, y: _y +_h -5, w: HIT_AREA +5, h: HIT_AREA +5}
2801 function update( _x, _y, _w, _h ){
2803 _x = _x !== undefined ? _x : currentX;
2804 _y = _y !== undefined ? _y : currentY;
2805 _w = _w !== undefined ? _w : currentW;
2806 _h = _h !== undefined ? _h : currentH;
2808 if( currentIsTextElement === false && currentIndex > 3 && app.shiftEnabled() === true){
2809 if( startAspect >= 1 ){
2811 _w = FLOOR( startAspect * _h );
2812 _x = _x +( currentIndex % 2 === 0 ? __w - _w : 0);
2815 _h = FLOOR( _w / startAspect );
2816 _y = _y + ( currentIndex <= 5 ? __h - _h : 0);
2819 draw( x = _x, y = _y, w = _w, h = _h );
2820 currentElement.resize( _x, _y, _w, _h );
2821 currentIsTextElement === true && TAIL_OPERATOR.update( _w, _h );
2822 CONSOLE_CONTROLER.show( currentElement, _w, _h );
2823 INFOMATION_WINDOW.update( currentElement);
2826 function flip( _flipH, _flipV ){
2827 var p = CURSOR_AND_FLIP[ currentIndex ];
2828 currentIndex = _flipH === true || _flipV === true ? p[
2829 _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v' )
2831 updateMouseCursor( CURSOR_AND_FLIP[ currentIndex ].cursor );
2832 elmResizerContainer.className = 'current-resizer-is-' + currentIndex;
2833 currentElement.flip( _flipH, _flipV );
2837 elmResizerContainer = document.getElementById( 'comic-element-resizer-container');
2838 elmResizerContainerStyle = elmResizerContainer.style;
2839 elmResizerContainerStyle.display = 'none';
2841 elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style;
2842 elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style;
2843 elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style;
2844 elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style;
2846 delete RESIZE_OPERATOR.init;
2849 index: function( _mouseX, _mouseY ){
2851 for( i=4; i<8; i++ ){
2852 p = POSITION_ARRAY[ i ];
2853 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY ){
2854 updateMouseCursor( CURSOR_AND_FLIP[ i].cursor);
2855 elmResizerContainer.className = 'current-resizer-is-' +i;
2856 return currentIndex = i;
2859 for( i=0; i<4; i++ ){
2860 p = POSITION_ARRAY[ i ];
2861 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){
2862 updateMouseCursor( CURSOR_AND_FLIP[ i].cursor);
2863 elmResizerContainer.className = 'current-resizer-is-' +i;
2864 return currentIndex = i;
2867 updateMouseCursor( '' );
2868 elmResizerContainer.className = '';
2871 show: function( _currentElement ){
2872 currentElement = _currentElement;
2873 currentIsTextElement = _currentElement.type === PANEL_ELEMENT_TYPE_TEXT;
2874 elmResizerContainerStyle.display = '';
2877 currentElement = null;
2878 elmResizerContainerStyle.display = 'none';
2880 onStart: function( _currentElement, _mouseX, _mouseY ){
2881 currentElement = _currentElement;
2882 currentIsTextElement = _currentElement.type === PANEL_ELEMENT_TYPE_TEXT;
2883 if( _currentElement.keepSize === true) return false;
2884 currentIndex = this.index( _mouseX, _mouseY);
2885 if( currentIndex === -1) return false;
2888 startX = baseX = _currentElement.x;
2889 startY = baseY = _currentElement.y;
2890 startW = baseW = _currentElement.w;
2891 startH = baseH = _currentElement.h;
2892 if( _currentElement.type === PANEL_ELEMENT_TYPE_IMAGE){
2893 startFilpV = _currentElement.flipV();
2894 startFilpH = _currentElement.flipH();
2896 startAspect = startW /startH;
2899 onDrag: function( _mouseX, _mouseY ){
2900 var com = RESIZE_WORK_ARRAY[ currentIndex],
2901 moveX = _mouseX -offsetX,
2902 moveY = _mouseY -offsetY,
2903 _updated = moveX !== 0 || moveY !== 0,
2912 * Opera 11+ often forget values, why ??
2914 while( _x === undefined || _y === undefined || _w === undefined || _h === undefined){
2915 _x = _x !== undefined ? _x : baseX +moveX *com.x;
2916 _y = _y !== undefined ? _y : baseY +moveY *com.y;
2917 _w = _w !== undefined ? _w : baseW +moveX *com.w;
2918 _h = _h !== undefined ? _h : baseH +moveY *com.h;
2919 error += _thisError === 0 ? 0 : 1;
2921 if( _thisError > 9999){
2923 //alert( 'opera error' +error);
2929 if( _w >= MIN_ELEMENT_SIZE && _h >= MIN_ELEMENT_SIZE){
2932 if( _w >= -MIN_ELEMENT_SIZE && _h >= -MIN_ELEMENT_SIZE){
2934 if( _w < MIN_ELEMENT_SIZE){
2935 //_x += Math.abs( MIN_ELEMENT_SIZE -_w);
2937 _w = MIN_ELEMENT_SIZE;
2939 if( _h < MIN_ELEMENT_SIZE){
2940 //_y += Math.abs( MIN_ELEMENT_SIZE -_h);
2942 _h = MIN_ELEMENT_SIZE;
2945 if( currentElement.type === PANEL_ELEMENT_TYPE_TEXT){
2948 if( _w < -MIN_ELEMENT_SIZE || _h < -MIN_ELEMENT_SIZE){
2950 if( _w < -MIN_ELEMENT_SIZE && _h > MIN_ELEMENT_SIZE){
2953 baseX = _x = _x +_w;
2955 baseW = _w = _memoryX -_x;
2958 flipV = currentElement.flipV();
2960 if( _w > MIN_ELEMENT_SIZE && _h < -MIN_ELEMENT_SIZE){
2964 baseY = _y = _y +_h;
2966 baseH = _h = _memoryY -_y;
2968 flipH = currentElement.flipH();
2973 baseX = _x = _x +_w;
2974 baseY = _y = _y +_h;
2975 baseW = _w = _memoryX -_x;
2976 baseH = _h = _memoryY -_y;
2978 flipV = currentElement.flipV();
2979 flipH = currentElement.flipH();
2989 _updated === true && update( _x, _y, _w, _h );
2992 'currentIndex:', currentIndex,
2993 'baseW', baseW, 'baseH', baseH,'<br>',
2994 'mouse', _mouseX, _mouseY,'<br>',
2995 'move', moveX, moveY,'<br>',
2996 'xy', _x, _y, 'wh',_w, _h,'<br>',
2997 'com.w', com.w, 'com.h', com.h,'<br>',
2998 'current',currentW, currentH,'<br>',
3003 onFinish: function(){
3004 updateMouseCursor( '');
3005 if( w === startW && h === startH && x === startX && y === startY) return;
3006 PANEL_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h);
3007 currentElement.resize( x, y, w, h);
3008 PANEL_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY, startW, startH, undefined, startFilpV, startFilpH);
3010 onCancel: function(){
3011 updateMouseCursor( '');
3012 PANEL_ELEMENT_OPERATION_MANAGER.resize( startX, startY, startW, startH);
3013 currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ?
3014 currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) :
3015 currentElement.animate( startX, startY, startW, startH, angle);
3017 lock: function( _lock ){
3018 if( _lock !== undefined){
3019 elmResizerContainerStyle.borderColor = _lock === true ? 'blue' : '';
3024 onShiftUpdate: update,
3025 onCtrlUpdate: update
3029 /* --------------------------------------------------------------------------------------------
3031 * - panelElementOperator
3033 var POSITION_OPERATOR = ( function(){
3039 function update( _x, _y ){
3040 x = _x !== undefined ? _x : x;
3041 y = _y !== undefined ? _y : y;
3042 RESIZE_OPERATOR.update( x, y );
3043 currentElement.resize( x, y );
3044 INFOMATION_WINDOW.update( currentElement );
3048 delete POSITION_OPERATOR.init;
3050 onStart: function( _currentElement, _mouseX, _mouseY ){
3051 currentElement = _currentElement;
3054 startX = x = _currentElement.x;
3055 startY = y = _currentElement.y;
3056 updateMouseCursor( 'move' );
3058 onDrag: function( _mouseX, _mouseY ){
3059 var moveX = _mouseX - offsetX,
3060 moveY = _mouseY - offsetY,
3061 _x = startX + moveX,
3062 _y = startY + moveY;
3063 if( GRID_CONTROL.enabled() === true ){
3064 _x = Math.floor( _x / 10 ) * 10;
3065 _y = Math.floor( _y / 10 ) * 10;
3069 onFinish: function(){
3070 updateMouseCursor( '' );
3071 if( x === startX && y === startY ) return;
3072 PANEL_ELEMENT_OPERATION_MANAGER.resize( x, y );
3073 currentElement.resize( x, y );
3074 PANEL_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY );
3076 onCancel: function(){
3077 updateMouseCursor( '' );
3078 PANEL_ELEMENT_OPERATION_MANAGER.resize( startX, startY );
3079 currentElement.animate( startX, startY );
3081 onShiftUpdate: update,
3082 onCtrlUpdate: update
3087 /* --------------------------------------------------------------------------------------------
3088 * PANEL_ELEMENT_OPERATION_MANAGER
3090 var PANEL_ELEMENT_OPERATION_MANAGER = ( function(){
3091 var HIT_AREA = MOUSE_HIT_AREA,
3092 currentIsTextElement = false,
3093 currentOperator = null,
3094 currentElement = null,
3095 currentX, currentY, currentW, currentH, angle, flipV, flipH;
3097 function resize( _x, _y, _w, _h, _angle ){
3098 currentX = _x = _x !== undefined ? _x : currentX;
3099 currentY = _y = _y !== undefined ? _y : currentY;
3100 currentW = _w = _w !== undefined ? _w : currentW;
3101 currentH = _h = _h !== undefined ? _h : currentH;
3102 angle = _angle = _angle !== undefined ? _angle : angle;
3104 RESIZE_OPERATOR.update( _x, _y, _w, _h );
3105 currentIsTextElement === true && TAIL_OPERATOR.update( _w, _h, angle );
3106 CONSOLE_CONTROLER.show( currentElement, _w, _h );
3107 INFOMATION_WINDOW.update( currentElement );
3109 function show( _currentElement ){
3110 currentElement === null && RESIZE_OPERATOR.show( _currentElement );
3111 if( currentElement !== _currentElement ){
3112 currentElement = _currentElement;
3114 currentIsTextElement = ( _currentElement.type === PANEL_ELEMENT_TYPE_TEXT );
3115 currentIsTextElement === true ? TAIL_OPERATOR.show( _currentElement ) : TAIL_OPERATOR.hide();
3117 flipV = currentIsTextElement === false ? _currentElement.flipV() : 0;
3118 flipH = currentIsTextElement === false ? _currentElement.flipH() : 0;
3121 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,
3122 currentIsTextElement === true ? _currentElement.angle() : 0
3129 TAIL_OPERATOR.init();
3130 RESIZE_OPERATOR.init();
3131 POSITION_OPERATOR.init();
3133 app.addKeyEventListener( 'keychange', function( e ){
3134 currentOperator !== null && currentOperator.onShiftUpdate && currentOperator.onShiftUpdate();
3137 app.addKeyEventListener( 'keychange', function( e ){
3138 currentOperator !== null && currentOperator.onCtrlUpdate && currentOperator.onCtrlUpdate();
3141 app.addKeyEventListener( 'keydown', function( e ){
3142 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();
3143 currentOperator = null;
3145 }, 27, false, false );
3147 delete PANEL_ELEMENT_OPERATION_MANAGER.init;
3150 PANEL_ELEMENT_OPERATION_MANAGER.hide();
3152 delete PANEL_ELEMENT_OPERATION_MANAGER.open;
3158 currentElement !== null && RESIZE_OPERATOR.hide();
3159 currentElement = null;
3160 updateMouseCursor( '' );
3161 TAIL_OPERATOR.hide();
3162 CONSOLE_CONTROLER.hide();
3163 INFOMATION_WINDOW.update( null );
3166 restoreState: function( arg ){
3167 if( arg && arg.length !== 8 ) return;
3168 var _currentElement = arg[ 0 ],
3169 _x = arg[ 1 ], _y = arg[ 2 ], _w = arg[ 3 ], _h = arg[ 4 ],
3171 _flipV = arg[ 6 ], _flipH = arg[ 7 ];
3172 if( !_currentElement && !currentOperator ) return;
3173 _currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ?
3174 _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH ) :
3175 _currentElement.animate( _x, _y, _w, _h, _a );
3176 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();
3177 currentOperator = null;
3178 currentElement === _currentElement ? resize( _x, _y, _w, _h, _a ) : show( _currentElement );
3180 saveStatus: function( startX, startY, startW, startH, startA, startFilpV, startFilpH ){
3181 startX = startX !== undefined ? startX : currentX;
3182 startY = startY !== undefined ? startY : currentY;
3183 startW = startW !== undefined ? startW : currentW;
3184 startH = startH !== undefined ? startH : currentH;
3185 startA = startA !== undefined ? startA : angle;
3186 startFilpV = startFilpV !== undefined ? startFilpV : flipV;
3187 startFilpH = startFilpH !== undefined ? startFilpH : flipH;
3188 currentElement && HISTORY_CONTROL.saveState( PANEL_ELEMENT_OPERATION_MANAGER.restoreState,
3189 [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH],
3190 [ currentElement, currentX, currentY, currentW, currentH, angle, flipV, flipH]
3194 return currentOperator !== null;
3196 hitTest: function( _mouseX, _mouseY, _panelElement ){
3198 if( _panelElement === currentElement ){
3199 var _consoleX = CONSOLE_CONTROLER.x;
3200 _x = currentX +( _consoleX < 0 ? _consoleX : 0 ) - HIT_AREA;
3201 _y = currentY - HIT_AREA;
3202 var _consoleW = CONSOLE_CONTROLER.w;
3203 _w = ( _consoleW < currentW ? currentW : _consoleW ) + HIT_AREA * 2;
3204 var _consoleY = CONSOLE_CONTROLER.y;
3205 _h = ( _consoleY < currentH ? currentH : _consoleY + CONSOLE_CONTROLER.h ) + HIT_AREA * 2;
3207 _x = _panelElement.x - HIT_AREA;
3208 _y = _panelElement.y - HIT_AREA;
3209 _w = _panelElement.w + HIT_AREA *2;
3210 _h = _panelElement.h + HIT_AREA *2;
3212 return _x <= _mouseX && _mouseX <= _x + _w && _y <= _mouseY && _mouseY <= _y + _h;
3214 mousedown: function( _currentElement, _mouseX, _mouseY ){
3215 //show( _currentElement);
3216 if( currentIsTextElement === true && TAIL_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){
3217 currentOperator = TAIL_OPERATOR;
3219 if( RESIZE_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){
3220 currentOperator = RESIZE_OPERATOR;
3222 POSITION_OPERATOR.onStart( _currentElement, _mouseX, _mouseY)
3223 currentOperator = POSITION_OPERATOR;
3226 mousemove: function( _currentElement, _mouseX, _mouseY ){
3227 show( _currentElement);
3228 if( currentOperator !== null){
3229 currentOperator.onDrag( _mouseX, _mouseY );
3231 if( currentElement !== null){
3232 CONSOLE_CONTROLER.mousemove( _mouseX - currentX, _mouseY - currentY );
3233 if( currentIsTextElement === false || TAIL_OPERATOR.hitTest( _mouseX -currentX, _mouseY -currentY) === false){
3234 RESIZE_OPERATOR.index( _mouseX, _mouseY);
3238 mouseup: function( _currentElement, _mouseX, _mouseY ){
3239 currentOperator !== null && currentOperator.onFinish();
3240 currentOperator = null;
3245 * // PANEL_ELEMENT_OPERATION_MANAGER
3248 var AbstractPanelElement = function( COMIC_ELM_TYPE ){
3249 this.type = COMIC_ELM_TYPE;
3250 this.hitTest = function( _mouseX, _mouseY ){
3251 return PANEL_ELEMENT_OPERATION_MANAGER.hitTest( _mouseX, _mouseY, this );
3253 this.shift = function( _shiftX, _shiftY ){
3254 this.resize( this.x + _shiftX, this.y + _shiftY);
3256 this.busy = function(){
3257 return PANEL_ELEMENT_OPERATION_MANAGER.busy();
3259 this.mousemove = function( _mouseX, _mouseY ){
3260 PANEL_ELEMENT_OPERATION_MANAGER.mousemove( this, _mouseX, _mouseY );
3262 this.mouseup = function( _mouseX, _mouseY ){
3263 PANEL_ELEMENT_OPERATION_MANAGER.mouseup( this, _mouseX, _mouseY );
3265 this.mousedown = function( _mouseX, _mouseY ){
3266 PANEL_ELEMENT_OPERATION_MANAGER.mousedown( this, _mouseX, _mouseY );
3270 /* --------------------------------------------------------------------------------------------
3273 var jqImageElementOrigin;
3274 var ImageElementClass = function( data ){
3275 jqImageElementOrigin = jqImageElementOrigin || $( app.fetchHTMLElement( 'imgElementTemplete' ) );
3277 var jqWrap = jqImageElementOrigin.clone( true ),
3278 flipH = data.width < 0 ? -1 : 1,
3279 flipV = data.height < 0 ? -1 : 1,
3280 resourcePicture = data.resource_picture,
3281 actualW = data.resource_picture.width,
3282 actualH = data.resource_picture.height,
3283 reversibleImage = null,
3286 function flipReversibleImage(){
3287 reversibleImage && reversibleImage.resize( flipH * w, flipV * h );
3289 function updateResourcePicture( _resourcePicture ){
3290 resourcePicture = _resourcePicture;
3292 actualW = _resourcePicture.width;
3293 actualH = _resourcePicture.height;
3295 var _reversibleImage = pettanr.image.createReversibleImage(
3296 [ pettanr.CONST.RESOURCE_PICTURE_PATH, _resourcePicture.id, '.', _resourcePicture.ext ].join(''),
3297 flipH * w, flipV * h
3299 if( reversibleImage !== null ){
3300 jqWrap.children( reversibleImage.elm ).replaceWith( _reversibleImage.elm );
3301 reversibleImage.destroy();
3303 jqWrap.append( _reversibleImage.elm );
3305 reversibleImage = _reversibleImage;
3307 /* global methods */
3314 this.timing = data.t || PANEL_ELEMENT_ARRAY.length + 1;
3315 this.keepSize = false;
3316 this.init = function(){
3317 updateResourcePicture( data.resource_picture );
3318 self.resize( data.x, data.y, Math.abs( data.width ), Math.abs( data.height ) );
3321 this.flip = function( _updateH, _updateV ){
3322 if( _updateH !== true && _updateV !== true ) return;
3323 flipH = _updateH === true ? -flipH : flipH;
3324 flipV = _updateV === true ? -flipV : flipV;
3325 reversibleImage.resize( flipH * w, flipV * h );
3327 this.flipV = function(){ return flipV;}
3328 this.flipH = function(){ return flipH;}
3329 this.resourcePicture = function( _resourcePicture ){
3330 if( _resourcePicture && _resourcePicture !== resourcePicture ){
3331 HISTORY_CONTROL.saveState( updateResourcePicture, resourcePicture, _resourcePicture );
3332 updateResourcePicture( _resourcePicture );
3334 return resourcePicture;
3336 this.getArtistID = function(){
3337 return resourcePicture.artist_id || resourcePicture.artist.id || -1;
3339 this.actualW = function(){ return actualW;}
3340 this.actualH = function(){ return actualH;}
3341 this.resize = function( _x, _y, _w, _h, animate ){
3342 self.x = x = Type.isFinite( _x ) === true ? _x : x;
3343 self.y = y = Type.isFinite( _y ) === true ? _y : y;
3344 self.w = w = Type.isFinite( _w ) === true ? _w : w;
3345 self.h = h = Type.isFinite( _h ) === true ? _h : h;
3346 jqWrap[ animate === true ? 'animate' : 'css' ]( {
3351 }, 250, flipReversibleImage );
3352 animate !== true && flipReversibleImage();
3354 this.animate = function ( _x, _y, _w, _h, _flipH, _flipV ){
3355 flipH = _flipH !== undefined ? _flipH : flipH;
3356 flipV = _flipV !== undefined ? _flipV : flipV;
3357 self.resize( _x, _y, _w, _h, true );
3359 this.destroy = function(){
3360 delete self.destroy;
3362 reversibleImage.destroy();
3363 jqWrap.stop().remove();
3364 jqWrap = reversibleImage = resourcePicture = data = self = null;
3367 ImageElementClass.prototype = new AbstractPanelElement( PANEL_ELEMENT_TYPE_IMAGE );
3369 * / ImageElementClass
3370 * --------------------------------------------------------------------------------------------
3374 /* --------------------------------------------------------------------------------------------
3382 * 4.black-box( dq style)
3383 * 5.blue-box( ff style)
3386 var jqTextElementOrigin;
3387 var TextElementClass = function( data ){
3388 jqTextElementOrigin = jqTextElementOrigin || ( function(){
3389 var _OLD_IE = $( app.fetchHTMLElement( 'textElementTempleteForOldIE' ) ),
3390 _MODERN = $( app.fetchHTMLElement( 'textElementTemplete' ) );
3391 return UA.isIE === true && UA.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;
3394 var JQ_WRAPPER = jqTextElementOrigin.clone( true ),
3395 elmText = JQ_WRAPPER.find( 'td,.speach-inner' ).get( 0 ),
3396 type = data.balloon_template_id,
3397 text = ( function(){
3398 var _speachs = data.speeches_attributes;
3399 for( var k in _speachs ){
3400 return _speachs[ k ].content || '';
3404 balloon = pettanr.balloon.createBalloon( data.width, data.height, data.tail, type ),
3408 JQ_WRAPPER.find( 'img' ).eq( 0 ).replaceWith( balloon.elm );
3410 function updateType( _type ){
3411 if( type !== _type ){
3412 type = _type || type;
3413 balloon.type( type );
3416 function updateAngle( _a ){
3417 if( _a !== undefined && a !== _a ){
3418 a = _a !== undefined ? _a : a;
3422 function updateText( _text ){
3423 text = _text || text || '';
3424 elmText.firstChild.data = text;
3426 function resizeBalloon(){
3427 balloon && balloon.resize( a, w, h );
3430 /* global methods */
3431 this.$ = JQ_WRAPPER;
3437 this.timing = data.t || PANEL_ELEMENT_ARRAY.length + 1;
3438 this.init = function(){
3440 self.resize( data.x, data.y, data.width, data.height, data.tail );
3443 this.angle = function( _a ){
3444 _a !== undefined && self.resize( x, y, w, h, _a );
3447 this.text = function( _text ){
3448 if( _text && text !== _text) {
3449 HISTORY_CONTROL.saveState( updateText, text || '', _text );
3450 updateText( _text );
3454 this.resize = function( _x, _y, _w, _h, _a, animate ){
3455 self.x = x = _x !== undefined ? _x : x;
3456 self.y = y = _y !== undefined ? _y : y;
3457 self.w = w = _w !== undefined ? _w : w;
3458 self.h = h = _h !== undefined ? _h : h;
3459 a = _a !== undefined ? _a : a;
3461 JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {
3466 }, 250, resizeBalloon
3468 animate !== true && resizeBalloon();
3470 this.animate = function ( _x, _y, _w, _h, _a ){
3471 self.resize( _x, _y, _w, _h, _a, true );
3473 this.destroy = function(){
3474 delete self.destroy;
3476 JQ_WRAPPER.stop().remove();
3478 JQ_WRAPPER = elmText = data = balloon = self = null;
3481 TextElementClass.prototype = new AbstractPanelElement( PANEL_ELEMENT_TYPE_TEXT );
3483 /* --------------------------------------------------------------------------------------------
3484 * PANEL_ELEMENT_CONTROL
3485 * - mouseEventListener
3487 var PANEL_ELEMENT_CONTROL = ( function(){
3489 currentElement = null,
3490 currentLockTest = false,
3491 currentLock = false,
3492 panelX, panelY, panelW, panelH,
3495 * append, remove, replace
3497 * panelElement には、z-position と dom-index がある。
3498 * z-position は 表示上の位置。大きいほど前に表示される( z-index)
3499 * dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。
3501 * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。
3502 * dom-index は、数値のみ保持して、投稿時にpanelElementを適宜に並び替える。
3504 * append panelElement
3505 * 1. 新しい panelElement の z-position を得る
3506 * 2. z の同じ panelElementを見つけ、その前に加える。または一番先頭へ。(PANEL_ELEMENT_ARRAY)
3507 * zが大きいほど、PANEL_ELEMENT_ARRAYの先頭へ。
3508 * 3. dom位置は、PANEL_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。
3511 * remove panelElement
3515 function appendPanelElement( _panelElement ) {
3516 var z = Type.isFinite( _panelElement.z ) === true ? _panelElement.z : -1,
3517 l = PANEL_ELEMENT_ARRAY.length,
3518 _jqElm = _panelElement.$.stop().css( {
3523 PANEL_ELEMENT_ARRAY.unshift( _panelElement );
3525 for( var i = 0; i < l; ++i ){
3526 if( PANEL_ELEMENT_ARRAY[ i ].z < z ) break;
3529 PANEL_ELEMENT_ARRAY.push( _panelElement );
3531 PANEL_ELEMENT_ARRAY.splice( i, 0, _panelElement );
3538 function onFadeOut(){
3539 this.parentNode.removeChild( this );
3542 * PANEL_ELEMENT_ARRAY の順番を基準に、zの再計算
3545 function renumber(){
3546 var _panelElement, jqElm, jqNext;
3547 for( var i = 0, l = PANEL_ELEMENT_ARRAY.length; i < l; ++i ){
3548 _panelElement = PANEL_ELEMENT_ARRAY[ i ];
3549 jqElm = _panelElement.$;
3550 i === 0 && elmContainer.appendChild( jqElm.get( 0 ) );
3551 jqNext && jqNext.before( jqElm );
3552 if( phase === 1 ) _panelElement.z = l - i - 1;
3556 function onTextInput( _panelElement ){
3557 appendPanelElement( _panelElement );
3558 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ false, _panelElement ], [ true, _panelElement ], true );
3563 elmContainer = document.getElementById( 'comic-element-container' );
3564 delete PANEL_ELEMENT_CONTROL.init;
3571 while( PANEL_ELEMENT_ARRAY.length > 0 ){
3572 _comicElm = PANEL_ELEMENT_ARRAY.shift();
3573 _comicElm.destroy && _comicElm.destroy();
3576 remove: function( _panelElement ){
3577 var l = PANEL_ELEMENT_ARRAY.length;
3578 for( var i=0; i<l; ++i ){
3579 if( PANEL_ELEMENT_ARRAY[ i ] === _panelElement ){
3580 PANEL_ELEMENT_ARRAY.splice( i, 1 );
3582 _panelElement.$.stop().css( {
3585 }).fadeOut( onFadeOut );
3586 currentElement = currentElement === _panelElement ? null : currentElement;
3591 restore: function( arg ){
3592 var isAppend = arg[ 0 ],
3593 panelElement = arg[ 1 ];
3594 isAppend === true ? appendPanelElement( panelElement ) : PANEL_ELEMENT_CONTROL.remove( panelElement );
3596 replace: function( _panelElement, goForward ){
3597 // PANEL_ELEMENT_ARRAYの再構築
3598 var l = PANEL_ELEMENT_ARRAY.length,
3600 for( var j = 0; j < l; ++j ){
3601 if( PANEL_ELEMENT_ARRAY[ j ] === _panelElement ){
3606 if( i === -1) return false;
3607 if( goForward === true ){
3608 if( i === 0 ) return false;
3609 PANEL_ELEMENT_ARRAY.splice( i, 1 );
3610 PANEL_ELEMENT_ARRAY.splice( i - 1, 0, _panelElement );
3612 if( i === l - 1 ) return false;
3613 PANEL_ELEMENT_ARRAY.splice( i, 1 );
3614 PANEL_ELEMENT_ARRAY.splice( i + 1, 0, _panelElement );
3619 restoreReplace: function( arg ){
3620 PANEL_ELEMENT_CONTROL.replace( arg[ 0 ], arg[ 1 ] );
3622 onPanelResize : function ( _panelX, _panelY, _panelW, _panelH, isResizerTopAction ){
3624 * リサイズが、ResizerTopによって行われた場合、panelElementのyを動かして見かけ上動かないようにする。
3626 if( isResizerTopAction === true){
3627 var _shiftX = _panelW - panelW,
3628 _shiftY = _panelH - panelH;
3629 for( var i = PANEL_ELEMENT_ARRAY.length; i; ){
3630 PANEL_ELEMENT_ARRAY[ --i ].shift( _shiftX, _shiftY );
3633 elmContainer.style.cssText = [
3634 'width:', panelW = _panelW, 'px;',
3635 'height:', panelH = _panelH, 'px;',
3636 'left:', panelX = _panelX, 'px;',
3637 'top:', panelY = _panelY, 'px'
3640 mousemove: function( _mouseX, _mouseY ){
3641 var l = PANEL_ELEMENT_ARRAY.length,
3642 _x = _mouseX - panelX,
3643 _y = _mouseY - panelY,
3644 _elm = currentElement;
3646 if( _elm !== null ){
3647 currentLockTest = currentLockTest === true && _x === 0 && _y === 0;
3648 if( _elm.busy() === true ){
3649 _elm.mousemove( _x, _y );
3652 if( _elm.hitTest( _x, _y ) === true ){
3653 _elm.mousemove( _x, _y ); // cursor
3656 if( currentLock === true ){
3657 currentLockTest = true;
3661 for( var i=0; i<l; ++i ){
3662 _elm = PANEL_ELEMENT_ARRAY[ i ];
3664 if( _elm.hitTest( _x, _y ) === true ){
3665 _elm.mousemove( _x, _y ); // cursor
3666 currentElement = _elm;
3670 currentElement = null;
3671 PANEL_ELEMENT_OPERATION_MANAGER.hide();
3674 mouseup: function( _mouseX, _mouseY ){
3675 var ret = currentElement !== null && currentElement.busy() === true;
3676 ret === true && currentElement.mouseup( _mouseX -startX || panelX, _mouseY -startY || panelY );
3677 currentLock = currentLockTest === true && currentElement.hitTest( _mouseX -panelX, _mouseY -panelY ) === true;
3678 RESIZE_OPERATOR.lock( currentLock );
3679 INFOMATION_WINDOW.lock( currentLock );
3682 mousedown: function( _mouseX, _mouseY ){
3685 if( currentElement === null) return false
3686 currentElement.mousedown( _mouseX -startX, _mouseY -startY);
3687 currentLockTest = true;
3691 return currentElement !== null;
3693 createImageElement: function( data ){
3694 if( Type.isObject( data ) === false ){
3695 PremiumSatge.boot( 1, PANEL_ELEMENT_CONTROL.onImageSelect );
3697 PANEL_ELEMENT_CONTROL.onImageSelect( data, true );
3700 onImageSelect: function( data, isPanelPictureData ){
3702 if( isPanelPictureData !== true ){
3703 _panelElement = new ImageElementClass( {
3704 resource_picture:data,
3705 x: Math.floor( panelW / 2 - data.width / 2 ),
3706 y: Math.floor( panelH / 2 - data.height / 2 ),
3708 t: PANEL_ELEMENT_ARRAY.length + 1,
3712 _panelElement.init();
3713 appendPanelElement( _panelElement );
3714 _panelElement.animate( undefined, undefined, Math.abs( data.width ), Math.abs( data.height ) );
3716 _panelElement = new ImageElementClass( data );
3717 _panelElement.init();
3718 appendPanelElement( _panelElement );
3720 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ false, _panelElement], [ true, _panelElement ], true );
3722 createTextElement: function( data ){
3724 if( Type.isObject( data ) === false ){
3726 balloon_template_id:1,
3729 x: Math.floor( panelW / 2 - 100 + Math.random() * 10 ),
3730 y: Math.floor( panelH / 2 - 100 + Math.random() * 10 ),
3732 t: PANEL_ELEMENT_ARRAY.length + 1,
3735 speeches_attributes: {
3741 _panelElement = new TextElementClass( data );
3742 _panelElement.init();
3743 TextEditor.boot( PANEL_CONTROL.x, PANEL_CONTROL.y, _panelElement, onTextInput );
3745 _panelElement = new TextElementClass( data );
3746 _panelElement.init();
3747 onTextInput( _panelElement );
3754 * end of PANEL_ELEMENT_CONTROL
3757 function updateMouseCursor( _cursor ){
3758 if( currentCursor !== _cursor ){
3759 currentCursor = _cursor;
3760 self.addAsyncCall( update );
3763 elmMouseEventChatcher.style.cursor = currentCursor;
3766 function centering(){
3767 self.onPaneResize( windowW, windowH );
3769 function mouseEventRellay( e ){
3770 var _mouseX = e.clientX,
3771 _mouseY = e.clientY,
3772 rellayMethod = e.type === 'mouseout' ? 'mouseup' : e.type;
3773 if( currentListener !== null && currentListener.busy() === true ){
3774 currentListener[ rellayMethod ]( _mouseX, _mouseY );
3776 currentListener = null;
3777 var l = MOUSE_LISTENER_ARRAY.length,
3779 for( var i=0; i<l; ++i ){
3780 _listener = MOUSE_LISTENER_ARRAY[ i ];
3781 if( _listener[ rellayMethod ]( _mouseX, _mouseY ) === true ){
3782 currentListener = _listener;
3788 //!document.selection && window.getSelection().removeAllRanges();
3794 this.MIN_WIDTH = 320;
3795 this.MIN_HEIGHT = 320;
3796 this.onInit = function(){
3797 app.rootElement.id = 'editor';
3798 app.rootElement.innerHTML = [
3799 '<div id="grid" style="display:none;"></div>',
3800 '<div id="comic-element-container"></div>',
3801 '<div id="whiteGlass-container">',
3802 '<div id="whiteGlass-top"></div>',
3803 '<div id="whiteGlass-left"></div>',
3804 '<div id="whiteGlass-right"></div>',
3805 '<div id="whiteGlass-bottom"></div>',
3807 '<div id="panel-tools-container">',
3808 '<div id="panel-resizer-top">▲</div>',
3809 '<div id="panel-resizer-bottom">▼</div>',
3810 '<div id="comic-element-resizer-container">',
3811 '<div class="comic-element-resizer" id="comic-element-resizer-top"></div>',
3812 '<div class="comic-element-resizer" id="comic-element-resizer-left"></div>',
3813 '<div class="comic-element-resizer" id="comic-element-resizer-right"></div>',
3814 '<div class="comic-element-resizer" id="comic-element-resizer-bottom"></div>',
3815 '<div class="comic-element-resizer" id="comic-element-resizer-top-left"></div>',
3816 '<div class="comic-element-resizer" id="comic-element-resizer-top-right"></div>',
3817 '<div class="comic-element-resizer" id="comic-element-resizer-bottom-left"></div>',
3818 '<div class="comic-element-resizer" id="comic-element-resizer-bottom-right"></div>',
3819 '<div id="balloon-tail-mover"></div>',
3820 '<div id="comic-element-consol-wrapper">',
3821 '<div id="comic-element-consol-tail"></div>',
3822 '<div id="comic-element-consol-wrapper-when-out">',
3823 '<div id="image-element-consol">',
3824 '<div id="change-image-button"></div>',
3825 '<div id="layer-back-button"></div>',
3826 '<div id="delete-image-button"></div>',
3827 '<div id="layer-forward-button"></div>',
3829 '<div id="text-element-consol">',
3830 '<div id="edit-text-button"></div>',
3831 '<div id="change-text-style-button"></div>',
3832 '<div id="back-text-button"></div>',
3833 '<div id="delete-text-button"></div>',
3834 '<div id="hide-text-tail-button"></div>',
3835 '<div id="forward-text-button"></div>',
3841 '<div id="window-container"></div>',
3842 '<div id="menu-bar"></div>',
3843 '<div id="mouse-operation-catcher" unselectable="on"></div>',
3845 '<div id="templete-container" style="display: none;">',
3847 '<div id="imgElementTemplete" class="comic-element-wrapper image-element"></div>',
3849 '<div id="textElementTemplete" class="comic-element-wrapper text-element">',
3851 '<div class="speach">',
3852 '<div class="speach-inner"> </div>',
3856 '<div id="textElementTempleteForOldIE" class="comic-element-wrapper text-element">',
3858 '<div class="speach">',
3859 '<table><tr><td> </td></tr></table>',
3863 '<div id="imageGroupItemTemplete" class="image-group-item">',
3864 '<div class="image-group-item-title">img-title</div>',
3867 '<div id="windowTemplete" class="window-wrapper">',
3868 '<div class="window-header">window title</div>',
3869 '<div class="window-close-button">x</div>',
3870 '<div class="window-body clearfix">',
3871 '<div class="window-body-insert-position"></div>',
3873 '<div class="window-footer">',
3874 '<div class="window-resize-button">/</div>',
3878 '<div id="infomation-window">',
3879 '<div id="panel-background-information">',
3880 '<div id="bg-pattern"></div>',
3881 '<div id="select-bg-pattern-button">pattern</div>',
3882 '<div id="reset-bg-pattern-button">x</div>',
3883 '<div id="bg-color"></div>',
3884 '<div id="select-bg-color-button">color</div>',
3885 '<div id="reset-bg-color-button">x</div>',
3886 '<!-- <div id="bg-pattern-x"></div>',
3887 '<div id="bg-pattern-y"></div>',
3888 '<div id="bg-pattern-repeat-x"></div>',
3889 '<div id="bg-pattern-repeat-y"></div> -->',
3892 '<div id="comic-element-infomation">',
3893 '<div id="comic-element-x">',
3894 '<span class="comic-element-attribute-label">x:</span>',
3895 '<span id="comic-element-x-value" class="comic-element-attribute-value editable-value">0</span>',
3897 '<div id="comic-element-y">',
3898 '<span class="comic-element-attribute-label">y:</span>',
3899 '<span id="comic-element-y-value" class="comic-element-attribute-value editable-value">0</span>',
3901 '<div id="comic-element-z">',
3902 '<span class="comic-element-attribute-label">z:</span>',
3903 '<span id="comic-element-z-value" class="comic-element-attribute-value editable-value">0</span>',
3905 '<div id="comic-element-a">',
3906 '<span id="comic-element-a-value" class="comic-element-attribute-value editable-value">0</span>',
3907 '<span class="comic-element-attribute-label">°</span>',
3909 '<div id="comic-element-w">',
3910 '<span class="comic-element-attribute-label">w:</span>',
3911 '<span id="comic-element-w-value" class="comic-element-attribute-value editable-value">0</span>',
3913 '<div id="comic-element-h">',
3914 '<span class="comic-element-attribute-label">h:</span>',
3915 '<span id="comic-element-h-value" class="comic-element-attribute-value editable-value">0</span>',
3917 '<div id="comic-element-w-percent">',
3918 '<span id="comic-element-w-percent-value" class="comic-element-attribute-value editable-value">0</span>',
3919 '<span class="comic-element-attribute-label">%</span>',
3921 '<div id="comic-element-h-percent">',
3922 '<span id="comic-element-h-percent-value" class="comic-element-attribute-value editable-value">0</span>',
3923 '<span class="comic-element-attribute-label">%</span>',
3925 '<div id="comic-element-keep-aspect"></div>',
3929 '<div id="toolbox-window">',
3930 '<div id="toolbox-add-image-button">add image</div>',
3931 '<div id="toolbox-add-text-button">add text</div>',
3932 '<div id="toolbox-edit-bg-button">edit bg</div>',
3933 '<div id="toolbox-switch-grid">grid</div>',
3934 '<div id="toolbox-popup-help-button">?</div>',
3935 '<div id="toolbox-post-button">post</div>',
3938 '<div id="image-exproler"><div id="image-exproler-container"></div></div>',
3945 this.onOpen = function( _w, _h, _file ){
3946 elmMouseEventChatcher = document.getElementById( 'mouse-operation-catcher' );
3948 MENU_BAR_CONTROL.init();
3949 HISTORY_CONTROL.init();
3950 SAVE_CONTROL.init();
3951 WINDOWS_CONTROL.init();
3952 GRID_CONTROL.init();
3953 WHITE_GLASS_CONTROL.init();
3954 PANEL_CONTROL.init();
3955 CONSOLE_CONTROLER.init();
3956 PANEL_ELEMENT_OPERATION_MANAGER.init();
3957 PANEL_ELEMENT_CONTROL.init();
3960 * MOUSE_LISTENER_ARRAY は、表示順に格納.手前の要素が最初
3963 * PANEL_ELEMENT_CONTROL,
3965 * .busy() === true なら、そのままmousemove()にイベントを流す.
3966 * mousemove()に流してみて、false が帰れば、次のリスナーにも流す.
3968 MOUSE_LISTENER_ARRAY.push( MENU_BAR_CONTROL, WINDOWS_CONTROL, PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM, PANEL_ELEMENT_CONTROL, PANEL_CONTROL );
3977 fileData, panelElements, panelElm;
3979 if( FileAPI.isFileInstance( _file ) === true ){
3980 if( Driver.isPettanrFileInstance( _file ) === true ){
3981 if( _file.getType() === FILE_TYPE.COMIC ){
3982 fileData = _file.read();
3983 panelW = fileData.width;
3984 panelH = fileData.height;
3985 comicID = fileData.id || -1;
3987 if( _file.getType() === FILE_TYPE.PANEL ){
3988 fileData = _file.read();
3989 panelW = fileData.width;
3990 panelH = fileData.height;
3991 borderSize = fileData.border;
3992 panelElements = fileData.panel_elements;
3993 comicID = fileData.comic ? fileData.comic.id || -1 : -1;
3994 panelID = fileData.id || -1;
3995 panelTimming = fileData.t || -1;
3996 if( Type.isArray( panelElements ) === true ){
3997 for( var i=0; i<panelElements.length; ++i ){
3998 panelElm = panelElements[ i ];
3999 if( panelElm.resource_picture ){
4000 PANEL_ELEMENT_CONTROL.createImageElement( panelElm );
4002 if( panelElm.balloon_template_id ){
4003 PANEL_ELEMENT_CONTROL.createTextElement( panelElm );
4013 HISTORY_CONTROL.open();
4014 SAVE_CONTROL.open();
4015 WINDOWS_CONTROL.open();
4017 GRID_CONTROL.open();
4018 PANEL_CONTROL.open( panelW, panelH, borderSize );
4019 CONSOLE_CONTROLER.open();
4020 PANEL_ELEMENT_OPERATION_MANAGER.open();
4021 PANEL_ELEMENT_CONTROL.open();
4024 MENU_BAR_CONTROL.open();
4028 self.onPaneResize( _w, _h );
4033 self.addKeyEventListener( 'keydown', centering, 96, false, true ); // ctrl + 0
4034 self.addKeyEventListener( 'krydown, centering', 48, false, true ); // ctrl + 0
4035 MENU_BAR_CONTROL.EDIT.createOption( 'centering', 'ctrl + 0', centering, true, true, true);
4037 * jqMouseEventChacher は透明な要素で、
4038 * マウスイベントをcurrentElement(currentElement)に伝えるのが仕事
4039 * このような実装になるのは、ここの表示オブジェクトにイベントを設定した場合、表示が追いつかずマウスカーソルが外れたタイミングでイベントが終わってしまうため。
4041 self.addMouseEventListener( elmMouseEventChatcher, 'mousemove', mouseEventRellay );
4042 self.addMouseEventListener( elmMouseEventChatcher, 'mousedown', mouseEventRellay );
4043 self.addMouseEventListener( elmMouseEventChatcher, 'mouseup', mouseEventRellay );
4044 //self.addMouseEventListener( elmMouseEventChatcher, 'mouseout', mouseEventRellay );
4050 this.onClose = function(){
4052 HISTORY_CONTROL.close();
4054 WINDOWS_CONTROL.close();
4056 GRID_CONTROL.close();
4057 PANEL_CONTROL.close();
4059 PANEL_ELEMENT_OPERATION_MANAGER.close();
4060 PANEL_ELEMENT_CONTROL.close();
4063 MENU_BAR_CONTROL.close();
4067 this.onPaneResize = function( _windowW, _windowH ){
4068 windowW = _windowW || windowW;
4069 windowH = _windowH || windowH;
4073 self.rootElement.style.height = _windowH + 'px';
4074 elmMouseEventChatcher.style.height = _windowH + 'px';
4076 WINDOWS_CONTROL.onWindowResize( _windowW, _windowH );
4077 MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH );
4078 PANEL_CONTROL.onWindowResize( _windowW, _windowH );
4080 }, false, true, 'Panel Editor', 'paneleditor', null, '#2D89F0' );
4083 var ComicConsole = gOS.registerApplication( function(){
4084 var elmHeader, elmProgress,
4085 inputTitle, inputW, inputH,
4086 comboboxVisible, comboboxEditable,
4087 buttonSubmit, buttonCancel,
4092 isUploading = false,
4094 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
4097 if( !elmForm || !elmIframe || isUploading === true ) return false;
4100 elmProgress.innerHTML = '■';
4104 function copyAndSubmit(){
4105 var _inputList = elmForm.getElementsByTagName( 'input' ),
4107 for( var i = _inputList.length; i; ){
4108 _input = _inputList[ --i ];
4109 _name = _input.name;
4110 if( _name === 'comic[title]'){
4111 _input.value = inputTitle.value();
4113 if( _name === 'comic[width]'){
4114 _input.value = inputW.value();
4116 if( _name === 'comic[height]'){
4117 _input.value = inputH.value();
4120 var _selectList = elmForm.getElementsByTagName( 'select' ),
4121 _select, _optionList;
4122 for( i = _selectList.length; i; ){
4123 _select = _selectList[ --i ];
4124 _name = _select.name;
4125 _optionList = _select.getElementsByTagName( 'option' )
4126 if( _name === 'comic[visible]'){
4127 _select.selectedIndex = comboboxVisible.selectIndex();
4129 if( _name === 'comic[editable]'){
4130 _select.selectedIndex = comboboxEditable.selectIndex();
4136 elmProgress.innerHTML = 'submit() err..';
4137 isUploading = false;
4138 instance.addTimer( clickCancel , 3000, true );
4142 elmIframe.onreadystatechange = detectIframe;
4144 elmIframe.onload = onIframeUpdate;
4146 elmProgress.innerHTML = 'uploading..';
4149 * ie の 場合、readyState をチェック.
4151 function detectIframe(){
4152 if ( elmIframe.readyState === 'complete' ){
4153 elmIframe.onreadystatechange = new Function();
4154 elmIframe.onreadystatechange = null;
4158 function onIframeUpdate(){
4159 elmIframe.onload = null;
4160 ( elmIframe.contentWindow || elmIframe.contentDocument.parentWindow ).close();
4162 elmProgress.innerHTML = 'success!';
4163 instance.addTimer( clickCancel , 1000 );
4164 isUploading = false;
4167 function clickCancel(){
4168 if( isUploading === true ) return false;
4169 ComicConsole.shutdown();
4171 function detectForm(){
4172 elmForm = elmUploader.getElementsByTagName( 'form' )[ 0 ];
4174 var selectList = elmForm.getElementsByTagName( 'select' ),
4178 for( var i=0, l=selectList.length; i<l; ++i ){
4179 select = selectList[ i ];
4180 optionList = select.getElementsByTagName( 'option' );
4181 for( j=0, m=optionList.length; j<m; ++j ){
4182 option = optionList[ j ];
4183 if( select.name === 'comic[visible]' ){
4184 comboboxVisible.createOption( option.innerHTML, option.value, option.selected );
4186 if( select.name === 'comic[editable]' ){
4187 comboboxEditable.createOption( option.innerHTML, option.value, option.selected );
4192 instance.removeTimer( detectForm );
4193 Util.createIframe( 'targetFrameCreateComic', onCreateIframe );
4194 elmProgress.innerHTML = 'create iframe';
4197 function onCreateIframe( _iframe ){
4198 elmUploader.appendChild( _iframe );
4199 elmIframe = _iframe;
4200 elmForm.target = _iframe.name;
4201 elmProgress.innerHTML = '';
4205 this.MIN_WIDTH = 320;
4206 this.MIN_HEIGHT = 320;
4207 this.onInit = function(){
4208 instance.rootElement.id = 'comic-console-wrapper';
4209 instance.rootElement.className = 'console-wrapper';
4210 instance.rootElement.innerHTML = [
4211 '<div id="comic-console-header" class="console-header">Create New Comic</div>',
4212 '<div id="comic-console" class="console-inner">',
4213 '<div id="comic-console-title" class="field">',
4214 '<span class="field-label">Title:</span>',
4215 '<span id="comic-console-title-value" class="comic-console-value editable-value">No Title</span>',
4217 '<div id="comic-console-width" class="field">',
4218 '<span class="field-label">Default Width:</span>',
4219 '<span id="comic-console-width-value" class="comic-console-value editable-value">300</span>',
4221 '<div id="comic-console-height" class="field">',
4222 '<span class="field-label">Default Height:</span>',
4223 '<span id="comic-console-height-value" class="comic-console-value editable-value">200</span>',
4225 '<div id="comic-console-visible" class="field">',
4226 '<span class="field-label">Visible:</span>',
4227 '<span id="comic-console-visible-value" class="comic-console-value combobox"></span>',
4229 '<div id="comic-console-editable" class="field">',
4230 '<span class="field-label">Editable:</span>',
4231 '<span id="comic-console-editable-value" class="comic-console-value combobox"></span>',
4233 '<div class="console-button-container">',
4234 '<div id="comic-console-post-button" class="button console-submit-button">create</div>',
4235 '<div id="comic-console-cancel-button" class="button console-cancel-button">cancel</div>',
4237 '<div id="comic-console-progress" class="console-progress"> </div>',
4241 delete instance.onInit;
4243 this.onOpen = function( w, h ){
4244 var ui = instance.createUIGroup();
4246 inputTitle = ui.createInputText( document.getElementById( 'comic-console-title') );
4247 inputW = ui.createInputText( document.getElementById( 'comic-console-width') );
4248 inputH = ui.createInputText( document.getElementById( 'comic-console-height') );
4249 comboboxVisible = ui.createCombobox( document.getElementById( 'comic-console-visible') );
4250 comboboxEditable = ui.createCombobox( document.getElementById( 'comic-console-editable') );
4251 buttonSubmit = ui.createButton( document.getElementById( 'comic-console-post-button'), clickOK );
4252 buttonCancel = ui.createButton( document.getElementById( 'comic-console-cancel-button'), clickCancel );
4256 elmHeader = document.getElementById( 'comic-console-header' );
4257 elmProgress = document.getElementById( 'comic-console-progress' );
4259 elmUploader = document.createElement( 'div' );
4260 instance.rootElement.appendChild( elmUploader );
4261 elmUploader.id = 'newcomic';
4262 elmUploader.style.cssText = 'height:1px;line-height:1px;visibility:hidden;overflow:hidden;';
4264 elmScript = document.createElement( 'script' );
4265 document.body.appendChild( elmScript );
4266 elmScript.type = 'text\/javascript';
4267 elmScript.src = pettanr.CONST.CREATE_COMIC_JS;
4269 elmProgress.innerHTML = 'loading form.';
4271 instance.addTimer( detectForm, 250 );
4272 instance.onPaneResize( w, h );
4274 delete instance.onOpen;
4276 this.onPaneResize = function( _windowW, _windowH ){
4277 instance.rootElement.style.cssText = [
4278 'left:', Math.floor( ( _windowW - instance.rootElement.offsetWidth ) /2 ), 'px;',
4279 'top:', Math.floor( ( _windowH - instance.rootElement.offsetHeight ) /2 ), 'px;'
4282 this.onClose = function(){
4283 elmHeader = elmProgress = elmForm = elmUploader = instance = null;
4284 isUploading = false;
4286 }, true, true, 'Comic Console', 'comicConsole', null, '#D44A26' );
4288 var UploadConsole = gOS.registerApplication( function(){
4289 var windowW, windowH,
4290 TARGET_FRAME_NAME = 'targetFrame',
4297 isUploading = false,
4300 * upload ボタンが押されたらまず iframe をつくる.
4303 if( !elmForm || !elmIframe || isUploading === true ) return false;
4304 if( elmFile.value.length === 0 ) return false;
4305 elmProgress.innerHTML = 'uploading.';
4311 * form の target に iframe を指定したのち submit();
4317 elmProgress.innerHTML = 'submit() err..';
4318 isUploading = false;
4319 instance.addTimer( clickCancel , 3000, true );
4324 elmIframe.onreadystatechange = detectIframe;
4326 elmIframe.onload = onLoad;
4328 elmProgress.innerHTML = 'uploading..';
4331 * ie の 場合、readyState をチェック.
4333 function detectIframe(){
4334 if ( elmIframe.readyState === 'complete') {
4335 elmIframe.onreadystatechange = new Function();
4336 elmIframe.onreadystatechange = null;
4341 elmIframe.onload = null;
4342 ( elmIframe.contentWindow || elmIframe.contentDocument.parentWindow ).close();
4343 elmProgress.innerHTML = 'success!';
4344 instance.addTimer( clickCancel , 1000 );
4345 isUploading = false;
4348 function detectForm(){
4349 elmForm = elmContainer.getElementsByTagName( 'form' )[ 0 ];
4351 var _inputList = elmForm.getElementsByTagName( 'input' ),
4353 for( var i = _inputList.length; i; ){
4354 _input = _inputList[ --i ];
4355 if( _input.type === 'file' ){
4358 if( _input.type === 'submit' ){
4359 _input.style.display = 'none';
4362 instance.removeTimer( detectForm );
4363 Util.createIframe( TARGET_FRAME_NAME, onCreateIframe );
4364 elmProgress.innerHTML = 'create iframe';
4367 function onCreateIframe( _iframe ){
4368 elmContainer.appendChild( _iframe );
4369 elmIframe = _iframe;
4370 elmForm.target = _iframe.name;
4371 elmProgress.innerHTML = '';
4372 instance.onPaneResize( windowW, windowH );
4374 function clickCancel(){
4375 if( isUploading === true ) return false;
4376 UploadConsole.shutdown();
4381 this.MIN_WIDTH = 320;
4382 this.MIN_HEIGHT = 320;
4383 this.onInit = function(){
4384 instance.rootElement.id = 'upload-console-wrapper';
4385 instance.rootElement.className = 'console-wrapper';
4386 instance.rootElement.innerHTML = [
4387 '<div id="upload-console-header" class="console-header">Upload Picture</div>',
4388 '<div id="upload-console" class="console-inner">',
4389 '<div id="uploader"></div>',
4390 '<div class="console-button-container">',
4391 '<div id="upload-console-post-button" class="button console-submit-button">upload</div>',
4392 '<div id="upload-console-cancel-button" class="button console-cancel-button">cancel</div>',
4394 '<div id="upload-console-progress" class="console-progress"> </div>',
4398 delete instance.onInit;
4400 this.onOpen = function( w, h ){
4401 elmContainer = document.getElementById( 'uploader' );
4402 elmProgress = document.getElementById( 'upload-console-progress' );
4404 instance.addMouseEventListener( document.getElementById( 'upload-console-post-button' ), 'click', clickOK );
4405 instance.addMouseEventListener( document.getElementById( 'upload-console-cancel-button' ), 'click', clickCancel );
4407 * ie 6, 7 で fadeIn 中の要素に appendChild すると クラッシュするので、document.body に追加.
4409 elmScript = document.createElement( 'script' );
4410 document.body.appendChild( elmScript );
4411 elmScript.type = 'text\/javascript';
4412 elmScript.src = pettanr.CONST.UPLOAD_PICTURE_JS;
4414 instance.addTimer( detectForm, 250 );
4415 instance.onPaneResize( w, h );
4417 elmProgress.innerHTML = 'loading form.';
4419 this.onPaneResize = function( _windowW, _windowH){
4422 instance.rootElement.style.cssText = [
4423 'left:', Math.floor( ( _windowW - instance.rootElement.offsetWidth ) /2 ), 'px;',
4424 'top:', Math.floor( ( _windowH - instance.rootElement.offsetHeight ) /2 ), 'px;'
4427 this.onClose = function(){
4428 elmHeader = elmProgress = elmForm = elmUploader = instance = null;
4429 isUploading = false;
4431 }, true, true, 'Upload Console', 'uploadConsole', null, '#01A31C' );
4433 var PanelConsole = gOS.registerApplication( function(){
4434 var windowW, windowH,
4435 TARGET_FRAME_NAME = 'targetFrameCreateNewPanel',
4436 elmContainer, elmProgress,
4440 isUploading = false,
4443 * upload ボタンが押されたらまず iframe をつくる.
4446 if( !elmForm || !elmIframe || isUploading === true ) return false;
4447 elmProgress.innerHTML = 'uploading.';
4453 * form の target に iframe を指定したのち submit();
4459 elmProgress.innerHTML = 'submit() err..';
4460 isUploading = false;
4461 instance.addTimer( clickCancel , 3000, true );
4466 elmIframe.onreadystatechange = detectIframe;
4468 elmIframe.onload = onLoad;
4470 elmProgress.innerHTML = 'uploading..';
4473 * ie の 場合、readyState をチェック.
4475 function detectIframe(){
4476 if ( elmIframe.readyState === 'complete' ){
4477 elmIframe.onreadystatechange = new Function();
4478 elmIframe.onreadystatechange = null;
4483 elmIframe.onload = null;
4484 ( elmIframe.contentWindow || elmIframe.contentDocument.parentWindow ).close();
4485 elmProgress.innerHTML = 'success!';
4486 instance.addTimer( clickCancel , 1000, true );
4487 isUploading = false;
4490 function detectForm(){
4491 elmForm = elmContainer.getElementsByTagName( 'form' )[ 0 ];
4493 var _inputList = elmForm.getElementsByTagName( 'input' ),
4495 for( var i = _inputList.length; i; ){
4496 _input = _inputList[ --i ];
4497 if( _input.type === 'submit' ){
4498 _input.style.display = 'none';
4501 instance.removeTimer( detectForm );
4502 Util.createIframe( TARGET_FRAME_NAME, onCreateIframe );
4503 elmProgress.innerHTML = 'create iframe';
4506 function onCreateIframe( _iframe ){
4507 elmContainer.appendChild( _iframe );
4508 elmIframe = _iframe;
4509 elmForm.target = _iframe.name;
4510 elmProgress.innerHTML = '';
4511 instance.onPaneResize( windowW, windowH );
4513 function clickCancel(){
4514 if( isUploading === true) return false;
4515 PanelConsole.shutdown();
4520 this.MIN_WIDTH = 320;
4521 this.MIN_HEIGHT = 320;
4522 this.onInit = function(){
4523 instance.rootElement.id = 'panel-console-wrapper';
4524 instance.rootElement.className = 'console-wrapper';
4525 instance.rootElement.innerHTML = [
4526 '<div id="panel-console-header" class="console-header">Create New Panel (dev)</div>',
4527 '<div id="panel-console" class="console-inner">',
4528 '<div id="newpanel"></div>',
4529 '<div class="console-button-container">',
4530 '<div id="panel-console-post-button" class="button console-submit-button">post</div>',
4531 '<div id="panel-console-cancel-button" class="button console-cancel-button">cancel</div>',
4533 '<div id="panel-console-progress" class="console-progress"> </div>',
4537 delete instance.onInit;
4539 this.onOpen = function( w, h ){
4540 elmContainer = document.getElementById( 'newpanel' );
4541 elmProgress = document.getElementById( 'panel-console-progress' );
4543 instance.addMouseEventListener( document.getElementById( 'panel-console-post-button' ), 'click', clickOK );
4544 instance.addMouseEventListener( document.getElementById( 'panel-console-cancel-button' ), 'click', clickCancel );
4546 * ie 6, 7 で fadeIn 中の要素に appendChild すると クラッシュするので、document.body に追加.
4548 elmScript = document.createElement( 'script' );
4549 document.body.appendChild( elmScript );
4550 elmScript.type = 'text\/javascript';
4551 elmScript.src = pettanr.CONST.CREATE_PANEL_JS;
4553 instance.addTimer( detectForm, 250 );
4554 instance.onPaneResize( w, h );
4556 elmProgress.innerHTML = 'loading form.';
4558 this.onPaneResize = function( _windowW, _windowH ){
4561 instance.rootElement.style.cssText = [
4562 'left:', Math.floor( ( _windowW - instance.rootElement.offsetWidth ) /2 ), 'px;',
4563 'top:', Math.floor( ( _windowH - instance.rootElement.offsetHeight ) /2 ), 'px;'
4566 this.onClose = function(){
4567 elmHeader = elmProgress = elmForm = elmUploader = instance = null;
4568 isUploading = false;
4570 }, true, true, 'Panel Console', 'panelConsole', null, '#603CBA' );
4572 var ArtistConsole = gOS.registerApplication( function(){
4573 var windowW, windowH,
4574 TARGET_FRAME_NAME = 'targetFrameRegisterArtist',
4575 elmContainer, elmProgress,
4579 isUploading = false,
4582 * upload ボタンが押されたらまず iframe をつくる.
4585 if( !elmForm || !elmIframe || isUploading === true ) return false;
4586 elmProgress.innerHTML = 'uploading.';
4592 * form の target に iframe を指定したのち submit();
4598 elmProgress.innerHTML = 'submit() err..';
4599 isUploading = false;
4600 instance.addTimer( clickCancel , 3000, true );
4605 elmIframe.onreadystatechange = detectIframe;
4607 elmIframe.onload = onLoad;
4609 elmProgress.innerHTML = 'uploading..';
4612 * ie の 場合、readyState をチェック.
4614 function detectIframe(){
4615 if ( elmIframe.readyState === 'complete' ){
4616 elmIframe.onreadystatechange = new Function();
4617 elmIframe.onreadystatechange = null;
4622 elmIframe.onload = null;
4623 ( elmIframe.contentWindow || elmIframe.contentDocument.parentWindow ).close();
4624 elmProgress.innerHTML = 'success!';
4625 instance.addTimer( clickCancel , 1000, true );
4626 isUploading = false;
4629 function detectForm(){
4630 elmForm = elmContainer.getElementsByTagName( 'form' )[ 0 ];
4632 var _inputList = elmForm.getElementsByTagName( 'input' ),
4634 for( var i = _inputList.length; i; ){
4635 _input = _inputList[ --i ];
4636 if( _input.type === 'submit' ){
4637 _input.style.display = 'none';
4640 instance.removeTimer( detectForm );
4641 Util.createIframe( TARGET_FRAME_NAME, onCreateIframe);
4642 elmProgress.innerHTML = 'create iframe';
4645 function onCreateIframe( _iframe ){
4646 elmContainer.appendChild( _iframe );
4647 elmIframe = _iframe;
4648 elmForm.target = _iframe.name;
4649 elmProgress.innerHTML = '';
4650 instance.onPaneResize( windowW, windowH );
4652 function clickCancel(){
4653 if( isUploading === true) return false;
4654 ArtistConsole.shutdown();
4659 this.MIN_WIDTH = 320;
4660 this.MIN_HEIGHT = 320;
4661 this.onInit = function(){
4662 instance.rootElement.id = 'artist-console-wrapper';
4663 instance.rootElement.className = 'console-wrapper';
4664 instance.rootElement.innerHTML = [
4665 '<div id="artist-console-header" class="console-header">Register Artist</div>',
4666 '<div id="artist-console" class="console-inner">',
4667 '<div id="register"></div>',
4668 '<div class="console-button-container">',
4669 '<div id="artist-console-post-button" class="button console-submit-button">register</div>',
4670 '<div id="artist-console-cancel-button" class="button console-cancel-button">cancel</div>',
4672 '<div id="artist-console-progress" class="console-progress"> </div>',
4676 delete instance.onInit;
4678 this.onOpen = function( w, h ){
4679 elmContainer = document.getElementById( 'register');
4680 elmProgress = document.getElementById( 'artist-console-progress');
4682 instance.addMouseEventListener( document.getElementById( 'artist-console-post-button' ), 'click', clickOK );
4683 instance.addMouseEventListener( document.getElementById( 'artist-console-cancel-button' ), 'click', clickCancel );
4685 * ie 6, 7 で fadeIn 中の要素に appendChild すると クラッシュするので、document.body に追加.
4687 elmScript = document.createElement( 'script' );
4688 document.body.appendChild( elmScript );
4689 elmScript.type = 'text\/javascript';
4690 elmScript.src = pettanr.CONST.REGISTER_ARTIST_JS;
4692 instance.addTimer( detectForm, 250 );
4693 instance.onPaneResize( w, h );
4695 elmProgress.innerHTML = 'loading form.';
4697 this.onPaneResize = function( _windowW, _windowH ){
4700 instance.rootElement.style.cssText = [
4701 'left:', Math.floor( ( _windowW - instance.rootElement.offsetWidth ) /2 ), 'px;',
4702 'top:', Math.floor( ( _windowH - instance.rootElement.offsetHeight ) /2 ), 'px;'
4705 this.onClose = function(){
4706 elmHeader = elmProgress = elmForm = elmUploader = instance = null;
4707 isUploading = false;
4709 }, true, true, 'Artist Console', 'artistConsole', null, '#FFC40D' );
4711 var OutputConsole = gOS.registerApplication( function(){
4712 var FORMAT_LIST = [ 'json[POST]', 'json[GET]', 'XML', 'HTML', 'XHTML', 'MT export', 'Blogger ATOM' ];
4714 comboboxFormat, inputOption,
4715 buttonGenerate, buttonClose,
4718 comicID, panelID, panelTimming, panelW, panelH, borderSize, panelElementArray,
4720 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
4723 OutputConsole.shutdown();
4726 function getPanelElementByTiming(){
4727 var i, l = panelElementArray.length;
4728 while( timing < l * 2){
4729 for( i=0; i<l; ++i ){
4730 if( timing === panelElementArray[ i ].timing ){
4732 return panelElementArray[ i ];
4740 function getAsHtmlString( isAbsoluteUrl, isXHTML ){
4743 var HTML_ARRAY = [],
4744 l = panelElementArray.length,
4747 while( HTML_ARRAY.length < l ){
4748 _panelElement = getPanelElementByTiming();
4749 if( _panelElement === null) break;
4750 HTML_ARRAY.push( panelElementToHtml( _panelElement, isAbsoluteUrl, isXHTML ));
4755 '<div class="panel" ',
4757 'height:', panelH, 'px;',
4758 'background-color:', ';',
4763 HTML_ARRAY.push( '</div>');
4765 return HTML_ARRAY.join( pettanr.LINE_FEED_CODE_TEXTAREA);
4768 function panelElementToHtml( _panelElement, isAbsoluteUrl, isXHTML ){
4770 if( _panelElement.type === 0 ){
4771 url = [ pettanr.CONST.RESOURCE_PICTURE_PATH, _panelElement.resourcePicture().id, '.', _panelElement.resourcePicture().ext ].join( '' );
4774 'src="', isAbsoluteUrl !== true ? url : Util.getAbsolutePath( url ), '" ',
4775 'width="', _panelElement.w, '" ',
4776 'height="', _panelElement.h, '" ',
4778 'left:', _panelElement.x, 'px;',
4779 'top:', _panelElement.y, 'px;',
4780 'z-index:', _panelElement.z, ';',
4782 isXHTML !== true ? '>' : ' \/>'
4785 url = pettanr.balloon.getBalloonUrl( _panelElement.w, _panelElement.h, _panelElement.angle() );
4788 'src="', isAbsoluteUrl !== true ? url : Util.getAbsolutePath( url ), '" ',
4789 'width="', _panelElement.w, '" ',
4790 'height="', _panelElement.h, '" ',
4792 'left:', _panelElement.x, 'px;',
4793 'top:', _panelElement.y, 'px;',
4794 'z-index:', _panelElement.z, ';',
4796 isXHTML !== true ? '>' : ' \/>',
4797 pettanr.LINE_FEED_CODE_TEXTAREA,
4798 '<div class="balloon" style="',
4799 'left:', _panelElement.x, 'px;',
4800 'top:', _panelElement.y, 'px;',
4801 'width:', _panelElement.w, 'px;',
4802 'height:', _panelElement.h, 'px;',
4803 'z-index:', _panelElement.z,
4804 '"><span>', _panelElement.text(), '<\/span>', '<\/div>'
4810 function getJsonGetString(){
4813 var JSON_STRING_ARRAY = [],
4815 l = panelElementArray.length,
4816 cr = pettanr.LINE_FEED_CODE_TEXTAREA,
4819 while( ELEMENT_ARRAY.length <= l){
4820 _panelElement = getPanelElementByTiming();
4821 if( _panelElement === null ) break;
4823 ELEMENT_ARRAY.push( _panelElement.type === 0 ? getImageJsonGET( _panelElement ) : balloonToJson( _panelElement ));
4828 '"id": ', panelID, ',', cr,
4829 '"border": ', borderSize, ',', cr,
4830 '"comic_id": ', comicID, ',', cr,
4831 '"resource_picture_id": 1,', cr,
4832 '"x": ', 0, ',', cr,
4833 '"y": ', 0, ',', cr,
4834 '"z": ', 0, ',', cr,
4835 panelTimming !== -1 ? ( '"t": ' + panelTimming + ',' + cr ) : '',
4836 '"width": ', panelW, ',', cr,
4837 '"height": ', panelH, ',', cr,
4838 '"panel_elements": [', cr,
4839 ELEMENT_ARRAY.join( ',' + cr ), cr,
4845 function getImageJsonGET( _imageElement ){
4846 var cr = pettanr.LINE_FEED_CODE_TEXTAREA;
4849 '"resource_picture": {', cr,
4850 '"id": ', _imageElement.resourcePicture().id, ',', cr,
4851 '"ext": ', '"',_imageElement.resourcePicture().ext, '"', cr,
4853 '"x": ', _imageElement.x, ',', cr,
4854 '"y": ', _imageElement.y, ',', cr,
4855 '"z": ', _imageElement.z, ',', cr,
4856 '"width": ', _imageElement.flipH() * _imageElement.w, ',', cr,
4857 '"height": ', _imageElement.flipV() * _imageElement.h, ',', cr,
4858 '"t": ', timing, cr,
4863 function getJsonPostString(){
4866 var JSON_STRING_ARRAY = [],
4869 l = panelElementArray.length,
4871 cr = pettanr.LINE_FEED_CODE_TEXTAREA;
4873 while( IMAGE_ARRAY.length + BALLOON_ARRAY.length <= l){
4874 _panelElement = getPanelElementByTiming();
4875 if( _panelElement === null) break;
4876 _panelElement.type === 0 ?
4877 IMAGE_ARRAY.push( [ '"new', timing, '": ', imageToJson( _panelElement ) ].join( '' )) :
4878 BALLOON_ARRAY.push( [ '"new', timing, '": ', balloonToJson( _panelElement ) ].join( '' ) );
4883 '"id": ', panelID, ',', cr,
4884 '"border": ', borderSize, ',', cr,
4885 '"comic_id": ', comicID, ',', cr,
4886 '"resource_picture_id": 1,', cr,
4887 '"x": ', 0, ',', cr,
4888 '"y": ', 0, ',', cr,
4889 '"z": ', 0, ',', cr,
4890 '"t": ', panelTimming, ',', cr,
4891 '"width": ', panelW, ',', cr,
4892 '"height": ', panelH, ',', cr,
4893 '"panel_pictures_attributes": {', cr,
4894 IMAGE_ARRAY.join( ',' + cr ), cr,
4896 '"balloons_attributes": {', cr,
4897 BALLOON_ARRAY.join( ',' + cr ), cr,
4903 function imageToJson( _imageElement ){
4904 var cr = pettanr.LINE_FEED_CODE_TEXTAREA;
4907 '"resource_picture_id": ', _imageElement.resourcePicture().id, ',', cr,
4908 '"x": ', _imageElement.x, ',', cr,
4909 '"y": ', _imageElement.y, ',', cr,
4910 '"z": ', _imageElement.z, ',', cr,
4911 '"width": ', _imageElement.flipH() * _imageElement.w, ',', cr,
4912 '"height": ', _imageElement.flipV() * _imageElement.h, ',', cr,
4913 '"t": ', timing, cr,
4918 function balloonToJson( _textElement ){
4919 var cr = pettanr.LINE_FEED_CODE_TEXTAREA;
4922 '"balloon_template_id": ', 1, ',', cr,
4923 '"system_picture_id": ', 1, ',', cr,
4924 '"size": ', 1, ',', cr,
4925 '"tail": ', _textElement.angle(), ',', cr,
4926 '"x": ', _textElement.x, ',', cr,
4927 '"y": ', _textElement.y, ',', cr,
4928 '"z": ', _textElement.z, ',', cr,
4929 '"t": ', timing, ',', cr,
4930 '"width": ', _textElement.w, ',', cr,
4931 '"height": ', _textElement.h, ',', cr,
4932 '"speeches_attributes": {', cr,
4933 '"newf', timing, '": {', cr,
4934 '"content": "', _textElement.text(), '",', cr,
4935 '"x": ', _textElement.x, ',', cr,
4936 '"y": ', _textElement.y, ',', cr,
4937 '"t": ', timing, ',', cr,
4938 '"width": ', _textElement.w, ',', cr,
4939 '"height": ', _textElement.h, cr,
4946 function clickGenerate(){
4947 var i = comboboxFormat.selectIndex(),
4950 text = getJsonPostString();
4953 text = getJsonGetString();
4956 text = getAsHtmlString( false, false );
4960 elmOutputArea.value = text;
4962 function clickClose(){
4963 OutputConsole.shutdown();
4968 this.MIN_WIDTH = 320;
4969 this.MIN_HEIGHT = 320;
4970 this.onInit = function(){
4971 instance.rootElement.id = 'output-console-wrapper';
4972 instance.rootElement.className = 'console-wrapper';
4973 instance.rootElement.innerHTML = [
4974 '<div id="output-console-header" class="console-header">Output Console</div>',
4975 '<div id="output-console" class="console-inner">',
4976 '<div id="output-console-format" class="field">',
4977 '<span class="field-label">Format:</span>',
4978 '<span id="output-console-format-value" class="output-console-value combobox"></span>',
4980 '<div id="output-console-option" class="field">',
4981 '<span class="field-label">Options:</span>',
4982 '<span id="output-console-option-value" class="output-console-value editable-value">absolute-path</span>',
4984 '<div id="output-console-button-container" class="clearfix">',
4985 '<div id="output-console-generate-button" class="button console-submit-button">generate</div>',
4986 '<div id="output-console-close-button" class="button console-cancel-button">close</div>',
4988 '<textarea id="output-area" readonly></textarea>',
4992 delete instance.onInit;
4994 this.onOpen = function( _w, _h, _comicID, _panelID, _panelTimming, _panelW, _panelH, _borderSize, _panelElementArray ){
4995 elmOutputArea = document.getElementById( 'output-area' );
4997 var ui = instance.createUIGroup();
4998 comboboxFormat = ui.createCombobox( document.getElementById( 'output-console-format' ) );
5000 for( var i=0; FORMAT_LIST[ 0 ]; ++i ){
5001 comboboxFormat.createOption( FORMAT_LIST.pop(), null, i === 0 );
5003 inputOption = ui.createInputText( document.getElementById( 'output-console-option' ), null );
5004 buttonGenerate = ui.createButton( document.getElementById( 'output-console-generate-button' ), clickGenerate );
5005 buttonClose = ui.createButton( document.getElementById( 'output-console-close-button' ), clickClose );
5006 instance.onPaneResize( _w, _h );
5010 panelTimming = _panelTimming;
5013 borderSize = _borderSize;
5014 panelElementArray = _panelElementArray;
5018 this.onPaneResize = function( _windowW, _windowH ){
5021 instance.rootElement.style.cssText = [
5022 'left:', Math.floor( ( _windowW - instance.rootElement.offsetWidth ) /2 ), 'px;',
5023 'top:', Math.floor( ( _windowH - instance.rootElement.offsetHeight ) /2 ), 'px;'
5026 this.onClose = function(){
5027 elmOutputArea.value = '';
5028 elmOutputArea = comboboxFormat = inputOption = buttonGenerate = buttonClose = panelElementArray = instance = null;
5030 }, true, false, 'Output Console', 'outputConsole', null, '#2D89F0' );
5032 })( pettanr, gOS, window );