11 ( function( pettanr, gOS, window, document, undefined ){
13 * PettanR service driver.
15 var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
16 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
18 FileAPI = gOS.registerDriver( function(){
19 var self = Driver = this,
20 unregisteredFileDataJsonList = [];
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;
31 if( Type.isArray( json ) === true ){
32 for( i = 0, l = json.length; i < l; ++i ){
33 registerFileData( json[ i ], data );
36 if( Type.isNumber( json.id ) === true ){
37 registerFileData( json, data );
39 while( 0 < unregisteredFileDataJsonList.length ){
40 args = unregisteredFileDataJsonList.shift();
41 registerFileData( args[ 0 ], args[ 1 ] );
42 //alert( unregisteredFileDataJsonList.length )
44 file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, file, 'children', null ) );
46 function onErrorJson( file ){
47 var data = FileAPI.getFileData( file );
49 data.state = Const.FILE.STATE.ERROR;
51 file.dispatchEvent( FileAPI.createFileEvent( Const.FILE.EVENT.GET_SEQENTIAL_FILES, file, 'children', null ) );
53 function registerFileData( json, parent ){
57 case FILE_DATA_COMICS_ROOT :
58 case FILE_DATA_MY_COMICS_ROOT :
60 json.type = FILE_TYPE.COMIC;
61 data = createFileData( json, COMIC_ARRAY, 'title' );
62 if( data.json !== null ) data.json = true;
64 addChildData( data.author, data );
65 data.author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, data );
67 parent === FILE_DATA_COMICS_ROOT && addChildData( FILE_DATA_LATEST_COMICS, data );
71 json.type = FILE_TYPE.STORY;
72 data = createFileData( json, STORY_ARRAY, 'x,y,z,t' );
73 addChildData( FILE_DATA_STORY_ROOT, data );
77 case FILE_DATA_LISENCE :
79 json.type = FILE_TYPE.LICENSE;
80 data = createFileData( json, LICENSE_ARRAY, 'name,caption,url,system_picture_id,settings,credit_pictures' );
81 addChildData( FILE_DATA_LISENCE, data );
84 case FILE_DATA_LISENCE_GROUP :
85 case LICENSE_GROUP_ARRAY :
86 json.type = FILE_TYPE.LICENSE_GROUP;
87 data = createFileData( json, LICENSE_GROUP_ARRAY, 'name,caption,url,classname' );
88 addChildData( FILE_DATA_LISENCE_GROUP, data );
91 // Speech Balloon Templete
92 case FILE_DATA_BALLOON_ROOT :
93 case BALLOON_TEMPLETE_ARRAY :
94 json.type = FILE_TYPE.BALLOON_TEMPLETE;
95 data = createFileData( json, BALLOON_TEMPLETE_ARRAY, 'name,caption,classname,settings' );
96 addChildData( FILE_DATA_BALLOON_ROOT, data );
100 case FILE_DATA_AUTHOR_ROOT :
102 json.type = FILE_TYPE.AUTHOR;
103 data = createFileData( json, AUTHOR_ARRAY, 'name,email,homepage_url' );
104 addChildData( FILE_DATA_AUTHOR_ROOT, data );
108 case FILE_DATA_ARTIST_ROOT :
110 json.type = FILE_TYPE.ARTIST;
111 data = createFileData( json, ARTIST_ARRAY, 'name,email,homepage_url' );
112 addChildData( FILE_DATA_ARTIST_ROOT, data );
116 json.type = FILE_TYPE.PICTURE;
117 data = createFileData( json, PICTURE_ARRAY, 'ext,revision,credit,settings' );
121 case FILE_DATA_RESOURCE_PICTURES_ROOT :
122 case FILE_DATA_MY_RESOURCE_PICTURES_ROOT :
123 case RESOURCE_PICTURE_ARRAY :
124 json.type = FILE_TYPE.RESOURCE_PICTURE;
125 data = createFileData( json, RESOURCE_PICTURE_ARRAY, 'ext' );
127 addChildData( data.artist, data );
128 data.artist.id === MyArtistID && addChildData( FILE_DATA_MY_RESOURCE_PICTURES_ROOT, data );
133 case FILE_DATA_MY_ORIGINAL_PICTURES_ROOT :
134 case ORIGINAL_PICTURE_ARRAY :
135 json.type = FILE_TYPE.ORIGINAL_PICTURE;
136 data = createFileData( json, ORIGINAL_PICTURE_ARRAY, 'ext,filesize,width,height,md5' );
138 // addChildData( data.artist, data );
139 data.artist.id === MyArtistID && addChildData( FILE_DATA_MY_ORIGINAL_PICTURES_ROOT, data );
143 case FILE_DATA_PANELS_ROOT :
144 case FILE_DATA_MY_PANELS_ROOT :
146 json.type = FILE_TYPE.PANEL;
147 data = createFileData( json, PANEL_ARRAY, 'border,publish,width,height' );
148 addChildData( FILE_DATA_LATEST_PANELS, data );
149 data.author.id === MyAuthorID && addChildData( FILE_DATA_MY_PANELS_ROOT, data );
153 case PANEL_ELEMENT_ARRAY :
154 json.type = FILE_TYPE.PANEL_ELEMENT;
155 data = createFileData( json, PANEL_ELEMENT_ARRAY, 'caption,url,width,height,x,y,z,t' ); // 画像の分
161 if( parent.type === FILE_TYPE.COMIC ){
162 //alert( 'comicstory' )
163 data = registerFileData( json, STORY_ARRAY );
164 //addChildData( parent, data );
167 throw new Error( 'build file error!' );
172 * 1. すでに一度以上ファイルを取得している場合、そのオブジェクトを取得.または、新規に作成.
173 * 2. オブジェクトに値をコピー・上書き
176 function createFileData( json, array, copyProps ){
177 copyProps = copyProps + ',id,type';
179 var getIndex = Util.getIndex,
181 data = getResource( array, id ),
188 copyProps = copyProps.split( ',' );
190 if( getIndex( copyProps, p ) !== -1 ) data[ p ] = json[ p ];
194 data.driver = Driver;
195 if( Type.isString( json.created_at ) === true ) data.created_at = Math.floor( new Date( json.created_at ).getTime() / 1000 );
196 if( Type.isString( json.updated_at ) === true ) data.updated_at = Math.floor( new Date( json.updated_at ).getTime() / 1000 );
199 histories = json.pictures;
200 if( Type.isArray( histories ) === true ){
201 for( i = 0, l = histories.length; i < l; ++i ){
202 history = getResource( PICTURE_ARRAY, histories[ i ] );
203 addChildData( data, history );
205 data.picture = history;
209 stories = json.stories;
210 if( Type.isArray( stories ) === true ){
211 for( i = 0, l = stories.length; i < l; ++i ){
212 story = getResource( STORY_ARRAY, stories[ i ] );
216 addChildData( data, story );
221 elements = json.elements;
222 if( Type.isArray( elements ) === true ){
223 for( i = 0, l = elements.length; i<l; ++i ){
227 addChildData( data, getResource( PANEL_ELEMENT_ARRAY, elements[ i ] ) );
232 if( json.artist || json.artist_id ){
233 data.artist = getResource( ARTIST_ARRAY, json.artist || json.artist_id );
237 if( json.author || json.author_id ){
238 data.author = getResource( AUTHOR_ARRAY, json.author || json.author_id );
242 if( json.comic || json.comic_id ){
243 data.comic = getResource( COMIC_ARRAY, json.comic || json.comic_id );
247 if( json.panel || json.panel_id ){
248 data.panel = getResource( PANEL_ARRAY, json.panel || json.panel_id );
252 if( json.picture || json.picture_id ){
253 data.picture = getResource( PICTURE_ARRAY, json.picture || json.picture_id );
257 if( json.license || json.license_id ){
258 data.license = getResource( LICENSE_ARRAY, json.license || json.license_id );
262 if( json.license_group || json.license_group_id ){
263 data.license_group = getResource( LICENSE_GROUP_ARRAY, json.license_group || json.license_group_id );
267 if( json.original_picture || json.original_picture_id ){
268 data.original_picture = getResource( ORIGINAL_PICTURE_ARRAY, json.original_picture || {
269 id : json.original_picture_id,
271 filesize : json.filesize,
273 height : json.height,
275 artist : json.artist,
276 artist_id : json.artist_id
282 function addChildData( parent, child ){
283 if( Type.isArray( parent.children ) === false ){
284 parent.children = [ child ];
287 Util.getIndex( parent.children, child ) === -1 && parent.children.push( child );
289 function getResource( list, IDorOBJECT ){
291 if( Type.isNumber( IDorOBJECT ) === true ){
294 if( IDorOBJECT && Type.isNumber( IDorOBJECT.id ) === true ){
297 unregisteredFileDataJsonList.push( [ obj, list ] );
299 alert( 'getResource error' + IDorOBJECT.toString() );
303 if( !data ) data = list[ id ] = { id : id };
307 this.getSeqentialFiles = function( file ){
308 var data = FileAPI.getFileData( file ),
309 json = data.json || null;
310 if( data.type === FILE_TYPE.COMIC && json === true ){
311 if( pettanr.CONST.SERVER_SUPPORT === false ){
312 json = [ 'json\/comics_', data.id, '.json' ].join( '' );
314 json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'stories\/', data.id, '\/comic.json' ].join( '' );
318 if( typeof json === 'string' ){
319 FileAPI.getJson( file, json, onLoadJson, onErrorJson );
320 data.state = Const.FILE.STATE.LOADING;
321 if( data.json !== null ) delete data.json;
325 this.getName = function( file ){
326 var data = FileAPI.getFileData( file ),
327 type = data !== null ? data.type : null;
329 case FILE_TYPE.BALLOON :
331 case FILE_TYPE.PANEL_ELEMENT :
333 case FILE_TYPE.RESOURCE_PICTURE :
334 return [ '素材 ' + data.id, '.', data.ext ].join( '' );
335 case FILE_TYPE.PICTURE :
336 return [ '実素材 ' + data.id, '.', data.ext ].join( '' );
337 case FILE_TYPE.ORIGINAL_PICTURE :
338 return [ '原画 ', data.id, '.', data.ext ].join( '' );
339 case FILE_TYPE.COMIC :
341 case FILE_TYPE.STORY :
342 return [ 'story id:', data.id, ' ', data.comic ? data.comic.title : 'no comic', ':', data.t ].join( '' );
343 case FILE_TYPE.PANEL :
344 return [ 'panel id:', data.id ].join( '' );
345 case FILE_TYPE.AUTHOR :
346 return [ data.name, '先生' ].join( '' );
347 case FILE_TYPE.ARTIST :
348 return [ data.name, '画伯' ].join( '' );
349 case FILE_TYPE.BALLOON_TEMPLETE :
350 return [ data.id, data.caption ].join( ':' );
351 case FILE_TYPE.FOLDER :
355 this.getThumbnail = function( file ){
356 var data = FileAPI.getFileData( file ),
357 type = data !== null ? data.type : null;
358 if( data === FILE_DATA_COMICS_ROOT ) return { className: 'file-type-cabinet' };
361 case FILE_TYPE.PANEL_ELEMENT :
362 return { className: 'file-type-charactor' };
363 case FILE_TYPE.RESOURCE_PICTURE :
364 return { image: [ pettanr.CONST.THUMBNAIL_PATH, data.id, '.', data.ext ].join( '' )};
365 case FILE_TYPE.PICTURE :
366 //data = data.original_picture;
367 return { image: [ pettanr.CONST.THUMBNAIL_PATH, data.id, '.', data.ext ].join( '' )};
368 case FILE_TYPE.ORIGINAL_PICTURE :
369 return { className: 'file-type-charactor' };
370 // return { image: [ pettanr.CONST.THUMBNAIL_PATH, data.id, '.', data.ext ].join( '' )};
371 case FILE_TYPE.BALLOON :
373 case FILE_TYPE.COMIC :
374 return { className: 'file-type-comic' };
375 case FILE_TYPE.STORY :
377 case FILE_TYPE.PANEL :
378 return { className: 'file-type-panel' };
379 case FILE_TYPE.AUTHOR :
380 return { className: 'file-type-author' };
381 case FILE_TYPE.ARTIST :
382 return { className: 'file-type-artist' };
383 case FILE_TYPE.BALLOON_TEMPLETE :
384 return { className: 'file-type-balloon' };
385 case FILE_TYPE.FOLDER :
386 return { className: 'file-type-folder' };
388 return { className: 'file-type-broken' };
390 this.getSummary = function( file ){
391 var data = FileAPI.getFileData( file ),
392 type = data !== null ? data.type : null;
393 if( data === FILE_DATA_COMICS_ROOT ) return 'cabinet file';
395 case FILE_TYPE.BALLOON :
397 case FILE_TYPE.PANEL_ELEMENT :
398 return 'caption:' + data.caption + ' url:' + data.url + ' ' + data.width + 'x' + data.height + ' x:' + data.x + ' y:' + data.y + ' z:' + data.z + ' t:' + data.t;
399 case FILE_TYPE.RESOURCE_PICTURE :
401 case FILE_TYPE.PICTURE :
402 return '実素材情報 revision:' + data.revision + ' ' + data.credit + ' ' + data.settings;
403 case FILE_TYPE.ORIGINAL_PICTURE :
404 return [ '原画情報 ', data.width, 'x', data.height, ', filesize:', data.filesize, ' md5', data.md5 ].join( '' );
405 case FILE_TYPE.COMIC :
406 return 'comic id:' + data.id;
407 case FILE_TYPE.STORY :
409 case FILE_TYPE.PANEL :
410 return [ 'panel id:', data.id, ', width:', data.width, ', height:', data.height, ', 枠線:', data.border, ', 公開:', data.publish ].join( '' );
411 case FILE_TYPE.AUTHOR :
412 return 'author id:' + data.id;
413 case FILE_TYPE.ARTIST :
414 return [ 'artist id:', data.id, ' Email:', data.email || 'empty' , ', HP:', data.homepage_url || 'empty' ].join( '' );
415 case FILE_TYPE.BALLOON_TEMPLETE :
416 return data.name + ', ' + data.settings;
417 case FILE_TYPE.FOLDER :
418 return 'pettanR folder';
420 return 'pettanR unknown file';
422 this.read = function( file ){
423 var data = FileAPI.getFileData( file ),
424 type = data !== null ? data.type : null,
427 case FILE_TYPE.COMIC :
428 ret = Util.copy( data );
429 ret.panels = ret.children;
430 if( Type.isArray( ret.panels ) === true ){
431 for( i = ret.panels.length; i; ){
432 elm = ret.panels[ --i ];
433 elm.elements = elm.children;
437 case FILE_TYPE.STORY :
438 ret = Util.copy( data );
439 ret.panel.elements = ret.panel.children;
441 case FILE_TYPE.PANEL :
442 ret = Util.copy( data );
443 ret.elements = ret.children;
445 case FILE_TYPE.PANEL_ELEMENT :
446 case FILE_TYPE.BALLOON :
447 case FILE_TYPE.ORIGINAL_PICTURE :
450 this.write = function( file, newData, onUpdate ){
451 var data = FileAPI.getFileData( file ),
452 type = data !== null ? data.type : null;
454 case FILE_TYPE.COMIC :
455 case FILE_TYPE.PANEL :
456 case FILE_TYPE.PANEL_ELEMENT :
457 case FILE_TYPE.BALLOON :
458 case FILE_TYPE.ORIGINAL_PICTURE :
461 this.viewerApplicationList = function( file ){
462 var data = FileAPI.getFileData( file ),
463 type = data !== null ? data.type : null;
464 if( data === FILE_DATA_MY_ORIGINAL_PICTURES_ROOT ) return [ PremiumSatge ];
466 case FILE_TYPE.COMIC :
467 case FILE_TYPE.PANEL :
468 case FILE_TYPE.STORY :
470 case FILE_TYPE.PANEL_ELEMENT :
471 case FILE_TYPE.BALLOON :
472 case FILE_TYPE.ORIGINAL_PICTURE :
474 case FILE_TYPE.ARTIST :
475 return [ PremiumSatge ];
480 this.editorApplicationList = function( file ){
481 var data = FileAPI.getFileData( file ),
482 type = data !== null ? data.type : null;
484 case FILE_TYPE.COMIC :
485 return [ Editor, ComicConsole ];
486 case FILE_TYPE.PANEL :
488 case FILE_TYPE.PANEL_ELEMENT :
489 case FILE_TYPE.BALLOON :
490 case FILE_TYPE.ORIGINAL_PICTURE :
491 case FILE_TYPE.ARTIST :
497 Const = FileAPI.getConst(),
498 FILE_TYPE = Util.extend(
501 COMIC : FileAPI.createFileTypeID(),
502 STORY : FileAPI.createFileTypeID(),
503 PANEL : FileAPI.createFileTypeID(),
504 PANEL_ELEMENT : FileAPI.createFileTypeID(),
505 BALLOON : FileAPI.createFileTypeID(),
506 BALLOON_TEMPLETE : FileAPI.createFileTypeID(),
507 ORIGINAL_PICTURE : FileAPI.createFileTypeID(),
508 RESOURCE_PICTURE : FileAPI.createFileTypeID(),
509 PICTURE : FileAPI.createFileTypeID(),
510 AUTHOR : FileAPI.createFileTypeID(),
511 ARTIST : FileAPI.createFileTypeID(),
512 LICENSE : FileAPI.createFileTypeID(),
513 LICENSE_GROUP : FileAPI.createFileTypeID(),
523 LICENSE_GROUP_ARRAY = [],
524 PANEL_ELEMENT_ARRAY = [],
525 ORIGINAL_PICTURE_ARRAY = [],
526 RESOURCE_PICTURE_ARRAY = [],
527 BALLOON_TEMPLETE_ARRAY = [],
528 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ','),
529 FILE_DATA_SERVICE_ROOT = {
530 name: 'PettanR root',
531 type: FILE_TYPE.FOLDER,
534 FILE_DATA_COMICS_ROOT = {
536 type: FILE_TYPE.FOLDER,
539 json: pettanr.CONST.URL_COMICS_JSON
541 FILE_DATA_PANELS_ROOT = {
543 type: FILE_TYPE.FOLDER,
546 json: pettanr.CONST.URL_PANELS_JSON
548 FILE_DATA_RESOURCE_PICTURES_ROOT = {
550 type: FILE_TYPE.FOLDER,
553 json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON
555 FILE_DATA_ORIGINAL_PICTURES_ROOT = {
557 type: FILE_TYPE.FOLDER,
561 FILE_DATA_MY_COMICS_ROOT = {
563 type: FILE_TYPE.FOLDER,
567 json: pettanr.CONST.URL_MY_COMICS_JSON
569 FILE_DATA_LATEST_COMICS = {
570 name: 'Latest Comics',
571 type: FILE_TYPE.FOLDER,
574 FILE_DATA_STORY_ROOT = {
576 type: FILE_TYPE.FOLDER,
580 FILE_DATA_LATEST_PANELS = {
581 name: 'Latest Panels',
582 type: FILE_TYPE.FOLDER,
585 FILE_DATA_MY_PANELS_ROOT = {
587 type: FILE_TYPE.FOLDER,
590 json: pettanr.CONST.URL_MY_PANELS_JSON
592 FILE_DATA_MY_RESOURCE_PICTURES_ROOT = {
594 type: FILE_TYPE.FOLDER,
597 // json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON,
600 FILE_DATA_MY_ORIGINAL_PICTURES_ROOT = {
602 type: FILE_TYPE.FOLDER,
605 json: pettanr.CONST.URL_MY_ORIGINAL_PICTURES_JSON,
608 FILE_DATA_AUTHOR_ROOT = {
610 type: FILE_TYPE.FOLDER,
613 FILE_DATA_ARTIST_ROOT = {
615 type: FILE_TYPE.FOLDER,
618 FILE_DATA_LISENCE_ROOT = {
619 name: 'Lisence Root',
620 type: FILE_TYPE.FOLDER,
623 FILE_DATA_LISENCE = {
625 type: FILE_TYPE.FOLDER,
628 FILE_DATA_LISENCE_GROUP = {
629 name: 'Lisence Group',
630 type: FILE_TYPE.FOLDER,
633 FILE_DATA_BALLOON_ROOT = {
634 name: 'Balloon Templetes',
635 type: FILE_TYPE.FOLDER,
638 json: pettanr.CONST.SPEECH_BALOON_TEMPLETE
640 FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_RESOURCE_PICTURES_ROOT, FILE_DATA_ORIGINAL_PICTURES_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT );
641 FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT, FILE_DATA_STORY_ROOT, FILE_DATA_PANELS_ROOT );
642 FILE_DATA_PANELS_ROOT.children.push( FILE_DATA_LATEST_PANELS, FILE_DATA_MY_PANELS_ROOT );
643 FILE_DATA_RESOURCE_PICTURES_ROOT.children.push( FILE_DATA_MY_RESOURCE_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT );
644 FILE_DATA_LISENCE_ROOT.children.push( FILE_DATA_LISENCE_GROUP, FILE_DATA_LISENCE );
645 FILE_DATA_ORIGINAL_PICTURES_ROOT.children.push( FILE_DATA_MY_ORIGINAL_PICTURES_ROOT );
647 FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT );
649 Driver.isPettanrFileInstance = function( file ){
650 if( FileAPI.isFileInstance( file ) === true ){
651 var _data = FileAPI.getFileData( file.getUID() );// file でなく file.getUID()
652 return _data !== null && _data.driver === Driver;
657 var Cabinet = gOS.registerApplication( function(){
667 this.bgColor = '#FFFFFF';
668 this.MIN_WIDTH = 500;
669 this.MIN_HEIGHT = 300;
670 this.onInit = function(){
671 self.rootElement.id = 'cabinet-root';
672 self.rootElement.innerHTML = [
673 '<div id="cabinet-header">',
674 '<div class="header-title">Cabinet</div>',
675 '<div id="cabinet-close-button">x</div>',
676 '<div id="cabinet-path" class="finder-path"></div>',
678 '<div id="cabinet-container" class="finder-container"></div>'
681 self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
683 tree = FileAPI.createTree( FILE_DATA_SERVICE_ROOT );
684 eventRoot = self.getPointingDeviceEventTreeRoot();
688 this.onOpen = function( _w, _h ){
689 headerH = Util.getElementSize( document.getElementById( 'cabinet-header' ) ).height;
691 nodeClose = eventRoot.createNode( document.getElementById( 'cabinet-close-button' ), false, false, 'close-button-hover', 'pointer' );
692 nodeClose.addEventListener( 'click', Cabinet.shutdown );
693 nodePath = eventRoot.createNode( document.getElementById( 'cabinet-path' ), false, false );
694 nodeBody = eventRoot.createNode( document.getElementById( 'cabinet-container' ), false, true, null, '', true );
696 finder = self.createFinder( nodeBody, tree );
697 finder.createPath( nodePath );
698 self.onPaneResize( _w, _h );
700 this.onClose = function(){
703 finder = tree = null;
705 this.onPaneResize = function( w, h ){
707 nodeBody.update( 0, headerH, w, h - headerH );
708 finder.resize( w, h - headerH );
710 }, false, true, 'Cabinet', 'cabinet', null, '#1C1C1C' );
712 var Gallery = gOS.registerApplication( function(){
722 this.bgColor = '#FFFFFF';
723 this.MIN_WIDTH = 500;
724 this.MIN_HEIGHT = 300;
725 this.onInit = function(){
726 self.rootElement.id = 'gallery-root';
727 self.rootElement.innerHTML = [
728 '<div id="gallery-header">',
729 '<div class="header-title">Gallery</div>',
730 '<div id="gallery-close-button">x</div>',
731 '<div id="gallery-path" class="finder-path"></div>',
733 '<div id="gallery-container" class="finder-container"></div>'
736 self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
738 tree = FileAPI.createTree( FILE_DATA_RESOURCE_PICTURES_ROOT );
739 var _root = tree.getRootFile(),
740 _myPic = _root.getChildFileAt( 0 ),
741 _pic = _root.getChildFileAt( 1 );
742 _myPic.getSeqentialFiles();
743 _pic.getSeqentialFiles();
747 eventRoot = self.getPointingDeviceEventTreeRoot();
749 this.onOpen = function( w, h ){
750 headerH = Util.getElementSize( document.getElementById( 'gallery-header' ) ).height;
752 nodeClose = eventRoot.createNode( document.getElementById( 'gallery-close-button' ), false, false, 'close-button-hover', 'pointer' );
753 nodeClose.addEventListener( 'click', Gallery.shutdown );
754 nodePath = eventRoot.createNode( document.getElementById( 'gallery-path' ), false, false );
755 nodeBody = eventRoot.createNode( document.getElementById( 'gallery-container' ), false, true, null, '', true );
757 finder = self.createFinder( nodeBody, tree );
758 finder.createPath( nodePath );
759 self.onPaneResize( w, h );
761 this.onClose = function(){
764 finder = tree = null;
766 this.onPaneResize = function( w, h ){
768 nodeBody.update( 0, headerH, w, h - headerH );
769 finder.resize( w, h - headerH );
771 }, false, true, 'Gallery', 'gallery', null, '#01A31C' );
773 var Backyard = gOS.registerApplication( function(){
776 this.bgColor = '#FFFFFF';
777 this.MIN_WIDTH = 500;
778 this.MIN_HEIGHT = 300;
779 this.onInit = function(){
781 this.onOpen = function( _w, _h, _option ){
783 this.onClose = function(){
785 this.onPaneResize = function( _w, _h){
787 }, false, false, 'Settings', 'settings', null, '#DDDDDD' );
789 if( pettanr.DEBUG === true){
790 var Debug = gOS.registerApplication( function(){
795 pettanR: pettanr.version,
796 ua: navigator.userAgent,
797 platform: navigator.platform,
798 appVersion: navigator.appVersion,
799 appCodeName: navigator.appCodeName,
800 appName: navigator.appName,
801 language: navigator.browserLanguage || navigator.language,
803 RenderingMode: UA.isStanderdMode === true ? 'Standerd' : 'Quirks'
806 data.version = UA.IE;
807 if( UA.ieVersion >= 8 ) data.RenderingVersion = UA.ieRenderingVersion;
808 data.browserType = UA.STANDALONE === true ? 'Standalone' : 'bundle';
809 if( UA.ieVersion < 9 ) {
818 this.bgColor = '#FFFFFF';
819 this.MIN_WIDTH = 500;
820 this.MIN_HEIGHT = 300;
821 this.onInit = function(){
822 self.rootElement.id = 'debug-root';
823 self.rootElement.innerHTML = '<dl id="useragent" class="dl-table clearfix"></dl>';
825 this.onOpen = function( _w, _h, _option ){
826 elmDl = document.getElementById( 'useragent' );
828 for( var key in data ){
829 elmDt = document.createElement( 'dt' );
830 elmDt.innerHTML = key;
831 elmDd = document.createElement( 'dd' );
832 elmDd.innerHTML = '' + data[ key];
833 if( !data[ key ] ) elmDd.style.color = 'red';
834 elmDl.appendChild( elmDt );
835 elmDl.appendChild( elmDd );
838 this.onClose = function(){
841 this.onPaneResize = function( _w, _h ){
844 }, false, true, 'Debug', 'debug', null, '#01A31C' );
847 /* ----------------------------------------
848 * Image Group Exproler
851 var PremiumSatge = gOS.registerApplication( function(){
852 var BASE_PATH = pettanr.CONST.RESOURCE_PICTURE_PATH,
853 THUMB_PATH = pettanr.CONST.THUMBNAIL_PATH,
854 LIMIT_FILESIZE = 1024 * 100,
860 elmContainer, elmIconOrigin, elmName, elmButton,
861 containerW, containerH,
862 itemW, itemH, buttonW,
865 onUpdateContext = null,
868 var ImageGroupIconClass = function( index, data ){
869 var elmIconWrap = elmIconOrigin.cloneNode( true ),
870 elmIconTitle = Util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
871 originalPicture = data.original_picture || data,
872 SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
873 LOW_SRC = originalPicture.filesize && originalPicture.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '' ) : null,
874 reversibleImage = null,
878 elmContainer.appendChild( elmIconWrap );
879 elmIconWrap.style.left = ( index * itemW ) + 'px';
880 elmIconTitle.appendChild( document.createTextNode( originalPicture.filesize + 'bytes' ) );
882 function onImageLoad( url, _imgW, _imgH ){
883 data.width = _imgW = _imgW || originalPicture.width || 64;
884 data.height = _imgH = _imgH || originalPicture.height || 64;
885 elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
886 var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
887 MATH_FLOOR = Math.floor,
888 h = MATH_FLOOR( _imgH * zoom ),
889 w = MATH_FLOOR( _imgW * zoom );
890 reversibleImage.elm.style.cssText = [
893 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
895 reversibleImage.resize( w, h );
896 self.addEventListener( elmIconWrap, 'click', onClick );
901 PremiumSatge.shutdown();
904 function asyncDraw(){
905 reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
906 elmIconWrap.appendChild( reversibleImage.elm );
911 this.onEnter = function( delay ){
912 self.addTimer( asyncDraw, delay, true );
913 delete instance.onEnter;
915 this.destroy = function(){
916 delete instance.destroy;
917 // timer && window.clearTimeout( timer );
918 self.removeTimer( asyncDraw );
919 self.removeEventListener( elmIconWrap );
920 reversibleImage !== null && reversibleImage.destroy();
921 // Util.removeAllChildren( elmIconWrap );
922 // elmContainer.removeChild( elmIconWrap );
923 reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
927 function onEnterShowImage(){
928 var l = ICON_ARRAY.length,
929 _start = -wrapX /itemW -1,
930 _end = _start + winW /itemW +1,
932 for( var i=0, c = 0; i<l; ++i){
933 _icon = ICON_ARRAY[ i ];
934 if( _start < i && i < _end && _icon.onEnter ){
935 _icon.onEnter( c * 100 );
939 //onEnterInterval !== null && window.clearTimeout( onEnterInterval );
940 //onEnterInterval = null;
941 self.removeTimer( onEnterShowImage );
943 function clickClose(){
944 PremiumSatge.shutdown();
946 function onMouseWheel( e ){
947 if( winW < containerW ){
948 wrapX += e.wheelDelta / 2;
949 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
950 elmContainer.style.left = wrapX + 'px';
952 self.removeTimer( onEnterShowImage );
953 self.addTimer( onEnterShowImage, 500 );
958 function drawIcons(){
959 while( ICON_ARRAY.length > 0 ){
960 ICON_ARRAY.shift().destroy();
962 var _index = rootFile.search( {
964 type : FILE_TYPE.ARTIST
966 _artistFile = rootFile.getChildFileAt( _index ),
968 if( _artistFile !== null ){
969 for( var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
970 file = _artistFile.getChildFileAt( i );
971 ICON_ARRAY.push( new ImageGroupIconClass( i, FileAPI.getFileData( file ) ));
974 elmName.firstChild.data = _artistFile.getName();
975 _artistFile.destroy();
979 function onFadeout(){
980 while( ICON_ARRAY.length > 0 ){
981 ICON_ARRAY.shift().destroy();
983 onUpdate !== null && onUpdateData !== null && onUpdate.call( onUpdateContext, onUpdateData );
984 onUpdate = onUpdateData = onUpdateContext = null;
985 PremiumSatge.shutdown();
989 this.MIN_WIDTH = 320;
990 this.MIN_HEIGHT = 320;
991 this.onInit = function(){
992 self.rootElement.id = 'image-group-wrapper';
994 self.rootElement.innerHTML = [
995 '<div id="image-group-icon-container"></div>',
996 '<div id="image-group-name">NO DATA...</div>',
997 '<div id="image-group-button" class="button">close</div>'
1000 self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
1002 tree = FileAPI.createTree( FILE_DATA_ARTIST_ROOT );
1003 rootFile = tree.getRootFile();
1005 this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdate, opt_thisObj ){
1006 elmContainer = document.getElementById( 'image-group-icon-container' );
1007 containerH = Util.getElementSize( elmContainer ).height;
1009 elmIconOrigin = ( function(){
1010 var ret = document.createElement( 'div' ),
1011 data = document.createElement( 'div' );
1012 ret.appendChild( data );
1013 ret.className = 'image-group-item';
1014 data.className = 'image-group-item-title';
1018 var size = Util.getElementSize( elmIconOrigin );
1020 itemH = size.height;
1022 elmName = document.getElementById( 'image-group-name' );
1023 elmButton = document.getElementById( 'image-group-button' );
1025 buttonW = Util.getElementSize( elmButton ).width;
1027 self.addEventListener( elmContainer, 'mousewheel', onMouseWheel );
1028 self.addEventListener( elmButton, 'click', clickClose );
1029 tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, drawIcons );
1031 var data = FileAPI.getFileData( _ARTISTIDorFILE );
1033 artistID = MyArtistID || -1;
1035 if( data.type === FILE_TYPE.ARTIST || FILE_DATA_MY_ORIGINAL_PICTURES_ROOT === data ){
1036 artistID = data.id || -1;
1038 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1039 artistID = _ARTISTIDorFILE;
1042 onUpdate = _onUpdate || null;
1043 onUpdateContext = opt_thisObj || null;
1044 onUpdateData = null;
1049 containerW = ICON_ARRAY.length * itemW;
1053 var w = winW > containerW ? winW : containerW,
1054 h = _windowH > containerH ? containerH : _windowH,
1055 MATH_FLOOR = Math.floor;
1057 $( elmContainer ).css( {
1061 top: MATH_FLOOR( _windowH /2 )
1062 }).stop().animate( {
1064 top: MATH_FLOOR( _windowH /2 - h /2 )
1065 }, onEnterShowImage );
1067 elmButton.style.cssText = [
1068 'left:', MATH_FLOOR( _windowW /2 - buttonW /2 ), 'px;',
1069 'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10 ), 'px'
1072 this.onPaneResize = function( _windowW, _windowH ){
1073 var w = _windowW > containerW ? _windowW : containerW,
1074 h = _windowH > containerH ? containerH : _windowH,
1075 MATH_FLOOR = Math.floor,
1076 offsetW = MATH_FLOOR( _windowW /2 -winW /2 );
1080 if( offsetW <= 0 ){ // smaller
1081 $( elmContainer ).stop().css( {
1086 top: MATH_FLOOR( _windowH /2 -h /2 )
1089 $( elmContainer ).stop().css( { // bigger
1092 borderLeftWidth: offsetW
1094 top: MATH_FLOOR( _windowH /2 -h /2 ),
1098 elmButton.style.cssText = [
1099 'left:', MATH_FLOOR( _windowW /2 -buttonW /2 ), 'px;',
1100 'top:', MATH_FLOOR( _windowH /2 +containerH /2 + 10 ), 'px'
1104 this.onClose = function(){
1105 if( tree === null ) return true;
1106 $( elmContainer ).stop().animate( {
1108 top: Math.floor( winH / 2 )
1110 // onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1111 // onEnterInterval = null;
1114 tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, drawIcons );
1116 tree = rootFile = null;
1120 }, true, true, 'Premium Stage', 'premiumStage', null, '#C3325F' );
1123 /* ----------------------------------------
1127 var TextEditor = gOS.registerApplication( function(){
1128 var elmTextarea, elmButton,
1129 textElement, onUpdate,
1135 textElement && textElement.text( elmTextarea.value );
1136 self.addAsyncCall( asyncCallback );
1139 function asyncCallback(){
1140 onUpdate && onUpdate( textElement );
1141 onUpdate = textElement = null;
1142 TextEditor.shutdown();
1146 function textareaFitHeight(){
1148 while( elmTextarea.offsetHeight < textElement.h ){
1150 elmTextarea.rows = rows;
1152 if( rows > 1 ) elmTextarea.rows = --rows;
1157 this.MIN_WIDTH = 320;
1158 this.MIN_HEIGHT = 320;
1159 this.onInit = function(){
1160 self.rootElement.id = 'speach-editor-wrapper';
1161 self.rootElement.innerHTML = '<textarea id="speach-editor"></textarea><div id="speach-edit-complete-button" class="button">OK</div>';
1163 this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdate ){
1164 elmTextarea = document.getElementById( 'speach-editor' );
1165 elmButton = document.getElementById( 'speach-edit-complete-button' );
1167 self.addKeyEventListener( 'keydown', new Function( 'return false' ), 69, false, true );
1168 self.addEventListener( elmButton, 'click', clickOK );
1172 textElement = _textElement;
1173 onUpdate = _onUpdate || null;
1175 self.onPaneResize( _w, _h );
1176 elmTextarea.value = _textElement.content;
1177 elmTextarea.focus();
1180 * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
1182 UA.isIE === true && UA.ieVersion <= 7 && self.addAsyncCall( textareaFitHeight );
1184 this.onPaneResize = function( _w, _h ){
1185 self.rootElement.style.cssText = [
1186 'left:', textElement.x + panelX, 'px;',
1187 'top:', textElement.y + panelY, 'px;',
1188 'width:', textElement.w, 'px;',
1189 'height:', textElement.h, 'px;'
1192 this.onClose = function(){
1193 self.removeKeyEventListener();
1194 self.removeEventListener( elmButton );
1196 elmTextarea = elmButton = onUpdate = textElement = self = null;
1198 }, true, false, 'Tetxt Editor', 'texteditor', null, '#DDDDDD' );
1201 var Reader = gOS.registerApplication( function(){
1202 var windowW, windowH,
1206 elmContainer, elmTitle, elmAuthor, elmBackButton, elmNextButton,
1210 currentPanel = null,
1215 function onBackClick(){
1216 currentIndex -= ( currentIndex > 0 ? 1 : 0 );
1220 function onNextClick(){
1221 currentIndex += ( currentIndex < numPanel - 1 ? 1 : 0 );
1226 var elm = elmContainer.childNodes[ currentIndex ],
1227 h = windowH - headerH - consoleH,
1230 top = headerH - elm.offsetTop + Math.floor( ( h - elm.offsetHeight ) / 2 );
1233 $( elmContainer ).stop().animate( {
1237 function getCurrentTopPosition(){
1241 var fileData, title, author, story;
1243 if( Driver.isPettanrFileInstance( currentFile ) === true ){
1244 switch( currentFile.getType() ){
1245 case FILE_TYPE.COMIC :
1246 fileData = currentFile.read();
1247 title = fileData.title;
1248 author = fileData.author.name;
1249 comicData = fileData;
1250 numPanel = currentFile.getChildFileLength();
1252 case FILE_TYPE.STORY :
1253 story = currentFile.read();
1254 fileData = story.panel;
1255 title = story.comic.title;
1256 author = fileData.author.name;
1257 comicData = fileData;
1260 case FILE_TYPE.PANEL :
1261 fileData = currentFile.read();
1263 author = fileData.author.name;
1264 comicData = fileData;
1271 if( comicData !== null ){
1272 elmTitle.data = title;
1273 elmAuthor.data = author;
1274 // bindWorker.json( comicData );
1275 bindWorker.file( currentFile );
1276 self.addAsyncCall( asyncResize );
1279 function asyncResize(){
1280 self.onPaneResize( windowW, windowH );
1285 this.MIN_WIDTH = 320;
1286 this.MIN_HEIGHT = 320;
1287 this.onInit = function(){
1288 self.rootElement.id = 'comic-reader-wrapper';
1289 self.rootElement.innerHTML = [
1290 '<div id="comic-reader-panel-container"></div>',
1291 '<div class="comic-reader-shadow" style="top:0;height:40px;"></div>',
1292 '<div id="comic-reader-header">',
1293 '<div id="comic-reader-header-content">',
1294 '<span id="comic-reader-title">NO DATA...</span>',
1295 '<span id="comic-reader-author">NO DATA...</span>',
1298 '<div class="comic-reader-shadow" style="bottom:0;height:100px;"></div>',
1299 '<div id="comic-reader-console">',
1300 '<div id="comic-reader-button-centering">',
1301 '<a href="#" id="comic-reader-back-button">▲</da>',
1302 '<a href="#" id="comic-reader-forward-button">▼</a>',
1307 self.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
1310 this.onOpen = function( _w, _h, file ){
1311 headerH = Util.getElementSize( document.getElementById( 'comic-reader-header' ) ).height;
1312 consoleH = Util.getElementSize( document.getElementById( 'comic-reader-console' ) ).height;
1313 elmContainer = document.getElementById( 'comic-reader-panel-container' );
1314 elmTitle = document.getElementById( 'comic-reader-title' ).firstChild;
1315 elmAuthor = document.getElementById( 'comic-reader-author' ).firstChild;
1316 elmBackButton = document.getElementById( 'comic-reader-back-button' );
1317 elmNextButton = document.getElementById( 'comic-reader-forward-button' );
1319 bindWorker = pettanr.bind.createBindWorker( elmContainer, null, false, false );
1321 self.addEventListener( elmBackButton, 'click', onBackClick );
1322 self.addEventListener( elmNextButton, 'click', onNextClick );
1324 numPanel = currentIndex = 0;
1326 elmContainer.style.cssText = 'left:' + ( _w / 2 ) + 'px;' + 'top:' + _h + 'px;';
1330 if( FileAPI.isFileInstance( file ) === true ){
1332 file.addEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw );
1333 file.getSeqentialFiles();
1337 this.onPaneResize = function( _windowW, _windowH ){
1340 var panelH = elmContainer.offsetHeight,
1341 panelW = elmContainer.offsetWidth,
1342 h = _windowH - headerH - consoleH;
1343 $( elmContainer ).stop().animate(
1345 left: Math.floor( ( _windowW - panelW ) / 2 ),
1346 top: headerH + ( panelH < h ? Math.floor( ( h - panelH ) / 2 ) : 0 )
1350 this.onClose = function(){
1351 self.removeEventListener( elmBackButton );
1352 self.removeEventListener( elmNextButton );
1354 bindWorker.destroy();
1357 currentFile && currentFile.removeEventListener( Const.FILE.EVENT.GET_SEQENTIAL_FILES, draw );
1358 currentFile = comicData = currentPanel = null;
1360 elmContainer = elmTitle = elmAuthor = elmBackButton = elmNextButton = null;
1362 }, true, true, 'Comic Reader', 'comicreader', null, '#01A31C' );
1365 var Editor = gOS.registerApplication( function(){
1367 var PANEL_ELEMENT_TYPE_IMAGE = 0,
1368 PANEL_ELEMENT_TYPE_TEXT = 1,
1370 PANEL_ELEMENT_ARRAY = [],
1371 MIN_PANEL_HEIGHT = 20,
1372 MIN_ELEMENT_SIZE = 19,
1373 MOUSE_HIT_AREA = 10,
1383 var kill = function(){
1386 if( o.hasOwnProperty && !o.hasOwnProperty( p ) ) continue;
1391 /* ----------------------------------------
1393 * - mouseEventListener
1404 var MENU_BAR_CONTROL = ( function(){
1405 var ELM_ITEM_CLASSNAME = 'menubar-item',
1408 nodeBar, nodeBox, layerBox,
1410 /** -----------------------------------------
1411 * PrivateOptionDataClass
1413 var PrivateOptionDataClass = function( menuData, option, title, shortcut, callback, visible, separateAfter, thisObject ){
1414 this.menuData = menuData;
1415 this.option = option;
1417 this.shortcut = shortcut || '';
1418 this.callback = callback;
1419 this.thisObject = thisObject;
1420 this.visible = visible;
1421 this.separateAfter = separateAfter;
1423 PrivateOptionDataClass.prototype = {
1428 visible : undefined,
1434 separateAfter : false,
1435 show : function( elm ){
1436 if( this.elm === elm ) return;
1438 elm = document.createElement( 'div' );
1439 elmBox.appendChild( elm );
1440 elm.appendChild( document.createElement( 'span' ) );
1441 elm.appendChild( document.createElement( 'kbd' ) );
1444 this.option.title( this.title );
1445 this.option.visible( !!this.visible );
1446 elm.lastChild.innerHTML = this.shortcut;
1447 elm.style.borderStyle = this.border === true ? 'solid' : 'none';
1449 this.node = nodeBox.createNode( elm, false, true, 'menubar-option-hover', 'pointer' );
1450 this.node.disabled( !this.visible );
1458 this.callback.call( this.thisObject || this.option, Util.getIndex( this.menuData.optionDataList, this ) );
1460 remove : function(){
1461 var list = PrivateOptionDataClass.list;
1462 list.splice( Util.getIndex( list, this ), 1 );
1465 PrivateOptionDataClass.list = [];
1466 PrivateOptionDataClass.get = function( OptionOrElm ){
1467 var list = PrivateOptionDataClass.list,
1472 if( data.option === OptionOrElm || data.elm === OptionOrElm ) return data;
1477 /** -----------------------------------------
1480 var OptionClass = function( menuData, title, shortcut, callback, visible, separateAfter, thisObject ){
1481 PrivateOptionDataClass.list.push( new PrivateOptionDataClass( menuData, this, title, shortcut, callback, visible, separateAfter, thisObject ) );
1483 OptionClass.prototype = {
1484 title: function( v ){
1485 var data = PrivateOptionDataClass.get( this );
1486 if( Type.isString( v ) === true ){
1488 if( data.elm ) data.elm.firstChild.innerHTML = v;
1492 visible : function( v ){
1493 var data = PrivateOptionDataClass.get( this );
1494 if( Type.isBoolean( v ) === true ){
1496 data.elm && Util.toggleClass( data.elm, 'menubar-option-disabled', !v );
1498 return data.visible;
1501 /** -----------------------------------------
1504 var AsyncOptionClass = function( menuData, callback, visible, separateAfter, thisObject ){
1505 var data = new PrivateOptionDataClass( menuData, this, null, null, callback, visible, separateAfter, thisObject );
1506 data.show = AsyncOptionClass.show;
1507 data.hide = AsyncOptionClass.hide;
1508 PrivateOptionDataClass.list.push( data );
1510 AsyncOptionClass.prototype = {
1511 title : function(){},
1512 visible : OptionClass.prototype.visible
1514 AsyncOptionClass.show = function( elm ){
1515 if( this.elm === elm ) return;
1517 elm = document.createElement( 'div' );
1518 elmBox.appendChild( elm );
1519 elm.appendChild( document.createElement( 'span' ) );
1520 elm.appendChild( document.createElement( 'kbd' ) );
1523 elm.className = 'loading';
1524 elm.style.height = '90px';
1525 elm.firstChild.innerHTML = this.elm.lastChild.innerHTML = '';
1526 elm.style.borderStyle = this.border === true ? 'solid' : 'none';
1530 AsyncOptionClass.hide = function(){
1531 this.elm.className = '';
1532 this.elm.style.height = '';
1536 /** -----------------------------------------
1537 * MenuPrivateDataClass
1539 var MenuPrivateDataClass = function( menu, title ){
1541 this.elm = document.createElement( 'div' );
1542 this.optionDataList = [];
1544 elmBar.appendChild( this.elm );
1545 this.elm.className = ELM_ITEM_CLASSNAME;
1546 this.elm.innerHTML = title;
1548 MenuPrivateDataClass.prototype = {
1555 optionDataList : null,
1557 this.elm.style.left = ( menuW * Util.getIndex( MenuPrivateDataClass.list, this ) ) + 'px';
1558 this.node = nodeBar.createNode( this.elm, false, false, ELM_ITEM_CLASSNAME + '-hover', 'pointer' );
1559 // this.node.addEventListener( 'click', this.onClick, this );
1560 this.node.addEventListener( 'click', this.onClick, this );
1564 while( o = this.optionDataList.shift() ) o.remove();
1568 onClick : function( e ){
1569 if( currentMenu !== this.menu ){
1570 currentMenu && currentMenu.hide();
1571 currentMenu = this.menu;
1575 onOptionClick : function( e ){
1576 var target = e.target,
1577 i = target.nodeIndex(),
1578 option = this.optionDataList[ i ];
1579 if( target === nodeBox ) return true;
1583 MenuPrivateDataClass.list = [];
1584 MenuPrivateDataClass.get = function( menu ){
1585 var list = MenuPrivateDataClass.list,
1588 if( list[ --i ].menu === menu ) return list[ i ];
1593 /** -----------------------------------------
1596 var MenuClass = function( title ){
1597 MenuPrivateDataClass.list.push( new MenuPrivateDataClass( this, title ) );
1599 MenuClass.prototype = {
1601 var data = MenuPrivateDataClass.get( this );
1602 if( data.visible === true ) return;
1604 data.elm.className = ELM_ITEM_CLASSNAME + '-focus';
1607 elmBox = document.createElement( 'div' );
1608 elmBar.appendChild( elmBox );
1609 elmBox.className = 'menubar-option-box';
1610 nodeBox = nodeBar.createNode( elmBox, false, false, 'menubar-option-box-hover' );
1612 nodeBox.disabled( false );
1613 elmBar.parentNode.insertBefore( elmBox, elmBar.nextSibling ); // ie6 では elmBar の 子にすると 選択肢が表示されない
1615 nodeBox.setPosition( data.node.x(), barH );
1618 children = elmBox.childNodes,
1619 list = data.optionDataList
1621 while( l < children.length ){
1622 elmBox.removeChild( elmBox.firstChild );
1624 for( i = 0; i < l; ++i ){
1625 list[ i ].show( children[ i ] );
1629 nodeBar.addEventListener( 'mouseout', this.hide, this );
1630 nodeBox.addEventListener( 'click', data.onOptionClick, data );
1631 data.visible = true;
1634 data = MenuPrivateDataClass.get( this );
1635 if( data.visible === false ) return;
1637 data.elm.className = ELM_ITEM_CLASSNAME;
1638 for( var i = data.optionDataList.length; i; ){
1639 data.optionDataList[ --i ].hide();
1641 elmBar.parentNode.removeChild( elmBox );
1642 nodeBox.disabled( true );
1644 nodeBar.removeEventListener( 'mouseout', this.hide );
1645 nodeBox.removeEventListener( 'click', data.onOptionClick );
1646 data.visible = false;
1649 createOption: function( title, shortcut, callback, visible, separateBefore, separateAfter, thisObject ){
1650 var data = MenuPrivateDataClass.get( this ),
1651 before = data.optionDataList[ data.optionDataList.length - 1 ],
1652 ret = new OptionClass( data, title, shortcut, callback, visible, separateAfter, thisObject ),
1653 dataOption = PrivateOptionDataClass.get( ret );
1654 if( before ) before.border = separateBefore === true || before.separateAfter === true;
1655 data.optionDataList.push( dataOption );
1656 if( data.visible === true ){
1662 createAsyncOption: function( onOpen, visible, separateBefore, separateAfter, thisObject ){
1663 var data = MenuPrivateDataClass.get( this ),
1664 before = data.optionDataList[ data.optionDataList.length -1 ],
1665 ret = new AsyncOptionClass( data, onOpen, visible, separateAfter, thisObject ),
1666 dataOption = PrivateOptionDataClass.get( ret );
1667 if( before ) before.border = separateBefore === true || before.separateAfter === true;
1668 data.optionDataList.push( dataOption );
1669 data.visible === true && dataOption.show();
1672 remove : function( option ){
1673 var data = MenuPrivateDataClass.get( this ),
1674 optionData = PrivateOptionDataClass.get( option ),
1675 i = Util.getIndex( data.optionDataList, optionData );
1676 if( i === -1 ) return;
1678 data.optionDataList.splice( i, 1 );
1680 data.visible === true && elmBox.removeChild( optionData.elm ) && optionData.hide();
1681 optionData.remove();
1683 !( option instanceof AsyncOptionClass ) && data.optionDataList.length === 0 && this.hide();
1688 id : 'MENU_BAR_CONTROL',
1691 elmBar = document.getElementById( 'menu-bar' );
1692 nodeBar = eventRoot.createNode( elmBar, false, false, 'menu-bar-hover' );
1694 MENU_BAR_CONTROL.QUIT = MENU_BAR_CONTROL.createItem( 'Quit' );
1695 MENU_BAR_CONTROL.EDIT = MENU_BAR_CONTROL.createItem( 'Edit' );
1696 MENU_BAR_CONTROL.WINDOW = MENU_BAR_CONTROL.createItem( 'Window' );
1697 MENU_BAR_CONTROL.HELP = MENU_BAR_CONTROL.createItem( 'Help' );
1699 var size = Util.getElementSize( MenuPrivateDataClass.list[ 0 ].elm );
1701 barH = MENU_BAR_CONTROL.h = size.height;
1703 elmBar.style.top = ( - barH ) + 'px';
1704 $( elmBar ).animate( { top: 0 } );
1706 delete MENU_BAR_CONTROL.init;
1709 for( var i = MenuPrivateDataClass.list.length; i; ) MenuPrivateDataClass.list[ --i ].open();
1710 delete MENU_BAR_CONTROL.open;
1714 while( data = MenuPrivateDataClass.list.shift() ) data.close();
1716 MenuPrivateDataClass.list = elmBar = layerBox = elmBox = null;
1717 MENU_BAR_CONTROL.kill = kill;
1718 MENU_BAR_CONTROL.kill();
1720 createItem : function( title ){
1721 return new MenuClass( title );
1723 busy : function( _busy ){
1726 onWindowResize: function( _windowW, _windowH ){
1737 /* ----------------------------------------
1741 var HISTORY_CONTROL = ( function() {
1749 * currentを控えてstackForward.push(current)
1750 * stackBack.pop()を実行してcurrentに
1752 if( stackBack.length === 0 ) return;
1754 var s = stackBack.pop();
1755 s.callback.apply( s.thisObj || {}, s.argBack );
1756 menubarBack.visible( stackBack.length !== 0 );
1757 SAVE_CONTROL.panelUpdated( stackBack.length !== 0 );
1759 stackForward.push( s );
1760 menubarForward.visible( true );
1763 if( stackForward.length === 0 ) return;
1765 var s = stackForward.pop();
1766 s.callback.apply( s.thisObj || {}, s.argForword );
1767 menubarForward.visible( stackForward.length !== 0 );
1769 stackBack.push( s );
1770 menubarBack.visible( true );
1771 SAVE_CONTROL.panelUpdated( true );
1773 var RecordClass = function( callback, argBack, argForword, destroy, opt_thisObject ){
1774 this.callback = callback;
1775 this.argBack = argBack;
1776 this.argForword = argForword;
1777 this.destroy = !!destroy;
1778 this.thisObj = opt_thisObject;
1780 RecordClass.prototype.kill = function( _callDestroy ){
1781 var _argBack = this.argBack,
1782 _argForword = this.argForword,
1787 if( _callDestroy !== true ) return;
1789 if( Type.isArray( _argBack ) === true ){ // isArray
1790 while( v = _argBack.shift() ){
1791 _callDestroy === true && Type.isFunction( v.destroy ) === true && v.destroy();
1794 if( Type.isArray( _argForword ) === true ){
1795 while( v = _argForword.shift() ){
1796 _callDestroy === true && Type.isFunction( v.destroy ) === true && v.destroy();
1802 app.addKeyEventListener( 'keydown', back, 90, false, true ); // ctrl + Z
1803 app.addKeyEventListener( 'keydown', forward, 90, true, true ); // ctrl + shift + Z
1804 app.addKeyEventListener( 'keydown', forward, 89, false, true ); // ctrl + Y
1806 delete HISTORY_CONTROL.init;
1809 menubarBack = MENU_BAR_CONTROL.EDIT.createOption( 'back', 'ctrl + z', back, false );
1810 menubarForward = MENU_BAR_CONTROL.EDIT.createOption( 'forward', 'ctrl + y', forward, false, false, true );
1812 delete HISTORY_CONTROL.open;
1816 while( s = stackBack.shift() ) s.kill( true );
1817 while( s = stackForward.shift() ) s.kill( true );
1818 menubarBack = menubarForward = stackBack = stackForward = null;
1820 saveState: function( _function, _argBack, _argForword, _onRecordDestroy, opt_thisObject ){
1821 stackBack.push( new RecordClass( _function, _argBack, _argForword, _onRecordDestroy, opt_thisObject ));
1822 menubarBack.visible( true );
1823 SAVE_CONTROL.panelUpdated( true );
1826 while( s = stackForward.shift() ) s.kill( s.destroy );
1827 menubarForward.visible( false );
1832 /* ----------------------------------------
1836 var SAVE_CONTROL = ( function(){
1837 var save, saveQuit, eXport, quit,
1844 PanelConsole.boot( Model.createPanel( {
1847 panelTimming : panelTimming,
1848 panelW : PANEL_CONTROL.w,
1849 panelH : PANEL_CONTROL.h,
1851 panelElementArray : PANEL_ELEMENT_ARRAY,
1855 function onSaveQuit(){
1856 // Editor.shutdown();
1859 function onExport(){
1861 comicID, panelID, panelTimming,
1862 PANEL_CONTROL.w, PANEL_CONTROL.h,
1863 2, // border, BackgroundImage
1869 delete SAVE_CONTROL.init;
1872 save = MENU_BAR_CONTROL.QUIT.createOption( 'save', 'ctrl + S', onSave, false );
1873 saveQuit = MENU_BAR_CONTROL.QUIT.createOption( 'save & quit', null, onSaveQuit, false, false, true );
1874 eXport = MENU_BAR_CONTROL.QUIT.createOption( 'export', null, onExport, true, false, true );
1875 quit = MENU_BAR_CONTROL.QUIT.createOption( 'quit', null, quit, true, true );
1877 delete SAVE_CONTROL.open;
1880 save = saveQuit = eXport = quit = null;
1881 SAVE_CONTROL.kill = kill;
1882 SAVE_CONTROL.kill();
1885 panelUpdated: function( _updated ){
1886 if( Type.isBoolean( _updated ) === true ){
1887 save.visible( _updated );
1888 saveQuit.visible( _updated );
1899 /* ----------------------------------------
1902 * - mouseEventListener
1904 var WINDOWS_CONTROL = ( function(){
1906 * 表示上手前にあるwindowは、WINDOW_DATA_LISTの先頭にあり、htmlでは後ろにある。
1908 var DEFAULT_MIN_WINDOW_WIDTH = 200,
1909 DEFAULT_MIN_WINDOW_HEIGHT = 200,
1910 WINDOW_DATA_LIST = [],
1911 WINDOW_BODY_BODER_SIZE = 1,
1920 var WindowPrivateData = function(){};
1921 WindowPrivateData.prototype = {
1923 menubarOption : null,
1951 init : function( win, bodyTempleteID, title, x, y, w, h, visible, closeEnabled, resizeEnabled, minWindowW, minWindowH ){
1953 this.bodyTempleteID = bodyTempleteID;
1959 this.visible = visible;
1960 this.closeEnabled = closeEnabled;
1961 this.resizeEnabled = resizeEnabled;
1962 this.minWindowW = minWindowW;
1963 this.minWindowH = minWindowH;
1965 WINDOW_DATA_LIST.push( this );
1967 create : function(){
1968 var win = this.window;
1969 this.elm = win.elm = elmWindowOrigin.cloneNode( true );
1970 this.menubarOption = MENU_BAR_CONTROL.WINDOW.createOption(
1971 ( this.visible !== true ? 'show ' : 'hide ' ) + this.title,
1972 null, this.onMenubarClick,
1981 onMenubarClick : function(){
1982 this.window[ this.visible === true ? 'close' : 'open' ]();
1984 update : function( x, y, w, h ){
1985 var win = this.window, bodyH;
1987 x = x !== undefined ? x : this.x;
1988 y = y !== undefined ? y : this.y;
1989 y = y > MENU_BAR_CONTROL.h ? y : MENU_BAR_CONTROL.h;
1990 w = w !== undefined ? w : this.w;
1991 h = h !== undefined ? h : this.h;
1993 this.nodeWindow.update( x, y, w, h );
1994 this.nodeHead && this.nodeHead.update( 0, 0, w, this.headerH );
1995 console.log( '************ hewader' + this.headerH )
1996 this.nodeBody.update( 0, this.headerH, w, this.bodyH = h - this.headerH - this.footerH );
1997 ( this.w !== w || this.h !== h ) && win.onResize && win.onResize( w, this.bodyH );
2004 firstOpen : function(){
2005 var win = this.window,
2006 elmHead = this.elmHead = Util.getElementsByClassName( this.elm, 'window-header' )[ 0 ],
2007 elmBody = this.elmBody = Util.getElementsByClassName( this.elm, 'window-body' )[ 0 ],
2008 elmClose = Util.getElementsByClassName( this.elm, 'window-close-button' )[ 0 ],
2009 elmFoot = Util.getElementsByClassName( this.elm, 'window-footer' )[ 0 ],
2010 elmResize = Util.getElementsByClassName( this.elm, 'window-resize-button' )[ 0 ],
2011 replaceID = this.bodyTempleteID;
2013 this.nodeWindow = nodeContainer.createNode( this.elm, false, true, 'window-wrapper-hover' );
2014 this.nodeWindow.addEventListener( 'mousemove', this.mousemove, this );
2015 this.nodeWindow.addEventListener( 'mousedown', this.mousedown, this );
2016 this.nodeWindow.addEventListener( 'mouseup', this.mouseup, this );
2017 this.nodeWindow.addEventListener( 'mouseout', this.mouseup, this );
2019 // this.nodeHead = this.nodeWindow.createNode( elmHead );
2020 win.title( this.title );
2022 this.nodeBody = this.nodeWindow.createNode( elmBody, false, true, null, '', true );
2023 replaceID && elmBody.appendChild( document.getElementById( replaceID ) );
2025 if( this.closeEnabled === true ){
2026 // this.nodeClose = this.nodeHead.createNode( elmClose );
2027 // this.nodeClose.addEventListener( 'mousedown', win.close, data );
2029 elmClose.parentNode.removeChild( elmClose );
2032 if( this.resizeEnabled === true ){
2033 // this.nodeFoot = this.nodeWindow.createNode( elmFoot );
2034 this.footerH = Util.getElementSize( elmFoot ).height; // this.nodeFoot.height();
2036 // this.nodeResize = this.nodeFoot.createNode( elmResize );
2037 // this.nodeResize.addEventListener( 'mousedrag', this.resizeDrag, data );
2039 elmFoot.parentNode.removeChild( elmFoot );
2042 this.update( this.x, this.y, this.w, this.h );
2043 if( win.onFirstOpen ){
2044 win.onFirstOpen( this.w, this.bodyH, this.nodeBody );
2045 delete win.onFirtOpen;
2048 this.firstOpen = null;
2050 onFadeIn : function(){
2051 var data = WindowPrivateData.get( this ),
2053 data.firstOpen && data.firstOpen();
2054 win.onOpen && win.onOpen( data.w, data.bodyH );
2055 data.nodeWindow.disabled( false );
2058 onFadeOut : function(){
2059 var data = WindowPrivateData.get( this ),
2061 elmRoot.removeChild( data.elm );
2062 win.onClose && app.addAsyncCall( win.onClose, null, win );
2064 mousedown : function( e ){
2065 currentWindowData !== this && this.goFront();
2069 if( this.resizeEnabled === true && this.w - 20 <= x && x < this.w && this.headerH + this.bodyH < y && y <= this.h ){
2070 this.isResizing = true;
2071 //this.startX = this.x;
2072 //this.startY = this.y;
2073 this.startW = this.w;
2074 this.startH = this.h;
2077 // app.updateCoursor( 'nw-resize' );
2078 this.nodeWindow.cursor( 'nw-resize' );
2082 // if( x < 0 || y < 0 || this.w < x || this.headerH < y ) return false;
2083 if( this.closeEnabled === true && this.w - closeButtonWidth < x && y < this.headerH ){
2084 this.window.close();
2088 if( y < this.headerH ){
2089 this.isDragging = true;
2090 this.startX = this.x;
2091 this.startY = this.y;
2092 this.startW = this.w;
2093 this.startH = this.h;
2097 // app.updateCoursor( 'move' );
2098 this.nodeWindow.cursor( 'move' );
2102 mouseup : function( e ){
2103 if( this.isResizing === true || this.isDragging === true ){
2104 this.isDragging = this.isResizing = false;
2107 this.nodeWindow.cursor( '' );
2109 mousemove : function( e ){
2110 currentWindowData !== this && this.goFront();
2115 if( this.isResizing === true ){
2116 w = this.startW + x - this.offsetX;
2117 h = this.startH + y - this.offsetY;
2118 this.w = w = w < this.minWindowW ? this.minWindowW : w;
2119 this.h = h = h < this.minWindowH ? this.minWindowH : h;
2120 this.elm.style.width = w + 'px';
2121 this.elm.style.height = h + 'px';
2124 if( this.isDragging === true ){
2125 this.x = x = this.startX + x - this.offsetX;
2126 this.y = y = this.startY + y - this.offsetY;
2127 this.elm.style.left = x + 'px';
2128 this.elm.style.top = y + 'px';
2131 // if( e.hit === false || ( this.headerH < layerY && layerY < this.headerH + this.bodyH ) ) return false;
2132 this.nodeWindow.cursor( ( /*0 < layerX && layerX < this.w && 0 <= layerY &&*/ y <= this.headerH ) ? 'pointer' : '' );
2134 goFront : function(){
2135 currentWindowData = this;
2136 var i = nodeContainer.numNode() - 1;
2137 // console.log( this.nodeWindow.nodeIndex() + ' , ' + this.nodeWindow.numNode() )
2138 if( this.nodeWindow.nodeIndex() !== i ){
2139 this.nodeWindow.nodeIndex( i );
2140 elmRoot.appendChild( this.elm );
2144 return this.isDragging === true || this.isResizing === true;
2146 destroy : function(){
2150 WindowPrivateData.get = function( windowOrElement ){
2151 if( windowOrElement instanceof WindowPrivateData ) return windowOrElement;
2152 var list = WINDOW_DATA_LIST,
2157 if( data.window === windowOrElement || data.elm === windowOrElement ) return data;
2165 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, closeEnabled, resizeEnabled, minWindowW, minWindowH ){
2166 ( new WindowPrivateData() ).init( this, bodyTempleteID, title, x, y, w, h, visible, closeEnabled, resizeEnabled, minWindowW, minWindowH );
2168 WindowClass.prototype = {
2171 var data = WindowPrivateData.get( this );
2172 if( data.visible === true ) return;
2174 data.visible = true;
2176 data.menubarOption.title( 'hide ' + data.title );
2178 // WINDOW_DATA_LIST.splice( Util.getIndex( WINDOW_DATA_LIST, data ), 1 );
2179 // WINDOW_DATA_LIST.unshift( data );
2180 currentWindowData = null;
2183 var data = WindowPrivateData.get( this );
2184 if( data.visible === false ) return;
2186 data.visible = false;
2187 $( data.elm ).fadeOut( data.onFadeOut );
2188 data.menubarOption.title( 'show ' + data.title );
2189 data.nodeWindow.disabled( true );
2191 title : function( _title ){
2192 if( Type.isString( _title ) === true ){
2193 var data = WindowPrivateData.get( this );
2194 data.elmHead.firstChild.innerHTML = data.title = _title;
2195 // data.nodeHead.mesure();
2196 //data.headerH = data.nodeHead.height();
2197 data.headerH = Util.getElementSize( data.elmHead ).height;
2201 createHeaderItem : function(){
2202 var data = WindowPrivateData.get( this ),
2203 elm = document.createElement( 'div' ),
2205 if( !data.nodeHead ) data.nodeHead = data.nodeWindow.createNode( data.elmHead, true, false );
2206 data.elmHead.appendChild( elm );
2207 elm.className = 'header-item finder-path';
2208 node = data.nodeHead.createNode( elm, false, true, 'header-item-hover', '' )
2209 // data.nodeHead.mesure();
2210 // data.headerH = data.nodeHead.height();
2212 data.headerH = Util.getElementSize( data.elmHead ).height;
2219 function openWindow( data ){
2220 if( data.visible !== true ) return;
2221 elmRoot.appendChild( data.elm );// appendした後に fadeIn() しないと ie で filterが適用されない.
2222 $( data.elm ).fadeIn( data.onFadeIn );
2227 id : 'WINDOWS_CONTROL',
2229 elmRoot = document.getElementById( 'window-container' );
2230 nodeContainer = eventRoot.createNode( elmRoot, true, false );
2231 elmWindowOrigin = app.fetchHTMLElement( 'windowTemplete' );
2232 closeButtonWidth = Util.getElementSize( Util.getElementsByClassName( elmWindowOrigin, 'window-close-button' )[ 0 ] ).width;
2234 delete WINDOWS_CONTROL.init;
2237 for( var i = WINDOW_DATA_LIST.length, data; i; ){
2238 data = WINDOW_DATA_LIST[ --i ];
2242 delete WINDOWS_CONTROL.open;
2246 onWindowResize : function( _windowW, _windowH ){
2251 createWindow : function( EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeEnabled, opt_resizeEnabled, opt_minWindowW, opt_minWindowH ){
2252 opt_visible = opt_visible !== false;
2253 opt_closeEnabled = opt_closeEnabled === true;
2254 opt_resizeEnabled = opt_resizeEnabled === true;
2255 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH ) ? w : DEFAULT_MIN_WINDOW_WIDTH;
2256 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT ) ? h : DEFAULT_MIN_WINDOW_HEIGHT;
2258 var win = new WindowClass( bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeEnabled, opt_resizeEnabled, opt_minWindowW, opt_minWindowH ),
2260 for( var key in EXTENDS ){
2261 win[ key ] = EXTENDS[ key ];
2263 if( Type.isUndefined( WINDOWS_CONTROL.init ) === true ){
2264 data = WindowPrivateData.get( win );
2273 /* ----------------------------------------
2277 var TOOL_BOX_WINDOW = ( function(){
2279 app.addKeyEventListener( 'keydown', addImage, 73, false, true );
2280 app.addKeyEventListener( 'keydown', addText, 84, false, true );
2281 app.addKeyEventListener( 'keydown', switchGrid, 71, false, true );
2283 function addImage(){
2284 // IMAGE_EXPLORER_WINDOW.open();
2285 app.addAsyncCall( IMAGE_EXPLORER_WINDOW.open, null, IMAGE_EXPLORER_WINDOW );
2286 //TOOL_BOX_WINDOW.bodyBackOrForward( true );
2289 app.addAsyncCall( PANEL_ELEMENT_CONTROL.createTextElement );
2291 function switchGrid(){
2292 app.addAsyncCall( GRID_CONTROL.update, null, GRID_CONTROL );
2294 function popupHelp(){
2295 //.bodyBackOrForward( true );
2296 app.addAsyncCall( HELP_DOCUMENTS_WINDOW.open, null, HELP_DOCUMENTS_WINDOW );
2298 function editBG( e ){
2299 //TOOL_BOX_WINDOW.bodyBackOrForward( true );
2300 app.addAsyncCall( INFOMATION_WINDOW.open, null, INFOMATION_WINDOW );
2303 return WINDOWS_CONTROL.createWindow(
2306 MENU_BAR_CONTROL.EDIT.createOption( 'Add Image', 'ctrl + I', addImage, true, true, false );
2307 MENU_BAR_CONTROL.EDIT.createOption( 'Add Text', 'ctrl + T', addText, true, false, true );
2308 MENU_BAR_CONTROL.EDIT.createOption( 'show Grid', 'ctrl + G', switchGrid, true, true, true );
2310 onFirstOpen: function( x, y, nodeBody ){
2311 nodeBody.createNode( document.getElementById( 'toolbox-add-image-button' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', addImage );
2312 nodeBody.createNode( document.getElementById( 'toolbox-add-text-button' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', addText );
2313 nodeBody.createNode( document.getElementById( 'toolbox-edit-bg-button' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', editBG );
2314 nodeBody.createNode( document.getElementById( 'toolbox-switch-grid' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', switchGrid );
2315 nodeBody.createNode( document.getElementById( 'toolbox-popup-help-button' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', popupHelp );
2316 // nodeBody.createNode( document.getElementById( 'toolbox-add-text-button' ), false, true, 'button-hover', 'pointer' ).addEventListener( 'click', addText );
2319 'toolbox-window', 'Tool box', 0, 215, 110, 290, true
2324 /* ----------------------------------------
2328 var IMAGE_EXPLORER_WINDOW = ( function(){
2331 function onFileSelect( file ){
2332 // 他の image ファイルも許可する?
2333 if( Driver.isPettanrFileInstance( file ) === true ){
2334 if( file.getType() === FILE_TYPE.RESOURCE_PICTURE ){
2335 PANEL_ELEMENT_CONTROL.onImageSelect( FileAPI.getFileData( file ) );
2340 return WINDOWS_CONTROL.createWindow(
2342 onInit: function(){},
2343 onFirstOpen: function( _w, _h, nodeBody ){
2344 tree = FileAPI.createTree( FILE_DATA_RESOURCE_PICTURES_ROOT );
2345 var _root = tree.getRootFile(),
2346 _myPic = _root.getChildFileAt( 0 ),
2347 _pic = _root.getChildFileAt( 1 );
2348 _myPic.getSeqentialFiles();
2349 _pic.getSeqentialFiles();
2353 finder = app.createFinder(
2358 finder.createPath( IMAGE_EXPLORER_WINDOW.createHeaderItem() );
2360 onOpen: function( _w, _h ){
2361 finder.resize( _w, _h );
2363 onResize: function( _w, _h ){
2364 finder.resize( _w, _h );
2367 null, 'Album', 0, 215, 600, 350, false, true, true, 300, 300
2372 /* ----------------------------------------
2376 var INFOMATION_WINDOW = ( function(){
2377 var backgroundInfomationElm;
2379 return WINDOWS_CONTROL.createWindow(
2381 onFirstOpen: function( _w, _h ){
2382 backgroundInfomationElm = $( '#panel-background-information');
2384 onResize: function( _w, _h ){
2386 update: function( currentElement ){
2390 'infomation-window', 'Infomation', 0, 30, 200, 180, true
2394 /* ----------------------------------------
2398 var HELP_DOCUMENTS_WINDOW = ( function(){
2403 currentPageIndex = 0,
2407 function onAjaxStart( _pageIndex ){
2408 delete asyncOption.callback;
2410 currentPageIndex = _pageIndex || currentPageIndex;
2411 if( onHelpLoad !== null ){
2421 var onHelpLoad = function( _xml ){
2422 var jqXML = $( _xml ),
2423 helpTitle = jqXML.find( 'pages' ).eq( 0 ).attr( 'title' ),
2424 elmRoot = document.createElement( 'div' ),
2425 elmNavi = document.createElement( 'div' ),
2426 elmItemOrigin = document.createElement( 'a' ),
2427 elmPages = document.createElement( 'div' ),
2428 elmPageOrigin = document.createElement( 'div' ),
2429 elmTitleOrigin = document.createElement( 'h2' ),
2431 elmRoot.className = 'multi-page-container clearfix';
2432 elmNavi.className = 'sidenavi';
2433 elmItemOrigin.className = 'sidenavi-item';
2434 elmItemOrigin.href = '#';
2435 elmPages.className = 'page-contents';
2436 elmPageOrigin.className = 'page-content main';
2437 elmPageOrigin.appendChild( elmTitleOrigin);
2439 MENU_BAR_CONTROL.HELP.remove( asyncOption );
2442 jqXML.find( 'page' ).each( function(){
2443 var xmlPage = $( this ),
2444 title = xmlPage.attr( 'title' ),
2445 content = xmlPage.text();
2447 elmItemOrigin.innerHTML = title;
2448 elmNavi.appendChild( elmItemOrigin.cloneNode( true ) );
2450 elmTitleOrigin.innerHTML = title;
2452 elmPage = elmPageOrigin.cloneNode( true );
2453 elmPage.innerHTML = content;
2455 Util.cleanElement( elmPage);
2457 if( elmPage.childNodes.length > 0 ){
2458 elmPage.insertBefore( elmTitleOrigin.cloneNode( true ), elmPage.childNodes[0]);
2460 elmPage.appendChild( elmTitleOrigin.cloneNode( true ));
2462 elmPages.appendChild( elmPage );
2464 MENU_BAR_CONTROL.HELP.createOption( title, null, onSelectionClick, true );
2467 elmRoot.appendChild( elmNavi );
2468 elmRoot.appendChild( elmPages );
2469 jqAjaxContents.removeClass( 'loading' ).append( elmRoot );
2471 jqNaviItems = jqAjaxContents.find( 'a.' + elmItemOrigin.className ).click( onNaviClick );
2472 jqPages = jqAjaxContents.find( '.page-content' );
2473 jqPages.find( 'a' ).click( onInnerLinkClick );
2475 app.addAsyncCall( jumpPage );
2477 function onSelectionClick( _pageIndex ){
2478 HELP_DOCUMENTS_WINDOW.open();
2479 jumpPage( _pageIndex );
2481 function jumpPage( _index ){
2482 if( Type.isNumber( _index ) === true && 0 <= _index && _index < numPage && currentPageIndex !== _index ){
2483 currentPageIndex = _index;
2485 jqNaviItems.removeClass( 'current' ).eq( currentPageIndex ).addClass( 'current' );
2486 jqPages.hide().eq( currentPageIndex ).show();
2488 function onNaviClick( e ){
2490 jumpPage( Util.getChildIndex( this.parentNode, this ) );
2493 function onInnerLinkClick( e ){
2494 var jump = ( this.href || '' ).split( '#jump' ),
2497 jumpPage( '' + parseFloat( n ) === n ? parseFloat( n ) : -1 );
2500 return WINDOWS_CONTROL.createWindow(
2503 asyncOption = MENU_BAR_CONTROL.HELP.createAsyncOption( onAjaxStart );
2504 jqAjaxContents = $( HELP_DOCUMENTS_WINDOW.elm ).find( '.window-body' ).addClass( 'loading' ).css( { overflow: 'auto' } );
2506 onFirstOpen: function( _w, _h ){
2507 jqAjaxContents.css( { height: _h } );
2508 onAjaxStart !== null && onAjaxStart();
2510 onResize: function( _w, _h ){
2511 jqAjaxContents && jqAjaxContents.css( { height: _h } );
2514 null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300
2518 /* ----------------------------------------
2521 * - panelResizeListener
2523 var GRID_CONTROL = ( function(){
2525 urlBG = "url('images/grid.gif')",
2530 elmGrid = document.getElementById( 'grid' );
2531 delete GRID_CONTROL.init;
2534 delete GRID_CONTROL.open;
2539 onPanelResize: function( _panelX, _panelY ){
2540 elmGrid.style.backgroundPosition = [ _panelX % 10, 'px ', _panelY % 10, 'px' ].join( '' );
2541 elmGrid.style.height = windowH +'px';
2543 enabled: function(){
2547 $( elmGrid ).stop().css( {
2550 })[ visible === true ? 'fadeOut' : 'fadeIn' ]();
2554 if( visible === true && urlBG !== null ){
2555 elmGrid.style.backgroundImage = urlBG;
2563 /* ----------------------------------------
2564 * WHITE_GLASS_CONTROL
2565 * - panelResizeListener
2567 var WHITE_GLASS_CONTROL = ( function(){
2568 var styleTop, styleLeft, styleRight, styleBottom;
2572 styleTop = document.getElementById( 'whiteGlass-top' ).style;
2573 styleLeft = document.getElementById( 'whiteGlass-left' ).style;
2574 styleRight = document.getElementById( 'whiteGlass-right' ).style;
2575 styleBottom = document.getElementById( 'whiteGlass-bottom' ).style;
2576 delete WHITE_GLASS_CONTROL.init;
2578 onPanelResize: function( _panelX, _panelY, _panelW, _panelH ){
2581 marginTop = _panelY,
2582 marginBottom = windowH -_h -marginTop,
2584 rightWidth = windowW -_w -marginX;
2586 styleTop.height = ( marginTop < 0 ? 0 : marginTop ) + 'px';
2588 styleLeft.top = marginTop + 'px';
2589 styleLeft.width = ( marginX < 0 ? 0 : marginX ) + 'px';
2590 styleLeft.height = ( _h + marginBottom ) + 'px';
2592 styleRight.top = marginTop + 'px';
2593 styleRight.left = _w +marginX + 'px';
2594 styleRight.width = ( rightWidth < 0 ? 0 : rightWidth ) + 'px';
2595 styleRight.height = ( _h + marginBottom ) + 'px';
2597 styleBottom.top = ( _h +marginTop ) + 'px';
2598 styleBottom.left = marginX + 'px';
2599 styleBottom.width = _w + 'px';
2600 styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom ) + 'px';
2606 /* --------------------------------------------------------------------------------------------
2608 * - mouseEventListener
2610 var PanelResizerClass = function( id, isTop ){
2614 PanelResizerClass.BORDER_SIZE = 2;
2615 PanelResizerClass.HEIGHT = 30;
2616 PanelResizerClass.prototype = {
2621 x : - PanelResizerClass.BORDER_SIZE / 2,
2624 h : PanelResizerClass.HEIGHT,
2634 this.node = PANEL_CONTROL.node.createNode( document.getElementById( this.id ), false, false, 'panel-resizer-hover', 'pointer' );
2635 this.node.addEventListener( 'mousedown', this.mousedown, this );
2636 this.style = document.getElementById( this.id ).style;
2637 this.y = this.isTop === true ? ( -5 - PanelResizerClass.HEIGHT - PanelResizerClass.BORDER_SIZE ) : 0;
2639 mousedown : function( e ){
2641 var x = e.layerX, // - this.panelX,
2642 y = e.layerY; // - this.panelY;
2644 this.startY = this.panelY;
2645 this.startH = this.panelH;
2646 this.isDragging = true;
2647 // app.updateCoursor( 'n-resize' );
2648 this.node.addEventListener( 'mousemove', this.mousemove, this );
2649 this.node.addEventListener( 'mouseup', this.mouseup, this );
2650 this.node.cursor( 'n-resize' );
2653 mousemove : function( e ){
2654 var move = e.layerY - this.offsetY,
2657 if( this.isTop === true ){
2658 if( this.panelH - move < MIN_PANEL_HEIGHT ){
2659 move = this.panelH - MIN_PANEL_HEIGHT;
2661 PANEL_CONTROL.resizeElement( true, this.panelX, this.panelY + move, this.panelW, this.panelH - move );
2663 h = this.startH + move;
2664 if( 0 < h && h < windowH - this.panelY - PanelResizerClass.HEIGHT - 5 - PanelResizerClass.BORDER_SIZE ){
2665 PANEL_CONTROL.resizeElement( false, this.panelX, this.panelY, this.panelW, h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : h );
2670 mouseup : function( e ){
2671 if( this.isDragging !== true ) return;
2672 ( this.startY !== this.panelY || this.startH !== this.panelH ) &&
2673 HISTORY_CONTROL.saveState(
2675 [ undefined, this.startY, undefined, this.startH ],
2676 [ undefined, this.panelY, undefined, this.panelH ],
2679 this.isDragging = false;
2680 var move = e.layerY - this.offsetY,
2683 if( this.isTop === true ){
2684 if( this.panelH - move < MIN_PANEL_HEIGHT ){
2685 move = this.panelH - MIN_PANEL_HEIGHT;
2687 PANEL_CONTROL.resize( true, this.panelX, this.panelY + move, this.panelW, this.panelH - move );
2689 h = this.startH + move;
2690 if( 0 < h && h < windowH - this.panelY - PanelResizerClass.HEIGHT - 5 - PanelResizerClass.BORDER_SIZE ){
2691 PANEL_CONTROL.resize( false, this.panelX, this.panelY, this.panelW, h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : h );
2694 // app.updateCoursor( '' );
2695 this.node.removeEventListener( 'mousemove', this.mousemove );
2696 this.node.removeEventListener( 'mouseup', this.mouseup );
2697 this.node.cursor( 'pointer' );
2699 restoreState : function( x, y, w, h ){
2700 PANEL_CONTROL.resize( this.isTop, x || this.panelX, y || this.panelY, w || this.panelW, h || this.panelH );
2703 return this.isDragging;
2705 onPanelResize : function( x, y, w, h ){
2708 if( this.panelW !== w ){
2709 this.style.width = ( w + 2 ) + 'px';
2713 this.y = this.isTop === true ? this.y : ( this.panelH + 5 + PanelResizerClass.BORDER_SIZE );
2714 this.w = this.panelW + 2;
2715 this.node.update( undefined, undefined, this.w );
2719 /* ----------------------------------------
2722 * - mouseEventListener
2724 * panel-border の表示と onPanelResize の通知.
2728 var PANEL_CONTROL = ( function(){
2729 var elmPanel, stylePanel,
2731 DEFAULT_PANEL_WIDTH = 400,
2732 DEFAULT_PANEL_HEIGHT = 300,
2734 offsetX, offsetY, startX, startY,
2736 isDraggable = false,
2737 resizerTop = new PanelResizerClass( 'panel-resizer-top', true ),
2738 resizerBottom = new PanelResizerClass( 'panel-resizer-bottom', false );
2740 app.addKeyEventListener( 'keychange', onSpaceUpdate, 32, false, false );
2742 function onSpaceUpdate( e ){
2743 if( e.type === 'keyup' ){
2744 app.isCurrentInteractiveEventListener( null ) === true && app.updateCoursor( '' );
2745 isDraggable = false;
2747 app.isCurrentInteractiveEventListener( null ) === true && app.updateCoursor( 'move' );
2754 id : 'PANEL_CONTROL',
2762 elmPanel = this.elm = document.getElementById( 'panel-tools-container' );
2763 nodePanel = this.node = eventRoot.createNode( elmPanel, true, false );
2766 resizerBottom.init();
2768 stylePanel = elmPanel.style;
2769 delete PANEL_CONTROL.init;
2771 open: function( _panelW, _panelH, _borderSize ){
2772 PANEL_CONTROL.w = Type.isFinite( _panelW ) === true ? _panelW : DEFAULT_PANEL_WIDTH;
2773 PANEL_CONTROL.h = Type.isFinite( _panelH ) === true ? _panelH : DEFAULT_PANEL_HEIGHT;
2774 borderSize = Type.isFinite( _borderSize ) === true ? _borderSize : borderSize;
2776 delete PANEL_CONTROL.open;
2781 resize: function( isResizerTopAction, x, y, w, h ){
2782 PANEL_CONTROL.x = x = x !== undefined ? x : PANEL_CONTROL.x;
2783 PANEL_CONTROL.y = y = y !== undefined ? y : PANEL_CONTROL.y;
2784 PANEL_CONTROL.w = w = w !== undefined ? w : PANEL_CONTROL.w;
2785 PANEL_CONTROL.h = h = h !== undefined ? h : PANEL_CONTROL.h;
2787 nodePanel.update( x - borderSize, y - borderSize, w, h );
2790 resizerTop.onPanelResize( x, y, w, h );
2791 resizerBottom.onPanelResize( x, y, w, h );
2792 GRID_CONTROL.onPanelResize( x, y );
2793 WHITE_GLASS_CONTROL.onPanelResize( x, y, w, h );
2794 PANEL_ELEMENT_CONTROL.onPanelResize( x, y, w, h, isResizerTopAction === true );
2796 resizeElement : function( isResizerTopAction, x, y, w, h ){
2797 stylePanel.cssText = [ 'left:', ( x - borderSize ), 'px;',
2798 'top:', ( y - borderSize ), 'px;',
2800 'height:', h, 'px' ].join( '' );
2801 // PANEL_RESIZER_TOP.onPanelResize( x, y, w, h );
2802 // PANEL_RESIZER_BOTTOM.onPanelResize( x, y, w, h );
2803 GRID_CONTROL.onPanelResize( x, y );
2804 WHITE_GLASS_CONTROL.onPanelResize( x, y, w, h );
2805 PANEL_ELEMENT_CONTROL.onPanelResize( x, y, w, h, isResizerTopAction );
2807 onWindowResize: function( _windowW, _windowH ){
2808 PANEL_CONTROL.x = Math.floor( ( _windowW - PANEL_CONTROL.w ) / 2 );
2809 PANEL_CONTROL.y = Math.floor( ( _windowH - PANEL_CONTROL.h ) / 2 );
2810 PANEL_CONTROL.resize();
2812 mousemove: function( _mouseX, _mouseY ){
2813 if( isDraggable === true && isDragging === true ){
2814 PANEL_CONTROL.resize( false, startX + _mouseX - offsetX, startY + _mouseY - offsetY );
2817 mouseup: function( _mouseX, _mouseY ){
2818 if( isDraggable === true ){
2820 app.updateCoursor( '' );
2823 mousedown: function( _mouseX, _mouseY ){
2824 if( isDraggable === true ){
2827 startX = PANEL_CONTROL.x;
2828 startY = PANEL_CONTROL.y;
2830 app.updateCoursor( 'move' );
2835 return isDragging === true;
2840 /* --------------------------------------------------------------------------------------------
2842 * - panelElementOperator
2844 var TailOperator = ( function(){
2851 DEG_TO_RAD = Math.PI / 180,
2852 RAD_TO_DEG = 1 / DEG_TO_RAD,
2856 balloonW, balloonH, balloonA, radA,
2862 var elm = document.getElementById( 'balloon-tail-mover' );
2863 SIZE = Util.getElementSize( elm ).width;
2864 styleMover = elm.style;
2865 delete TailOperator.init;
2867 update: function ( _w, _h, _a ){
2868 balloonW = _w !== undefined ? _w : balloonW;
2869 balloonH = _h !== undefined ? _h : balloonH;
2870 balloonA = _a !== undefined ? _a : balloonA;
2871 radA = ( balloonA - 90 ) * DEG_TO_RAD;
2872 tailX = FLOOR( ( ( COS( radA ) / 2 + 0.5 ) * ( balloonW + SIZE )) - SIZE / 2 );
2873 tailY = FLOOR( ( ( SIN( radA ) / 2 + 0.5 ) * ( balloonH + SIZE )) - SIZE / 2 );
2874 styleMover.left = tailX + 'px';
2875 styleMover.top = tailY + 'px';
2877 show: function( _currentText ){
2879 * visibilityのほうがいい, display:none だと ie で描画が狂う
2881 styleMover.visibility = '';
2882 currentText = _currentText;
2883 TailOperator.update( _currentText.w, _currentText.h, _currentText.a );
2886 styleMover.visibility = 'hidden';
2889 hitTest: function( _mouseX, _mouseY ){
2890 var _x = tailX -SIZE / 2,
2891 _y = tailY -SIZE / 2,
2892 ret = _x <= _mouseX && _y <= _mouseY && _x + SIZE >= _mouseX && _y + SIZE >= _mouseY;
2893 ret === true && app.updateCoursor( 'move' );
2896 onStart: function( _mouseX, _mouseY ){
2897 if( currentText.type !== PANEL_ELEMENT_TYPE_TEXT ) return false;
2898 if( TailOperator.hitTest( _mouseX, _mouseY ) === true ){
2901 startA = currentText.a;
2906 onDrag: function( _mouseX, _mouseY ){
2907 _mouseX = _mouseX - w / 2;
2908 _mouseY = _mouseY - h / 2; //Balloonの中心を0,0とする座標系に変換
2909 TailOperator.update( w, h,
2911 ATAN( _mouseY / _mouseX ) * RAD_TO_DEG + ( _mouseX > 0 ? 90 : 270 ) :
2912 _mouseY > 0 ? 180 : 0
2914 currentText && currentText.angle( FLOOR( balloonA + 0.5 ) );
2915 CONSOLE_CONTROLER.update( currentText );
2917 onFinish: function(){
2918 startA !== currentText.a && PanelElementOperatorManager.saveStatus( undefined, undefined, w, h, startA );
2919 startA !== currentText.a && PanelElementOperatorManager.resize( undefined, undefined, w, h, currentText.a );
2921 onCancel: function(){
2922 currentText.angle( startA );
2923 PanelElementOperatorManager.resize( undefined, undefined, w, h, startA );
2928 /* --------------------------------------------------------------------------------------------
2930 * - panelElementOperator
2932 var ResizeOperator = ( function(){
2933 var HIT_AREA = MOUSE_HIT_AREA,
2934 POSITION_ARRAY = [],
2937 { cursor: 'n-resize', v: 3 },
2938 { cursor: 'e-resize', h: 2 },
2939 { cursor: 'e-resize', h: 1 },
2940 { cursor: 'n-resize', v: 0 },
2941 { cursor: 'nw-resize', h: 5, v: 6, vh: 7 },
2942 { cursor: 'ne-resize', h: 4, v: 7, vh: 6 },
2943 { cursor: 'ne-resize', h: 7, v: 4, vh: 5 },
2944 { cursor: 'nw-resize', h: 6, v: 5, vh: 4 }
2957 var RESIZE_WORK_ARRAY = [
2958 { x: 0, w: 0, y: 1, h: -1}, //top
2959 { x: 1, w: -1, y: 0, h: 0}, //left
2960 { x: 0, w: 1, y: 0, h: 0}, //right
2961 { x: 0, w: 0, y: 0, h: 1}, //bottom
2962 { x: 1, w: -1, y: 1, h: -1}, //top-left
2963 { x: 0, w: 1, y: 1, h: -1}, //top-right
2964 { x: 1, w: -1, y: 0, h: 1}, //bottom-left
2965 { x: 0, w: 1, y: 0, h: 1} //bottom-right
2967 startX, startY, startW, startH,
2968 flipV, flipH, startFilpV, startFilpH, startAspect,
2969 baseX, baseY, baseW, baseH,
2970 currentX, currentY, currentW, currentH,
2974 function update( _x, _y, _w, _h ){
2976 _x = _x !== undefined ? _x : currentX;
2977 _y = _y !== undefined ? _y : currentY;
2978 _w = _w !== undefined ? _w : currentW;
2979 _h = _h !== undefined ? _h : currentH;
2981 if( isSpeach === false && currentIndex > 3 && app.shiftEnabled() === true ){
2982 if( startAspect >= 1 ){
2984 _w = FLOOR( startAspect * _h );
2985 _x = _x + ( currentIndex % 2 === 0 ? __w - _w : 0 );
2988 _h = FLOOR( _w / startAspect );
2989 _y = _y + ( currentIndex <= 5 ? __h - _h : 0 );
2992 ResizeOperator.update( x = _x, y = _y, w = _w, h = _h );
2993 currentElement.resize( _x, _y, _w, _h );
2994 isSpeach === true && TailOperator.update( _w, _h );
2995 CONSOLE_CONTROLER.show( currentElement, _w, _h );
2996 // CONSOLE_CONTROLER.update( currentElement );
2999 function flip( _flipH, _flipV ){
3000 var p = CURSOR_AND_FLIP[ currentIndex ];
3001 currentIndex = _flipH === true || _flipV === true ? p[
3002 _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v' )
3004 app.updateCoursor( CURSOR_AND_FLIP[ currentIndex ].cursor );
3005 elmInner.className = 'current-resizer-is-' + currentIndex;
3006 currentElement.flip( _flipH, _flipV );
3010 elmInner = document.getElementById( 'comic-element-resizer-container-inner' );
3011 styleInner = elmInner.style;
3013 styleResizerTop = document.getElementById( 'comic-element-resizer-top' ).style;
3014 styleResizerLeft = document.getElementById( 'comic-element-resizer-left' ).style;
3015 styleResizerRight = document.getElementById( 'comic-element-resizer-right' ).style;
3016 styleResizerBottom = document.getElementById( 'comic-element-resizer-bottom' ).style;
3018 delete ResizeOperator.init;
3020 update: function( _x, _y, _w, _h ){
3021 x = _x = _x !== undefined ? _x : x;
3022 y = _y = _y !== undefined ? _y : y;
3023 w = _w = _w !== undefined ? _w : w;
3024 h = _h = _h !== undefined ? _h : h;
3026 PanelElementOperatorManager.resizeElement( _x, _y, _w, _h );
3028 styleInner.width = _w + 'px';
3029 styleInner.height = _h + 'px';
3031 styleResizerTop.left = styleResizerBottom.left = FLOOR( _w / 2 - 5 ) + 'px';
3032 styleResizerLeft.top = styleResizerRight.top = FLOOR( _h / 2 - 5 ) + 'px';
3034 POSITION_ARRAY.length = 0;
3035 POSITION_ARRAY.push(
3036 {x: 5, y: -HIT_AREA, w: _w - 5, h: HIT_AREA * 2 }, // top
3037 {x: -HIT_AREA, y: 5, w: HIT_AREA * 2, h: _h - 5 }, // left
3038 {x: _w - 5, y: HIT_AREA + 5, w: HIT_AREA * 2, h: _h - 5 }, // right
3039 {x: 5, y: _h - 5, w: _w - 5, h: HIT_AREA * 2 }, // bottom
3040 {x: -HIT_AREA, y: -HIT_AREA, w: HIT_AREA + 5, h: HIT_AREA + 5}, // top left
3041 {x: _w - 5, y: -HIT_AREA, w: HIT_AREA + 5, h: HIT_AREA + 5}, // top right
3042 {x: -HIT_AREA, y: _h - 5, w: HIT_AREA + 5, h: HIT_AREA + 5}, // bottom left
3043 {x: _w - 5, y: _h - 5, w: HIT_AREA + 5, h: HIT_AREA + 5} // bottom right
3046 index: function( _mouseX, _mouseY ){
3048 for( i = 4; i < 8; ++i ){
3049 p = POSITION_ARRAY[ i ];
3050 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y + p.h >= _mouseY ){
3051 app.updateCoursor( CURSOR_AND_FLIP[ i ].cursor );
3052 elmInner.className = 'current-resizer-is-' + i;
3053 return currentIndex = i;
3056 for( i = 0; i < 4; ++i ){
3057 p = POSITION_ARRAY[ i ];
3058 if( p.x <= _mouseX && _mouseX <= p.x + p.w && p.y <= _mouseY && _mouseY <= p.y + p.h ){
3059 app.updateCoursor( CURSOR_AND_FLIP[ i ].cursor );
3060 elmInner.className = 'current-resizer-is-' + i;
3061 return currentIndex = i;
3064 app.updateCoursor( '' );
3065 elmInner.className = '';
3068 show: function( _currentElement ){
3069 currentElement = _currentElement;
3070 isSpeach = _currentElement.type === PANEL_ELEMENT_TYPE_TEXT;
3071 ResizeOperator.update( _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h );
3074 currentElement = null;
3076 onStart: function( _mouseX, _mouseY ){
3077 isSpeach = currentElement.type === PANEL_ELEMENT_TYPE_TEXT;
3078 if( currentElement.keepSize === true ) return false;
3079 currentIndex = this.index( _mouseX, _mouseY );
3080 if( currentIndex === -1 ) return false;
3083 startX = baseX = currentElement.x;
3084 startY = baseY = currentElement.y;
3085 startW = baseW = currentElement.w;
3086 startH = baseH = currentElement.h;
3087 startFilpV = currentElement.flipV;
3088 startFilpH = currentElement.flipH;
3089 startAspect = startW / startH;
3092 onDrag: function( _mouseX, _mouseY ){
3093 var com = RESIZE_WORK_ARRAY[ currentIndex ],
3094 moveX = _mouseX - offsetX,
3095 moveY = _mouseY - offsetY,
3096 _updated = moveX !== 0 || moveY !== 0,
3103 * Opera 11+ often forget values, why ??
3105 while( _x === undefined || _y === undefined || _w === undefined || _h === undefined ){
3106 _x = _x !== undefined ? _x : baseX + moveX * com.x;
3107 _y = _y !== undefined ? _y : baseY + moveY * com.y;
3108 _w = _w !== undefined ? _w : baseW + moveX * com.w;
3109 _h = _h !== undefined ? _h : baseH + moveY * com.h;
3110 error += _thisError === 0 ? 0 : 1;
3112 if( _thisError > 9999 ){
3114 //alert( 'opera error' +error);
3120 if( _w >= MIN_ELEMENT_SIZE && _h >= MIN_ELEMENT_SIZE ){
3123 if( _w >= -MIN_ELEMENT_SIZE && _h >= -MIN_ELEMENT_SIZE ){
3125 if( _w < MIN_ELEMENT_SIZE){
3126 //_x += Math.abs( MIN_ELEMENT_SIZE -_w);
3128 _w = MIN_ELEMENT_SIZE;
3130 if( _h < MIN_ELEMENT_SIZE){
3131 //_y += Math.abs( MIN_ELEMENT_SIZE -_h);
3133 _h = MIN_ELEMENT_SIZE;
3136 if( currentElement.type === PANEL_ELEMENT_TYPE_TEXT ){
3139 if( _w < -MIN_ELEMENT_SIZE || _h < -MIN_ELEMENT_SIZE ){
3141 if( _w < -MIN_ELEMENT_SIZE && _h > MIN_ELEMENT_SIZE ){
3144 baseX = _x = _x +_w;
3146 baseW = _w = _memoryX -_x;
3148 flip( true, false );
3149 flipV = currentElement.flipV;
3151 if( _w > MIN_ELEMENT_SIZE && _h < -MIN_ELEMENT_SIZE ){
3155 baseY = _y = _y +_h;
3157 baseH = _h = _memoryY -_y;
3159 flipH = currentElement.flipH;
3164 baseX = _x = _x + _w;
3165 baseY = _y = _y + _h;
3166 baseW = _w = _memoryX - _x;
3167 baseH = _h = _memoryY - _y;
3169 flipV = currentElement.flipV;
3170 flipH = currentElement.flipH;
3180 _updated === true && update( _x, _y, _w, _h );
3183 'currentIndex:', currentIndex,
3184 'baseW', baseW, 'baseH', baseH,'<br>',
3185 'mouse', _mouseX, _mouseY,'<br>',
3186 'move', moveX, moveY,'<br>',
3187 'xy', _x, _y, 'wh',_w, _h,'<br>',
3188 'com.w', com.w, 'com.h', com.h,'<br>',
3189 'current',currentW, currentH,'<br>',
3194 onFinish: function(){
3195 app.updateCoursor( '' );
3196 if( w === startW && h === startH && x === startX && y === startY ) return;
3197 PanelElementOperatorManager.resize( x, y, w, h );
3198 currentElement.resize( x, y, w, h );
3199 PanelElementOperatorManager.saveStatus( startX, startY, startW, startH, undefined, startFilpV, startFilpH );
3201 onCancel: function(){
3202 app.updateCoursor( '' );
3203 PanelElementOperatorManager.resize( startX, startY, startW, startH );
3204 currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ?
3205 currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH ) :
3206 currentElement.animate( startX, startY, startW, startH, angle );
3208 onShiftUpdate: update,
3209 onCtrlUpdate: update
3213 /* --------------------------------------------------------------------------------------------
3215 * - panelElementOperator
3217 var PositionOperator = ( function(){
3218 var HIT_AREA = MOUSE_HIT_AREA,
3224 function update( _x, _y ){
3225 x = _x !== undefined ? _x : x;
3226 y = _y !== undefined ? _y : y;
3227 // ResizeOperator.update( x, y );
3229 PanelElementOperatorManager.resizeElement( x, y );
3231 currentElement.resize( x, y );
3232 // CONSOLE_CONTROLER.update( currentElement );
3236 delete PositionOperator.init;
3238 show : function( _currentElement ){
3239 currentElement = _currentElement;
3242 currentElement = null;
3244 onStart: function( _mouseX, _mouseY ){
3247 startX = x = currentElement.x;
3248 startY = y = currentElement.y;
3249 app.updateCoursor( 'move' );
3251 onDrag: function( _mouseX, _mouseY ){
3252 var moveX = _mouseX - offsetX,
3253 moveY = _mouseY - offsetY,
3254 _x = startX + moveX,
3255 _y = startY + moveY;
3256 if( GRID_CONTROL.enabled() === true ){
3257 _x = Math.floor( _x / 10 ) * 10;
3258 _y = Math.floor( _y / 10 ) * 10;
3262 onFinish: function(){
3263 app.updateCoursor( '' );
3264 if( x === startX && y === startY ) return;
3265 PanelElementOperatorManager.resize( x, y );
3266 currentElement.resize( x, y );
3267 PanelElementOperatorManager.saveStatus( startX, startY );
3269 onCancel: function(){
3270 app.updateCoursor( '' );
3271 PanelElementOperatorManager.resize( startX, startY );
3272 currentElement.animate( startX, startY );
3274 onShiftUpdate: update,
3275 onCtrlUpdate: update
3280 /* --------------------------------------------------------------------------------------------
3281 * PanelElementOperatorManager
3283 var PanelElementOperatorManager = ( function(){
3284 var HIT_AREA = MOUSE_HIT_AREA,
3286 currentOperator = null,
3287 currentElement = null,
3289 styleContainer = null,
3290 currentX, currentY, currentW, currentH, angle, flipV, flipH;
3292 function mousedown( e ){
3293 var x = e.layerX - HIT_AREA / 2 - 5,
3294 y = e.layerY - HIT_AREA / 2 - 5;
3295 if( isSpeach === true && TailOperator.onStart( x, y ) === true ){
3296 currentOperator = TailOperator;
3298 if( ResizeOperator.onStart( x, y ) === true ){
3299 currentOperator = ResizeOperator;
3301 PositionOperator.onStart( x, y );
3302 currentOperator = PositionOperator;
3306 function mousemove( e ){
3307 var x = e.layerX - HIT_AREA / 2 - 5,
3308 y = e.layerY - HIT_AREA / 2 - 5;
3309 if( currentOperator !== null ){
3310 currentOperator.onDrag( x, y );
3313 if( currentElement !== null ){
3314 ( isSpeach === false || TailOperator.hitTest( x, y ) === false ) && ResizeOperator.index( x, y );
3317 function mouseup( e ){
3318 currentOperator !== null && currentOperator.onFinish();
3319 currentOperator = null;
3326 TailOperator.init();
3327 ResizeOperator.init();
3328 PositionOperator.init();
3329 CONSOLE_CONTROLER.init();
3331 app.addKeyEventListener( 'keychange', function( e ){
3332 currentOperator !== null && currentOperator.onShiftUpdate && currentOperator.onShiftUpdate();
3335 app.addKeyEventListener( 'keychange', function( e ){
3336 currentOperator !== null && currentOperator.onCtrlUpdate && currentOperator.onCtrlUpdate();
3339 app.addKeyEventListener( 'keydown', function( e ){
3340 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();
3341 currentOperator = null;
3343 }, 27, false, false );
3345 delete PanelElementOperatorManager.init;
3348 var elm = document.getElementById( 'comic-element-resizer-container' );
3349 PanelElementOperatorManager.elm = elm;
3350 PanelElementOperatorManager.node = eventRoot.createNode( elm, false, false );
3351 PanelElementOperatorManager.node.addEventListener( 'mouseout', PanelElementOperatorManager.hide, PanelElementOperatorManager );
3352 styleContainer = elm.style;
3353 PanelElementOperatorManager.node.disabled( true );
3354 PanelElementOperatorManager.node.addEventListener( 'mousemove', mousemove );
3355 PanelElementOperatorManager.node.addEventListener( 'mousedown', mousedown );
3356 PanelElementOperatorManager.node.addEventListener( 'mouseup', mouseup );
3358 CONSOLE_CONTROLER.open();
3359 PanelElementOperatorManager.hide();
3361 delete PanelElementOperatorManager.open;
3366 show : function( _currentElement ){
3367 if( currentElement === null ){
3368 styleContainer.display = '';
3369 PanelElementOperatorManager.node.disabled( false );
3371 if( currentElement !== _currentElement ){
3372 currentElement = _currentElement;
3374 ResizeOperator.show( _currentElement );
3375 PositionOperator.show( _currentElement );
3377 isSpeach = ( _currentElement.type === PANEL_ELEMENT_TYPE_TEXT );
3378 isSpeach === true ? TailOperator.show( _currentElement ) : TailOperator.hide();
3380 flipV = _currentElement.flipV;
3381 flipH = _currentElement.flipH;
3383 PanelElementOperatorManager.resize(
3384 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,
3385 isSpeach === true ? _currentElement.a : 0
3390 if( currentElement !== null ){
3391 styleContainer.display = 'none';
3392 PanelElementOperatorManager.node.disabled( true );
3394 currentElement = null;
3395 app.updateCoursor( '' );
3396 TailOperator.hide();
3397 ResizeOperator.hide();
3398 PositionOperator.hide();
3399 CONSOLE_CONTROLER.hide();
3401 resizeElement : function( _x, _y, _w, _h, _angle ){
3402 _x = _x !== undefined ? _x : currentX;
3403 _y = _y !== undefined ? _y : currentY;
3404 _w = _w !== undefined ? _w : currentW;
3405 _h = _h !== undefined ? _h : currentH;
3407 var style = PanelElementOperatorManager.elm.style;
3408 style.left = ( PANEL_CONTROL.x + _x - HIT_AREA / 2 - 5 ) + 'px';
3409 style.top = ( PANEL_CONTROL.y + _y - HIT_AREA / 2 - 5 ) + 'px';
3410 style.width = ( _w + HIT_AREA + 5 ) + 'px';
3411 style.heught = ( _h + HIT_AREA + 5 ) + 'px';
3413 // ResizeOperator.update( _x, _y, _w, _h );
3414 isSpeach === true && TailOperator.update( _w, _h, angle );
3415 CONSOLE_CONTROLER.show( currentElement, _w, _h );
3417 resize: function( _x, _y, _w, _h, _angle ){
3418 currentX = _x = _x !== undefined ? _x : currentX;
3419 currentY = _y = _y !== undefined ? _y : currentY;
3420 currentW = _w = _w !== undefined ? _w : currentW;
3421 currentH = _h = _h !== undefined ? _h : currentH;
3422 angle = _angle = _angle !== undefined ? _angle : angle;
3424 // ResizeOperator.update( _x, _y, _w, _h );
3425 isSpeach === true && TailOperator.update( _w, _h, angle );
3426 CONSOLE_CONTROLER.show( currentElement, _w, _h );
3427 //CONSOLE_CONTROLER.update( currentElement );
3428 PanelElementOperatorManager.node.update( PANEL_CONTROL.x + _x - HIT_AREA / 2 - 5, PANEL_CONTROL.y + _y - HIT_AREA / 2 - 5, _w + HIT_AREA + 5, _h + HIT_AREA + 5 );
3431 restoreState: function( _currentElement, _x, _y, _w, _h, _a, _flipV, _flipH ){
3432 if( arguments.length !== 8 ) return;
3433 if( !_currentElement && !currentOperator ) return;
3434 _currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ?
3435 _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH ) :
3436 _currentElement.animate( _x, _y, _w, _h, _a );
3437 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();
3438 currentOperator = null;
3439 currentElement === _currentElement ? PanelElementOperatorManager.resize( _x, _y, _w, _h, _a ) : PanelElementOperatorManager.show( _currentElement );
3441 saveStatus: function( startX, startY, startW, startH, startA, startFilpV, startFilpH ){
3442 startX = startX !== undefined ? startX : currentX;
3443 startY = startY !== undefined ? startY : currentY;
3444 startW = startW !== undefined ? startW : currentW;
3445 startH = startH !== undefined ? startH : currentH;
3446 startA = startA !== undefined ? startA : angle;
3447 startFilpV = startFilpV !== undefined ? startFilpV : flipV;
3448 startFilpH = startFilpH !== undefined ? startFilpH : flipH;
3449 currentElement && HISTORY_CONTROL.saveState( PanelElementOperatorManager.restoreState,
3450 [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH ],
3451 [ currentElement, currentX, currentY, currentW, currentH, angle, flipV, flipH ]
3457 * // PanelElementOperatorManager
3460 /* --------------------------------------------------------------------------------------------
3463 var CONSOLE_CONTROLER = ( function(){
3464 var LAYER_BACK_BUTTON, LAYER_FORWARD_BUTTON, DELETE_BUTTON, EDIT_BUTTON, CHANGE_BUTTON,
3465 PUSH_OUT_RATIO = 0.5,
3467 elmRoot, elmContainer, elmPushout, elmTail,
3472 currentElement = null,
3475 ui, inputX, inputY, inputZ, inputA, inputW, inputH, inputPercentW, inputPercentH, inputAspectRatio,
3476 buttonBack, buttonForward, buttonDel, buttonEdit, butonChange;
3478 function layerBack(){
3479 if( currentElement === null ) return;
3480 if( PANEL_ELEMENT_CONTROL.replace( currentElement, false ) === false ) return;
3481 CONSOLE_CONTROLER.update( currentElement );
3482 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.replace, [ currentElement, true ], [ currentElement, false ] );
3483 var _z = currentElement.z;
3484 LAYER_BACK_BUTTON.visible( _z > 0 );
3485 LAYER_FORWARD_BUTTON.visible( _z < PANEL_ELEMENT_ARRAY.length - 1 );
3487 function layerForward(){
3488 if( currentElement === null ) return;
3489 if( PANEL_ELEMENT_CONTROL.replace( currentElement, true ) === false ) return;
3490 CONSOLE_CONTROLER.update( currentElement );
3491 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.replace, [ currentElement, false ], [ currentElement, true ] );
3492 var _z = currentElement.z;
3493 LAYER_BACK_BUTTON.visible( _z > 0 );
3494 LAYER_FORWARD_BUTTON.visible( _z < PANEL_ELEMENT_ARRAY.length - 1 );
3497 if( currentElement === null ) return;
3498 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ true, currentElement ], [ false, currentElement ], false ); // true
3499 PANEL_ELEMENT_CONTROL.remove( currentElement );
3500 PanelElementOperatorManager.hide();
3503 if( currentElement === null || currentElement.type !== PANEL_ELEMENT_TYPE_TEXT ) return;
3504 TextEditor.boot( PANEL_CONTROL.x, PANEL_CONTROL.y, currentElement );
3507 if( currentElement === null ) return;
3508 PremiumSatge.boot( currentElement.artistID, currentElement.realPicture, currentElement );
3517 app.addKeyEventListener( 'keydown', layerBack, 66, false, true );
3518 app.addKeyEventListener( 'keydown', layerForward, 70, false, true );
3519 app.addKeyEventListener( 'keydown', del, 68, false, true );
3520 app.addKeyEventListener( 'keydown', edit, 69, false, true );
3521 app.addKeyEventListener( 'keydown', change, 85, false, true );
3523 elmContainer = document.getElementById( 'comic-element-consol-container' );
3524 elmRoot = elmContainer.parentNode;
3525 elmPushout = document.getElementById( 'comic-element-consol-pushout-wrapper' );
3526 elmTail = document.getElementById( 'comic-element-consol-pushout-tail' );
3527 delete CONSOLE_CONTROLER.init;
3530 LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'layer back', 'ctrl + B', layerBack, false, true, false );
3531 LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'layer forward', 'ctrl + F', layerForward, false, false, false );
3532 DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'delete', 'ctrl + D', del, false, true, true );
3533 EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'Edit Text', 'ctrl + E', edit, false, true, false );
3534 CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createOption( 'change', 'ctrl + U', change, false, false, true );
3535 // inputAspectRatio = $( '#comic-element-keep-aspect' );
3537 delete CONSOLE_CONTROLER.open;
3539 onMouseover : function( e ){
3540 node.mesureChildren();
3543 show: function( _currentElement, w, h ){
3544 if( node === null ){
3545 node = CONSOLE_CONTROLER.node = PanelElementOperatorManager.node.createNode( elmContainer, false, false, 'comic-element-consol-container-hover' );
3546 node.addEventListener( 'mouseover', CONSOLE_CONTROLER.onMouseover, CONSOLE_CONTROLER );
3547 ui = app.createUIGroup( node );
3548 inputX = ui.createInputText( document.getElementById( 'comic-element-x' ), null );
3549 inputY = ui.createInputText( document.getElementById( 'comic-element-y' ), null );
3550 inputZ = ui.createInputText( document.getElementById( 'comic-element-z' ), null );
3551 inputA = ui.createInputText( document.getElementById( 'comic-element-a' ), null );
3552 inputW = ui.createInputText( document.getElementById( 'comic-element-w' ), null );
3553 inputH = ui.createInputText( document.getElementById( 'comic-element-h' ), null );
3554 inputPercentW = ui.createInputText( document.getElementById( 'comic-element-w-percent' ), null );
3555 inputPercentH = ui.createInputText( document.getElementById( 'comic-element-h-percent' ), null );
3556 butonChange = ui.createButton( document.getElementById( 'change-image-button' ), change ),
3557 buttonBack = ui.createButton( document.getElementById( 'layer-back-button' ), layerBack ),
3558 buttonDel = ui.createButton( document.getElementById( 'delete-button' ), del ),
3559 buttonForward = ui.createButton( document.getElementById( 'layer-forward-button' ), layerForward ),
3560 buttonEdit = ui.createButton( document.getElementById( 'edit-text-button' ), edit );
3563 currentElement = _currentElement;
3565 var type = currentElement.type,
3566 z = currentElement.z;
3568 LAYER_BACK_BUTTON.visible( z > 0 );
3569 buttonBack.enabled( z > 0 );
3570 LAYER_FORWARD_BUTTON.visible( z < PANEL_ELEMENT_ARRAY.length - 1 );
3571 buttonForward.enabled( z < PANEL_ELEMENT_ARRAY.length - 1 )
3572 DELETE_BUTTON.visible( true );
3573 EDIT_BUTTON.visible( type === PANEL_ELEMENT_TYPE_TEXT );
3574 CHANGE_BUTTON.visible( false );
3576 //CONSOLE_CONTROLER.x = Math.floor( ( _w - CONSOLE_CONTROLER.w ) / 2 );
3577 CONSOLE_CONTROLER.w = w;
3578 CONSOLE_CONTROLER.h = elmContainer.offsetHeight;
3579 CONSOLE_CONTROLER.y = h - CONSOLE_CONTROLER.h;
3581 if( h * PUSH_OUT_RATIO < CONSOLE_CONTROLER.h ){
3582 if( pushout === false ){
3584 elmPushout.lastChild.appendChild( elmContainer );
3585 elmPushout.style.display = 'block';
3586 pushoutW = elmPushout.offsetWidth;
3587 pushoutH = elmPushout.offsetHeight;
3588 elmTail.style.top = ( pushoutH / 2 - tailSize / 2 ) + 'px';
3590 elmPushout.style.left = ( -pushoutW ) + 'px';
3591 elmPushout.style.top = ( h / 2 - pushoutH / 2 ) + 'px';
3592 elmPushout.className = 'satellite-left';
3594 if( pushout === true ){
3596 elmRoot.insertBefore( elmContainer, elmRoot.firstChild );
3597 elmPushout.style.cssText = '';
3600 CONSOLE_CONTROLER.update( currentElement );
3604 update : function( _currentElement ){
3605 if( _currentElement === null ){
3609 currentElement = _currentElement;
3610 var type = currentElement.type,
3611 x = currentElement.x,
3612 y = currentElement.y,
3613 z = currentElement.z,
3614 a = type === PANEL_ELEMENT_TYPE_TEXT ? Math.floor( currentElement.a ) : 0,
3615 w = currentElement.w,
3616 h = currentElement.h,
3617 actualW = type === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualW : 1,
3618 actualH = type === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualH : 1,
3619 wPercent = type === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( w / actualW * 100 ) : 0,
3620 hPercent = type === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( h / actualH * 100 ) : 0,
3621 keepAspect = currentElement.keepAspect;
3623 if( currentType !== type ){
3624 if( type === PANEL_ELEMENT_TYPE_TEXT ){
3625 inputA.visible( true );
3626 inputPercentW.visible( false );
3627 inputPercentH.visible( false );
3628 buttonEdit.enabled( true );
3629 //inputAspectRatio.hide();
3631 inputA.visible( false );
3632 inputPercentW.visible( true );
3633 inputPercentH.visible( true );
3634 buttonEdit.enabled( false );
3635 //inputAspectRatio.show();
3643 type === 1 && inputA.value( a );
3646 type === 0 && inputPercentW.value( wPercent );
3647 type === 0 && inputPercentH.value( hPercent );
3650 // if( visible === true ) styleConsoleWrapper.display = 'none';
3651 ui && ui.visible( false );
3653 currentElement = null;
3654 LAYER_BACK_BUTTON.visible( false );
3655 LAYER_FORWARD_BUTTON.visible( false );
3656 DELETE_BUTTON.visible( false );
3657 EDIT_BUTTON.visible( false );
3658 CHANGE_BUTTON.visible( false );
3665 var AbstractPanelElement = function( COMIC_ELM_TYPE ){
3666 this.type = COMIC_ELM_TYPE;
3668 AbstractPanelElement.prototype = {
3682 shift : function( shiftX, shiftY ){
3683 this.resize( this.x + shiftX, this.y + shiftY );
3685 mouseover : function( e ){
3686 PanelElementOperatorManager.show( this );
3690 /* --------------------------------------------------------------------------------------------
3693 var jqImageElementOrigin;
3694 var ImageElementClass = function( data ){
3695 jqImageElementOrigin = jqImageElementOrigin || $( app.fetchHTMLElement( 'imgElementTemplete' ) );
3697 this.$ = jqImageElementOrigin.clone( true );
3700 this.timing = data.t || PANEL_ELEMENT_ARRAY.length;
3701 this.keepSize = false;
3702 this.flipV = data.height < 0 ? -1 : 1;
3703 this.flipH = data.width < 0 ? -1 : 1;
3704 this.rPicture = data.picture;
3707 function animeComplete(){
3709 self._flipReversibleImage();
3711 this.animeComplete = animeComplete;
3713 ImageElementClass.prototype = Util.extend(
3714 new AbstractPanelElement( PANEL_ELEMENT_TYPE_IMAGE ),
3716 reversibleImage : null,
3718 this._updateResourcePicture( this.rPicture );
3719 this.node = PANEL_ELEMENT_CONTROL.node.createNode( this.$.get( 0 ), false, true );
3720 this.node.addEventListener( 'mouseover', this.mouseover, this );
3721 this.resize( this.data.x, this.data.y, Math.abs( this.data.width ), Math.abs( this.data.height ) );
3724 flip : function( updateH, updateV ){
3725 if( updateH !== true && updateV !== true ) return;
3726 this.flipH = updateH === true ? -this.flipH : this.flipH;
3727 this.flipV = updateV === true ? -this.flipV : this.flipV;
3728 this.reversibleImage.resize( this.flipH * this.w, this.flipV * this.h );
3730 realPicture : function( _rPicture ){
3731 if( _rPicture && _rPicture !== this.rPicture ){
3732 HISTORY_CONTROL.saveState( this._updateResourcePicture, this.rPicture, _rPicture, this );
3733 this._updateResourcePicture( _rPicture );
3735 return this.rPicture;
3737 resize : function( x, y, w, h, animate ){
3738 this.x = x = Type.isFinite( x ) === true ? x : this.x;
3739 this.y = y = Type.isFinite( y ) === true ? y : this.y;
3740 this.w = w = Type.isFinite( w ) === true ? w : this.w;
3741 this.h = h = Type.isFinite( h ) === true ? h : this.h;
3742 if( animate === true ){
3748 }, 250 , this.animeComplete );
3750 this.node.update( x, y, w, h );
3751 this._flipReversibleImage();
3754 animate : function ( x, y, w, h, flipH, flipV ){
3755 this.flipH = flipH !== undefined ? flipH : this.flipH;
3756 this.flipV = flipV !== undefined ? flipV : this.flipV;
3757 this.resize( x, y, w, h, true );
3759 destroy : function(){
3760 this.reversibleImage.destroy();
3761 this.$.stop().remove();
3764 this.destroy = null;
3766 _updateResourcePicture : function( _rPicture ){
3767 this.rPicture = _rPicture;
3768 this.oPicture = this.rPicture.original_picture;
3769 this.artistID = this.oPicture.artist.id || -1;
3771 this.actualW = this.oPicture.width;
3772 this.actualH = this.oPicture.height;
3774 var _reversibleImage = pettanr.image.createReversibleImage(
3775 [ pettanr.CONST.PICTURE_PATH, this.rPicture.id, '.', this.rPicture.ext ].join( '' ),
3776 this.flipH * this.w, this.flipV * this.h
3778 if( this.reversibleImage !== null ){
3779 this.$.children( this.reversibleImage.elm ).replaceWith( _reversibleImage.elm );
3780 this.reversibleImage.destroy();
3782 this.$.append( _reversibleImage.elm );
3784 this.reversibleImage = _reversibleImage;
3786 _flipReversibleImage : function(){
3787 this.reversibleImage && this.reversibleImage.resize( this.flipH * this.w, this.flipV * this.h );
3794 * / ImageElementClass
3795 * --------------------------------------------------------------------------------------------
3799 /* --------------------------------------------------------------------------------------------
3807 * 4.black-box( dq style)
3808 * 5.blue-box( ff style)
3811 var jqTextElementOrigin;
3812 var TextElementClass = function( data ){
3813 jqTextElementOrigin = jqTextElementOrigin || ( function(){
3814 var _OLD_IE = $( app.fetchHTMLElement( 'textElementTempleteForOldIE' ) ),
3815 _MODERN = $( app.fetchHTMLElement( 'textElementTemplete' ) );
3816 return UA.isIE === true && UA.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;
3819 this.$ = jqTextElementOrigin.clone( true );
3821 this.elmText = this.$.find( 'td,.speach-inner' ).get( 0 );
3822 this.type = data.balloon_template_id;
3823 this.content = ( function(){
3824 var _speachs = data.speeches_attributes;
3825 for( var k in _speachs ){
3826 return _speachs[ k ].content || '';
3830 this.balloon = pettanr.balloon.createBalloon( data.width, data.height, data.tail, this.type );
3832 this.timing = data.t || PANEL_ELEMENT_ARRAY.length;
3834 this.$.find( 'img' ).eq( 0 ).replaceWith( this.balloon.elm );
3837 function animeComplete(){
3839 self._resizeBalloon();
3841 this.animeComplete = animeComplete;
3843 TextElementClass.prototype = Util.extend(
3844 new AbstractPanelElement( PANEL_ELEMENT_TYPE_TEXT ),
3848 this.node = PANEL_ELEMENT_CONTROL.node.createNode( this.$.get( 0 ), false, true );
3849 this.node.addEventListener( 'mouseover', this.mouseover, this );
3850 this.resize( this.data.x, this.data.y, this.data.width, this.data.height, this.data.tail );
3853 _updateType : function( _type ){
3854 if( this.type !== _type ){
3855 this.type = _type || this.type;
3856 this.balloon.type( this.type );
3859 _updateAngle : function( _a ){
3860 if( _a !== undefined && a !== _a ){
3861 this.a = _a !== undefined ? _a : this.a;
3862 this.balloon.angle( this.a );
3866 _updateText : function( _text ){
3867 this.content = _text || this.content || '';
3868 this.elmText.firstChild.data = this.content;
3870 _resizeBalloon : function(){
3871 this.balloon && this.balloon.resize( this.a, this.w, this.h );
3873 angle : function( _a ){
3874 _a !== undefined && this.resize( this.x, this.y, this.w, this.h, _a );
3877 text : function( _text ){
3878 if( _text && this.content !== _text ){
3879 HISTORY_CONTROL.saveState( this._updateText, this.content || '', _text, this );
3880 this._updateText( _text );
3882 return this.content;
3884 resize : function( x, y, w, h, a, animate ){
3885 this.x = x = x !== undefined ? x : this.x;
3886 this.y = y = y !== undefined ? y : this.y;
3887 this.w = w = w !== undefined ? w : this.w;
3888 this.h = h = h !== undefined ? h : this.h;
3889 this.a = a !== undefined ? a : this.a;
3891 if( animate === true ){
3897 }, 250 , this.animeComplete );
3899 this.node.update( x, y, w, h );
3900 this._resizeBalloon();
3903 animate : function ( _x, _y, _w, _h, _a ){
3904 this.resize( _x, _y, _w, _h, _a, true );
3906 destroy : function(){
3907 this.$.stop().remove();
3908 this.balloon.destroy();
3911 this.destroy = null;
3916 /* --------------------------------------------------------------------------------------------
3917 * PANEL_ELEMENT_CONTROL
3918 * - mouseEventListener
3920 var PANEL_ELEMENT_CONTROL = ( function(){
3921 var elmContainer = null,
3922 currentElement = null,
3924 panelX, panelY, panelW, panelH,
3927 * append, remove, replace
3929 * panelElement には、z-position と dom-index がある。
3930 * z-position は 表示上の位置。大きいほど前に表示される( z-index)
3931 * dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。
3933 * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。
3934 * dom-index は、数値のみ保持して、投稿時にpanelElementを適宜に並び替える。
3936 * append panelElement
3937 * 1. 新しい panelElement の z-position を得る
3938 * 2. z の同じ panelElementを見つけ、その前に加える。または一番先頭へ。(PANEL_ELEMENT_ARRAY)
3939 * zが大きいほど、PANEL_ELEMENT_ARRAYの先頭へ。
3940 * 3. dom位置は、PANEL_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。
3943 * remove panelElement
3947 function onFadeOut(){
3948 this.parentNode.removeChild( this );
3951 * PANEL_ELEMENT_ARRAY の順番を基準に、zの再計算
3954 function renumber(){
3955 var _panelElement, jqElm, jqAfter,
3956 i = PANEL_ELEMENT_ARRAY.length;
3958 _panelElement = PANEL_ELEMENT_ARRAY[ --i ];
3959 jqElm = _panelElement.$;
3960 !jqAfter && elmContainer.appendChild( jqElm.get( 0 ) );
3961 jqAfter && jqAfter.before( jqElm );
3963 _panelElement.z = i;
3964 _panelElement.node.nodeIndex( i );
3969 function onTextInput( _panelElement ){
3970 PANEL_ELEMENT_CONTROL.add( _panelElement );
3971 _panelElement.animate( undefined, undefined, _panelElement.w, _panelElement.h );
3972 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ false, _panelElement ], [ true, _panelElement ], true, PANEL_ELEMENT_CONTROL );
3976 id : 'PANEL_ELEMENT_CONTROL',
3979 elmContainer = document.getElementById( 'comic-element-container' );
3980 node = PANEL_ELEMENT_CONTROL.node = eventRoot.createNode( elmContainer, true, false );
3981 node.nodeIndex( 0 );
3982 delete PANEL_ELEMENT_CONTROL.init;
3985 delete PANEL_ELEMENT_CONTROL.open;
3989 while( panelElm = PANEL_ELEMENT_ARRAY.shift() ){
3990 panelElm.destroy && panelElm.destroy();
3993 add : function( _panelElement ){
3994 var z = Type.isFinite( _panelElement.z ) === true ? _panelElement.z : -1,
3995 i = PANEL_ELEMENT_ARRAY.length,
3996 _jqElm = _panelElement.$.stop().css( {
4002 PANEL_ELEMENT_ARRAY.push( _panelElement );
4005 if( PANEL_ELEMENT_ARRAY[ --i ].z < z ){
4011 PANEL_ELEMENT_ARRAY.unshift( _panelElement );
4013 PANEL_ELEMENT_ARRAY.splice( i + 1, 0, _panelElement );
4018 _panelElement.node.disabled( false );
4020 remove : function( _panelElement ){
4021 for( var i = PANEL_ELEMENT_ARRAY.length; i; ){
4022 if( PANEL_ELEMENT_ARRAY[ --i ] === _panelElement ){
4023 console.log( PANEL_ELEMENT_ARRAY.length );
4024 PANEL_ELEMENT_ARRAY.splice( i, 1 );
4025 _panelElement.node.disabled( true );
4026 _panelElement.node.nodeIndex( PANEL_ELEMENT_ARRAY.length );
4028 _panelElement.$.stop().css( {
4031 }).fadeOut( onFadeOut );
4032 if( currentElement === _panelElement ) currentElement = null;
4038 restore : function( isAppend, panelElement ){
4039 PANEL_ELEMENT_CONTROL[ isAppend === true ? 'add' : 'remove' ]( panelElement );
4041 replace: function( _panelElement, goForward ){
4042 // PANEL_ELEMENT_ARRAYの再構築
4043 var l = PANEL_ELEMENT_ARRAY.length,
4047 if( PANEL_ELEMENT_ARRAY[ --j ] === _panelElement ){
4052 if( i !== j ) return false;
4053 if( goForward === true ){
4054 if( i === 0 ) return false;
4055 PANEL_ELEMENT_ARRAY.splice( i, 1 );
4056 PANEL_ELEMENT_ARRAY.splice( i + 1, 0, _panelElement );
4058 if( i === l - 1 ) return false;
4059 PANEL_ELEMENT_ARRAY.splice( i, 1 );
4060 PANEL_ELEMENT_ARRAY.splice( i - 1, 0, _panelElement );
4065 onPanelResize : function ( _panelX, _panelY, _panelW, _panelH, isResizerTopAction ){
4067 * リサイズが、ResizerTopによって行われた場合、panelElementのyを動かして見かけ上動かないようにする。
4069 if( isResizerTopAction === true ){
4070 var _shiftX = _panelW - panelW,
4071 _shiftY = _panelH - panelH;
4072 for( var i = PANEL_ELEMENT_ARRAY.length; i; ){
4073 PANEL_ELEMENT_ARRAY[ --i ].shift( _shiftX, _shiftY );
4076 node.update( panelX = _panelX, panelY = _panelY, panelW = _panelW, panelH = _panelH );
4078 createImageElement: function( data ){
4079 if( Type.isObject( data ) === false ){
4080 PremiumSatge.boot( 1, PANEL_ELEMENT_CONTROL.onImageSelect );
4082 PANEL_ELEMENT_CONTROL.onImageSelect( data, true );
4085 onImageSelect: function( data, isPanelPictureData ){
4087 if( isPanelPictureData !== true ){
4088 _panelElement = new ImageElementClass( {
4089 picture : data.picture,
4090 x : Math.floor( panelW / 2 - data.width / 2 ),
4091 y : Math.floor( panelH / 2 - data.height / 2 ),
4097 _panelElement.init();
4098 PANEL_ELEMENT_CONTROL.add( _panelElement );
4099 _panelElement.animate( undefined, undefined, Math.abs( data.picture.original_picture.width ), Math.abs( data.picture.original_picture.height ) );
4101 _panelElement = new ImageElementClass( data );
4102 _panelElement.init();
4103 PANEL_ELEMENT_CONTROL.add( _panelElement );
4105 HISTORY_CONTROL.saveState( PANEL_ELEMENT_CONTROL.restore, [ false, _panelElement ], [ true, _panelElement ], true );
4107 createTextElement: function( data ){
4109 if( Type.isObject( data ) === false ){
4111 balloon_template_id:1,
4114 x: Math.floor( panelW / 2 - 100 + Math.random() * 10 ),
4115 y: Math.floor( panelH / 2 - 100 + Math.random() * 10 ),
4120 speeches_attributes: {
4126 _panelElement = new TextElementClass( data );
4127 _panelElement.init();
4128 TextEditor.boot( PANEL_CONTROL.x, PANEL_CONTROL.y, _panelElement, onTextInput );
4130 _panelElement = new TextElementClass( data );
4131 _panelElement.init();
4132 onTextInput( _panelElement );
4139 * end of PANEL_ELEMENT_CONTROL
4142 function centering(){
4143 app.onPaneResize( windowW, windowH );
4148 this.MIN_WIDTH = 320;
4149 this.MIN_HEIGHT = 320;
4150 this.onInit = function(){
4151 app.rootElement.id = 'editor';
4152 app.rootElement.innerHTML = [
4153 '<div id="grid" style="display:none;"></div>',
4154 '<div id="comic-element-container"></div>',
4155 '<div id="whiteGlass-container">',
4156 '<div id="whiteGlass-top"></div>',
4157 '<div id="whiteGlass-left"></div>',
4158 '<div id="whiteGlass-right"></div>',
4159 '<div id="whiteGlass-bottom"></div>',
4161 '<div id="panel-tools-container">',
4162 '<div id="panel-resizer-top">▲</div>',
4163 '<div id="panel-resizer-bottom">▼</div>',
4165 '<div id="window-container"></div>',
4166 '<div id="comic-element-resizer-container">',
4167 '<div id="comic-element-resizer-container-inner">',
4168 '<div id="comic-element-consol-wrapper">',
4169 '<div id="comic-element-consol-container" class="clearfix">',
4170 '<div class="comic-element-consol-item">',
4171 '<div id="comic-element-x">',
4172 '<span class="comic-element-attribute-label">x:</span>',
4173 '<span id="comic-element-x-value" class="comic-element-attribute-value editable-value">0</span>',
4175 '<div id="comic-element-y">',
4176 '<span class="comic-element-attribute-label">y:</span>',
4177 '<span id="comic-element-y-value" class="comic-element-attribute-value editable-value">0</span>',
4180 '<div class="comic-element-consol-item">',
4181 '<div id="comic-element-z">',
4182 '<span class="comic-element-attribute-label">z:</span>',
4183 '<span id="comic-element-z-value" class="comic-element-attribute-value editable-value">0</span>',
4185 '<div id="comic-element-a">',
4186 '<span id="comic-element-a-value" class="comic-element-attribute-value editable-value">0</span>',
4187 '<span class="comic-element-attribute-label">°</span>',
4190 '<div class="comic-element-consol-item">',
4191 '<div id="comic-element-w">',
4192 '<span class="comic-element-attribute-label">w:</span>',
4193 '<span id="comic-element-w-value" class="comic-element-attribute-value editable-value">0</span>',
4195 '<div id="comic-element-h">',
4196 '<span class="comic-element-attribute-label">h:</span>',
4197 '<span id="comic-element-h-value" class="comic-element-attribute-value editable-value">0</span>',
4200 '<div class="comic-element-consol-item">',
4201 '<!-- <div id="comic-element-keep-aspect"></div> -->',
4202 '<div id="comic-element-w-percent">',
4203 '<span id="comic-element-w-percent-value" class="comic-element-attribute-value editable-value">0</span>',
4204 '<span class="comic-element-attribute-label">%</span>',
4206 '<div class="comic-element-consol-item" id="comic-element-h-percent">',
4207 '<span id="comic-element-h-percent-value" class="comic-element-attribute-value editable-value">0</span>',
4208 '<span class="comic-element-attribute-label">%</span>',
4211 '<div class="comic-element-consol-item-small">',
4212 '<div class="button" id="change-image-button">change</div>',
4214 '<div class="comic-element-consol-item-small">',
4215 '<div class="button" id="layer-back-button">back</div>',
4217 '<div class="comic-element-consol-item-small">',
4218 '<div class="button" id="delete-button">delete</div>',
4220 '<div class="comic-element-consol-item-small">',
4221 '<div class="button" id="layer-forward-button">forward</div>',
4223 '<div class="comic-element-consol-item-small">',
4224 '<div class="button" id="edit-text-button">edit</div>',
4226 '<!-- <div class="comic-element-consol-item-small">',
4227 '<div class="button" id="hide-text-tail-button">tail</div>',
4231 '<div class="comic-element-resizer" id="comic-element-resizer-top"></div>',
4232 '<div class="comic-element-resizer" id="comic-element-resizer-left"></div>',
4233 '<div class="comic-element-resizer" id="comic-element-resizer-right"></div>',
4234 '<div class="comic-element-resizer" id="comic-element-resizer-bottom"></div>',
4235 '<div class="comic-element-resizer" id="comic-element-resizer-top-left"></div>',
4236 '<div class="comic-element-resizer" id="comic-element-resizer-top-right"></div>',
4237 '<div class="comic-element-resizer" id="comic-element-resizer-bottom-left"></div>',
4238 '<div class="comic-element-resizer" id="comic-element-resizer-bottom-right"></div>',
4239 '<div id="comic-element-consol-pushout-wrapper">',
4240 '<div id="comic-element-consol-pushout-tail"></div>',
4241 '<div id="comic-element-consol-pushout-inner"></div>',
4243 '<div id="balloon-tail-mover"></div>',
4246 '<div id="menu-bar"></div>',
4248 '<div id="templete-container" style="display: none;">',
4249 '<div id="imgElementTemplete" class="comic-element-wrapper image-element"></div>',
4251 '<div id="textElementTemplete" class="comic-element-wrapper text-element">',
4253 '<div class="speach">',
4254 '<div class="speach-inner"> </div>',
4258 '<div id="textElementTempleteForOldIE" class="comic-element-wrapper text-element">',
4260 '<div class="speach">',
4261 '<table><tr><td> </td></tr></table>',
4265 '<div id="imageGroupItemTemplete" class="image-group-item">',
4266 '<div class="image-group-item-title">img-title</div>',
4269 '<div id="windowTemplete" class="window-wrapper">',
4270 '<div class="window-header">',
4271 '<div class="window-header-title">window title</div>',
4272 '<div class="window-close-button">x</div>',
4274 '<div class="window-body"></div>',
4275 '<div class="window-footer">',
4276 '<div class="window-resize-button"></div>',
4280 '<div id="infomation-window">',
4281 '<div id="panel-background-information">',
4282 '<div id="bg-pattern"></div>',
4283 '<div id="select-bg-pattern-button">pattern</div>',
4284 '<div id="reset-bg-pattern-button">x</div>',
4285 '<div id="bg-color"></div>',
4286 '<div id="select-bg-color-button">color</div>',
4287 '<div id="reset-bg-color-button">x</div>',
4288 '<!-- <div id="bg-pattern-x"></div>',
4289 '<div id="bg-pattern-y"></div>',
4290 '<div id="bg-pattern-repeat-x"></div>',
4291 '<div id="bg-pattern-repeat-y"></div> -->',
4295 '<div id="toolbox-window">',
4296 '<div id="toolbox-add-image-button" class="button">add image</div>',
4297 '<div id="toolbox-add-text-button" class="button">add text</div>',
4298 '<div id="toolbox-edit-bg-button" class="button">edit bg</div>',
4299 '<div id="toolbox-switch-grid" class="button">grid</div>',
4300 '<div id="toolbox-popup-help-button" class="button">?</div>',
4301 '<div id="toolbox-post-button" class="button">post</div>',
4307 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
4308 eventRoot = app.getPointingDeviceEventTreeRoot();
4312 this.onOpen = function( _w, _h, file ){
4313 // 表示奥の物から順に init() していく
4314 PANEL_ELEMENT_CONTROL.init();
4315 PANEL_CONTROL.init();
4316 // PANEL_RESIZER_BOTTOM.init();
4317 // PANEL_RESIZER_TOP.init();
4318 WINDOWS_CONTROL.init();
4319 MENU_BAR_CONTROL.init();
4321 // レイヤーにあまり関係ないモジュール
4322 HISTORY_CONTROL.init();
4323 SAVE_CONTROL.init();
4324 GRID_CONTROL.init();
4325 WHITE_GLASS_CONTROL.init();
4326 PanelElementOperatorManager.init();
4335 fileData, panelElements, panelElm;
4337 if( FileAPI.isFileInstance( file ) === true ){
4338 if( Driver.isPettanrFileInstance( file ) === true ){
4339 if( file.getType() === FILE_TYPE.COMIC ){
4340 fileData = file.read();
4341 panelW = fileData.width;
4342 panelH = fileData.height;
4343 comicID = fileData.id || -1;
4345 if( file.getType() === FILE_TYPE.PANEL ){
4346 fileData = file.read();
4347 panelW = fileData.width;
4348 panelH = fileData.height;
4349 borderSize = fileData.border;
4350 panelElements = fileData.elements;
4351 comicID = fileData.comic ? fileData.comic.id || -1 : -1;
4352 panelID = fileData.id || -1;
4353 panelTimming = fileData.t || -1;
4360 // open() は各モジュールの init() 後に実施可能になる.
4361 HISTORY_CONTROL.open();
4362 SAVE_CONTROL.open();
4363 WINDOWS_CONTROL.open();
4365 GRID_CONTROL.open();
4366 PANEL_CONTROL.open( panelW, panelH, borderSize );
4367 PanelElementOperatorManager.open();
4368 PANEL_ELEMENT_CONTROL.open();
4371 MENU_BAR_CONTROL.open();
4375 app.onPaneResize( _w, _h );
4378 if( Type.isArray( panelElements ) === true ){
4379 for( var i=0; i<panelElements.length; ++i ){
4380 panelElm = panelElements[ i ];
4381 if( panelElm.picture ){
4382 PANEL_ELEMENT_CONTROL.createImageElement( panelElm );
4384 if( panelElm.balloon_template_id ){
4385 PANEL_ELEMENT_CONTROL.createTextElement( panelElm );
4393 app.addKeyEventListener( 'keydown', centering, 96, false, true ); // ctrl + 0
4394 app.addKeyEventListener( 'krydown', centering, 48, false, true ); // ctrl + 0
4395 MENU_BAR_CONTROL.EDIT.createOption( 'centering', 'ctrl + 0', centering, true, true, true);
4401 this.onClose = function(){
4403 HISTORY_CONTROL.close();
4405 WINDOWS_CONTROL.close();
4407 GRID_CONTROL.close();
4408 PANEL_CONTROL.close();
4410 PanelElementOperatorManager.close();
4411 PANEL_ELEMENT_CONTROL.close();
4414 MENU_BAR_CONTROL.close();
4418 this.onPaneResize = function( _windowW, _windowH ){
4419 windowW = _windowW || windowW;
4420 windowH = _windowH || windowH;
4422 app.rootElement.style.height = _windowH + 'px';
4424 WINDOWS_CONTROL.onWindowResize( _windowW, _windowH );
4425 MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH );
4426 PANEL_CONTROL.onWindowResize( _windowW, _windowH );
4428 }, false, true, 'Panel Editor', 'paneleditor', null, '#2D89F0' );
4430 var FormApplicationHelper = function( app ){
4431 app.isUploading = false;
4432 app.elmProgress = null;
4433 app.elmUploader = null;
4434 app.elmScript = null;
4435 app.elmIframeWrap = null;
4436 app.elmIframe = null;
4438 app.fetchScript = function(){
4439 app.elmProgress = document.getElementById( app.elmProgressID );
4441 if( !( app.elmUploader = document.getElementById( app.elmUploaderID ) ) ){
4442 app.elmUploader = document.createElement( 'div' );
4443 app.rootElement.appendChild( app.elmUploader );
4444 app.elmUploader.id = app.elmUploaderID;
4445 if( app.hideUploader === true ){
4446 app.elmUploader.style.cssText = 'height:1px;line-height:1px;visibility:hidden;overflow:hidden;';
4450 app.elmIframeWrap = document.getElementById( app.iframeWrapID );
4451 app.elmScript = document.createElement( 'script' );
4452 document.body.appendChild( app.elmScript );
4453 app.elmScript.type = 'text\/javascript';
4454 app.elmScript.src = app.scriptSrc;
4456 app.elmProgress.innerHTML = 'loading form.';
4458 app.addTimer( app.detectForm, 250 );
4460 delete app.fetchScript;
4462 app.detectForm = function(){
4463 app.elmForm = app.elmUploader.getElementsByTagName( 'form' )[ 0 ];
4464 if( !app.elmForm ) return;
4465 app.removeTimer( app.detectForm );
4467 Util.createIframe( 'targetFrame', app.onCreateIframe );
4468 app.elmProgress.innerHTML = 'create iframe';
4469 delete app.detectForm;
4471 app.onCreateIframe = function( _iframe ){
4472 app.elmIframeWrap.appendChild( _iframe );
4473 _iframe.className = 'form-iframe';
4474 app.elmIframe = _iframe;
4475 app.elmForm.target = _iframe.name;
4476 app.elmProgress.innerHTML = '';
4477 app.onFormReady && app.onFormReady();
4479 delete app.onCreateIframe;
4481 app.submit = function(){
4482 app.elmProgress.innerHTML = 'submit!';
4484 app.elmForm.submit();
4485 app.isUploading = true;
4487 app.elmProgress.innerHTML = 'submit err..';
4488 app.submitError && app.submitError();
4491 if( app.detectIframe ){
4492 app.elmIframe.onreadystatechange = app.detectIframe;
4494 app.elmIframe.onload = app.onIframeUpdate;
4496 app.elmProgress.innerHTML = 'uploading..';
4501 app.detectIframe = function(){
4502 if ( this.readyState !== 'complete' ) return;
4503 this.onreadystatechange = new Function();
4504 this.onreadystatechange = null;
4505 app.onIframeUpdate();
4506 delete app.detectIframe;
4509 app.onIframeUpdate = function(){
4510 app.elmIframe.onload = null;
4512 console.log( ( app.elmIframe.contentWindow || app.elmIframe.contentDocument.parentWindow ).document.body.innerHTML );
4513 console.log( ( app.elmIframe.contentWindow || app.elmIframe.contentDocument.parentWindow )[ 'current_author' ] );
4517 ( app.elmIframe.contentWindow || app.elmIframe.contentDocument.parentWindow ).close();
4518 app.elmIframe = null;
4519 app.elmProgress.innerHTML = 'success!';
4520 app.isUploading = false;
4521 // app.submitSuccess && app.submitSuccess();
4522 delete app.onIframeUpdate;
4524 app.destroyHelper = function(){
4525 app.elmUploader.parentNode.removeChild( app.elmUploader );
4530 var ComicConsole = gOS.registerApplication( function(){
4531 var elmHeader, elmProgress,
4533 inputTitle, inputW, inputH,
4535 comboboxVisible, // comboboxEditable,
4536 buttonSubmit, buttonCancel,
4540 if( !app.elmForm || !app.elmIframe || app.isUploading === true ) return false;
4543 var _inputList = app.elmForm.getElementsByTagName( 'input' ),
4545 for( var i = _inputList.length; i; ){
4546 _input = _inputList[ --i ];
4547 _name = _input.name;
4548 if( _name === 'comic[title]' ){
4549 _input.value = inputTitle.value();
4551 if( _name === 'comic[width]' ){
4552 _input.value = inputW.value();
4554 if( _name === 'comic[height]' ){
4555 _input.value = inputH.value();
4558 var _selectList = app.elmForm.getElementsByTagName( 'select' ),
4559 _select, _optionList;
4560 for( i = _selectList.length; i; ){
4561 _select = _selectList[ --i ];
4562 _name = _select.name;
4563 _optionList = _select.getElementsByTagName( 'option' )
4564 if( _name === 'comic[visible]' ){
4565 _select.selectedIndex = comboboxVisible.selectIndex();
4567 if( _name === 'comic[editable]' ){
4568 _select.selectedIndex = comboboxEditable.selectIndex();
4571 buttonSubmit.enabled( false );
4574 function clickCancel(){
4575 if( app.isUploading === true ) return false;
4576 ComicConsole.shutdown();
4580 this.MIN_WIDTH = 320;
4581 this.MIN_HEIGHT = 320;
4582 this.onInit = function(){
4583 app.rootElement.id = 'comic-console-wrapper';
4584 app.rootElement.className = 'console-wrapper';
4585 app.rootElement.innerHTML = [
4586 '<div id="comic-console-header" class="console-header">Create New Comic</div>',
4587 '<div id="comic-console" class="console-inner">',
4588 '<div id="comic-console-title" class="field">',
4589 '<span class="field-label">Title:</span>',
4590 '<span id="comic-console-title-value" class="comic-console-value editable-value">No Title</span>',
4592 '<div id="comic-console-width" class="field">',
4593 '<span class="field-label">Default Width:</span>',
4594 '<span id="comic-console-width-value" class="comic-console-value editable-value">300</span>',
4596 '<div id="comic-console-height" class="field">',
4597 '<span class="field-label">Default Height:</span>',
4598 '<span id="comic-console-height-value" class="comic-console-value editable-value">200</span>',
4600 '<div id="comic-console-visible" class="field">',
4601 '<span class="field-label">Visible:</span>',
4602 '<span id="comic-console-visible-value" class="comic-console-value combobox"></span>',
4604 //'<div id="comic-console-editable" class="field">',
4605 // '<span class="field-label">Editable:</span>',
4606 // '<span id="comic-console-editable-value" class="comic-console-value combobox"></span>',
4608 '<div class="console-button-container">',
4609 '<div id="comic-console-post-button" class="button console-submit-button">create</div>',
4610 '<div id="comic-console-cancel-button" class="button console-cancel-button">cancel</div>',
4612 '<div id="comic-console-progress" class="console-progress"> </div>',
4613 '<div id="comic-console-iframe-container"></div>',
4617 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
4618 eventRoot = app.getPointingDeviceEventTreeRoot();
4622 this.elmProgressID = 'comic-console-progress';
4623 this.elmUploaderID = 'newcomic';
4624 this.iframeWrapID = 'comic-console-iframe-container';
4625 this.elmIframeName = 'targetFrameCreateComic'
4626 this.scriptSrc = pettanr.CONST.CREATE_COMIC_JS;
4627 this.hideUploader = true;
4629 FormApplicationHelper( this );
4631 this.onOpen = function( w, h ){
4632 node = eventRoot.createNode( app.rootElement, true, true );
4634 var ui = app.createUIGroup( node );
4636 inputTitle = ui.createInputText( document.getElementById( 'comic-console-title') );
4637 inputW = ui.createInputText( document.getElementById( 'comic-console-width') );
4638 inputH = ui.createInputText( document.getElementById( 'comic-console-height') );
4639 comboboxVisible = ui.createCombobox( document.getElementById( 'comic-console-visible') );
4640 // comboboxEditable = ui.createCombobox( document.getElementById( 'comic-console-editable') );
4641 buttonSubmit = ui.createButton( document.getElementById( 'comic-console-post-button'), clickOK );
4642 buttonCancel = ui.createButton( document.getElementById( 'comic-console-cancel-button'), clickCancel );
4644 app.onPaneResize( w, h );
4648 this.onPaneResize = function( w, h ){
4651 node.update( w / 2 - node.width() / 2, h / 2 - node.height() / 2 );
4653 this.onClose = function(){
4654 app.destroyHelper();
4655 app = inputTitle = inputW = inputH = comboboxVisible = buttonSubmit = buttonCancel = null;
4657 this.onFormReady = function(){
4658 var selectList = app.elmForm.getElementsByTagName( 'select' ),
4662 for( var i=0, l=selectList.length; i<l; ++i ){
4663 select = selectList[ i ];
4664 optionList = select.getElementsByTagName( 'option' );
4665 for( j=0, m=optionList.length; j<m; ++j ){
4666 option = optionList[ j ];
4667 if( select.name === 'comic[visible]' ){
4668 comboboxVisible.createOption( option.innerHTML, option.value, option.selected );
4670 if( select.name === 'comic[editable]' ){
4671 comboboxEditable.createOption( option.innerHTML, option.value, option.selected );
4678 app.onPaneResize( windowW, windowH );
4680 delete app.onFormReady;
4682 this.submitError = function(){
4683 app.addTimer( clickCancel , 5000, true );
4685 this.submitSuccess = function(){
4686 app.addTimer( clickCancel , 5000, true );
4688 }, true, true, 'Comic Console', 'comicConsole', null, '#D44A26' );
4690 var UploadConsole = gOS.registerApplication( function(){
4691 var windowW, windowH,
4692 eventRoot, node, nodeForm,
4693 buttonSubmit, buttonCancel,
4698 if( !app.elmForm || !app.elmIframe || app.isUploading === true ) return false;
4699 if( elmFile.value.length === 0 ) return false;
4701 buttonSubmit.enabled( false );
4704 function clickCancel(){
4705 if( app.isUploading === true ) return false;
4706 UploadConsole.shutdown();
4711 this.MIN_WIDTH = 320;
4712 this.MIN_HEIGHT = 320;
4713 this.onInit = function(){
4714 app.rootElement.id = 'upload-console-wrapper';
4715 app.rootElement.className = 'console-wrapper';
4716 app.rootElement.innerHTML = [
4717 '<div id="upload-console-header" class="console-header">Upload Picture</div>',
4718 '<div id="upload-console" class="console-inner">',
4719 '<div id="upload-console-uiform"></div>',
4720 '<div class="console-button-container">',
4721 '<div id="upload-console-post-button" class="button console-submit-button">upload</div>',
4722 '<div id="upload-console-cancel-button" class="button console-cancel-button">cancel</div>',
4724 '<div id="upload-console-progress" class="console-progress"> </div>',
4725 '<div id="upload-console-iframe-container"></div>',
4729 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
4731 eventRoot = app.getPointingDeviceEventTreeRoot();
4732 document.body.appendChild( Util.pullHtmlAsTemplete( '<div id="uploader"></div>' ) );
4735 this.elmProgressID = 'upload-console-progress';
4736 this.elmUploaderID = 'uploader';
4737 this.iframeWrapID = 'upload-console-iframe-container';
4738 this.elmIframeName = 'targetFrameUpload';
4739 this.scriptSrc = pettanr.CONST.UPLOAD_PICTURE_JS;
4740 this.hideUploader = false;
4741 FormApplicationHelper( this );
4742 this.onOpen = function( w, h ){
4743 node = eventRoot.createNode( app.rootElement, true, true );
4744 nodeForm = node.createNode( document.getElementById( 'upload-console-uiform' ), false, true );
4745 var ui = app.createUIGroup( node );
4747 buttonSubmit = ui.createButton( document.getElementById( 'upload-console-post-button' ), clickOK );
4748 buttonCancel = ui.createButton( document.getElementById( 'upload-console-cancel-button' ), clickCancel );
4750 app.onPaneResize( w, h );
4753 this.onPaneResize = function( w, h ){
4756 node.update( w / 2 - node.width() / 2, h / 2 - node.height() / 2 );
4758 this.onClose = function(){
4759 app.destroyHelper();
4760 app = elmFile = buttonSubmit = buttonCancel = null;
4762 this.onFormReady = function(){
4763 var elmForm = app.elmForm,
4764 _inputList = elmForm.getElementsByTagName( 'input' ),
4766 for( var i = _inputList.length; i; ){
4767 _input = _inputList[ --i ];
4768 if( _input.type === 'file' ){
4771 if( _input.type === 'submit' ){
4772 _input.style.display = 'none';
4776 app.createUIForm( nodeForm, elmForm );
4778 node.mesureChildren();
4779 app.onPaneResize( windowW, windowH );
4780 delete app.onFormReady;
4782 this.submitError = function(){
4783 app.addTimer( clickCancel , 5000, true );
4785 this.submitSuccess = function(){
4786 app.addTimer( clickCancel , 5000, true );
4788 }, true, true, 'Upload Console', 'uploadConsole', null, '#01A31C' );
4790 var ArtistConsole = gOS.registerApplication( function(){
4791 var windowW, windowH,
4793 elmName, elmLicense,
4794 inputName, inputLicense,
4795 buttonSubmit, buttonCancel,
4799 if( !app.elmForm || !app.elmIframe || app.isUploading === true ) return false;
4802 buttonSubmit.enabled( false );
4805 function clickCancel(){
4806 if( app.isUploading === true) return false;
4807 ArtistConsole.shutdown();
4810 function inputUpdate( v ){
4811 elmName.value = inputName.value();
4812 elmLicense.value = inputLicense.value();
4816 this.MIN_WIDTH = 320;
4817 this.MIN_HEIGHT = 320;
4818 this.onInit = function(){
4819 app.rootElement.id = 'artist-console-wrapper';
4820 app.rootElement.className = 'console-wrapper';
4821 app.rootElement.innerHTML = [
4822 '<div id="artist-console-header" class="console-header">Register Artist</div>',
4823 '<div id="artist-console" class="console-inner">',
4824 '<div id="artist-console-name" class="field">',
4825 '<span class="field-label">Name:</span>',
4826 '<span id="artist-console-name-value" class="comic-console-value editable-value">artist name here.</span>',
4828 '<div id="artist-console-license" class="field">',
4829 '<span class="field-label">License:</span>',
4830 '<span id="artist-console-license-value" class="comic-console-value editable-value">license here.</span>',
4832 '<div class="console-button-container">',
4833 '<div id="artist-console-post-button" class="button console-submit-button">register</div>',
4834 '<div id="artist-console-cancel-button" class="button console-cancel-button">cancel</div>',
4836 '<div id="artist-console-progress" class="console-progress"> </div>',
4837 '<div id="register" style="display:none;"></div>',
4838 '<div id="artist-console-iframe-container"></div>',
4842 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
4843 eventRoot = app.getPointingDeviceEventTreeRoot();
4847 this.elmProgressID = 'artist-console-progress';
4848 this.elmUploaderID = 'register';
4849 this.iframeWrapID = 'artist-console-iframe-container';
4850 this.elmIframeName = 'targetFrameArtistRegister'
4851 this.scriptSrc = pettanr.CONST.REGISTER_ARTIST_JS;
4852 this.hideUploader = false;
4853 FormApplicationHelper( this );
4854 this.onFormReady = function(){
4855 var _inputList = app.elmForm.getElementsByTagName( 'input' ),
4857 for( var i = _inputList.length; i; ){
4858 _input = _inputList[ --i ];
4859 if( _input.type === 'submit' ){
4860 _input.style.display = 'none';
4862 if( _input.name === 'artist[name]' ){
4865 if( _input.name === 'artist[default_license_id]' ){
4866 elmLicense = _input;
4871 app.onPaneResize( windowW, windowH );
4872 node.mesureChildren();
4874 delete app.onFormReady;
4876 this.submitError = function(){
4877 app.addTimer( clickCancel , 5000, true );
4879 this.submitSuccess = function(){
4880 app.addTimer( clickCancel , 5000, true );
4882 this.onOpen = function( w, h ){
4883 node = eventRoot.createNode( app.rootElement, true, true );
4884 var ui = app.createUIGroup( node );
4886 inputName = ui.createInputText( document.getElementById( 'artist-console-name' ), inputUpdate );
4887 inputLicense = ui.createInputText( document.getElementById( 'artist-console-license' ), inputUpdate );
4888 buttonSubmit = ui.createButton( document.getElementById( 'artist-console-post-button' ), clickOK );
4889 buttonCancel = ui.createButton( document.getElementById( 'artist-console-cancel-button' ), clickCancel );
4891 app.onPaneResize( w, h );
4894 this.onPaneResize = function( w, h ){
4897 //app.rootElement.style.cssText = [
4898 // 'left:', Math.floor( ( _w - app.rootElement.offsetWidth ) /2 ), 'px;',
4899 // 'top:', Math.floor( ( _h- app.rootElement.offsetHeight ) /2 ), 'px;'
4901 node.update( w / 2 - node.width() / 2, h / 2 - node.height() / 2 );
4903 this.onClose = function(){
4904 app.destroyHelper();
4905 app = buttonSubmit = buttonCancel = null;
4907 }, true, true, 'Artist Console', 'artistConsole', null, '#FFC40D' );
4909 var PanelConsole = gOS.registerApplication( function(){
4910 var windowW, windowH,
4911 eventRoot, node, inputData,
4912 comboboxPublish, buttonSubmit, buttonClose,
4918 * upload ボタンが押されたらまず iframe をつくる.
4921 if( !app.elmForm || !app.elmIframe || app.isUploading === true ) return false;
4924 buttonSubmit.enabled( false );
4928 function clickCancel(){
4929 if( app.isUploading === true ) return false;
4930 PanelConsole.shutdown();
4933 function publishUpdate(){
4935 model.publish( comboboxPublish.selectIndex() === 1 );
4936 elmInput.value = model.getJsonPostString().replace( /\n/g, '' );
4937 inputData.value( elmInput.value );
4939 elmInput.value = inputData.value();
4944 this.MIN_WIDTH = 320;
4945 this.MIN_HEIGHT = 320;
4946 this.onInit = function(){
4947 app.rootElement.id = 'panel-console-wrapper';
4948 app.rootElement.className = 'console-wrapper';
4949 app.rootElement.innerHTML = [
4950 '<div id="panel-console-header" class="console-header">Create New Panel (dev)</div>',
4951 '<div id="panel-console" class="console-inner">',
4952 '<div id="panel-console-data" class="field">',
4953 '<span class="field-label">POST DATA:</span>',
4954 '<span id="panel-console-data-value" class="comic-console-value editable-value">panel json here.</span>',
4956 '<div id="panel-console-publish" class="field">',
4957 '<span class="field-label">Publish:</span>',
4958 '<span id="panel-console-publish-value" class="combobox"></span>',
4960 '<div class="console-button-container">',
4961 '<div id="panel-console-post-button" class="button console-submit-button">post</div>',
4962 '<div id="panel-console-cancel-button" class="button console-cancel-button">cancel</div>',
4964 '<div id="panel-console-progress" class="console-progress"> </div>',
4965 '<div id="newpanel" style="display:none;"></div>',
4966 '<div id="panel-console-iframe-container"></div>',
4970 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
4971 eventRoot = app.getPointingDeviceEventTreeRoot();
4975 this.elmProgressID = 'panel-console-progress';
4976 this.elmUploaderID = 'newpanel';
4977 this.iframeWrapID = 'panel-console-iframe-container';
4978 this.elmIframeName = 'targetFrameNewPanel';
4979 this.scriptSrc = pettanr.CONST.CREATE_PANEL_JS;
4980 this.hideUploader = false;
4981 FormApplicationHelper( this );
4983 this.onOpen = function( w, h, _model ){
4984 node = eventRoot.createNode( app.rootElement, true, true );
4985 var ui = app.createUIGroup( node ),
4986 elm = document.getElementById( 'panel-console-publish' );
4988 inputData = ui.createInputText( document.getElementById( 'panel-console-data' ), publishUpdate );
4991 comboboxPublish = ui.createCombobox( elm, publishUpdate );
4992 comboboxPublish.createOption( 'only me', '0', _model.publish() === false );
4993 comboboxPublish.createOption( 'publish', '1', _model.publish() === true );
4996 elm.parentNode.removeChild( elm );
4999 buttonSubmit = ui.createButton( document.getElementById( 'panel-console-post-button' ), clickOK );
5000 buttonClose = ui.createButton( document.getElementById( 'panel-console-cancel-button' ), clickCancel );
5002 app.onPaneResize( w, h );
5005 this.onPaneResize = function( w, h ){
5008 node.update( w / 2 - node.width() / 2, h / 2 - node.height() / 2 );
5010 this.onClose = function(){
5011 app.destroyHelper();
5012 model && model.destroy();
5013 app = model = comboboxPublish = buttonSubmit = buttonClose = elmInput = null;
5015 this.onFormReady = function(){
5016 var _inputList = app.elmForm.getElementsByTagName( 'input' ),
5018 for( var i = _inputList.length; i; ){
5019 _input = _inputList[ --i ];
5020 if( _input.type === 'submit' ){
5021 _input.style.display = 'none';
5023 if( _input.name === 'json' ){
5030 node.mesureChildren();
5031 app.onPaneResize( windowW, windowH );
5033 delete app.onFormReady;
5035 this.submitError = function(){
5036 app.addTimer( clickCancel , 5000, true );
5038 this.submitSuccess = function(){
5039 app.addTimer( clickCancel , 5000, true );
5041 }, true, true, 'Panel Console', 'panelConsole', null, '#603CBA' );
5043 var Model = ( function(){
5045 var PanelModelClass = function( panel ){
5046 var comicID = panel.comicID || -1,
5047 panelID = panel.panelID || -1,
5048 panelTimming = panel.panelTimming || -1,
5049 panelW = panel.panelW,
5050 panelH = panel.panelH,
5051 borderSize = panel.borderSize,
5052 panelElementArray = panel.panelElementArray,
5053 publish = panel.publish,
5056 function getPanelElementByTiming(){
5057 var i, l = panelElementArray.length;
5058 while( timing < l * 2 ){
5059 for( i = 0; i < l; ++i ){
5060 if( timing === panelElementArray[ i ].timing ){
5061 // console.log( timing + ' , ' + panelElementArray[ i ].timing );
5063 return panelElementArray[ i ];
5070 function panelElementToHtml( _panelElement, isAbsoluteUrl, isXHTML ){
5072 if( _panelElement.type === 0 ){
5073 rPic = _panelElement.realPicture();
5074 url = [ pettanr.CONST.RESOURCE_PICTURE_PATH, rPic.id, '.', rPic.ext ].join( '' );
5077 'src="', isAbsoluteUrl !== true ? url : Util.getAbsolutePath( url ), '" ',
5078 'width="', _panelElement.w, '" ',
5079 'height="', _panelElement.h, '" ',
5081 'left:', _panelElement.x, 'px;',
5082 'top:', _panelElement.y, 'px;',
5083 'z-index:', _panelElement.z, ';',
5085 isXHTML !== true ? '>' : ' \/>'
5088 url = pettanr.balloon.getBalloonUrl( _panelElement.w, _panelElement.h, _panelElement.a );
5091 'src="', isAbsoluteUrl !== true ? url : Util.getAbsolutePath( url ), '" ',
5092 'width="', _panelElement.w, '" ',
5093 'height="', _panelElement.h, '" ',
5095 'left:', _panelElement.x, 'px;',
5096 'top:', _panelElement.y, 'px;',
5097 'z-index:', _panelElement.z, ';',
5099 isXHTML !== true ? '>' : ' \/>',
5100 pettanr.LINE_FEED_CODE_TEXTAREA,
5101 '<div class="balloon" style="',
5102 'left:', _panelElement.x, 'px;',
5103 'top:', _panelElement.y, 'px;',
5104 'width:', _panelElement.w, 'px;',
5105 'height:', _panelElement.h, 'px;',
5106 'z-index:', _panelElement.z,
5107 '"><span>', _panelElement.content, '<\/span>', '<\/div>'
5112 function getImageJsonGET( _imageElement ){
5113 var cr = pettanr.LINE_FEED_CODE_TEXTAREA,
5114 rPic = _imageElement.realPicture();
5117 '"resource_picture": {', cr,
5118 '"id": ', rPic.id, ',', cr,
5119 '"ext": ', '"', rPic.ext, '"', cr,
5121 '"x": ', _imageElement.x, ',', cr,
5122 '"y": ', _imageElement.y, ',', cr,
5123 '"z": ', _imageElement.z, ',', cr,
5124 '"width": ', _imageElement.flipH * _imageElement.w, ',', cr,
5125 '"height": ', _imageElement.flipV * _imageElement.h, ',', cr,
5126 '"t": ', timing, cr,
5130 function imageToJson( _imageElement, t ){
5131 var cr = pettanr.LINE_FEED_CODE_TEXTAREA;
5134 '"picture_id": ', _imageElement.realPicture().id, ',', cr,
5135 '"x": ', _imageElement.x, ',', cr,
5136 '"y": ', _imageElement.y, ',', cr,
5137 '"z": ', _imageElement.z + 1, ',', cr,
5138 '"t": ', t, ',', cr,
5139 '"width": ', _imageElement.flipH * _imageElement.w, ',', cr,
5140 '"height": ', _imageElement.flipV * _imageElement.h, cr,
5145 function balloonToJson( _textElement, t ){
5146 var cr = pettanr.LINE_FEED_CODE_TEXTAREA;
5149 '"speech_balloon_template_id": ', 1, ',', cr,
5150 '"classname": "Square",',
5151 '"z": ', _textElement.z + 1, ',', cr,
5152 '"t": ', t, ',', cr,
5153 '"settings": "{\'tail\':' + _textElement.a + '}",',
5154 '"balloons_attributes": {', cr,
5155 '"newb', t, '": {', cr,
5156 '"system_picture_id": ', 2, ',', cr,
5157 '"caption": "alt text",', cr,
5158 '"x": ', _textElement.x, ',', cr,
5159 '"y": ', _textElement.y, ',', cr,
5160 '"width": ', _textElement.w, ',', cr,
5161 '"height": ', _textElement.h, cr,
5164 '"speeches_attributes": {', cr,
5165 '"news', t, '": {', cr,
5166 '"content": "', _textElement.content, '",', cr,
5167 '"x": ', Math.floor( _textElement.w * 0.16 ), ',', cr,
5168 '"y": ', Math.floor( _textElement.w * 0.16 ), ',', cr,
5169 '"width": ', Math.floor( _textElement.w * 0.66 ), ',', cr,
5170 '"height": ', Math.floor( _textElement.h * 0.66 ), cr,
5177 this.getJsonPostString = function(){
5180 var JSON_STRING_ARRAY = [],
5183 l = panelElementArray.length,
5185 cr = pettanr.LINE_FEED_CODE_TEXTAREA;
5187 while( IMAGE_ARRAY.length + BALLOON_ARRAY.length <= l ){
5188 _panelElement = getPanelElementByTiming();
5189 if( _panelElement === null) break;
5190 n = IMAGE_ARRAY.length + BALLOON_ARRAY.length;
5191 _panelElement.type === 0 ?
5192 IMAGE_ARRAY.push( [ '"new', n, '": ', imageToJson( _panelElement, n ) ].join( '' ) ) :
5193 BALLOON_ARRAY.push( [ '"new', n, '": ', balloonToJson( _panelElement, n ) ].join( '' ) );
5197 panelID !== -1 ? ( '"id": ' + panelID + ',' + cr ) : '',
5198 // comicID !== -1 ? ( '"comic_id": ' + comicID + ',' + cr ) : '',
5199 '"width": ', panelW, ',', cr,
5200 '"height": ', panelH, ',', cr,
5201 '"border": ', borderSize, ',', cr,
5203 // '"picture_id": 1,', cr,
5204 '"x": ', 0, ',', cr,
5205 '"y": ', 0, ',', cr,
5206 '"z": ', 1, ',', cr,
5207 panelTimming !== -1 ? ( '"t": ' + panelTimming + ',' + cr ) : '',
5208 '"panel_pictures_attributes": {', cr,
5209 IMAGE_ARRAY.join( ',' + cr ), cr,
5211 '"speech_balloons_attributes": {', cr,
5212 BALLOON_ARRAY.join( ',' + cr ), cr,
5214 '"publish": ', ( publish === true ? 1 : 0 ), cr,
5218 this.getJsonGetString = function(){
5221 var JSON_STRING_ARRAY = [],
5223 l = panelElementArray.length,
5224 cr = pettanr.LINE_FEED_CODE_TEXTAREA,
5227 while( ELEMENT_ARRAY.length <= l){
5228 _panelElement = getPanelElementByTiming();
5229 if( _panelElement === null ) break;
5231 ELEMENT_ARRAY.push( _panelElement.type === 0 ? getImageJsonGET( _panelElement ) : balloonToJson( _panelElement ));
5236 //'"id": ', panelID, ',', cr,
5237 '"border": ', borderSize, ',', cr,
5238 // '"comic_id": ', comicID, ',', cr,
5239 // '"picture_id": 1,', cr,
5240 '"x": ', 0, ',', cr,
5241 '"y": ', 0, ',', cr,
5242 '"z": ', 1, ',', cr,
5243 // panelTimming !== -1 ? ( '"t": ' + panelTimming + ',' + cr ) : '',
5244 '"width": ', panelW, ',', cr,
5245 '"height": ', panelH, ',', cr,
5246 '"elements": [', cr,
5247 ELEMENT_ARRAY.join( ',' + cr ), cr,
5253 this.getAsHtmlString = function( isAbsoluteUrl, isXHTML ){
5256 var HTML_ARRAY = [],
5257 l = panelElementArray.length,
5260 while( HTML_ARRAY.length < l ){
5261 _panelElement = getPanelElementByTiming();
5262 if( _panelElement === null) break;
5263 HTML_ARRAY.push( panelElementToHtml( _panelElement, isAbsoluteUrl, isXHTML ));
5268 '<div class="panel" ',
5270 'height:', panelH, 'px;',
5271 'background-color:', ';',
5276 HTML_ARRAY.push( '</div>');
5278 return HTML_ARRAY.join( pettanr.LINE_FEED_CODE_TEXTAREA );
5280 this.publish = function( v ){
5281 return publish = Type.isBoolean( v ) === true ? v : publish;
5283 this.destroy = function(){
5284 panel = panelElementArray = null;
5289 createPanel: function( panelData ){
5290 return new PanelModelClass( panelData );
5296 var OutputConsole = gOS.registerApplication( function(){
5297 var FORMAT_LIST = [ 'json[POST]', 'json[GET]', 'XML', 'HTML', 'XHTML', 'MT export', 'Blogger ATOM' ];
5300 comboboxFormat, inputOption,
5301 buttonSubmit, buttonClose,
5303 comicID, panelID, panelTimming, panelW, panelH, borderSize, panelElementArray,
5308 OutputConsole.shutdown();
5311 function formatUpdate(){
5312 var i = comboboxFormat.selectIndex(),
5314 // buttonSubmit.enabled( false );
5316 text = model.getJsonPostString();
5317 // buttonSubmit.enabled( true );
5320 text = model.getJsonGetString();
5323 text = model.getAsHtmlString( false, false );
5327 elmOutputArea.value = text;
5329 function clickClose(){
5330 OutputConsole.shutdown();
5334 function clickPost(){
5335 // PanelConsole.boot( elmOutputArea.value );
5340 this.MIN_WIDTH = 320;
5341 this.MIN_HEIGHT = 320;
5342 this.onInit = function(){
5343 app.rootElement.id = 'output-console-wrapper';
5344 app.rootElement.className = 'console-wrapper';
5345 app.rootElement.innerHTML = [
5346 '<div id="output-console-header" class="console-header">Output Console</div>',
5347 '<div id="output-console" class="console-inner">',
5348 '<div id="output-console-format" class="field">',
5349 '<span class="field-label">Format:</span>',
5350 '<span id="output-console-format-value" class="output-console-value combobox"></span>',
5352 '<div id="output-console-option" class="field">',
5353 '<span class="field-label">Options:</span>',
5354 '<span id="output-console-option-value" class="output-console-value editable-value">absolute-path</span>',
5356 '<textarea id="output-area" readonly></textarea>',
5357 '<div id="output-console-close-button" class="button">close</div>',
5361 app.fetchCSS( pettanr.CONST.URL_PETA_APPS_CSS );
5362 eventRoot = app.getPointingDeviceEventTreeRoot();
5366 this.onOpen = function( _w, _h, _comicID, _panelID, _panelTimming, _panelW, _panelH, _borderSize, _panelElementArray ){
5367 elmOutputArea = document.getElementById( 'output-area' );
5369 node = eventRoot.createNode( app.rootElement, true, true );
5370 var ui = app.createUIGroup( node );
5371 comboboxFormat = ui.createCombobox( document.getElementById( 'output-console-format' ), formatUpdate );
5373 for( var i=0; FORMAT_LIST[ 0 ]; ++i ){
5374 comboboxFormat.createOption( FORMAT_LIST.shift(), null, i === 0 );
5376 inputOption = ui.createInputText( document.getElementById( 'output-console-option' ), null );
5377 // buttonSubmit = ui.createButton( document.getElementById( 'output-console-post-button' ), clickPost );
5378 buttonClose = ui.createButton( document.getElementById( 'output-console-close-button' ), clickClose );
5380 app.onPaneResize( _w, _h );
5382 comboboxFormat.focus( true );
5384 model = Model.createPanel( {
5387 panelTimming : _panelTimming,
5390 borderSize : _borderSize,
5391 panelElementArray : _panelElementArray,
5397 this.onPaneResize = function( w, h ){
5400 //app.rootElement.style.cssText = [
5401 // 'left:', Math.floor( ( _windowW - app.rootElement.offsetWidth ) /2 ), 'px;',
5402 // 'top:', Math.floor( ( _windowH - app.rootElement.offsetHeight ) /2 ), 'px;'
5404 node.update( w / 2 - node.width() / 2, h / 2 - node.height() / 2 );
5406 this.onClose = function(){
5407 elmOutputArea.value = '';
5409 elmOutputArea = comboboxFormat = inputOption = buttonSubmit = buttonClose = panelElementArray = model = null;
5411 }, true, false, 'Output Console', 'outputConsole', null, '#2D89F0' );
5413 })( pettanr, gOS, window, document );