11 * ----------------------------------------
\r
12 * - naming of comic's elements -
\r
14 * 0.comic strip(en) : koma manga(jp)
\r
16 * 1.panel(en) : koma(jp)
\r
24 * 2.speach balloon(en) : fukidasi(jp)
\r
35 * ----------------------------------------
\r
37 * +----------------------------+
\r
38 * | CANVAS_CONTROL |
\r
41 * | | +----------+ |
\r
46 * | - WHITE_GLASS_CONTROL |
\r
47 * +----------------------------+
\r
49 * ----------------------------------------
\r
55 * const & Singleton Class
\r
56 * THIS_IS_CONST = 'this is const';
\r
62 * jqWrapper, JQ_WRAPPER
\r
64 * value of dom element
\r
65 * elmWrapper, ELM_WRAP
\r
67 * value of vml element
\r
72 var h2c = ( function(){
\r
73 var FUNCTION_ARRAY = [],
\r
74 URL = document.location.href.split( '#')[ 0],
\r
75 IS_LOCAL = URL.indexOf( 'file:') === 0,
\r
76 URL_PARAMS = ( function(){
\r
77 var search = document.location.search,
\r
80 var query = search.substring( 1),
\r
81 params = query.split( '&'),
\r
82 ret = {}, elm, name;
\r
83 while( params.length > 0){
\r
84 elm = params.shift().split( '=');
\r
85 name = decodeURIComponent( elm[ 0]);
\r
86 if( elm.length === 2){
\r
87 ret[ name] = ( function( v){
\r
88 if( '' + parseFloat( v) === v) return parseFloat( v);
\r
89 if( v === 'true') return true;
\r
90 if( v === 'false') return false;
\r
91 if( v === 'null') return null;
\r
92 if( v === 'undefined') return undefined;
\r
94 })( decodeURIComponent( elm[ 1]));
\r
96 if( elm.length === 1){
\r
104 IS_DEBUG = IS_LOCAL === true || URL_PARAMS.debug === true,
\r
105 isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,
\r
106 ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,
\r
107 ieMode = ieVersion === 8 ? document.documentMode : 0,
\r
108 isStanderdMode = document.compatMode === 'CSS1Compat',
\r
109 jqWindow , jqDocument , jqBody;
\r
113 jqWindow = $( window);
\r
114 jqDocument = $( document);
\r
115 jqBody = $( document.body);
\r
117 var l = FUNCTION_ARRAY.length,
\r
119 for( var i=0; i<l; i++){
\r
120 _fn = FUNCTION_ARRAY[ i];
\r
121 _fn.init && _fn.init( _fn === h2c.view ? FUNCTION_ARRAY : undefined);
\r
126 fn: function( _fn){
\r
127 FUNCTION_ARRAY.push( _fn);
\r
128 h2c.init === undefined && _fn.init && _fn.init();
\r
131 ieVersion: ieVersion,
\r
132 ieRenderingVersion: ieMode !== 0 ? ieMode : ieVersion,
\r
133 isStanderdMode: isStanderdMode,
\r
134 VENDER_PREFIX: ( function() {
\r
135 var ua = navigator.userAgent.toLowerCase();
\r
136 if ( ua.indexOf('opera') !== -1) {
\r
138 } else if ( ua.indexOf('msie') !== -1) {
\r
140 } else if ( ua.indexOf('webkit') !== -1) {
\r
142 } else if ( navigator.product === 'Gecko') {
\r
147 ACTIVEX: ( function(){
\r
148 if( isIE === false || ieVersion > 8) return false;
\r
149 var className = document.body.className,
\r
151 if( className && className.indexOf( 'h2c-ActiveX-enabled') !== -1) return true;
\r
152 if( className && className.indexOf( 'h2c-ActiveX-disabled') !== -1) return false;
\r
154 test = new ActiveXObject('DXImageTransform.Microsoft.gradient');
\r
161 if( isIE === false || ieVersion > 8) return false;
\r
162 var globalObjectName = '_global',
\r
164 document.write( [ '<!--[if gte vml 1]><script>window', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));
\r
165 if( window[globalObjectName] === 1){
\r
166 //script = document.getElementById( globalObjectName);
\r
167 //script.parentNode.removeChild( script);
\r
168 window[globalObjectName] = undefined;
\r
173 startVML: function(){
\r
174 if( h2c.VML !== true) return false;
\r
175 if (!document.namespaces["v"]) {
\r
176 document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");
\r
178 document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";
\r
179 delete this.startVML;
\r
181 jqWindow: function(){
\r
184 jqDocument: function(){
\r
187 jqBody: function(){
\r
190 URL_PARAMS: URL_PARAMS,
\r
193 LINE_FEED_CODE_TEXTAREA : ( function(){
\r
194 var text = document.getElementById( 'shadowTxtarea'),
\r
195 form = text.parentNode;
\r
196 form.parentNode.removeChild( form);
\r
199 LINE_FEED_CODE_PRE : ( function(){
\r
200 var pre = document.getElementById( 'shadowPre');
\r
201 pre.parentNode.removeChild( pre);
\r
202 return isIE === true ? this.LINE_FEED_CODE_TEXTAREA : pre.innerHTML; // ie ??
\r
210 * getElementSize( _elm)
\r
214 h2c.util = ( function(){
\r
215 var ELM_SIZE_GETTER = ( function(){
\r
216 var ret = document.createElement( 'DIV'),
\r
218 ret.id = 'elmSizeGetter';
\r
219 style.position = 'absolute';
\r
220 style.left = '0px';
\r
221 style.top = '-9999px';
\r
222 style.visibility = 'hidden';
\r
223 document.body.appendChild( ret);
\r
226 IMG_SIZE_GETTER = ( function(){
\r
227 var ret = ELM_SIZE_GETTER.cloneNode( true);
\r
228 ret.id = 'imgSizeGetter';
\r
229 document.body.appendChild( ret);
\r
232 CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',');
\r
234 // cleanCommnetNode();
\r
235 function cleanCommnetNode( _targetElm){
\r
236 var _elms = ( _targetElm || document).getElementsByTagName( '*'),
\r
239 while( i < _elms.length){
\r
241 if( _elm.nodeType === 8 && _elm.parentNode){
\r
242 _elm.parentNode.removeChild( _elm);
\r
249 extend: function( baseInstance, extend){
\r
250 for( var key in extend){
\r
251 baseInstance[ key] = extend[ key];
\r
253 return baseInstance;
\r
255 cleanCommnetNode: cleanCommnetNode,
\r
256 cleanElement: function( _targetElm){
\r
257 var l = CLEAN_TARGET_ELEMENT.length,
\r
259 for( var i=0; i<l; ++i){
\r
260 elms = _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ i]);
\r
261 if( elms.length > 0){
\r
262 for( j=0; i<elms.length; ++j){
\r
264 elm.parentNode && elm.parentNode.removeChild( elm);
\r
268 cleanCommnetNode( _targetElm);
\r
269 if( h2c.isIE === false) return;
\r
270 elms = document.getElementsByName( '*');
\r
272 for(i=0; i<l; ++i){
\r
274 elm.style.filter = '';
\r
275 elm.style.behavior = '';
\r
278 getElementSize: function( _elm){
\r
285 var parentElm = _elm.parentNode,
\r
286 prevElm = _elm.previousSibling,
\r
287 nextElm = _elm.nextSibling,
\r
288 displayNone = _elm.style.display === 'none';
\r
289 if( displayNone === true) _elm.style.display = '';
\r
290 ELM_SIZE_GETTER.appendChild( _elm);
\r
292 width: _elm.offsetWidth,
\r
293 height: _elm.offsetHeight
\r
295 if( displayNone === true) _elm.style.display = 'none';
\r
297 parentElm.insertBefore( _elm, nextElm);
\r
299 if( prevElm && prevElm.nextSibling){
\r
300 parentElm.insertBefore( _elm, prevElm.nextSibling);
\r
302 parentElm && parentElm.appendChild( _elm);
\r
306 getImageSize: function( img){
\r
307 var parentElm = img.parentNode,
\r
308 prevElm = img.previousSibling,
\r
309 nextElm = img.nextSibling,
\r
310 displayNone = img.style.display === 'none';
\r
311 if( displayNone === true) img.style.display = '';
\r
312 IMG_SIZE_GETTER.appendChild( img);
\r
313 var size = getActualDimension( img);
\r
314 IMG_SIZE_GETTER.removeChild( img);
\r
315 if( displayNone === true) img.style.display = 'none';
\r
317 parentElm.insertBefore( img, nextElm);
\r
319 if( prevElm && prevElm.nextSibling){
\r
320 parentElm.insertBefore( img, prevElm.nextSibling);
\r
322 parentElm && parentElm.appendChild( img);
\r
327 * AUTHOR: uupaa.js@gmail.com
\r
329 function getActualDimension(image) {
\r
330 var run, mem, w, h, key = "actual";
\r
332 // for Firefox, Safari, Google Chrome
\r
333 if ("naturalWidth" in image) {
\r
335 width: image.naturalWidth,
\r
336 height: image.naturalHeight
\r
340 if ("src" in image) { // HTMLImageElement
\r
341 if (image[key] && image[key].src === image.src) {
\r
344 if (document.uniqueID) { // for IE
\r
345 run = image.runtimeStyle;
\r
346 mem = { w: run.width, h: run.height }; // keep runtimeStyle
\r
347 run.width = "auto"; // override
\r
348 run.height = "auto";
\r
351 run.width = mem.w; // restore
\r
352 run.height = mem.h;
\r
353 } else { // for Opera and Other
\r
359 mem = { w: image.width, h: image.height }; // keep current style
\r
360 image.removeAttribute("width");
\r
361 image.addEventListener("DOMAttrModified", fn, false);
\r
362 image.removeAttribute("height");
\r
364 image.removeEventListener("DOMAttrModified", fn, false);
\r
365 image.width = mem.w; // restore
\r
366 image.height = mem.h;
\r
368 mem = { w: image.width, h: image.height }; // keep current style
\r
369 image.removeAttribute("width");
\r
370 image.removeAttribute("height");
\r
373 image.width = mem.w; // restore
\r
374 image.height = mem.h;
\r
376 return image[key] = { width: w, height: h, src: image.src }; // bond
\r
378 // HTMLCanvasElement
\r
379 return { width: image.width, height: image.height };
\r
382 loadImage: function( URLorELM, onLoad, onError, delay, timeout){
\r
383 delay = delay || 250;
\r
384 timeout = timeout || 5000;
\r
385 var type = typeof URLorELM,
\r
386 img, images, src, abstractPath;
\r
387 if( type === 'string'){
\r
391 // http://d.hatena.ne.jp/hottolinkblog/20090228/1235823487
\r
392 if( type === 'object' && typeof URLorELM.hspace !== 'undefined' && typeof URLorELM.vspace !== 'undefined'){
\r
399 abstractPath = this.getAbsolutePath( src);
\r
401 loadImage( images, abstractPath,
\r
402 function( abspath, actualW, actualH){
\r
403 if( abstractPath !== abspath) return;
\r
404 onLoad && setTimeout( function(){ // 一度読み込まれた画像は即座にonLoadされてしまうので遅延
\r
405 onLoad( src, actualW, actualH);
\r
408 function( abspath){
\r
409 if( abstractPath !== abspath) return;
\r
410 onError && setTimeout( function(){
\r
417 * URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631
\r
418 * AUTHOR: uupaa.js@gmail.com
\r
420 * fixed for ie6-8 by h2c
\r
421 * new Image -> document.createElement( 'IMG')
\r
423 function loadImage( images, abspath, onLoad, onError, delay, timeout) {
\r
424 images = images || document.images;
\r
426 i = 0, l = images.length,
\r
428 for(; i < l; ++i) {
\r
430 if ( img.src === abspath && img.complete) {
\r
431 var size = h2c.util.getImageSize( img);
\r
432 onLoad( abspath, size.width, size.height);
\r
436 img = document.createElement( 'IMG'); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る
\r
437 img.finish = false;
\r
438 img.onabort = img.onerror = function() {
\r
439 if (img.finish) { return; }
\r
442 img.onload = img.onabort = img.onerror = "";
\r
444 img.onload = function() {
\r
446 if (window.opera && !img.complete) {
\r
448 img.onload = img.onabort = img.onerror = "";
\r
451 var size = h2c.util.getImageSize( img);
\r
452 onLoad( abspath, size.width, size.height);
\r
453 img.onload = img.onabort = img.onerror = "";
\r
457 if (!img.finish && timeout) {
\r
458 setTimeout(function() {
\r
459 if (img.finish) { return; }
\r
460 if (img.complete) {
\r
462 if (img.width) { return; }
\r
464 img.onload = img.onabort = img.onerror = "";
\r
467 if ((tick += delay) > timeout) {
\r
470 img.onload = img.onabort = img.onerror = "";
\r
473 setTimeout(arguments.callee, delay);
\r
478 getAbsolutePath: function( path) {
\r
479 var e = document.createElement("div");
\r
480 e.innerHTML = '<a href=\"' + path + '\" />';
\r
481 return e.firstChild.href;
\r
487 * window resize event, overlay と currentなviewに流す
\r
489 * editor, overlay, comic-viewer, image-explorer
\r
492 h2c.view = ( function(){
\r
497 viewID = ( function(){
\r
498 var _viewID = h2c.URL_PARAMS.view || HOME_ID,
\r
499 _elmView = document.getElementById( _viewID),
\r
500 _elmHome = document.getElementById( HOME_ID);
\r
502 _elmHome.style.display = '';
\r
503 _elmView.style.display = 'block';
\r
504 elmCurrent = _elmView;
\r
507 elmCurrent = _elmHome;
\r
512 function onWindowResize(){
\r
514 l = funcArray.length,
\r
515 w = jqWindow.width(),
\r
516 h = jqWindow.height();
\r
517 for( var i=0; i<l; ++i){
\r
518 _fn = funcArray[ i];
\r
519 _fn.onWindowResize && _fn.onWindowResize( w, h);
\r
523 init: function( _funcArray){
\r
524 funcArray = _funcArray;
\r
525 jqWindow = h2c.jqWindow();
\r
526 jqWindow.resize( onWindowResize);
\r
527 currentView = h2c[ viewID];
\r
528 setTimeout( onWindowResize, 100);
\r
530 delete h2c.view.init;
\r
532 show: function( _view){
\r
533 for( var key in h2c){
\r
534 if( h2c[ key] === _view){
\r
535 var elm = document.getElementById( key);
\r
536 if( currentView !== _view && elm){
\r
537 this.currentID = viewID = key;
\r
538 currentView = _view;
\r
539 elmCurrent.style.display = '';
\r
540 elm.style.display = 'block';
\r
550 COMICS: 'comic-list',
\r
551 IMAGES: 'image-list',
\r
552 SETTING: 'setting',
\r
558 h2c.overlay = ( function(){
\r
559 var SHADOW_OPACITY = 0.5,
\r
560 jqBody, jqConteiner, jqShadow, jqCloseButton,
\r
561 currentOverlay = null,
\r
565 currentOverlay && currentOverlay.onClose && currentOverlay.onClose();
\r
566 h2c.overlay.hide();
\r
570 jqBody = h2c.jqBody();
\r
571 jqConteiner = $( '#overlay-container');
\r
572 jqShadow = $( '#overlay-shadow');
\r
573 jqCloseButton = $( '#overlay-close-button').click( function( e){
\r
575 e.preventDefault();
\r
579 h2c.key.addKeyDownEvent( h2c.view.OVERLAY, 27, false, false, close); // 27.esc
\r
581 delete h2c.overlay.init;
\r
583 show: function( _currentOverlay){
\r
584 if( visible === true && currentOverlay === _currentOverlay) return;
\r
585 jqConteiner.stop().css( {
\r
589 this.visible = visible = true;
\r
590 currentOverlay = _currentOverlay;
\r
591 this.currentID = _currentOverlay.ID;
\r
592 jqCloseButton.toggle( !!_currentOverlay.onClose);
\r
595 currentOverlay = null;
\r
596 if( visible === false) return;
\r
597 jqConteiner.stop().css( {
\r
601 this.visible = visible = false;
\r
602 this.currentID = null;
\r
606 onWindowResize: function( _windowW, _windowH){
\r
607 jqConteiner.css( { height: _windowH});
\r
608 jqShadow.css( { height: _windowH});
\r
609 currentOverlay && currentOverlay.onWindowResize && setTimeout( function(){ // 先にeditorのcanvasを確定する。
\r
610 currentOverlay.onWindowResize( _windowW, _windowH);
\r
616 /* ----------------------------------------
\r
619 * - EDITABLE_TEXT_CONTROL
\r
620 * - EditableTextClass
\r
621 * .update: function,
\r
624 * .start: function,
\r
626 * .enabled: function,
\r
627 * .index: function,
\r
628 * .instance: function
\r
630 * .SHIFT_DOWN_EVENT: 'shiftDown',
\r
631 * .SHIFT_UP_EVENT: 'shiftUp',
\r
632 * .CTRL_DOWN_EVENT: 'ctrlDown',
\r
633 * .CTRL_UP_EVENT: 'ctrlUp',
\r
634 * .SPACE_DOWN_EVENT: 'spaceDown',
\r
635 * .SPACE_UP_EVENT: 'spaceUp',
\r
637 * .addKeyDownEvent: function,
\r
638 * .keyEventDispatcher: function,
\r
639 * .createEditableText: function,
\r
641 * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。
\r
642 * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。
\r
645 h2c.key = ( function(){
\r
648 keyOperationChatcher,
\r
649 KEYEVENT_ARRAY = [],
\r
650 shiftEnabled = false,
\r
651 ctrlEnabled = false;
\r
653 var EDITABLE_TEXT_CONTROL = ( function(){
\r
654 var EDITABLE_TEXT_TABLE = {},
\r
655 currentText = null;
\r
657 var EditableTextClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID){
\r
658 var ELM = WRAPPER_ELM.children( '.editable-value').eq( 0),
\r
659 value = ELM.html(),
\r
661 index = EDITABLE_TEXT_TABLE[ GROUP_ID].length,
\r
664 A = $( '<a href="#" onclick="return false;"></a>').html( value).click( function(e){
\r
665 instance = instance || EDITABLE_TEXT_TABLE[ GROUP_ID][ index];
\r
666 EDITABLE_TEXT_CONTROL.start( instance);
\r
668 jqInput = $( '<input type="text"/>').val( value)//.keydown( finish).keypress( finish);
\r
669 ELM.append( jqInput);
\r
670 jqInput.focus().select();
\r
671 e.preventDefault();
\r
674 ELM.addClass( 'editable-text').html( A);
\r
676 function finish(e){
\r
678 var keyCode = e.keyCode;
\r
679 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt
\r
680 _finish( keyCode !== 27 ? jqInput.val() : value);
\r
681 keyCode === 9 && GROUP_ID && EDITABLE_TEXT_CONTROL.tabShift( GROUP_ID, index, e.shiftKey === true ? -1 : 1);
\r
684 _finish( jqInput.val());
\r
686 function _finish( VALUE_NEW){
\r
688 A.html( VALUE_NEW).show();
\r
691 ON_UPDATE_FUNCTION && VALUE_NEW !== value && ON_UPDATE_FUNCTION( VALUE_NEW, value);
\r
692 EDITABLE_TEXT_CONTROL.finish( instance);
\r
696 update: function( _value){
\r
697 value = _value !== undefined ? _value : value;
\r
699 jqInput && jqInput.val( value);
\r
700 currentText === instance && finish();
\r
703 enabled === false && WRAPPER_ELM.show();
\r
707 enabled === true && WRAPPER_ELM.hide();
\r
711 !jqInput && A.click();
\r
714 enabled: function(){
\r
719 var CheckboxClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID){
\r
720 var ELM = WRAPPER_ELM.children( '.checkbox-value').eq( 0),
\r
721 value = ELM.html(),
\r
723 index = EDITABLE_TEXT_TABLE[ GROUP_ID].length,
\r
726 A = $( '<a href="#" onclick="return false;"></a>').html( value).click( function(e){
\r
727 instance = instance || EDITABLE_TEXT_TABLE[ GROUP_ID][ index];
\r
728 EDITABLE_TEXT_CONTROL.start( instance);
\r
730 jqInput = $( '<input type="text"/>').val( value)//.keydown( finish).keypress( finish);
\r
731 ELM.append( jqInput);
\r
732 jqInput.focus().select();
\r
733 e.preventDefault();
\r
736 ELM.addClass( 'editable-text').html( A);
\r
738 function finish(e){
\r
740 var keyCode = e.keyCode;
\r
741 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt
\r
742 _finish( keyCode !== 27 ? jqInput.val() : value);
\r
743 keyCode === 9 && GROUP_ID && EDITABLE_TEXT_CONTROL.tabShift( GROUP_ID, index, e.shiftKey === true ? -1 : 1);
\r
746 _finish( jqInput.val());
\r
748 function _finish( VALUE_NEW){
\r
750 A.html( VALUE_NEW).show();
\r
753 ON_UPDATE_FUNCTION && VALUE_NEW !== value && ON_UPDATE_FUNCTION( VALUE_NEW, value);
\r
754 EDITABLE_TEXT_CONTROL.finish( instance);
\r
758 update: function( _value){
\r
759 value = _value !== undefined ? _value : value;
\r
761 jqInput && jqInput.val( value);
\r
762 currentText === instance && finish();
\r
765 enabled === false && WRAPPER_ELM.show();
\r
769 enabled === true && WRAPPER_ELM.hide();
\r
773 !jqInput && A.click();
\r
776 enabled: function(){
\r
782 createEditableText: function( ELM, ON_UPDATE_FUNCTION, GROUP_ID){
\r
783 if( GROUP_ID && !EDITABLE_TEXT_TABLE[ GROUP_ID]) EDITABLE_TEXT_TABLE[ GROUP_ID] = [];
\r
784 var ret = EditableTextClass.apply( {}, [ ELM, ON_UPDATE_FUNCTION, GROUP_ID]);
\r
785 GROUP_ID && EDITABLE_TEXT_TABLE[ GROUP_ID].push( ret);
\r
788 createCheckbox: function( ELM, ON_UPDATE_FUNCTION, GROUP_ID){
\r
791 start: function( _currentText){
\r
792 currentText !== _currentText && currentText && currentText.finish();
\r
793 currentText = _currentText;
\r
795 finish: function( _currentText){
\r
796 if( currentText !== _currentText) return;
\r
797 currentText = null
\r
799 keyEventRellay: function( e){
\r
800 currentText && currentText.finish( e);
\r
801 return !!currentText;
\r
803 tabShift: function( _groupID, _index, _way){
\r
804 var GROUP_ARRAY = EDITABLE_TEXT_TABLE[ _groupID] || [],
\r
805 l = GROUP_ARRAY.length,
\r
808 while( i !== _index){
\r
811 i === l ? 0 : i; // 0 < i < l
\r
812 if( GROUP_ARRAY[ i].enabled() === true) break;
\r
815 if( i === _index) return;
\r
816 setTimeout( function(){ GROUP_ARRAY[ i].start();}, 0);
\r
821 function keyHit( e){
\r
822 log.html( [ e.keyCode, e.shiftKey, e.ctrlKey, e.altKey, e.type].join( ','));
\r
823 //keyOperationChatcher.val( '');
\r
824 var cancel = false,
\r
825 callback = ( function(){
\r
827 if( type === 'keypress') return 'keydown';
\r
831 overlayEnabled = h2c.overlay.visible === true,
\r
832 currentViewID = overlayEnabled === true ? h2c.overlay.currentID : h2c.view.currentID;
\r
833 if( callback === 'keyup' || EDITABLE_TEXT_CONTROL.keyEventRellay( e) === false){
\r
834 var shift = e.shiftKey,
\r
836 l = KEYEVENT_ARRAY.length,
\r
839 shiftEnabled = callback !== 'keyup' ?
\r
841 key !== 16 ? shiftEnabled : false;
\r
842 ctrlEnabled = callback !== 'keyup' ?
\r
844 key !== 17 ? ctrlEnabled : false;;
\r
846 for( var i=0; i<l; i++){
\r
847 d = KEYEVENT_ARRAY[ i];
\r
849 d.viewID === currentViewID ||
\r
850 ( overlayEnabled === true && d.viewID === h2c.view.OVERLAY)
\r
852 d.keyCode === key &&
\r
853 ( d.shift === undefined || d.shift === shift) &&
\r
854 ( d.ctrl === undefined || d.ctrl === ctrl)
\r
856 ( function( func, e){
\r
857 func && setTimeout( function(){
\r
861 })( d[callback], e);
\r
866 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true){ // 13.enter 18.esc 9.tab 27.esc || ( key === 13 && overlayEnabled === false)
\r
867 e.preventDefault();
\r
869 e.cancelBubble = true;
\r
870 e.returnValue = false;
\r
877 log = $( '#key-event-log').html( 'ready');
\r
879 jqWindow = h2c.jqWindow().focus();
\r
880 keyOperationChatcher = h2c.jqDocument()
\r
883 .mouseenter( function(){
\r
886 h2c.isIE === true && h2c.ieRenderingVersion < 8 && keyOperationChatcher.keypress( function( e){
\r
887 var key = e.keyCode;
\r
888 if( key === 13 || key === 27){
\r
894 delete h2c.key.init;
\r
896 addKeyDownEvent: function( _viewID, _keyCode, _shift, _ctrl, _callbackFunction){
\r
897 KEYEVENT_ARRAY.push( {
\r
902 keydown: _callbackFunction
\r
905 addKeyUpdateEvent: function( _viewID, _keyCode, _shift, _ctrl, _callbackFunction){
\r
906 KEYEVENT_ARRAY.push( {
\r
911 keydown: _callbackFunction,
\r
912 keyup: _callbackFunction
\r
915 addCursorEvent: function( _viewID, _shift, _ctrl, _callbackFunction){
\r
918 keyEventDispatcher: function(){
\r
919 return keyOperationChatcher;
\r
921 createEditableText: EDITABLE_TEXT_CONTROL.createEditableText,
\r
922 createCheckbox: EDITABLE_TEXT_CONTROL.createCheckbox,
\r
923 shiftEnabled: function(){
\r
924 return shiftEnabled;
\r
926 ctrlEnabled: function(){
\r
927 return ctrlEnabled;
\r
932 /* ----------------------------------------
\r
945 * -----------------------
\r
946 * ie9, other modern browser
\r
949 * -----------------------
\r
952 * 内部の角度計算は radian で統一したい。
\r
953 * 当初 vectorEnabled = true で一度書いてみる。
\r
954 * 駄目なら、代替のイメージのsrcの用意もここで担当。
\r
958 h2c.balloon = ( function() {
\r
959 var MIN_BALLOON_WIDTH = 30,
\r
960 MIN_BALLOON_HEIGHT = 30,
\r
963 STROKE_WIDTH = 1.2,
\r
964 PADDING_TOP = TAIL_HEIGHT,
\r
965 PADDING_LEFT = TAIL_HEIGHT,
\r
966 ACCURACY = 1, // 有効少数桁
\r
967 IS_VML = h2c.isIE === true && h2c.ieVersion < 9,
\r
968 ELM_BALLOON_ORIGIN = ( function(){
\r
971 if( IS_VML === true){
\r
972 ret = document.createElement( 'DIV');
\r
973 var shape = document.createElement( 'v:shape');
\r
974 shape.coordorigin = "0,0";
\r
975 shape.strokecolor = "black";
\r
976 shape.strokeweight = STROKE_WIDTH;
\r
977 shape.fillcolor = "white";
\r
978 ret.appendChild( shape);
\r
980 var kSVGNS = 'http://www.w3.org/2000/svg';
\r
981 ret = document.createElementNS( kSVGNS, 'svg');
\r
982 var path = document.createElementNS( kSVGNS, 'path');
\r
983 path.setAttribute( 'fill', "white");
\r
984 path.setAttribute( 'stroke', "black");
\r
985 path.setAttribute( 'strokeWidth', STROKE_WIDTH);
\r
986 ret.appendChild( path);
\r
993 NUM_BALLOON_IMAGE = 24,
\r
994 vectorEnabled = ELM_BALLOON_ORIGIN !== null && h2c.URL_PARAMS.vector !== false;
\r
995 if( IS_VML === true && h2c.VML === false) vectorEnabled = false;
\r
997 var XBROWSER_BALLOON_CLASS = function( w, h, a){
\r
998 var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true) : document.createElement( 'IMG'), // h2c.imageに変更
\r
999 path = balloonElm.getElementsByTagName( 'path')[ 0],
\r
1000 shape = balloonElm.getElementsByTagName( 'shape')[ 0],
\r
1001 cos = Math.cos, sin = Math.sin,
\r
1002 abs = Math.abs, pow = Math.pow,
\r
1003 round = Math.round,
\r
1004 floor = Math.floor,
\r
1005 TARGET = TAIL_WIDTH * TAIL_WIDTH,
\r
1006 DEG_TO_RAD = Math.PI / 180,
\r
1011 function draw( _a, _w, _h){
\r
1012 a = _a !== undefined ? _a : a;
\r
1013 w = _w !== undefined ? _w -PADDING_TOP *2 : w;
\r
1014 h = _h !== undefined ? _h -PADDING_LEFT *2 : h;
\r
1016 if( vectorEnabled === false){
\r
1017 balloonElm.setAttribute( 'src', balloonUrlBuilder( a));
\r
1023 tailRad = a * DEG_TO_RAD,
\r
1024 tailX = rx +( rx +TAIL_HEIGHT) * cos( tailRad),
\r
1025 tailY = ry +( ry +TAIL_HEIGHT) * sin( tailRad),
\r
1026 startX, startY, endX, endY;
\r
1028 * tailの太さをTAIL_WIDTHに一致させるため、角度を絞りつつ計算
\r
1030 var startRad, endRad,
\r
1031 _startX, _startY, _endX, _endY,
\r
1034 for( var i = 45; i > 0.01; i /= 2){
\r
1035 d = ( tailDeg +i) /2;
\r
1036 startRad = ( a +d) * DEG_TO_RAD;
\r
1037 endRad = ( a -d) * DEG_TO_RAD;
\r
1039 _startX = rx +cos( startRad) *rx;
\r
1040 _startY = ry +sin( startRad) *ry;
\r
1041 _endX = rx +cos( endRad) *rx;
\r
1042 _endY = ry +sin( endRad) *ry; //円弧上のY位置=円中心Y+sin(角度×PI÷180)×円半径
\r
1044 if( pow( ( _startX -_endX), 2) + pow( ( _startY -_endY), 2) < TARGET){
\r
1056 if( IS_VML === true){
\r
1057 var _tailX = tailX *10,
\r
1058 _tailY = tailY *10,
\r
1059 __startX = startX *10,
\r
1060 __startY = startY *10,
\r
1061 __endX = endX *10,
\r
1062 __endY = endY *10,
\r
1066 shape.style.width = w +'px';
\r
1067 shape.style.height = h +'px';
\r
1068 shape.coordsize = [ __w, __h].join( l);
\r
1070 ' ar ', 0, l, 0, l, __w, l, __h, l,
\r
1071 round( __endX), l, round( __endY), l,
\r
1072 round( __startX), l, round( __startY),
\r
1073 ' l ', round( _tailX), l, round( _tailY),
\r
1077 balloonElm.style.marginTop = _tailY < 0 ? floor( ( 60 +_tailY) /10) : 10;
\r
1078 balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 +_tailX) /10) : 10;
\r
1080 balloonElm.setAttribute( 'width', w +PADDING_LEFT *2);
\r
1081 balloonElm.setAttribute( 'height', h +PADDING_TOP *2);
\r
1082 path.setAttribute( 'd', [
\r
1083 'M', cround( tailX + PADDING_LEFT), l, cround( tailY +PADDING_TOP),
\r
1084 'L', cround( startX +PADDING_LEFT), l, cround( startY +PADDING_TOP),
\r
1087 cround( endX +PADDING_LEFT), l, cround( endY +PADDING_TOP),
\r
1091 function cround( v, r){
\r
1092 r = r || ACCURACY;
\r
1093 return round( v *pow( 10.0, r)) /pow( 10.0, r);
\r
1097 function balloonUrlBuilder( _a){
\r
1098 var d = 360 /NUM_BALLOON_IMAGE;
\r
1100 return [ 'balloon\/_w', _a < 360 -d /2 ? floor( _a /d) : 0, '.gif'].join( '');
\r
1105 angle: function( _a){
\r
1106 _a !== undefined && _a !== a &&
\r
1107 vectorEnabled === false ? balloonUrlBuilder( _a) : draw( _a);
\r
1110 type: function( _type){
\r
1113 getURL: function(){
\r
1114 return balloonUrlBuilder( a);
\r
1116 destroy: function(){
\r
1117 balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm);
\r
1118 balloonElm = null;
\r
1119 delete this.destroy;
\r
1124 IS_VML === false && vectorEnabled === true && ( function(){
\r
1125 var detect = XBROWSER_BALLOON_CLASS.apply( {}, [ 100, 100, 0]),
\r
1126 size = h2c.util.getElementSize( detect.elm);
\r
1127 vectorEnabled = size.width !== 0 && size.height !== 0;
\r
1129 detect = size = null;
\r
1134 delete h2c.balloon.init;
\r
1136 enabled: function() {
\r
1137 return vectorEnabled;
\r
1139 VML: IS_VML === true && vectorEnabled === true,
\r
1140 createBalloon: function( _w, _h, _a){
\r
1141 return XBROWSER_BALLOON_CLASS.apply( {}, [ _w, _h, _a]);
\r
1144 TYPE_SPEACH_BALLOON: 1,
\r
1147 TYPE_BLACK_BOX: 4,
\r
1152 /* ----------------------------------------
\r
1155 * xBackendな画像反転、画像描画機能。
\r
1166 * png画像の表示(アルファpngをサポートしないie6以下のため)
\r
1172 * -moz-transform:scale( -1, -1);
\r
1174 h2c.image = ( function(){
\r
1175 var REG_PNG = /\.png?/i,
\r
1181 IS_SILVERLIGHT = 5,
\r
1183 IS_ACTIVEX_SERVER = 7,
\r
1184 BACKEND = ( function(){
\r
1185 if( h2c.DEBUG === true && h2c.URL_PARAMS.rimg){
\r
1186 var rimg = h2c.URL_PARAMS.rimg.toLowerCase();
\r
1187 if( rimg === 'css3') return IS_CSS3;
\r
1188 if( rimg === 'activex') return IS_ACTIVEX;
\r
1189 if( rimg === 'vml') return IS_VML;
\r
1191 if( h2c.isIE === false || h2c.ieVersion >= 9) return IS_CSS3; // 不十分!
\r
1192 if( h2c.VML === true) return IS_VML;
\r
1193 if( h2c.ACTIVEX === true) return IS_ACTIVEX;
\r
1194 if( h2c.FLASH === true) return IS_FLASH;
\r
1195 if( h2c.SILVERLIGHT === true) return IS_SILVERLIGHT;
\r
1198 PNG_FIX = h2c.isIE === true && h2c.ieVersion <= 6,
\r
1199 BACKEND_WHEN_PNG = PNG_FIX === false ? BACKEND : ( function(){
\r
1200 if( h2c.balloon.VML === true) return IS_VML;
\r
1201 if( h2c.FLASH === true) return IS_FLASH;
\r
1202 if( h2c.SILVERLIGHT === true) return IS_SILVERLIGHT;
\r
1203 if( h2c.ACTIVEX === true) return IS_ACTIVEX_SERVER;
\r
1207 var XBackendReversibleImageClass = ( function(){
\r
1208 var CLASS_NAME = 'reversible-image-container',
\r
1209 CLASS_NAME_LOADING = CLASS_NAME + ' loading',
\r
1210 CLASS_NAME_ERROR = CLASS_NAME +' error',
\r
1211 RETRY_DELAY = 5000;
\r
1214 var css3Image = function( url, w, h, onLoadCallback){
\r
1215 var elmWrap = document.createElement( 'div'),
\r
1218 retryTimer = null;
\r
1219 elmWrap.className = CLASS_NAME_LOADING;
\r
1220 h2c.util.loadImage( url, onLoad, onError, 100, 10000);
\r
1221 function onLoad( _url, _actualW, _actualH){
\r
1222 if( elmWrap === null) return;
\r
1223 elmImg = new Image;
\r
1225 * createElement 直後に append しないと、ie(ActiveX)で img が正しく表示されない.
\r
1227 elmWrap.appendChild( elmImg);
\r
1228 elmImg.setAttribute( 'src', url);
\r
1229 elmWrap.className = CLASS_NAME;
\r
1230 onLoadCallback && onLoadCallback( _url, _actualW, _actualH);
\r
1231 onLoadCallback = null;
\r
1235 function onError( _url){
\r
1236 if( elmWrap === null) return;
\r
1237 elmWrap.className = CLASS_NAME_ERROR;
\r
1238 retryTimer = setTimeout( function(){
\r
1239 elmWrap.className = CLASS_NAME_LOADING;
\r
1240 h2c.util.loadImage( url, onLoad, onError, 100, 10000);
\r
1243 function resize( _w, _h){
\r
1244 w = _w !== undefined ? _w : w;
\r
1245 h = _h !== undefined ? _h : h;
\r
1246 if( loaded === false) return;
\r
1247 elmImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'v' : 'h'))) : '';
\r
1252 destroy: function(){
\r
1253 loaded === true && elmWrap.removeChild( elmImg);
\r
1254 retryTimer !== null && clearTimeout( retryTimer);
\r
1255 elmWrap = vmlImg = onLoadCallback = retryTimer = null;
\r
1256 elmWrap = elmImg = onLoadCallback = null;
\r
1257 delete this.destroy;
\r
1261 var activexImage = css3Image;
\r
1262 var vmlImage = function( url, w, h, onLoadCallback){
\r
1263 var elmWrap = document.createElement( 'div'),
\r
1266 retryTimer = null;
\r
1267 elmWrap.className = CLASS_NAME_LOADING;
\r
1268 h2c.util.loadImage( url, onLoad, onError, 100, 10000);
\r
1269 function onLoad( _url, _actualW, _actualH){
\r
1270 if( elmWrap === null) return;
\r
1271 elmWrap.className = CLASS_NAME;
\r
1272 vmlImg = document.createElement( 'v:image');
\r
1276 onLoadCallback && onLoadCallback( _url, _actualW, _actualH);
\r
1277 onLoadCallback = null;
\r
1279 function onError( _url){
\r
1280 if( elmWrap === null) return;
\r
1281 elmWrap.className = CLASS_NAME_ERROR;
\r
1282 retryTimer = setTimeout( function(){
\r
1283 elmWrap.className = CLASS_NAME_LOADING;
\r
1284 h2c.util.loadImage( url, onLoad, onError, 100, 10000);
\r
1287 function resize( _w, _h){
\r
1288 w = _w !== undefined ? _w : w;
\r
1289 h = _h !== undefined ? _h : h;
\r
1290 if( loaded !== true) return;
\r
1291 vmlImg.style.width = w < 0 ? -w : w +'px';
\r
1292 vmlImg.style.height = h < 0 ? -h : h +'px';
\r
1293 //if( flipH !== _flipH || flipV !== _flipV){
\r
1294 vmlImg.parentNode === elmWrap && elmWrap.removeChild( vmlImg);
\r
1296 vmlImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'v' : 'h'))) : '';
\r
1297 elmWrap.appendChild( vmlImg);
\r
1302 destroy: function(){
\r
1303 loaded === true && elmWrap.removeChild( vmlImg);
\r
1304 retryTimer !== null && clearTimeout( retryTimer);
\r
1305 elmWrap = vmlImg = onLoadCallback = retryTimer = null;
\r
1306 delete this.destroy;
\r
1310 var serverImage = function( url, w, h, onLoadCallback){
\r
1314 return function( url, w, h, onLoadCallback){
\r
1315 var flipH = w < 0,
\r
1317 onLoadCallbackAsync = onLoadCallback,// ? function(){ setTimeout( onLoadCallback, 0);} : undefined,// 一度読み込んだ画像は即座にonLoadになるため遅延
\r
1318 xBackendImage = ( function( urlIsXDomain){
\r
1319 if( BACKEND === IS_CSS3) return css3Image.apply( {}, [ url, w, h, onLoadCallbackAsync]);
\r
1320 if( BACKEND === IS_VML) return vmlImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);
\r
1321 if( BACKEND === IS_ACTIVEX) return activexImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);
\r
1322 return serverImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);
\r
1325 elm: xBackendImage.elm,
\r
1327 _w !== undefined && xBackendImage.resize( _w, h);
\r
1331 _h !== undefined && xBackendImage.resize( w, _h);
\r
1334 resize: xBackendImage.resize,
\r
1335 destroy: function(){
\r
1336 xBackendImage.destroy && xBackendImage.destroy();
\r
1337 xBackendImage = onLoadCallback = onLoadCallbackAsync = null;
\r
1338 delete this.destroy;
\r
1347 createReversibleImage: function( url, w, h, onLoadCallback){
\r
1348 return XBackendReversibleImageClass.apply( {}, [ url, w, h, onLoadCallback]);
\r
1353 /* ----------------------------------------
\r
1356 * - WINDOW_CONTROL
\r
1358 * - INFOMATION_WINDOW
\r
1359 * - TOOL_BOX_WINDOW
\r
1360 * - CANVAS_CONTROL
\r
1362 * - WHITE_GLASS_CONTROL
\r
1363 * - PANEL_BORDER_CONTROL
\r
1364 * - COMIC_ELEMENT_CONTROL
\r
1365 * - PanelResizerClass
\r
1366 * - COMIC_ELEMENT_OPERATOR
\r
1367 * - TAIL_CONTROLER
\r
1368 * - ImageElementClass
\r
1369 * - TextElementClass
\r
1372 h2c.editor = ( function(){
\r
1373 var COMIC_ELEMENT_TYPE_IMAGE = 0,
\r
1374 COMIC_ELEMENT_TYPE_TEXT = 1,
\r
1375 MOUSE_LISTENER_ARRAY = [],
\r
1376 currentListener = null,
\r
1377 ELM_MOUSE_EVENT_CHATCHER = document.getElementById( 'mouse-operation-catcher'),
\r
1378 jqMouseEventChacher,
\r
1381 currentCursor = '';
\r
1383 /* ----------------------------------------
\r
1393 var MENU_BAR_CONTROL = ( function(){
\r
1394 var BAR_ID = 'menu-bar',
\r
1395 ELM_BAR = document.getElementById( BAR_ID),
\r
1396 ELM_ITEM_CLASSNAME = 'menu-bar-item',
\r
1397 ELM_ITEM_ORIGN = ( function(){
\r
1398 var ret = document.createElement( 'DIV'),
\r
1399 div = document.createElement( 'DIV'),
\r
1400 ul = document.createElement( 'UL');
\r
1401 ret.className = ELM_ITEM_CLASSNAME;
\r
1402 ret.appendChild( div);
\r
1403 ret.appendChild( ul);
\r
1406 ELM_SELECTION_ORIGN = ( function(){
\r
1407 var ret = document.createElement( 'LI'),
\r
1408 a = document.createElement( 'A'),
\r
1409 span = document.createElement( 'SPAN'),
\r
1410 key = document.createElement( 'KBD');
\r
1412 a.appendChild( span);
\r
1413 a.appendChild( key);
\r
1414 ret.appendChild( a);
\r
1417 EMPTY_FUNCTION = new Function,
\r
1419 barH = h2c.util.getElementSize( ELM_BAR).height,
\r
1420 itemW = h2c.util.getElementSize( ELM_ITEM_ORIGN).width,
\r
1421 selectionW = h2c.util.getElementSize( ELM_ITEM_ORIGN.getElementsByTagName( 'UL')[ 0]).width,
\r
1423 ELM_BAR.style.top = ( -barH) +'px';
\r
1425 var MenubarSelectionClass = function( container, title, shortcut, visible, separateAfter){
\r
1426 var ELM_WRAPPER = ELM_SELECTION_ORIGN.cloneNode( true),
\r
1427 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'SPAN')[ 0];
\r
1428 updateTitle( title);
\r
1429 updateVisible( visible);
\r
1432 var ELM_SHORTCUT = ELM_WRAPPER.getElementsByTagName( 'KBD')[ 0];
\r
1434 ELM_SHORTCUT.innerHTML = shortcut;
\r
1436 ELM_SHORTCUT.parentNode.removeChild( ELM_SHORTCUT);
\r
1440 container.appendChild( ELM_WRAPPER);
\r
1442 function updateTitle( _title){
\r
1443 ELM_TITLE.innerHTML = title = _title;
\r
1445 function updateVisible( _visible){
\r
1446 _visible !== undefined && ( function(){
\r
1447 visible = !!_visible;
\r
1448 ELM_WRAPPER.className = visible === true ? '' : 'disabled';
\r
1453 title: function( _title){
\r
1454 _title !== undefined && updateTitle( _title);
\r
1457 visible: function( _visible){
\r
1458 visible !== !!_visible && updateVisible( _visible);
\r
1461 separateAfter: separateAfter
\r
1465 var MenuBarItemClass = function( title, opt_callbackArray){
\r
1466 var ELM_WRAPPER = ELM_ITEM_ORIGN.cloneNode( true),
\r
1467 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'DIV')[ 0],
\r
1468 ELM_SELECTION = ELM_WRAPPER.getElementsByTagName( 'UL')[ 0],
\r
1469 INDEX = ITEM_ARRAY.length,
\r
1470 SELECTION_CALLBACK_ARRAY = opt_callbackArray || [],
\r
1473 ELM_TITLE.innerHTML = title;
\r
1475 ELM_WRAPPER.style.left = ( itemW * INDEX) +'px';
\r
1476 ELM_BAR.appendChild( ELM_WRAPPER);
\r
1478 function onClick( e){
\r
1481 var parent = that.parentNode,
\r
1482 children = parent.getElementsByTagName( 'LI'),
\r
1483 l = children.length;
\r
1484 for(var i=0; i<l; ++i){
\r
1485 if( children[ i] === that) return i;
\r
1489 i !== -1 && this.className !== 'disabled' && SELECTION_CALLBACK_ARRAY[ i]();
\r
1490 e.stopPropagation();
\r
1497 $( ELM_SELECTION).children( 'li').click( onClick);
\r
1501 if( visible === true) return;
\r
1502 jqStage.append( ELM_WRAPPER);
\r
1503 ELM_WRAPPER.className = ELM_ITEM_CLASSNAME +'-focus';
\r
1504 this.onShow && setTimeout( this.onShow, 0);
\r
1508 if( visible === false) return;
\r
1509 ELM_BAR.appendChild( ELM_WRAPPER);
\r
1510 ELM_WRAPPER.className = ELM_ITEM_CLASSNAME;
\r
1511 this.onHide && setTimeout( this.onHide, 0);
\r
1514 createSelection: function( title, shortcut, callback, visible, separateBefore, separateAfter){
\r
1515 var ret = MenubarSelectionClass.apply( {}, [ ELM_SELECTION, title, shortcut, visible, separateAfter]),
\r
1516 before = SELECTION_CALLBACK_ARRAY.length > 0 ? SELECTION_CALLBACK_ARRAY[ SELECTION_CALLBACK_ARRAY.length -1] : null;
\r
1517 SELECTION_CALLBACK_ARRAY.push( callback);
\r
1518 if( ( separateBefore === true && before) || ( before && before.separateAfter === true)){
\r
1519 ret.elm.style.borderTop = '1px solid #ccc';
\r
1527 function createMenubarItem( title){
\r
1528 var _item = MenuBarItemClass.apply( {}, [ title]);
\r
1529 ITEM_ARRAY.push( _item);
\r
1534 jqStage = jqEditor;
\r
1535 jqBar = $( '#' +BAR_ID).animate( { top: 0});
\r
1537 var l = ITEM_ARRAY.length;
\r
1538 for( var i=0; i<l; ++i){
\r
1539 ITEM_ARRAY[ i].init();
\r
1542 delete MENU_BAR_CONTROL.init;
\r
1545 onMouseMove: function( _mouseX, _mouseY){
\r
1546 if( barH >= _mouseY){
\r
1549 var l = ITEM_ARRAY.length;
\r
1550 for( var i=0; i<l; ++i){
\r
1551 ITEM_ARRAY[ i].hide();
\r
1555 onMouseUp: function( _mouseX, _mouseY){
\r
1558 onMouseDown: function( _mouseX, _mouseY){
\r
1559 var l = ITEM_ARRAY.length;
\r
1560 if( barH < _mouseY || itemW * l < _mouseX) return false;
\r
1561 for( var i=0; i<l; ++i){
\r
1562 if( i * itemW <= _mouseX && _mouseX < ( i +1) * itemW){
\r
1563 ITEM_ARRAY[ i].show();
\r
1565 ITEM_ARRAY[ i].hide();
\r
1570 busy: function( _busy){
\r
1573 onWindowResize: function( _windowW, _windowH){
\r
1576 QUIT: createMenubarItem( 'Quit'),
\r
1577 EDIT: createMenubarItem( 'Edit'),
\r
1578 WINDOW: createMenubarItem( 'Window'),
\r
1579 HELP: h2c.util.extend( createMenubarItem( 'Help'), {
\r
1580 createAjaxSelection: function( callback){
\r
1581 var elmLoading = document.createElement( 'li'),
\r
1583 elmSelection = this.elm.getElementsByTagName( 'UL')[ 0];
\r
1584 elmSelection.appendChild( elmLoading);
\r
1585 elmLoading.className = 'loading';
\r
1586 elmLoading.style.height = '90px';
\r
1588 this.onShow = callback;
\r
1591 delete this.createAjaxSelection;
\r
1592 return function(){
\r
1593 elmSelection.removeChild( elmLoading);
\r
1594 $( elmSelection).children( 'li').click( that.onClick);
\r
1595 elmLoading = elmSelection = null;
\r
1596 delete that.onShow;
\r
1605 /* ----------------------------------------
\r
1608 var HISTORY = ( function() {
\r
1609 var STACK_BACK = [],
\r
1610 STACK_FORWARD = [],
\r
1611 MENUBAR_BACK = MENU_BAR_CONTROL.EDIT.createSelection( 'back', 'ctrl + z', back, false),
\r
1612 MENUBAR_FORWARD = MENU_BAR_CONTROL.EDIT.createSelection( 'forward', 'ctrl + y', forward, false, false, true),
\r
1615 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 90, false, true, back); // ctrl + Z
\r
1616 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 90, true, true, forward); // ctrl + shift + Z
\r
1617 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 89, false, true, forward); // ctrl + Y
\r
1621 * currentを控えてSTACK_FORWARD.push(current)
\r
1622 * STACK_BACK.pop()を実行してcurrentに
\r
1624 if( STACK_BACK.length === 0) return;
\r
1626 var state = STACK_BACK.pop();
\r
1627 state && state.fn( state.argBack);
\r
1628 MENUBAR_BACK.visible( STACK_BACK.length !== 0);
\r
1629 SAVE_CONTROL.panelUpdated( STACK_BACK.length !== 0);
\r
1631 STACK_FORWARD.push( state);
\r
1632 MENUBAR_FORWARD.visible( true);
\r
1634 function forward(){
\r
1635 if( STACK_FORWARD.length === 0) return;
\r
1637 var state = STACK_FORWARD.pop();
\r
1638 state.fn( state.argForword);
\r
1639 MENUBAR_FORWARD.visible( STACK_FORWARD.length !== 0);
\r
1641 STACK_BACK.push( state);
\r
1642 MENUBAR_BACK.visible( true);
\r
1643 SAVE_CONTROL.panelUpdated( true);
\r
1647 log = $( '#history-log');
\r
1648 delete HISTORY.init;
\r
1650 saveState: function( _function, _argBack, _argForword, _destory) {
\r
1651 STACK_BACK.push( {
\r
1653 argBack: _argBack,
\r
1654 argForword: _argForword,
\r
1657 MENUBAR_BACK.visible( true);
\r
1658 SAVE_CONTROL.panelUpdated( true);
\r
1660 while( STACK_FORWARD.length > 0){
\r
1661 _argBack = _stack.argBack;
\r
1662 _argForword = _stack.argForword;
\r
1663 var _stack = STACK_FORWARD.shift(),
\r
1664 _destroy = _stack.destroy,
\r
1667 if( typeof _argBack === 'array'){
\r
1668 while( _argBack.length > 0){
\r
1669 _value = _argBack.shift();
\r
1670 _destroy === true && _value.destroy && _value.destroy();
\r
1673 if( typeof _argForword === 'array'){
\r
1674 while( _argForword.length > 0){
\r
1675 _value = _argForword.shift();
\r
1676 _destroy === true && _value.destroy && _value.destroy();
\r
1680 MENUBAR_FORWARD.visible( false);
\r
1686 /* ----------------------------------------
\r
1690 var SAVE_CONTROL = ( function(){
\r
1691 var SAVE = MENU_BAR_CONTROL.QUIT.createSelection( 'save', 'ctrl + S', quit, false),
\r
1692 SAVE_AND_QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'save & quit', null, quit, false, false, true),
\r
1693 SAVE_AS_HTML = MENU_BAR_CONTROL.QUIT.createSelection( 'get as html', null, outputAsHtml, true, false, true),
\r
1694 SAVE_AS_JSON_STRING = MENU_BAR_CONTROL.QUIT.createSelection( 'get JsonStr', null, outputAsJsonString, true, false, true),
\r
1695 QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'quit', null, quit, true, true),
\r
1701 function outputAsHtml(){
\r
1702 alert( CANVAS_CONTROL.getAsHTML( true, false));
\r
1704 function outputAsJsonString(){
\r
1705 alert( CANVAS_CONTROL.getAsJsonString());
\r
1709 panelUpdated: function( _updated){
\r
1710 if( _updated !== undefined && updated !== _updated){
\r
1711 SAVE.visible( !!_updated);
\r
1712 SAVE_AND_QUIT.visible( !!_updated);
\r
1713 updated = !!_updated;
\r
1723 /* ----------------------------------------
\r
1724 * Text Editor (Overlay)
\r
1727 var TEXT_EDITOR_CONTROL = ( function(){
\r
1728 var jqWrap, jqTextarea, jqButton,
\r
1729 textElement, onUpdateFunction;
\r
1731 h2c.key.addKeyDownEvent( this.ID, 69, false, false, clickOK);
\r
1735 textElement = onUpdateFunction = null;
\r
1737 function clickOK(){
\r
1738 h2c.overlay.hide();
\r
1739 textElement && textElement.text( jqTextarea.val());
\r
1740 onUpdateFunction && onUpdateFunction( textElement);
\r
1745 this.jqWrap = jqWrap = $( '#speach-editor-wrapper').hide();
\r
1746 jqTextarea = $( '#speach-editor').keydown( function( e){
\r
1747 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
\r
1749 e.preventDefault();
\r
1751 e.cancelBubble = true;
\r
1752 e.returnValue = false;
\r
1756 jqButton = $( '#speach-edit-complete-button').click( clickOK);
\r
1757 delete TEXT_EDITOR_CONTROL.init;
\r
1760 show: function( _textElement, _onUpdateFunction){
\r
1761 textElement = _textElement;
\r
1762 onUpdateFunction = _onUpdateFunction || null;
\r
1763 h2c.overlay.show( this);
\r
1764 var h = _textElement.h;
\r
1765 jqWrap.show().css( {
\r
1766 left: _textElement.x +CANVAS_CONTROL.x(),
\r
1767 top: _textElement.y +CANVAS_CONTROL.y(),
\r
1768 width: _textElement.w,
\r
1771 jqTextarea.val( _textElement.text()).focus();
\r
1774 * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
\r
1776 h2c.isIE === true && h2c.ieVersion <= 7 && setTimeout( function(){
\r
1778 while( jqTextarea.height() < h){
\r
1780 jqTextarea.attr( 'rows', rows);
\r
1782 rows > 1 && jqTextarea.attr( 'rows', rows -1);
\r
1785 onWindowResize: function(){
\r
1786 textElement && this.show( textElement);
\r
1793 /* ----------------------------------------
\r
1794 * Image Group Exproler (Overlay)
\r
1796 var IMAGE_GROUP_EXPROLER = ( function(){
\r
1797 var ICON_ARRAY = [],
\r
1799 containerW, containerH, wrapX,
\r
1800 jqWrap, jqContainer, jqItemOrigin,
\r
1802 jqName, jqButton, buttonW,
\r
1805 onEnterInterval = null;
\r
1807 var BASE_PATH = h2c.LOCAL === false ? 'http://pettan.heroku.com/images/' : 'images/',
\r
1808 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
\r
1809 LIMIT_FILESIZE = 1024 * 10; // 10KB
\r
1810 var IMAGE_DATA = {
\r
1813 "created_at": "2011-11-13T08:57:39Z",
\r
1815 "filesize": 9969,
\r
1818 "updated_at": "2011-11-13T08:57:39Z",
\r
1822 "created_at": "2011-11-13T08:57:54Z",
\r
1824 "filesize": 5418,
\r
1827 "updated_at": "2011-11-13T08:57:54Z",
\r
1831 "created_at": "2011-11-13T08:58:06Z",
\r
1833 "filesize": 8758,
\r
1836 "updated_at": "2011-11-13T08:58:06Z",
\r
1840 "created_at": "2011-11-13T08:58:23Z",
\r
1842 "filesize": 9383,
\r
1845 "updated_at": "2011-11-13T08:58:23Z",
\r
1849 "created_at": "2011-11-13T08:58:33Z",
\r
1851 "filesize": 11061,
\r
1854 "updated_at": "2011-11-13T08:58:33Z",
\r
1858 "created_at": "2011-11-20T09:50:43Z",
\r
1860 "filesize": 1131,
\r
1863 "updated_at": "2011-11-20T09:50:43Z",
\r
1867 "created_at": "2011-11-20T09:50:55Z",
\r
1869 "filesize": 1125,
\r
1872 "updated_at": "2011-11-20T09:50:55Z",
\r
1876 "created_at": "2011-11-20T11:33:12Z",
\r
1878 "filesize": 17919,
\r
1881 "updated_at": "2011-11-20T11:33:12Z",
\r
1885 "created_at": "2011-11-20T11:33:12Z",
\r
1887 "filesize": 17919,
\r
1890 "updated_at": "2011-11-20T11:33:12Z",
\r
1894 "created_at": "2011-11-20T11:33:12Z",
\r
1896 "filesize": 17919,
\r
1899 "updated_at": "2011-11-20T11:33:12Z",
\r
1903 "created_at": "2011-11-20T11:33:12Z",
\r
1905 "filesize": 17919,
\r
1908 "updated_at": "2011-11-20T11:33:12Z",
\r
1912 "created_at": "2011-11-22T09:17:20Z",
\r
1914 "filesize": 9055,
\r
1917 "updated_at": "2011-11-22T09:17:20Z",
\r
1921 "created_at": "2011-11-22T10:11:07Z",
\r
1923 "filesize": 8758,
\r
1926 "updated_at": "2011-11-22T10:11:07Z",
\r
1930 "created_at": "2011-11-24T09:05:12Z",
\r
1932 "filesize": 6431,
\r
1935 "updated_at": "2011-11-24T09:05:12Z",
\r
1939 "created_at": "2011-11-26T04:52:12Z",
\r
1941 "filesize": 6421,
\r
1944 "updated_at": "2011-11-26T04:52:12Z",
\r
1948 "created_at": "2011-11-26T04:52:12Z",
\r
1950 "filesize": 6421,
\r
1953 "updated_at": "2011-11-26T04:52:12Z",
\r
1957 "created_at": "2011-11-26T04:52:12Z",
\r
1959 "filesize": 6421,
\r
1962 "updated_at": "2011-11-26T04:52:12Z",
\r
1966 "created_at": "2011-11-26T04:52:12Z",
\r
1968 "filesize": 6421,
\r
1971 "updated_at": "2011-11-26T04:52:12Z",
\r
1975 "created_at": "2011-11-26T04:52:12Z",
\r
1977 "filesize": 6421,
\r
1980 "updated_at": "2011-11-26T04:52:12Z",
\r
1986 var ImageGroupIconClass = function( INDEX, data){
\r
1987 var JQ_ICON_WRAP = jqItemOrigin.clone( true),
\r
1988 SRC = [ BASE_PATH, data.id, '.', data.ext].join( ''),
\r
1989 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext].join( '') : null,
\r
1990 reversibleImage = null,
\r
1991 onEnterFlag = false;
\r
1992 JQ_ICON_WRAP.children( 'div').eq( 0).html( data.filesize + 'bytes');
\r
1993 jqContainer.append( JQ_ICON_WRAP.css( { left: INDEX * itemW}));
\r
1996 onEnter: function(){
\r
1997 if( onEnterFlag === true) return;
\r
1998 reversibleImage = h2c.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, function( url, imgW, imgH){
\r
1999 if( reversibleImage === null) {
\r
2006 imgW = imgW || data.width || 64;
\r
2007 imgH = imgH || data.height || 64;
\r
2008 JQ_ICON_WRAP.children( 'div').eq( 1).html( imgW +'x' +imgH);
\r
2009 var zoom = 128 /( imgW > imgH ? imgW : imgH),
\r
2010 h = Math.floor( imgH *zoom),
\r
2011 w = Math.floor( imgW *zoom);
\r
2012 reversibleImage.elm.style.width = w +'px';
\r
2013 reversibleImage.elm.style.height = h +'px';
\r
2014 reversibleImage.elm.style.margin = Math.floor( itemH /2 -h /2)+'px 0 0';
\r
2015 reversibleImage.resize( w, h);
\r
2016 JQ_ICON_WRAP.click( function( e){
\r
2017 h2c.overlay.hide();
\r
2018 if (onUpdateFunction) {
\r
2019 if( LOW_SRC === null){
\r
2020 onUpdateFunction( SRC, imgW, imgH);
\r
2022 ( function( onUpdate){
\r
2023 h2c.util.loadImage( SRC,
\r
2024 function( _abspath, imgW, imgH){
\r
2025 onUpdate( SRC, imgW, imgH);
\r
2028 function( _abspath){
\r
2029 onUpdate( SRC, data.width || 64, data.height || 64);
\r
2033 })( onUpdateFunction); // close()で値が消えるので、クロージャに保持
\r
2039 JQ_ICON_WRAP.children( 'img').replaceWith( reversibleImage.elm);
\r
2040 onEnterFlag = true;
\r
2042 destroy: function(){
\r
2043 reversibleImage && reversibleImage.destroy();
\r
2044 JQ_ICON_WRAP.remove();
\r
2045 reversibleImage = JQ_ICON_WRAP = null;
\r
2046 delete this.destroy;
\r
2052 jqContainer.stop().animate( {
\r
2054 top: Math.floor( windowH /2)
\r
2058 while( ICON_ARRAY.length > 0){
\r
2059 ICON_ARRAY.shift().destroy();
\r
2061 onEnterInterval !== null && window.clearTimeout( onEnterInterval);
\r
2062 onUpdateFunction = onEnterInterval = null;
\r
2064 function onEnterShowImage(){
\r
2065 var l = ICON_ARRAY.length,
\r
2066 _start = -wrapX /itemW -1,
\r
2067 _end = _start + winW /itemW +1;
\r
2068 for( var i=0; i<l; ++i){
\r
2069 _start < i && i < _end && ICON_ARRAY[ i].onEnter();
\r
2071 onEnterInterval !== null && window.clearTimeout( onEnterInterval);
\r
2072 onEnterInterval = null;
\r
2074 function clickOK(){
\r
2075 h2c.overlay.hide();
\r
2076 // onUpdateFunction && onUpdateFunction( textElement);
\r
2081 this.jqWrap = jqWrap = $( '#image-gruop-wrapper').hide();
\r
2082 jqContainer = $( '#image-icon-container').mousewheel(
\r
2083 function( e, delta){
\r
2084 if( winW < containerW){
\r
2085 wrapX += delta *WHEEL_DELTA;
\r
2086 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
\r
2087 jqContainer.css( { left: wrapX});
\r
2089 onEnterInterval !== null && window.clearTimeout( onEnterInterval);
\r
2090 onEnterInterval = window.setTimeout( onEnterShowImage, 500);
\r
2092 //e.stopPropagation();
\r
2095 containerH = h2c.util.getElementSize( jqContainer.get( 0)).height;
\r
2096 jqItemOrigin = $( $( '#imageGruopItemTemplete').remove().html());
\r
2097 var itemSize = h2c.util.getElementSize( jqItemOrigin.get( 0));
\r
2098 itemW = itemSize.width;
\r
2099 itemH = itemSize.height;
\r
2100 jqName = $( '#gruop-name-display');
\r
2101 jqButton = $( '#image-gruop-button').click( clickOK);
\r
2102 buttonW = h2c.util.getElementSize( jqButton.get( 0)).width;
\r
2104 delete IMAGE_GROUP_EXPROLER.init;
\r
2107 show: function( _onUpdateFunction){
\r
2108 onUpdateFunction = _onUpdateFunction;
\r
2109 h2c.overlay.show( this);
\r
2111 var CURRENT_GROUP_ARRAY = IMAGE_DATA[ 'pen001'] || [],
\r
2112 l = CURRENT_GROUP_ARRAY.length;
\r
2113 for( var i=0; i<l; ++i){
\r
2114 ICON_ARRAY.push( ImageGroupIconClass.apply( {}, [ i, CURRENT_GROUP_ARRAY[ i]]));
\r
2117 containerW = l * itemW;
\r
2120 var w = winW > containerW ? winW : containerW,
\r
2121 h = windowH > containerH ? containerH : windowH;
\r
2124 jqContainer.css( {
\r
2128 top: Math.floor( windowH /2)
\r
2129 }).stop().animate( {
\r
2131 top: Math.floor( windowH /2 -h /2)
\r
2135 left: Math.floor( winW /2 -buttonW /2),
\r
2136 top: Math.floor( windowH /2 +containerH /2 +10)
\r
2139 onEnterShowImage();
\r
2141 onWindowResize: function( _windowW, _windowH){
\r
2142 var w = _windowW > containerW ? _windowW : containerW,
\r
2143 h = _windowH > containerH ? containerH : _windowH,
\r
2144 offsetW = Math.floor( _windowW /2 -winW /2);
\r
2146 if( offsetW <= 0){ // smaller
\r
2147 jqContainer.css( {
\r
2152 top: Math.floor( _windowH /2 -h /2)
\r
2155 jqContainer.css( { // bigger
\r
2158 borderLeftWidth: offsetW
\r
2160 top: Math.floor( _windowH /2 -h /2),
\r
2161 borderLeftWidth: 0
\r
2165 left: Math.floor( _windowW /2 -buttonW /2),
\r
2166 top: Math.floor( _windowH /2 +containerH /2 +10)
\r
2168 onEnterShowImage();
\r
2171 ID: 'imageGroupExproler'
\r
2175 /* ----------------------------------------
\r
2178 var WINDOWS_CONTROL = ( function(){
\r
2180 * 表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。
\r
2182 var DEFAULT_MIN_WINDOW_WIDTH = 200,
\r
2183 DEFAULT_MIN_WINDOW_HEIGHT = 200,
\r
2184 WINDOW_ARRAY = [],
\r
2187 currentWindowIndex = -1,
\r
2190 var jqWindowOrigin,
\r
2192 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH){
\r
2193 var MOUSE_CURSOR = updateMouseCursor,
\r
2194 MENUBAR_SELWCTION = MENU_BAR_CONTROL.WINDOW.createSelection(
\r
2195 ( visible !== true ? 'show ' : 'hide ') +title,
\r
2198 visible === true ? instance.close() : instance.open();
\r
2202 jqWrapper, jqHeader, elmBody, elmBodyStyle,
\r
2203 startX, startY, startW, startH,
\r
2206 isDragging = false,
\r
2207 isResizing = false,
\r
2208 bodyIsTachable = false,
\r
2211 function update( _x, _y, _w, _h){
\r
2212 ( w !== _w || h !== _h) && instance.onResize && instance.onResize( _w, _h);
\r
2213 x = _x !== undefined ? _x : x;
\r
2214 y = _y !== undefined ? _y : y;
\r
2215 w = _w !== undefined ? _w : w;
\r
2216 h = _h !== undefined ? _h : h;
\r
2217 y = y > MENU_BAR_CONTROL.h ? y : MENU_BAR_CONTROL.h;
\r
2224 bodyH = h -headerH;
\r
2225 elmBodyStyle.height = bodyH +'px';
\r
2227 function bodyBackOrForward( isBack){
\r
2228 if( !instance) return;
\r
2229 if( bodyIsTachable === !isBack) return;
\r
2230 elmBodyStyle.position = isBack === true ? 'relative' : 'absolute';
\r
2231 elmBodyStyle.left = isBack === true ? 0 : x +'px';
\r
2232 elmBodyStyle.top = isBack === true ? 0 : y +headerH +'px';
\r
2233 elmBodyStyle.width = isBack === true ? '' : w +'px';
\r
2234 bodyIsTachable === isBack && isBack === true ? jqWrapper.append( elmBody) : jqStage.append( elmBody);
\r
2235 bodyIsTachable = !isBack;
\r
2237 function onWindowResize( e){
\r
2238 bodyBackOrForward( true);
\r
2239 isResizing = true;
\r
2244 xOffset = e.pageX;
\r
2245 yOffset = e.pageY;
\r
2246 MOUSE_CURSOR( 'nw-resize');
\r
2247 e.stopPropagation();
\r
2251 init: function( jqContainer){
\r
2253 * setTimeout で呼ばれるグローバルメソッドは、this でなく instance を使う.
\r
2257 jqWindowOrigin = jqWindowOrigin || ( function(){
\r
2258 return $( $( '#windowTemplete').remove().html());
\r
2260 closeButtonWidth = closeButtonWidth || ( function(){
\r
2261 return h2c.util.getElementSize( jqWindowOrigin.clone( true).find( '.window-close-button').get( 0)).width;
\r
2264 jqStage = jqEditor;
\r
2265 this.$ = jqWrapper = jqWindowOrigin.clone( true);
\r
2266 jqHeader = jqWrapper.children( '.window-header').eq( 0).html( title);
\r
2267 headerH = h2c.util.getElementSize( jqHeader.get( 0)).height;
\r
2268 elmBody = jqWrapper.children( '.window-body').get( 0);
\r
2269 elmBodyStyle = elmBody.style;
\r
2270 if( bodyTempleteID) {
\r
2271 jqWrapper.find( '.window-body-insert-position').replaceWith( $( $( '#' +bodyTempleteID).remove().html()));
\r
2273 jqWrapper.find( '.window-body-insert-position').remove();
\r
2275 CLOSE_BUTTON_ENABLED !== true && jqWrapper.find( '.window-close-button').remove();
\r
2277 this.onInit && this.onInit();
\r
2280 x: function(){ return x;},
\r
2281 y: function(){ return y;},
\r
2282 w: function(){ return w;},
\r
2283 h: function(){ return h;},
\r
2285 title: function( _title){
\r
2286 _title !== undefined && jqHeader.html( _title);
\r
2287 title = _title || title;
\r
2291 firstOpen: function(){
\r
2292 if( RESIZE_BUTTON_ENABLED === true){
\r
2293 jqWrapper.find( '.window-resize-button').eq( 0).mousedown( onWindowResize);
\r
2295 jqWrapper.find( '.window-resize-button').remove();
\r
2297 update( x, y, w, h);
\r
2299 this.onFirstOpen && this.onFirstOpen();
\r
2301 delete this.firstOpen;
\r
2304 if( visible === true) return;
\r
2305 instance.visible = visible = true;
\r
2306 openWindow( instance);
\r
2307 MENUBAR_SELWCTION.title( 'hide ' +title);
\r
2309 for( var i=0, l = WINDOW_ARRAY.length; i<l; ++i){
\r
2310 if( WINDOW_ARRAY[ i] === instance){
\r
2311 WINDOW_ARRAY.splice( i, 1);
\r
2312 WINDOW_ARRAY.unshift( instance);
\r
2313 currentWindow = null;
\r
2314 currentWindowIndex = -1;
\r
2318 close: function(){
\r
2319 if( visible === false) return;
\r
2320 instance.visible = visible = false;
\r
2321 instance.onClose && setTimeout( instance.onClose, 0);
\r
2322 closeWindow( instance);
\r
2323 MENUBAR_SELWCTION.title( 'show ' +title);
\r
2325 bodyBackOrForward: bodyBackOrForward,
\r
2326 onMouseDown: function( _mouseX, _mouseY){
\r
2327 if( x > _mouseX || y > _mouseY || x +w < _mouseX || y +headerH < _mouseY ) return;
\r
2328 if( CLOSE_BUTTON_ENABLED === true && x +w -closeButtonWidth < _mouseX){
\r
2332 isDragging = true;
\r
2333 MOUSE_CURSOR( 'move');
\r
2338 xOffset = _mouseX;
\r
2339 yOffset = _mouseY;
\r
2341 onMouseUp: function( _mouseX, _mouseY){
\r
2342 isDragging = isResizing = false;
\r
2343 MOUSE_CURSOR( '');
\r
2345 onMouseMove: function( _mouseX, _mouseY){
\r
2346 var _updateX = _mouseX -xOffset,
\r
2347 _updateY = _mouseY -yOffset;
\r
2349 if( isResizing === true){
\r
2350 var _w = startW +_updateX,
\r
2351 _h = startH +_updateY;
\r
2352 update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h);
\r
2355 if( isDragging === true) {
\r
2356 update( startX +_updateX, startY +_updateY);
\r
2359 if( x > _mouseX || x +w < _mouseX ) return;
\r
2361 ( y <= _mouseY && y +headerH >= _mouseY ) ?
\r
2362 MOUSE_CURSOR( 'pointer') : // hit to header
\r
2363 MOUSE_CURSOR( '');
\r
2364 bodyBackOrForward( y +headerH > _mouseY || y +headerH +bodyH < _mouseY);
\r
2366 onMouseOut: function( _mouseX, _mouseY){
\r
2367 bodyIsTachable === true && bodyBackOrForward( true);
\r
2368 isDragging = false;
\r
2369 MOUSE_CURSOR( '');
\r
2372 return isDragging === true || isResizing === true;
\r
2374 bodyHeight: function(){
\r
2380 function getCurrentWindow( _mouseX, _mouseY){
\r
2381 if( currentWindow && currentWindow.busy() === true) return currentWindowIndex;
\r
2382 var l = WINDOW_ARRAY.length,
\r
2383 _currentWindow = null,
\r
2385 currentWindowIndex = -1;
\r
2386 for( var i=0; i<l; i++){
\r
2387 _win = WINDOW_ARRAY[ i];
\r
2388 if( _win.visible !== true) continue;
\r
2391 if( _x <= _mouseX && _y <= _mouseY && _x +_win.w() >= _mouseX && _y +_win.h() >= _mouseY){
\r
2392 _currentWindow = _win;
\r
2393 currentWindowIndex = i;
\r
2397 currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY);
\r
2398 currentWindow = _currentWindow;
\r
2399 return currentWindowIndex;
\r
2401 function openWindow( _window){
\r
2402 if( _window.visible !== true) return;
\r
2403 var _jqWindow = _window.$;
\r
2404 jqContainer.append( _jqWindow);// appendした後に fadeIn() しないと ie で filterが適用されない.
\r
2407 _window.firstOpen && _window.firstOpen();
\r
2408 _window.onOpen && setTimeout( _window.onOpen, 0);
\r
2413 function closeWindow( _window){
\r
2414 if( _window.visible !== false) return;
\r
2415 var l = WINDOW_ARRAY.length;
\r
2416 for( var i=0; i<l; ++i){
\r
2417 if( WINDOW_ARRAY[ i] === _window){
\r
2418 //WINDOW_ARRAY.splice( i, 1);
\r
2419 //WINDOW_ARRAY.push( _window);
\r
2420 _window.$.stop().fadeOut( function(){
\r
2421 this.parentNode.removeChild( this);
\r
2430 jqContainer = $( '#window-container');
\r
2432 var l = WINDOW_ARRAY.length,
\r
2434 for( var i=l-1; i >= 0; --i){
\r
2435 _window = WINDOW_ARRAY[ i];
\r
2436 _window.init && _window.init( jqContainer);
\r
2437 _window.visible === true && openWindow( _window);
\r
2439 log = $( '#window-log');
\r
2441 delete WINDOWS_CONTROL.init;
\r
2443 onMouseMove: function( _mouseX, _mouseY){
\r
2444 var _index = getCurrentWindow( _mouseX, _mouseY);
\r
2445 if( _index === 0){
\r
2446 currentWindow.onMouseMove( _mouseX, _mouseY);
\r
2449 if( _index !== -1){ // 先頭のクリックでない場合
\r
2451 WINDOW_ARRAY.splice( currentWindowIndex, 1);
\r
2452 WINDOW_ARRAY.unshift( currentWindow);
\r
2454 jqContainer.append( currentWindow.$);
\r
2455 currentWindowIndex = 0;
\r
2460 onMouseUp: function( _mouseX, _mouseY){
\r
2461 if( getCurrentWindow( _mouseX, _mouseY) === 0){
\r
2462 currentWindow.onMouseUp( _mouseX, _mouseY);
\r
2467 onMouseDown: function( _mouseX, _mouseY){
\r
2468 if( getCurrentWindow( _mouseX, _mouseY) === 0){
\r
2469 currentWindow.onMouseDown( _mouseX, _mouseY);
\r
2474 onMouseClick: function( _mouseX, _mouseY){
\r
2478 return currentWindow !== null;
\r
2480 onWindowResize: function( _windowW, _windowH){
\r
2485 createWindow: function( scope, EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH){
\r
2486 opt_visible = opt_visible !== false;
\r
2487 opt_closeButtonEnabled = opt_closeButtonEnabled === true;
\r
2488 opt_resizeButtonEnabled = opt_resizeButtonEnabled === true;
\r
2489 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH) ? w : DEFAULT_MIN_WINDOW_WIDTH;
\r
2490 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT) ? h : DEFAULT_MIN_WINDOW_HEIGHT;
\r
2492 var _window = h2c.util.extend(
\r
2493 WindowClass.apply( scope, [ bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH]),
\r
2496 WINDOW_ARRAY.unshift( _window);
\r
2497 WINDOWS_CONTROL.init === undefined && _window.init( jqContainer);
\r
2498 WINDOWS_CONTROL.init === undefined && openWindow( _window);
\r
2504 /* ----------------------------------------
\r
2507 var TOOL_BOX_WINDOW = ( function(){
\r
2508 var addImageButton, addTextButton, editBgButton, switchGridButton, popupHelpButton, postButton,
\r
2509 gridSwitchFunction,
\r
2512 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 73, false, true, addImage);
\r
2513 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Image', 'ctrl + I', addImage, true, true, false);
\r
2515 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 84, false, true, addText);
\r
2516 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Text', 'ctrl + T', addText, true, false, true);
\r
2518 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 71, false, true, switchGrid);
\r
2519 MENU_BAR_CONTROL.EDIT.createSelection( 'show Grid', 'ctrl + G', switchGrid, true, true, true);
\r
2521 function addImage( e){
\r
2522 setTimeout( CANVAS_CONTROL.createImageElement, 0);
\r
2523 e && e.preventDefault();
\r
2526 function addText( e){
\r
2527 setTimeout( CANVAS_CONTROL.createTextElement, 0);
\r
2528 e && e.preventDefault();
\r
2531 function switchGrid( e){
\r
2532 setTimeout( gridSwitchFunction, 0);
\r
2533 e && e.preventDefault();
\r
2536 function popupHelp( e){
\r
2537 instance.bodyBackOrForward( true);
\r
2538 setTimeout( HELP_DOCUMENTS_WINDOW.open, 0); // setTimeout で囲むと window が開かない
\r
2539 e && e.preventDefault();
\r
2542 function editBG( e){
\r
2543 instance.bodyBackOrForward( true);
\r
2544 setTimeout( INFOMATION_WINDOW.open, 0);
\r
2545 e && e.preventDefault();
\r
2549 return WINDOWS_CONTROL.createWindow(
\r
2552 onInit: function(){
\r
2554 delete this.onInit;
\r
2556 onFirstOpen: function(){
\r
2557 addImageButton = $( '#toolbox-add-image-button').click( addImage);
\r
2558 addTextButton = $( '#toolbox-add-text-button').click( addText);
\r
2559 editBgButton = $( '#toolbox-edit-bg-button').click( editBG);
\r
2560 switchGridButton = $( '#toolbox-switch-grid').click( switchGrid);
\r
2561 popupHelpButton = $( '#toolbox-popup-help-button').click( popupHelp);
\r
2563 postButton = $( '#toolbox-post-button');
\r
2565 delete this.onFirstOpen;
\r
2567 setGridSwitchFunction: function( _gridSwitchFunction){
\r
2568 gridSwitchFunction = _gridSwitchFunction || gridSwitchFunction;
\r
2571 'toolbox-window', 'Tool box', 0, 215, 110, 290, true
\r
2574 /* ----------------------------------------
\r
2575 * INFOMATION_WINDOW
\r
2577 var INFOMATION_WINDOW = ( function(){
\r
2578 var FADE_EFFECT_ENABLED = h2c.isIE === false || h2c.ieVersion >= 8,
\r
2579 FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show',
\r
2580 FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide',
\r
2581 backgroundInfomationElm,
\r
2582 jqComicElementInformation,
\r
2583 elmValueX, elmValueY, elmValueZ, elmValueA, elmValueW, elmValueH, elmAspect,
\r
2584 elmPercentW, elmPercentH,
\r
2585 currentComicElement = null,
\r
2586 currentElementType = -1;
\r
2588 return WINDOWS_CONTROL.createWindow(
\r
2591 onFirstOpen: function(){
\r
2592 backgroundInfomationElm = $( '#panel-background-information');
\r
2594 jqComicElementInformation = $( '#comic-element-infomation').hide().css( {
\r
2595 height: this.bodyHeight()
\r
2597 var TAB_GROUP_ID = 'comic-element-attribute';
\r
2598 var CREATER = h2c.key.createEditableText;
\r
2599 elmValueX = CREATER( $( '#comic-element-x'), null, TAB_GROUP_ID);
\r
2600 elmValueY = CREATER( $( '#comic-element-y'), null, TAB_GROUP_ID);
\r
2601 elmValueZ = CREATER( $( '#comic-element-z'), null, TAB_GROUP_ID);
\r
2602 elmValueA = CREATER( $( '#comic-element-a'), null, TAB_GROUP_ID);
\r
2603 elmValueW = CREATER( $( '#comic-element-w'), null, TAB_GROUP_ID);
\r
2604 elmValueH = CREATER( $( '#comic-element-h'), null, TAB_GROUP_ID);
\r
2605 elmPercentW = CREATER( $( '#comic-element-w-percent'), null, TAB_GROUP_ID);
\r
2606 elmPercentH = CREATER( $( '#comic-element-h-percent'), null, TAB_GROUP_ID);
\r
2607 elmAspect = $( '#comic-element-keep-aspect');
\r
2608 delete this.onFirstOpen;
\r
2610 onResize: function( w, h){
\r
2611 jqComicElementInformation && jqComicElementInformation.css( {
\r
2612 height: this.bodyHeight()
\r
2615 update: function( _elementType, x, y, z, a, w, h, wPercent, hPercent, keepAspect){
\r
2616 if( !backgroundInfomationElm) return; // なぜか !backgroundInfomationElm が必要
\r
2617 if( currentElementType !== _elementType){
\r
2618 if( _elementType !== -1){
\r
2619 if( _elementType === 1){
\r
2621 elmPercentW.hide();
\r
2622 elmPercentH.hide();
\r
2626 elmPercentW.show();
\r
2627 elmPercentH.show();
\r
2630 currentElementType === -1 && jqComicElementInformation.stop().css( {
\r
2633 })[ FADE_IN_EFFECT]();
\r
2635 currentElementType !== -1 && jqComicElementInformation.stop().css({
\r
2638 })[ FADE_OUT_EFFECT]();
\r
2640 currentElementType = _elementType;
\r
2642 if( currentElementType !== -1){
\r
2643 elmValueX.update( x);
\r
2644 elmValueY.update( y);
\r
2645 elmValueZ.update( z);
\r
2646 _elementType === 1 && elmValueA.update( a);
\r
2647 elmValueW.update( w);
\r
2648 elmValueH.update( h);
\r
2649 _elementType === 0 && elmPercentW.update( wPercent);
\r
2650 _elementType === 0 && elmPercentH.update( hPercent);
\r
2656 'infomation-window', 'Infomation', 0, 30, 200, 180, true
\r
2660 /* ----------------------------------------
\r
2663 var HELP_DOCUMENTS_WINDOW = ( function(){
\r
2664 var visible = true,
\r
2665 hasAjaxContents = false,
\r
2669 HELP = MENU_BAR_CONTROL.HELP,
\r
2670 onLoadFunction = HELP.createAjaxSelection( onFirstOpen),
\r
2672 function jumpPage( _index){
\r
2675 function onFirstOpen( _pageIndex){
\r
2676 _pageIndex = _pageIndex || 0;
\r
2677 if( hasAjaxContents === false){
\r
2679 url: 'help/jp.xml',
\r
2681 success: function( _xml){
\r
2682 var jqXML = $( _xml),
\r
2683 helpTitle = jqXML.find( 'pages').eq( 0).attr( 'title'),
\r
2684 elmNavi = document.createElement( 'DIV'),
\r
2685 elmItemOrigin = document.createElement( 'A'),
\r
2686 elmPages = document.createElement( 'DIV'),
\r
2687 elmPageOrigin = document.createElement( 'DIV'),
\r
2688 elmTitleOrigin = document.createElement( 'H2'),
\r
2691 elmNavi.className = 'sidenavi';
\r
2692 elmItemOrigin.className = 'sidenavi-item';
\r
2693 elmItemOrigin.href = '#';
\r
2694 elmPages.className = 'page-contents';
\r
2695 elmPageOrigin.className = 'page-content';
\r
2696 elmPageOrigin.appendChild( elmTitleOrigin);
\r
2698 // helpTitle && instance.title( helpTitle);
\r
2700 jqXML.find( 'page').each( function(){
\r
2701 var xmlPage = $( this),
\r
2702 title = xmlPage.attr( 'title'),
\r
2703 content = xmlPage.text();
\r
2705 elmItemOrigin.innerHTML = title;
\r
2706 elmNavi.appendChild( elmItemOrigin.cloneNode( true));
\r
2708 elmTitleOrigin.innerHTML = title;
\r
2709 elmPage = elmPageOrigin.cloneNode( true);
\r
2710 elmPage.innerHTML = content;
\r
2712 h2c.util.cleanElement( elmPage);
\r
2714 if( elmPage.childNodes.length > 0){
\r
2715 elmPage.insertBefore( elmTitleOrigin.cloneNode( true), elmPage.childNodes[0]);
\r
2717 elmPage.appendChild( elmTitleOrigin.cloneNode( true));
\r
2719 elmPages.appendChild( elmPage);
\r
2721 HELP.createSelection( title, null, ( function( _pageIndex){
\r
2722 return function(){
\r
2723 HELP_DOCUMENTS_WINDOW.open();
\r
2724 onOpen( _pageIndex);
\r
2726 })( numPage), true);
\r
2730 onLoadFunction = null;
\r
2732 jqAjaxContents.removeClass( 'loading').append( elmNavi, elmPages);
\r
2734 jqNaviItems = jqAjaxContents.find( 'a.' +elmItemOrigin.className)
\r
2735 .click( function( e){
\r
2737 parent = this.parentNode,
\r
2739 var children = parent.getElementsByTagName( 'A'),
\r
2740 l = children.length;
\r
2741 for( var i=0; i<l; ++i){
\r
2742 if( children[ i] === that) return i;
\r
2746 e.stopPropagation();
\r
2747 if( i === -1) return false;
\r
2748 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');
\r
2749 jqPages.hide().eq( i).show();
\r
2753 jqAjaxContents.find( '.' +elmPageOrigin.className).find( 'a')
\r
2754 .click( function( e){
\r
2757 var href = that.href,
\r
2758 i = href.split( '#jump'),
\r
2760 if( n && '' +parseFloat( n) === n){
\r
2761 return parseFloat( n)
\r
2765 e.stopPropagation();
\r
2766 if( i === -1) return false;
\r
2767 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');
\r
2768 jqPages.hide().eq( i).show();
\r
2772 jqNaviItems.eq( _pageIndex).addClass( 'current');
\r
2773 jqPages = jqAjaxContents.find( '.page-content');
\r
2774 jqPages.eq( _pageIndex).show();
\r
2777 hasAjaxContents = true;
\r
2779 function onOpen( _pageIndex){
\r
2780 _pageIndex = _pageIndex || 0;
\r
2781 jqNaviItems.removeClass( 'current').eq( _pageIndex).addClass( 'current');
\r
2782 jqPages.hide().eq( _pageIndex).show();
\r
2785 return WINDOWS_CONTROL.createWindow(
\r
2788 onInit: function(){
\r
2790 jqAjaxContents = this.$.find( '.window-body').addClass( 'loading').css( { height: this.bodyHeight()});
\r
2791 delete this.onInit;
\r
2793 onFirstOpen: onFirstOpen,
\r
2794 onResize: function( w, h){
\r
2795 jqAjaxContents && jqAjaxContents.css( { height: this.bodyHeight()});
\r
2797 setAjaxContent: function( html){
\r
2799 delete this.onLoadAjaxContent;
\r
2802 null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300
\r
2806 /* ----------------------------------------
\r
2807 * - CANVAS_CONTROL
\r
2809 * - WHITE_GLASS_CONTROL
\r
2810 * - PANEL_BORDER_CONTROL
\r
2811 * - COMIC_ELEMENT_CONTROL
\r
2812 * - PanelResizerClass
\r
2813 * - COMIC_ELEMENT_OPERATOR
\r
2814 * - ImageElementClass
\r
2815 * - TextElementClass
\r
2817 var CANVAS_CONTROL = ( function(){
\r
2818 var DEFAULT_PANEL_WIDTH = 400,
\r
2819 DEFAULT_PANEL_HEIGHT = 300,
\r
2820 MIN_PANEL_HEIGHT = 20,
\r
2822 RESIZER_BORDER_WIDTH = 1,
\r
2823 SPACE_ENABLED = h2c.key.spaceEnabled,
\r
2824 canvasW, canvasH, canvasX, canvasY,
\r
2825 xOffset, yOffset, startCanvasX, startCanvasY,
\r
2826 isDragging = false,
\r
2827 isCanvasDraggble = false;
\r
2829 var GRID_CONTROL = ( function(){
\r
2830 var elmGrid = document.getElementById( 'grid'),
\r
2834 function update(){
\r
2838 }).stop()[ visible === true ? 'fadeOut' : 'fadeIn']();
\r
2839 visible = !visible;
\r
2840 if( visible === true){
\r
2841 elmGrid.style.backgroundImage = "url('grid.gif')";
\r
2847 jQGrid = $( elmGrid);
\r
2849 TOOL_BOX_WINDOW.setGridSwitchFunction( update);
\r
2850 delete GRID_CONTROL.init;
\r
2852 resize: function(){
\r
2853 elmGrid.style.backgroundPosition = [ canvasX % 10, 'px ', canvasY % 10, 'px'].join( '');
\r
2854 elmGrid.style.height = windowH +'px';
\r
2856 enabled: function(){
\r
2863 * WHITE_GLASS_CONTROL
\r
2865 var WHITE_GLASS_CONTROL = ( function(){
\r
2866 var styleTop = document.getElementById( 'whiteGlass-top').style,
\r
2867 styleLeft = document.getElementById( 'whiteGlass-left').style,
\r
2868 styleRight = document.getElementById( 'whiteGlass-right').style,
\r
2869 styleBottom = document.getElementById( 'whiteGlass-bottom').style;
\r
2870 function resize(){
\r
2873 marginTop = canvasY,
\r
2874 marginBottom = windowH -_h -marginTop,
\r
2875 marginX = canvasX,
\r
2876 rightWidth = windowW -_w -marginX;
\r
2878 styleTop.height = ( marginTop < 0 ? 0 : marginTop) +'px';
\r
2880 styleLeft.top = marginTop +'px';
\r
2881 styleLeft.width = ( marginX < 0 ? 0 : marginX) +'px';
\r
2882 styleLeft.height = ( _h + marginBottom) +'px';
\r
2884 styleRight.top = marginTop +'px';
\r
2885 styleRight.left = _w +marginX +'px';
\r
2886 styleRight.width = ( rightWidth < 0 ? 0 : rightWidth) +'px';
\r
2887 styleRight.height = ( _h + marginBottom) +'px';
\r
2889 styleBottom.top = ( _h +marginTop) +'px';
\r
2890 styleBottom.left = marginX +'px';
\r
2891 styleBottom.width = _w +'px';
\r
2892 styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom) +'px';
\r
2900 * PANEL_BORDER_CONTROL
\r
2902 var PANEL_BORDER_CONTROL = ( function(){
\r
2903 var panelElm, borderWidth;
\r
2905 function resize(){
\r
2907 left: canvasX -BORDER_WIDTH,
\r
2908 top: canvasY -BORDER_WIDTH,
\r
2916 panelElm = $( '#panel-border');
\r
2917 borderWidth = panelElm.css( 'border-width');
\r
2919 delete PANEL_BORDER_CONTROL.init;
\r
2926 * COMIC_ELEMENT_CONTROL
\r
2927 * - PanelResizerClass
\r
2928 * - COMIC_ELEMENT_OPERATOR
\r
2929 * - ImageElementClass
\r
2930 * - TextElementClass
\r
2932 var COMIC_ELEMENT_CONTROL = ( function( _onResizeFunction){
\r
2933 var MIN_OBJECT_SIZE = 19,
\r
2935 currentElement = null,
\r
2936 _canvasX, _canvasY, _canvasW, _canvasH,
\r
2937 MOUSE_HIT_AREA = 10,
\r
2938 SAVE = HISTORY.saveState;
\r
2940 * --------------------------------------------------------------------------------------------
\r
2943 var PanelResizerClass = function( ELM, onPanelResizeFunction, isTop){
\r
2944 var BORDER_WIDTH = 2,
\r
2945 yOffset, y, _canvasY, _canvasH,
\r
2946 RESIZER_HEIGHT = 30,
\r
2947 isDragging = false,
\r
2948 SAVE = HISTORY.saveState,
\r
2949 MOUSE_CURSOR = updateMouseCursor;
\r
2951 function restoreState( arg){
\r
2952 if( arg && arg.length > 3){
\r
2953 canvasX = arg[ 0] || canvasX;
\r
2954 canvasY = arg[ 1] || canvasY;
\r
2955 canvasW = arg[ 2] || canvasW;
\r
2956 canvasH = arg[ 3] || canvasH;
\r
2957 onPanelResizeFunction( isTop);
\r
2962 init: function( _elm){
\r
2964 ELM.style.width = ( canvasW +2)+'px';
\r
2967 hitareaX: function(){ return -1;},
\r
2968 hitareaY: function(){ return isTop === true ? ( -35 -BORDER_WIDTH) : ( canvasH +5 +BORDER_WIDTH);},
\r
2969 hitareaW: function(){ return canvasW +2;},
\r
2970 hitareaH: function(){ return RESIZER_HEIGHT;},
\r
2973 return isDragging;
\r
2975 onMouseDown: function( _mouseX, _mouseY){
\r
2976 yOffset = _mouseY;
\r
2977 _canvasY = canvasY;
\r
2978 _canvasH = canvasH;
\r
2979 isDragging = true;
\r
2981 onMouseMove: function( _mouseX, _mouseY){
\r
2982 if( isDragging !== true){
\r
2983 COMIC_ELEMENT_OPERATOR.hide();
\r
2984 MOUSE_CURSOR( 'n-resize');
\r
2986 var move = _mouseY -yOffset;
\r
2987 if( isTop === true){
\r
2988 //if( 0 < _canvasH - move){
\r
2989 if( _canvasH - move < MIN_PANEL_HEIGHT){
\r
2990 move = _canvasH -MIN_PANEL_HEIGHT;
\r
2992 canvasY = _canvasY +move;
\r
2993 canvasH = _canvasH -move;
\r
2995 onPanelResizeFunction( true);
\r
2998 var _h = _canvasH +move;
\r
2999 if( 0 < _h && _h < windowH -canvasY -RESIZER_HEIGHT -5 -BORDER_WIDTH){
\r
3000 if( _h < MIN_PANEL_HEIGHT){
\r
3001 _h = MIN_PANEL_HEIGHT;
\r
3004 onPanelResizeFunction( false);
\r
3009 onMouseUp: function( _mouseX, _mouseY){
\r
3010 ( _canvasY !== canvasY || _canvasH !== canvasH) && SAVE( restoreState, [ NaN, _canvasY, NaN, _canvasH], [ NaN, canvasY, NaN, canvasH]);
\r
3011 isDragging = false;
\r
3016 var PANEL_RESIZER_TOP = PanelResizerClass.apply( {}, [ document.getElementById( 'panel-resizer-top'), _onResizeFunction, true]),
\r
3017 PANEL_RESIZER_BOTTOM = PanelResizerClass.apply( {}, [ document.getElementById( 'panel-resizer-bottom'), _onResizeFunction, false]),
\r
3018 DRAGGABLE_ELEMENT_ARRAY = [ PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM],
\r
3019 NUM_RESIZER = DRAGGABLE_ELEMENT_ARRAY.length;
\r
3021 _onResizeFunction = PanelResizerClass = undefined;
\r
3024 * --------------------------------------------------------------------------------------------
\r
3025 * COMIC_ELEMENT_OPERATOR
\r
3027 var COMIC_ELEMENT_OPERATOR = ( function(){
\r
3028 var MOUSE_CURSOR = updateMouseCursor,
\r
3029 SAVE = HISTORY.saveState,
\r
3030 INFOMATION = INFOMATION_WINDOW.update,
\r
3031 GRID_ENABLED = GRID_CONTROL.enabled,
\r
3032 HIT_AREA = MOUSE_HIT_AREA,
\r
3033 currentIsTextElement = false,
\r
3034 currentControler = null,
\r
3035 currentElement = null,
\r
3036 x, y, w, h, angle, flipV, flipH,
\r
3037 COMIC_ELEMENT_CONSOLE = ( function(){
\r
3038 var LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer back', 'ctrl + B', layerBack, false, true, false),
\r
3039 LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer forward', 'ctrl + F', layerForward, false, false, false),
\r
3040 DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'delete', 'ctrl + D', del, false, true, true),
\r
3041 EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'Edit Text', 'ctrl + E', edit, false, true, false),
\r
3042 CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'change', 'ctrl + U', change, false, false, true),
\r
3047 jqImgConsole, jqTextConsole,
\r
3048 currentElement = null,
\r
3051 imgConsoleWidth, imgConsoleHeight,
\r
3052 textConsoleWidth, textConsoleHeight,
\r
3053 consoleWidth, consoleHeight,
\r
3054 consoleX, consoleY,
\r
3056 buttonClickable = false;
\r
3058 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 66, false, true, layerBack);
\r
3059 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 70, false, true, layerForward);
\r
3061 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 68, false, true, del);
\r
3062 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 69, false, true, edit);
\r
3063 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 85, false, true, change);
\r
3065 function buttonBackOrForward( isBack){
\r
3066 var offest = jqConsoleWrapper.offset();
\r
3067 jqConsoleWrapper.css( {
\r
3068 position: isBack === true ? '' : 'absolute',
\r
3069 left: isBack === true ? consoleX : offest.left,
\r
3070 top: isBack === true ? consoleY : offest.top
\r
3072 buttonClickable === isBack && ( isBack === true ? jqConsoleParent : jqStage).append( jqConsoleWrapper);
\r
3073 buttonClickable = !isBack;
\r
3075 function layerBack(){
\r
3076 if( currentElement === null) return;
\r
3077 replaceComicElement( currentElement, false);
\r
3078 updateInfomation();
\r
3079 SAVE( restoreReplaceObject, [ currentElement, true], [ currentElement, false]);
\r
3080 var _z = currentElement.z;
\r
3081 LAYER_BACK_BUTTON.visible( _z > 0);
\r
3082 LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);
\r
3084 function layerForward(){
\r
3085 if( currentElement === null) return;
\r
3086 replaceComicElement( currentElement, true);
\r
3087 updateInfomation();
\r
3088 SAVE( restoreReplaceObject, [ currentElement, false], [ currentElement, true]);
\r
3089 var _z = currentElement.z;
\r
3090 LAYER_BACK_BUTTON.visible( _z > 0);
\r
3091 LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);
\r
3094 if( currentElement === null) return;
\r
3095 buttonBackOrForward( true);
\r
3096 removeComicElement( currentElement);
\r
3097 SAVE( restoreComicElement, [ true, currentElement], [ false, currentElement], true);
\r
3098 COMIC_ELEMENT_OPERATOR.hide();
\r
3101 if( currentElement === null) return;
\r
3102 TEXT_EDITOR_CONTROL.show( currentElement);
\r
3103 buttonBackOrForward( true);
\r
3105 function change(){
\r
3106 if( currentElement === null) return;
\r
3107 buttonBackOrForward( true);
\r
3108 IMAGE_GROUP_EXPROLER.show( currentElement.url);
\r
3112 jqStage = jqEditor;
\r
3113 jqConsoleTail = $( '#comic-element-consol-tail');
\r
3114 jqImgConsole = $( '#image-element-consol').hide();
\r
3115 var imgConsoleSize = h2c.util.getElementSize( jqImgConsole.get( 0));
\r
3116 imgConsoleWidth = imgConsoleSize.width;
\r
3117 imgConsoleHeight = imgConsoleSize.height;
\r
3119 jqTextConsole = $( '#text-element-consol').hide();
\r
3120 var textConsoleSize = h2c.util.getElementSize( jqTextConsole.get( 0));
\r
3121 textConsoleWidth = textConsoleSize.width;
\r
3122 textConsoleHeight = textConsoleSize.height;
\r
3124 jqConsoleWrapper = $( '#comic-element-consol-wrapper').hide();
\r
3125 jqConsoleParent = jqConsoleWrapper.parent();
\r
3127 $( '#edit-text-button').click( edit);
\r
3128 $( '#delete-image-button, #delete-text-button').click( del);
\r
3129 $( '#change-image-button').click( change);
\r
3130 $( '#layer-forward-button, #forward-text-button').click( layerForward);
\r
3131 $( '#layer-back-button, #back-text-button').click( layerBack);
\r
3133 delete COMIC_ELEMENT_CONSOLE.init;
\r
3135 show: function( _currentElement, _w, _h){
\r
3136 visible === false && jqConsoleWrapper.show();
\r
3138 currentElement = _currentElement;
\r
3139 var _currentType = _currentElement.type,
\r
3140 _z = _currentElement.z;
\r
3141 if( currentType !== _currentType){
\r
3142 currentType = _currentType;
\r
3143 jqImgConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_IMAGE);
\r
3144 jqTextConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_TEXT);
\r
3145 consoleWidth = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth;
\r
3146 consoleHeight = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight;
\r
3148 consoleX = Math.floor( ( _w -consoleWidth) /2);
\r
3150 LAYER_BACK_BUTTON.visible( _z > 0);
\r
3151 LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);
\r
3152 DELETE_BUTTON.visible( true);
\r
3153 EDIT_BUTTON.visible( _currentType === COMIC_ELEMENT_TYPE_TEXT);
\r
3154 CHANGE_BUTTON.visible( false);
\r
3156 if( _w > consoleWidth * 1.5 && _h > consoleHeight * 1.5){
\r
3157 consoleY = Math.floor( ( _h -consoleHeight) /2);
\r
3158 jqConsoleWrapper.css( {
\r
3161 }).removeClass( 'console-out');
\r
3163 consoleY = _h +tailSize;
\r
3164 jqConsoleWrapper.css( {
\r
3167 }).addClass( 'console-out');
\r
3170 hide: function (){
\r
3171 visible === true && jqConsoleWrapper.hide();
\r
3173 currentElement = null;
\r
3174 LAYER_BACK_BUTTON.visible( false);
\r
3175 LAYER_FORWARD_BUTTON.visible( false);
\r
3176 DELETE_BUTTON.visible( false);
\r
3177 EDIT_BUTTON.visible( false);
\r
3178 CHANGE_BUTTON.visible( false);
\r
3180 x: function(){ return consoleX;},
\r
3181 y: function(){ return consoleY;},
\r
3182 w: function(){ return consoleWidth;},
\r
3183 h: function(){ return consoleHeight;},
\r
3184 onMouseMove: function( _mouseX, _mouseY){
\r
3185 if( consoleX > _mouseX || consoleY > _mouseY || consoleX +consoleWidth < _mouseX || consoleY +consoleHeight < _mouseY){
\r
3186 buttonClickable === true && buttonBackOrForward( true);
\r
3189 buttonClickable === false && buttonBackOrForward( false);
\r
3192 onMouseOut: function( _mouseX, _mouseY){
\r
3193 buttonClickable === true && buttonBackOrForward( true);
\r
3197 TAIL_CONTROLER = ( function(){
\r
3198 var ELM_MOVER = document.getElementById( 'balloon-tail-mover'),
\r
3199 SIZE = h2c.util.getElementSize( ELM_MOVER).width,
\r
3203 FLOOR = Math.floor,
\r
3204 DEG_TO_RAD = Math.PI / 180,
\r
3205 RAD_TO_DEG = 1 /DEG_TO_RAD,
\r
3206 currentText = null,
\r
3208 balloonW, balloonH, balloonA, radA,
\r
3212 function draw( _w, _h, _a){
\r
3213 balloonW = _w !== undefined ? _w : balloonW;
\r
3214 balloonH = _h !== undefined ? _h : balloonH;
\r
3215 balloonA = _a !== undefined ? _a : balloonA;
\r
3216 radA = balloonA *DEG_TO_RAD;
\r
3217 tailX = FLOOR( ( ( COS( radA) /2 +0.5) *( balloonW +SIZE)) -SIZE /2);
\r
3218 tailY = FLOOR( ( ( SIN( radA) /2 +0.5) *( balloonH +SIZE)) -SIZE /2);
\r
3219 ELM_MOVER.style.left = tailX +'px';
\r
3220 ELM_MOVER.style.top = tailY +'px';
\r
3221 log.html( [ balloonW, balloonH, balloonA].join());
\r
3223 function hitTest( _mouseX, _mouseY){
\r
3224 var _x = tailX -SIZE /2,
\r
3225 _y = tailY -SIZE /2;
\r
3226 ret = currentIsTextElement === true && _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY;
\r
3227 ret === true && MOUSE_CURSOR( 'move');
\r
3232 show: function( _currentText){
\r
3234 * visibilityのほうがいい, display:none だと ie で描画が狂う
\r
3236 ELM_MOVER.style.visibility = '';
\r
3237 draw( _currentText.w, _currentText.h, _currentText.angle());
\r
3238 currentText = _currentText;
\r
3242 ELM_MOVER.style.visibility = 'hidden';
\r
3243 currentText = null;
\r
3245 onStart: function( _currentText, _mouseX, _mouseY){
\r
3246 if( hitTest( _mouseX -x, _mouseY -y) === true){
\r
3247 currentText = _currentText;
\r
3248 startA = _currentText.angle();
\r
3251 currentText = null;
\r
3254 onDrag: function( _mouseX, _mouseY){
\r
3255 _mouseX = _mouseX -currentText.x -w /2;
\r
3256 _mouseY = _mouseY -currentText.y -h /2; //Balloonの中心を0,0とする座標系に変換
\r
3260 ATAN( _mouseY /_mouseX) *RAD_TO_DEG +( _mouseX < 0 ? 180 : 0) :
\r
3261 _mouseY > 0 ? 90 : -90
\r
3263 currentText && currentText.angle( balloonA);
\r
3264 updateInfomation( undefined, undefined, undefined, balloonA);
\r
3266 onFinish: function(){
\r
3267 startA !== currentText.angle() && saveComicElementStatus( x, y, w, h, startA);
\r
3268 currentText = null;
\r
3270 onCancel: function(){
\r
3271 resize( undefined, undefined, undefined, undefined, startA);
\r
3275 RESIZE_CONTROLER = ( function(){
\r
3276 var POSITION_ARRAY = [],
\r
3277 FLOOR = Math.floor,
\r
3278 CURSOR_AND_FLIP = [
\r
3279 { cursor: 'n-resize', v: 3},
\r
3280 { cursor: 'e-resize', h: 2},
\r
3281 { cursor: 'e-resize', h: 1},
\r
3282 { cursor: 'n-resize', v: 0},
\r
3283 { cursor: 'nw-resize', h: 5, v: 6, vh: 7},
\r
3284 { cursor: 'ne-resize', h: 4, v: 7, vh: 6},
\r
3285 { cursor: 'ne-resize', h: 7, v: 4, vh: 5},
\r
3286 { cursor: 'nw-resize', h: 6, v: 5, vh: 4}
\r
3288 elmResizerContainerStyle = document.getElementById( 'comic-element-resizer-container').style,
\r
3289 elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style,
\r
3290 elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style,
\r
3291 elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style,
\r
3292 elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style,
\r
3294 currentIndex = -1,
\r
3296 currentIsTextElement = false;
\r
3298 elmResizerContainerStyle.display = 'none';
\r
3300 var RESIZE_WORK_ARRAY = [
\r
3301 { x: 0, w: 0, y: 1, h: -1}, //top
\r
3302 { x: 1, w: -1, y: 0, h: 0}, //left
\r
3303 { x: 0, w: 1, y: 0, h: 0}, //right
\r
3304 { x: 0, w: 0, y: 0, h: 1}, //bottom
\r
3305 { x: 1, w: -1, y: 1, h: -1}, //top-left
\r
3306 { x: 0, w: 1, y: 1, h: -1}, //top-right
\r
3307 { x: 1, w: -1, y: 0, h: 1}, //bottom-left
\r
3308 { x: 0, w: 1, y: 0, h: 1} //bottom-right
\r
3310 startX, startY, startW, startH, startFilpV, startFilpH, startAspect,
\r
3311 baseX, baseY, baseW, baseH,
\r
3312 currentX, currentY, currentW, currentH,
\r
3313 transX, transY, transW, transH,
\r
3317 function draw( _x, _y, _w, _h){
\r
3318 x = _x !== undefined ? _x : x;
\r
3319 y = _y !== undefined ? _y : y;
\r
3320 w = _w !== undefined ? _w : w;
\r
3321 h = _h !== undefined ? _h : h;
\r
3322 elmResizerContainerStyle.left = x +'px';
\r
3323 elmResizerContainerStyle.top = y +'px';
\r
3324 elmResizerContainerStyle.width = w +'px';
\r
3325 elmResizerContainerStyle.height = h +'px';
\r
3326 elmResizerTopStyle.left = FLOOR( w /2 -10 /2) +'px';
\r
3327 elmResizerLeftStyle.top = FLOOR( h /2 -10 /2) +'px';
\r
3328 elmResizerRightStyle.top = FLOOR( h /2 -10 /2) +'px';
\r
3329 elmResizerBottomStyle.left = FLOOR( w /2 -10 /2) +'px';
\r
3331 POSITION_ARRAY.splice( 0, POSITION_ARRAY.length);
\r
3332 POSITION_ARRAY.push(
\r
3333 {x: x +5, y: y -HIT_AREA, w: w -5 *2, h: HIT_AREA +5},
\r
3334 {x: x -HIT_AREA, y: y +HIT_AREA +5, w: HIT_AREA +5, h: h -5 *2},
\r
3335 {x: x +w -5, y: y +HIT_AREA +5, w: HIT_AREA +5, h: h -5 *2},
\r
3336 {x: x +5, y: y +h -5, w: w -5 *2, h: HIT_AREA +5},
\r
3337 {x: x -HIT_AREA, y: y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5},
\r
3338 {x: x +w -HIT_AREA, y: y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5},
\r
3339 {x: x -HIT_AREA, y: y +h -5, w: HIT_AREA +5, h: HIT_AREA +5},
\r
3340 {x: x +w -5, y: y +h -5, w: HIT_AREA +5, h: HIT_AREA +5}
\r
3344 function update( _x, _y, _w, _h){
\r
3345 transX = _x !== undefined ? _x : currentX;
\r
3346 transY = _y !== undefined ? _y : currentY;
\r
3347 transW = _w !== undefined ? _w : currentW;
\r
3348 transH = _h !== undefined ? _h : currentH;
\r
3350 if( currentIsTextElement === false && currentIndex > 3 && h2c.key.shiftEnabled() === true){
\r
3351 if( startAspect >= 1){
\r
3353 transW = Math.floor( startAspect * transH);
\r
3354 transX = transX +( currentIndex % 2 === 0 ? _w -transW : 0);
\r
3357 transH = Math.floor( transW / startAspect);
\r
3358 transY = transY + ( currentIndex <= 5 ? _h -transH : 0);
\r
3361 draw( transX, transY, transW, transH);
\r
3362 currentElement.resize( transX, transY, transW, transH);
\r
3363 currentIsTextElement === true && TAIL_CONTROLER.update( transW, transH);
\r
3364 COMIC_ELEMENT_CONSOLE.show( currentElement, transW, transH);
\r
3365 updateInfomation( transX, transY, undefined, undefined, transW, transH);
\r
3367 function getIndex( _mouseX, _mouseY){
\r
3369 l = POSITION_ARRAY.length;
\r
3370 for( var i=0; i<l; i++){
\r
3371 p = POSITION_ARRAY[ i];
\r
3372 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){
\r
3373 MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor);
\r
3374 return currentIndex = i;
\r
3379 function flip( _flipV, _flipH){
\r
3380 var p = CURSOR_AND_FLIP[ currentIndex];
\r
3381 currentIndex = _flipH === true || _flipV === true ? p[
\r
3382 _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v')
\r
3384 MOUSE_CURSOR( CURSOR_AND_FLIP[ currentIndex].cursor);
\r
3385 currentElement.flip( _flipV, _flipH);
\r
3388 x: function(){ return x;},
\r
3389 y: function(){ return y;},
\r
3390 w: function(){ return w;},
\r
3391 h: function(){ return h;},
\r
3394 show: function( _currentElement){
\r
3395 currentElement = _currentElement;
\r
3396 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;
\r
3397 elmResizerContainerStyle.display = '';
\r
3400 currentElement = null;
\r
3401 elmResizerContainerStyle.display = 'none';
\r
3403 onStart: function( _currentElement, _mouseX, _mouseY){
\r
3404 currentElement = _currentElement;
\r
3405 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;
\r
3406 if( _currentElement.keepSize === true) return false;
\r
3407 currentIndex = getIndex( _mouseX, _mouseY);
\r
3408 if( currentIndex === -1) return false;
\r
3409 xOffset = _mouseX;
\r
3410 yOffset = _mouseY;
\r
3411 startX = baseX = _currentElement.x;
\r
3412 startY = baseY = _currentElement.y;
\r
3413 startW = baseW = _currentElement.w;
\r
3414 startH = baseH = _currentElement.h;
\r
3415 startFilpV = flipV;
\r
3416 startFilpH = flipH;
\r
3417 startAspect = startW /startH;
\r
3420 onDrag: function( _mouseX, _mouseY){
\r
3421 var com = RESIZE_WORK_ARRAY[ currentIndex],
\r
3422 moveX = _mouseX -xOffset,
\r
3423 moveY = _mouseY -yOffset,
\r
3424 _x = baseX +moveX *com.x,
\r
3425 _y = baseY +moveY *com.y,
\r
3426 _w = baseW +moveX *com.w,
\r
3427 _h = baseH +moveY *com.h,
\r
3428 _updated = moveX !== 0 || moveY !== 0;
\r
3430 // opera がときどき baseH の値を忘れる ??
\r
3431 if( _x === undefined || _y === undefined || _w === undefined || _h === undefined){
\r
3436 if( _w >= MIN_OBJECT_SIZE && _h >= MIN_OBJECT_SIZE){
\r
3439 if( _w >= -MIN_OBJECT_SIZE && _h >= -MIN_OBJECT_SIZE){
\r
3442 if( currentElement.type === COMIC_ELEMENT_TYPE_TEXT){
\r
3445 if( _w < -MIN_OBJECT_SIZE || _h < -MIN_OBJECT_SIZE){
\r
3448 if( _w < -MIN_OBJECT_SIZE && _h > MIN_OBJECT_SIZE){
\r
3451 baseX = _x = _x +_w;
\r
3453 baseW = _w = __x -_x;
\r
3455 flip( false, true);
\r
3456 flipV = currentElement.flipV();
\r
3458 if( _w > MIN_OBJECT_SIZE && _h < -MIN_OBJECT_SIZE){
\r
3462 baseY = _y = _y +_h;
\r
3464 baseH = _h = __y -_y;
\r
3465 flip( true, false);
\r
3466 flipH = currentElement.flipH();
\r
3471 baseX = _x = _x +_w;
\r
3472 baseY = _y = _y +_h;
\r
3473 baseW = _w = __x -_x;
\r
3474 baseH = _h = __y -_y;
\r
3475 flip( true, true);
\r
3476 flipV = currentElement.flipV();
\r
3477 flipH = currentElement.flipH();
\r
3480 xOffset = _mouseX;
\r
3481 yOffset = _mouseY;
\r
3487 _updated === true && update( _x, _y, _w, _h);
\r
3490 'currentIndex:', currentIndex,
\r
3491 'baseW', baseW, 'baseH', baseH,'<br>',
\r
3492 'mouse', _mouseX, _mouseY,'<br>',
\r
3493 'move', moveX, moveY,'<br>',
\r
3494 'xy', _x, _y, 'wh',_w, _h,'<br>',
\r
3495 'com.w', com.w, 'com.h', com.h,'<br>',
\r
3496 'current',currentW, currentH,'<br>',
\r
3497 'trans', transY, transH,
\r
3501 onFinish: function(){
\r
3502 MOUSE_CURSOR( '');
\r
3503 if( currentW === w && currentH === h && currentX === x && currentY === y) return;
\r
3504 resize( transX, transY, transW, transH);
\r
3505 currentElement.resize( transX, transY, transW, transH);
\r
3506 saveComicElementStatus( startX, startY, startW, startH, angle, startFilpV, startFilpH);
\r
3508 onCancel: function(){
\r
3509 MOUSE_CURSOR( '');
\r
3510 resize( startX, startY, startW, startH);
\r
3511 currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?
\r
3512 currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) :
\r
3513 currentElement.animate( startX, startY, startW, startH, angle);
\r
3515 onShiftUpdate: update,
\r
3516 onCtrlUpdate: update
\r
3519 POSITION_CONTROLER = ( function(){
\r
3520 var currentElement,
\r
3522 currentX, currentY,
\r
3526 function update( _x, _y){
\r
3527 _x = currentX = _x !== undefined ? _x : currentX;
\r
3528 _y = currentY = _y !== undefined ? _y : currentY;
\r
3529 RESIZE_CONTROLER.update( _x, _y);
\r
3530 currentElement.resize( _x, _y);
\r
3531 updateInfomation( _x, _y);
\r
3535 onStart: function( _currentElement, _mouseX, _mouseY){
\r
3536 currentElement = _currentElement;
\r
3537 xOffset = _mouseX;
\r
3538 yOffset = _mouseY;
\r
3539 startX = currentX = x;
\r
3540 startY = currentY = y;
\r
3541 MOUSE_CURSOR( 'move');
\r
3543 onDrag: function( _mouseX, _mouseY){
\r
3544 var moveX = _mouseX -xOffset,
\r
3545 moveY = _mouseY -yOffset,
\r
3548 if( GRID_ENABLED() === true){
\r
3549 _x = Math.floor( _x / 10) * 10;
\r
3550 _y = Math.floor( _y / 10) * 10;
\r
3554 onFinish: function(){
\r
3555 MOUSE_CURSOR( '');
\r
3556 if( currentX === startX && currentY === startY) return;
\r
3557 resize( currentX, currentY);
\r
3558 currentElement.resize( currentX, currentY);
\r
3559 saveComicElementStatus( startX, startY);
\r
3561 onCancel: function(){
\r
3562 MOUSE_CURSOR( '');
\r
3563 resize( startX, startY);
\r
3564 currentElement.animate( startX, startY);
\r
3566 onShiftUpdate: update,
\r
3567 onCtrlUpdate: update
\r
3571 function resize( _x, _y, _w, _h, _angle){
\r
3572 x = _x !== undefined ? _x : x;
\r
3573 y = _y !== undefined ? _y : y;
\r
3574 w = _w !== undefined ? _w : w;
\r
3575 h = _h !== undefined ? _h : h;
\r
3576 angle = _angle !== undefined ? _angle : angle;
\r
3578 RESIZE_CONTROLER.update( x, y, w, h);
\r
3579 currentIsTextElement === true && TAIL_CONTROLER.update( w, h, angle);
\r
3580 COMIC_ELEMENT_CONSOLE.show( currentElement, w, h);
\r
3581 updateInfomation( x, y, currentElement.z, angle, w, h);
\r
3583 function updateInfomation( _x, _y, _z, _a, _w, _h, keepAspect){
\r
3584 _w = _w !== undefined ? _w : w;
\r
3585 _h = _h !== undefined ? _h : h;
\r
3587 currentElement === null ? -1 : currentElement.type,
\r
3588 _x !== undefined ? _x : x,
\r
3589 _y !== undefined ? _y : y,
\r
3590 _z !== undefined ? _z : ( currentElement === null ? '*' : currentElement.z),
\r
3591 _a !== undefined ? Math.floor( _a) : ( currentIsTextElement === true ? Math.floor( angle) : '-'),
\r
3594 currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualW() === 0 ? '?' : Math.floor( _w / currentElement.actualW() *100)),
\r
3595 currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualH() === 0 ? '?' : Math.floor( _h / currentElement.actualH() *100)),
\r
3596 currentElement === null || currentIsTextElement === true ? '-' : currentElement.keepAspect
\r
3599 function show( _currentElement){
\r
3600 currentElement === null && RESIZE_CONTROLER.show( _currentElement);
\r
3601 if( currentElement !== _currentElement){
\r
3602 currentElement = _currentElement;
\r
3604 currentIsTextElement = ( _currentElement.type === COMIC_ELEMENT_TYPE_TEXT);
\r
3605 currentIsTextElement === true ? TAIL_CONTROLER.show( _currentElement) : TAIL_CONTROLER.hide();
\r
3607 flipV = currentIsTextElement === false ? _currentElement.flipV() : 0;
\r
3608 flipH = currentIsTextElement === false ? _currentElement.flipH() : 0;
\r
3611 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,
\r
3612 currentIsTextElement === true ? _currentElement.angle() : 0
\r
3617 currentElement !== null && RESIZE_CONTROLER.hide();
\r
3618 currentElement = null;
\r
3619 MOUSE_CURSOR( '');
\r
3620 TAIL_CONTROLER.hide();
\r
3621 COMIC_ELEMENT_CONSOLE.hide();
\r
3622 updateInfomation();
\r
3624 function restoreState( arg){
\r
3625 if( arg && arg.length !== 8) return;
\r
3626 var _currentElement = arg[ 0],
\r
3627 _x = arg[ 1], _y = arg[ 2], _w = arg[ 3], _h = arg[ 4],
\r
3629 _flipV = arg[ 6], _flipH = arg[ 7];
\r
3630 if( !_currentElement) return;
\r
3631 _currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?
\r
3632 _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH) :
\r
3633 _currentElement.animate( _x, _y, _w, _h, _a);
\r
3634 currentControler = null;
\r
3635 currentElement === _currentElement ? resize( _x, _y, _w, _h, _a) : show( _currentElement);
\r
3637 function saveComicElementStatus( startX, startY, startW, startH, startA, startFilpV, startFilpH){
\r
3638 startX = startX !== undefined ? startX : x;
\r
3639 startY = startY !== undefined ? startY : y;
\r
3640 startW = startW !== undefined ? startW : w;
\r
3641 startH = startH !== undefined ? startH : h;
\r
3642 startA = startA !== undefined ? startA : angle;
\r
3643 startFilpV = startFilpV !== undefined ? startFilpV : flipV;
\r
3644 startFilpH = startFilpH !== undefined ? startFilpH : flipH;
\r
3645 currentElement && SAVE( restoreState,
\r
3646 [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH],
\r
3647 [ currentElement, x, y, w, h, angle, flipV, flipH]
\r
3650 h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 16, true, undefined, function( e){
\r
3651 currentControler !== null && currentControler.onShiftUpdate && currentControler.onShiftUpdate();
\r
3653 h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 17, undefined, true, function(){
\r
3654 currentControler !== null && currentControler.onCtrlUpdate && currentControler.onCtrlUpdate();
\r
3656 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 27, false, false, function(){
\r
3657 currentControler !== null && currentControler.onCancel && currentControler.onCancel();
\r
3658 currentControler = null;
\r
3662 COMIC_ELEMENT_CONSOLE.init();
\r
3664 delete COMIC_ELEMENT_OPERATOR.init;
\r
3668 return currentControler !== null;
\r
3670 hitareaX: function( _comicElement, _x){
\r
3671 if( _comicElement === currentElement){
\r
3672 var _consoleX = COMIC_ELEMENT_CONSOLE.x();
\r
3673 return x +( _consoleX < 0 ? _consoleX : 0) -HIT_AREA;
\r
3675 return _x -HIT_AREA;
\r
3677 hitareaY: function( _comicElement, _y){
\r
3678 return _y -HIT_AREA;
\r
3680 hitareaW: function( _comicElement, _w){
\r
3681 if( _comicElement === currentElement){
\r
3682 var _consoleW = COMIC_ELEMENT_CONSOLE.w();
\r
3683 return ( _consoleW < w ? w : _consoleW) +HIT_AREA *2;
\r
3685 return _w +HIT_AREA *2;
\r
3687 hitareaH: function( _comicElement, _h){
\r
3688 if( _comicElement === currentElement){
\r
3689 var _consoleY = COMIC_ELEMENT_CONSOLE.y();
\r
3690 return ( _consoleY < h ? h : _consoleY +COMIC_ELEMENT_CONSOLE.h()) +HIT_AREA *2;
\r
3692 return _h +HIT_AREA *2;
\r
3694 onMouseDown: function( _currentElement, _mouseX, _mouseY){
\r
3695 //show( _currentElement);
\r
3696 if( currentIsTextElement === true && TAIL_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){
\r
3697 currentControler = TAIL_CONTROLER;
\r
3699 if( RESIZE_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){
\r
3700 currentControler = RESIZE_CONTROLER;
\r
3702 POSITION_CONTROLER.onStart( _currentElement, _mouseX, _mouseY)
\r
3703 currentControler = POSITION_CONTROLER;
\r
3706 onMouseMove: function( _currentElement, _mouseX, _mouseY){
\r
3707 show( _currentElement);
\r
3708 if( currentControler !== null){
\r
3709 currentControler.onDrag( _mouseX, _mouseY);
\r
3711 currentElement && COMIC_ELEMENT_CONSOLE.onMouseMove( _mouseX -x, _mouseY -y);
\r
3712 TAIL_CONTROLER.hitTest( _mouseX -x, _mouseY -y) === false && RESIZE_CONTROLER.index( _mouseX, _mouseY) === -1 && MOUSE_CURSOR( '');
\r
3715 onMouseUp: function( _currentElement, _mouseX, _mouseY){
\r
3716 currentControler !== null && currentControler.onFinish();
\r
3717 currentControler = null;
\r
3719 onMouseClick: function( _mouseX, _mouseY){
\r
3720 //return currentElement ? COMIC_ELEMENT_CONSOLE.onMouseClick( _mouseX -x, _mouseY -y) : false;
\r
3725 * // COMIC_ELEMENT_OPERATOR
\r
3728 var AbstractComicElement = function( JQ_WAPPER, COMIC_ELM_TYPE, update, x, y, w, h, z, timing){
\r
3729 var OPERATOR = COMIC_ELEMENT_OPERATOR;
\r
3732 type: COMIC_ELM_TYPE,
\r
3739 hitareaX: function(){ return OPERATOR.hitareaX( this, this.x);},
\r
3740 hitareaY: function(){ return OPERATOR.hitareaY( this, this.y);},
\r
3741 hitareaW: function(){ return OPERATOR.hitareaW( this, this.w);},
\r
3742 hitareaH: function(){ return OPERATOR.hitareaH( this, this.h);},
\r
3743 shift: function( _shiftX, _shiftY){
\r
3744 update( this.x +_shiftX, this.y +_shiftY);
\r
3747 return OPERATOR.busy();
\r
3749 onMouseMove: function( _mouseX, _mouseY){
\r
3750 OPERATOR.onMouseMove( this, _mouseX, _mouseY);
\r
3752 onMouseUp: function( _mouseX, _mouseY){
\r
3753 OPERATOR.onMouseUp( this, _mouseX, _mouseY);
\r
3755 onMouseDown: function( _mouseX, _mouseY){
\r
3756 OPERATOR.onMouseDown( this, _mouseX, _mouseY);
\r
3761 * --------------------------------------------------------------------------------------------
\r
3762 * ImageElementClass
\r
3764 var jqImageElementOrigin;
\r
3765 var ImageElementClass = function( url, IMAGE_SET_ID, x, y, z, w, h, timing){
\r
3766 jqImageElementOrigin = jqImageElementOrigin || $( $( '#imgElementTemplete').remove().html());
\r
3768 var JQ_WRAPPER = jqImageElementOrigin.clone( true),
\r
3769 OPERATOR = COMIC_ELEMENT_OPERATOR,
\r
3770 SAVE = HISTORY.saveState,
\r
3771 HIT_AREA = MOUSE_HIT_AREA,
\r
3772 reversibleImage = null,
\r
3773 actualW = 0, actualH = 0,
\r
3774 flipH = w < 0 ? -1 : 1,
\r
3775 flipV = h < 0 ? -1 : 1,
\r
3777 w = Math.floor( w);
\r
3778 h = Math.floor( h);
\r
3780 function update( _x, _y, _w, _h, animate){
\r
3781 instance.x = x = _x !== undefined ? _x : x;
\r
3782 instance.y = y = _y !== undefined ? _y : y;
\r
3783 instance.w = w = _w !== undefined ? _w : w;
\r
3784 instance.h = h = _h !== undefined ? _h : h;
\r
3785 JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {
\r
3790 }, 250, function(){ reversibleImage.resize( flipH * w, flipV * h);});
\r
3791 animate !== true && reversibleImage.resize( flipH * w, flipV * h);
\r
3794 function updateUrl( _url){
\r
3795 if( url === _url) return;
\r
3796 url = _url || url;
\r
3797 var _reversibleImage = h2c.image.createReversibleImage( url, flipH * w, flipV * h, function( _url, _actualW, _actualH){
\r
3798 actualW = _actualW;
\r
3799 actualH = _actualH;
\r
3801 if( reversibleImage !== null){
\r
3802 JQ_WRAPPER.children( reversibleImage.elm).replaceWith( _reversibleImage.elm);
\r
3803 reversibleImage.destroy();
\r
3805 JQ_WRAPPER.append( _reversibleImage.elm);
\r
3807 reversibleImage = _reversibleImage;
\r
3809 return h2c.util.extend(
\r
3810 AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_IMAGE, update, x, y, w, h, z, timing]),
\r
3818 flip: function( _flipH, _flipV){
\r
3819 if( _flipH !== true && _flipV !== true) return;
\r
3820 flipH = _flipH === true ? -flipH : flipH;
\r
3821 flipV = _flipV === true ? -flipV : flipV;
\r
3822 reversibleImage.resize( flipH * w, flipV * h);
\r
3824 flipV: function(){
\r
3827 flipH: function(){
\r
3830 url: function( _url, _actualW, _actualH){
\r
3831 if( _url && _url !== url){
\r
3832 SAVE( updateUrl, url, _url);
\r
3833 actualW = _actualW;
\r
3834 actualH = _actualH;
\r
3839 actualW: function(){ return actualW;},
\r
3840 actualH: function(){ return actualH;},
\r
3843 animate: function ( _x, _y, _w, _h, _flipH, _flipV){
\r
3844 flipH = _flipH !== undefined ? _flipH : flipH;
\r
3845 flipV = _flipV !== undefined ? _flipV : flipV;
\r
3846 update( _x, _y, _w, _h, true);
\r
3848 getAsHTML: function( isAbsoluteUrl, isXHTML){
\r
3851 'src="', isAbsoluteUrl !== true ? url : h2c.util.getAbsolutePath( url), '" ',
\r
3852 'width="', w, '" ',
\r
3853 'height="', h, '" ',
\r
3855 'left:', x, 'px;',
\r
3857 'z-index:', z, ';',
\r
3859 isXHTML !== true ? '>' : ' \/>'
\r
3862 getAsJsonString: function(){
\r
3863 var cr = h2c.LINE_FEED_CODE_TEXTAREA;
\r
3865 '"new', this.timing, '": {', cr,
\r
3866 '"resource_picture_id": "', url, '",', cr,
\r
3867 '"x": ', x, ',', cr,
\r
3868 '"y": ', y, ',', cr,
\r
3869 '"z": ', z, ',', cr,
\r
3870 '"w": ', w, ',', cr,
\r
3871 '"h": ', h, ',', cr,
\r
3872 '"flipv": ', flipV === true ? 1 : 0, ',', cr,
\r
3873 '"fliph": ', flipH === true ? 1 : 0, ',', cr,
\r
3874 '"t": ', this.timing, cr,
\r
3878 destroy: function(){
\r
3879 reversibleImage.destroy();
\r
3880 JQ_WRAPPER.remove();
\r
3881 JQ_WRAPPER = reversibleImage = OPERATOR = null;
\r
3882 delete this.destroy;
\r
3888 * / ImageElementClass
\r
3889 * --------------------------------------------------------------------------------------------
\r
3894 * --------------------------------------------------------------------------------------------
\r
3895 * TextElementClass
\r
3897 * ELM はh2c.domで書き出したものを突っ込むcreateの場合
\r
3901 * 1.speach balloon
\r
3904 * 4.black-box( dq style)
\r
3905 * 5.blue-box( ff style)
\r
3908 var jqTextElementOrigin;
\r
3909 var TextElementClass = function( type, a, text, x, y, z, w, h, timing){
\r
3910 jqTextElementOrigin = jqTextElementOrigin || ( function(){
\r
3911 var _OLD_IE = $( $( '#textElementTempleteForOldIE').remove().html()),
\r
3912 _MODERN = $( $( '#textElementTemplete').remove().html());
\r
3913 return h2c.isIE === true && h2c.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;
\r
3916 var JQ_WRAPPER = jqTextElementOrigin.clone( true),
\r
3917 XBROWSER_BALLOON = h2c.balloon.createBalloon( w, h, a, type),
\r
3918 TEXT_ELM = JQ_WRAPPER.find( 'td,.speach-inner').eq( 0),
\r
3919 OPERATOR = COMIC_ELEMENT_OPERATOR,
\r
3920 HIT_AREA = MOUSE_HIT_AREA,
\r
3921 SAVE = HISTORY.saveState,
\r
3924 JQ_WRAPPER.find( 'img').eq( 0).replaceWith( XBROWSER_BALLOON.elm);
\r
3926 function update( _x, _y, _w, _h, _a, animate){
\r
3927 instance.x = x = _x !== undefined ? _x : x;
\r
3928 instance.y = y = _y !== undefined ? _y : y;
\r
3929 instance.w = w = _w !== undefined ? _w : w;
\r
3930 instance.h = h = _h !== undefined ? _h : h;
\r
3931 a = _a !== undefined ? _a : a;
\r
3933 JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {
\r
3940 XBROWSER_BALLOON.resize( a, w, h);
\r
3943 animate !== true && XBROWSER_BALLOON.resize( a, w, h);
\r
3946 function updateType( _type){
\r
3947 if( type !== _type){
\r
3948 type = _type || type;
\r
3949 XBROWSER_BALLOON.type( type);
\r
3952 function updateAngle( _a){
\r
3953 if( _a !== undefined && a !== _a){
\r
3954 a = _a !== undefined ? _a : a;
\r
3955 XBROWSER_BALLOON.angle( a);
\r
3958 function updateText( _text){
\r
3959 text = _text || text || '';
\r
3960 TEXT_ELM.html( text);
\r
3963 return h2c.util.extend(
\r
3964 AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_TEXT, update, x, y, w, h, z, timing]),
\r
3972 angle: function( _a){
\r
3973 _a !== undefined && update( undefined, undefined, undefined, undefined, _a);
\r
3976 text: function( _text){
\r
3977 if( _text && text !== _text) {
\r
3978 SAVE( updateText, text || '', _text);
\r
3979 updateText( _text);
\r
3984 animate: function ( _x, _y, _w, _h, _a){
\r
3985 update( _x, _y, _w, _h, _a, true);
\r
3987 destroy: function(){
\r
3988 JQ_WRAPPER.remove();
\r
3989 XBROWSER_BALLOON.destroy();
\r
3991 delete this.destroy;
\r
3993 getAsJSON: function(){
\r
3996 getAsJsonString: function(){
\r
3997 var cr = h2c.LINE_FEED_CODE_TEXTAREA;
\r
3999 '"new', this.timing, '": {', cr,
\r
4000 '"balloon_template_id": ', 1, ',', cr,
\r
4001 '"resource_picture_id": ', 1, ',', cr,
\r
4002 '"border": ', 1, ',', cr,
\r
4003 '"tail": ', a, ',', cr,
\r
4004 '"x": ', x, ',', cr,
\r
4005 '"y": ', y, ',', cr,
\r
4006 '"z": ', z, ',', cr,
\r
4007 '"w": ', w, ',', cr,
\r
4008 '"h": ', h, ',', cr,
\r
4009 '"t": ', this.timing, ',', cr,
\r
4010 '"speaches_attributes": {', cr,
\r
4011 '"newf', this.timing, '": {', cr,
\r
4012 '"content": "', text, '",', cr,
\r
4013 '"x": ', x, ',', cr,
\r
4014 '"y": ', y, ',', cr,
\r
4015 '"w": ', w, ',', cr,
\r
4022 getAsHTML: function( isAbsoluteUrl, isXHTML){
\r
4023 var url = XBROWSER_BALLOON.getURL();
\r
4026 'src="', isAbsoluteUrl !== true ? url : h2c.util.getAbsolutePath( url), '" ',
\r
4027 'width="', w, '" ',
\r
4028 'height="', h, '" ',
\r
4030 'left:', x, 'px;',
\r
4032 'z-index:', z, ';',
\r
4034 isXHTML !== true ? '>' : ' \/>',
\r
4035 h2c.LINE_FEED_CODE_TEXTAREA,
\r
4036 '<div class="balloon" style="',
\r
4037 'left:', x, 'px;',
\r
4039 'width:', w, 'px;',
\r
4040 'height:', h, 'px;',
\r
4042 '"><span>', text, '<\/span>', '<\/div>'
\r
4046 getAsXML: function(){}
\r
4052 * リサイズが、ResizerTopによって行われた場合、comicElementのyを動かして見かけ上動かないようにする。
\r
4054 function resize( isResizerTopAction){
\r
4055 if( isResizerTopAction === true){
\r
4056 var _shiftX = canvasW -_canvasW,
\r
4057 _shiftY = canvasH -_canvasH,
\r
4058 l = DRAGGABLE_ELEMENT_ARRAY.length;
\r
4059 for( var i = NUM_RESIZER; i < l; i++){
\r
4060 DRAGGABLE_ELEMENT_ARRAY[ i].shift( _shiftX, _shiftY);
\r
4063 _canvasW = canvasW;
\r
4064 _canvasH = canvasH;
\r
4066 comicElementContainer.css( {
\r
4075 * append, remove, replace
\r
4077 * comicElement には、z-position と dom-index がある。
\r
4078 * z-position は 表示上の位置。大きいほど前に表示される( z-index)
\r
4079 * dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。
\r
4081 * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。
\r
4082 * dom-index は、数値のみ保持して、投稿時にcomicElementを適宜に並び替える。
\r
4084 * append comicElement
\r
4085 * 1. 新しい comicElement の z-position を得る
\r
4086 * 2. z の同じ comicElementを見つけ、その前に加える。または一番先頭へ。(DRAGGABLE_ELEMENT_ARRAY)
\r
4087 * zが大きいほど、DRAGGABLE_ELEMENT_ARRAYの先頭へ。但しNUM_RESIZER番目より下。
\r
4088 * 3. dom位置は、DRAGGABLE_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。
\r
4091 * remove comicElement
\r
4095 function appendComicElement( _comicElement) {
\r
4096 _comicElement.init && _comicElement.init();
\r
4097 var z = _comicElement.z,
\r
4098 l = DRAGGABLE_ELEMENT_ARRAY.length;
\r
4099 _comicElement.$.stop().css( {
\r
4103 if( z === undefined || z === NaN || z < 0 || z >= l -NUM_RESIZER){
\r
4104 DRAGGABLE_ELEMENT_ARRAY.splice( NUM_RESIZER, 0, _comicElement);
\r
4105 comicElementContainer.append( _comicElement.$.fadeIn());
\r
4107 var insertIndex = ( function(){
\r
4108 for( var ret = NUM_RESIZER; ret < l; ++ret){
\r
4109 if( DRAGGABLE_ELEMENT_ARRAY[ ret].z <= z) return ret +1;
\r
4111 return NUM_RESIZER;
\r
4113 DRAGGABLE_ELEMENT_ARRAY[ insertIndex -1].$.after( _comicElement.$.fadeIn());
\r
4114 DRAGGABLE_ELEMENT_ARRAY.splice( insertIndex, 0, _comicElement);
\r
4116 sortComicElement();
\r
4118 function removeComicElement( _comicElement) {
\r
4119 var l = DRAGGABLE_ELEMENT_ARRAY.length;
\r
4120 for( var i=NUM_RESIZER; i<l; ++i){
\r
4121 if( DRAGGABLE_ELEMENT_ARRAY[ i] === _comicElement){
\r
4122 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);
\r
4123 sortComicElement();
\r
4124 _comicElement.$.stop().css( {
\r
4127 }).fadeOut( function(){
\r
4128 this.parentNode.removeChild( this);
\r
4130 currentElement = currentElement === _comicElement ? null : currentElement;
\r
4135 function restoreComicElement( arg){
\r
4136 var isAppend = arg[ 0],
\r
4137 comicElement = arg[ 1];
\r
4138 isAppend === true ? appendComicElement( comicElement) : removeComicElement( comicElement);
\r
4141 * DRAGGABLE_ELEMENT_ARRAY の順番を基準に、zの再計算
\r
4144 function sortComicElement(){
\r
4145 var l = DRAGGABLE_ELEMENT_ARRAY.length,
\r
4146 _comicElement, jqElm, jqNext;
\r
4147 for( var i=NUM_RESIZER; i < l; ++i){
\r
4148 _comicElement = DRAGGABLE_ELEMENT_ARRAY[ i];
\r
4149 jqElm = _comicElement.$;
\r
4150 jqNext && jqNext.before( jqElm);
\r
4151 _comicElement.z = l -i -NUM_RESIZER +1;
\r
4155 function replaceComicElement( _comicElement, goForward){
\r
4156 // DRAGGABLE_ELEMENT_ARRAYの再構築
\r
4157 var l = DRAGGABLE_ELEMENT_ARRAY.length,
\r
4159 for( var ret = NUM_RESIZER; ret < l; ++ret){
\r
4160 if( DRAGGABLE_ELEMENT_ARRAY[ ret] === _comicElement) return ret;
\r
4164 if( i === -1) return;
\r
4165 if( goForward === true){
\r
4166 if( i === NUM_RESIZER) return;
\r
4167 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);
\r
4168 DRAGGABLE_ELEMENT_ARRAY.splice( i -1, 0, _comicElement);
\r
4170 if( i === l -1) return;
\r
4171 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);
\r
4172 DRAGGABLE_ELEMENT_ARRAY.splice( i +1, 0, _comicElement);
\r
4174 sortComicElement();
\r
4176 function restoreReplaceObject( arg){
\r
4177 replaceComicElement( arg[ 0], arg[ 1]);
\r
4185 PANEL_RESIZER_TOP.init();
\r
4186 PANEL_RESIZER_BOTTOM.init();
\r
4190 comicElementContainer = $( '#comic-element-container');
\r
4192 appendComicElement( ImageElementClass.apply( {}, [ 'images/13.gif', 'penchan', 10, 10, 0, 100, 140, 0]));
\r
4193 appendComicElement( TextElementClass.apply( {}, [ 0, 270, 'Hello', 50, 70, 1, 200, 160, 1]));
\r
4195 COMIC_ELEMENT_OPERATOR.init( updateMouseCursor);
\r
4199 log = $( '#operation-catcher-log');
\r
4202 log.html( 'vector' +h2c.balloon.enabled());
\r
4203 delete COMIC_ELEMENT_CONTROL.init;
\r
4206 onMouseMove: function( _mouseX, _mouseY){
\r
4207 var l = DRAGGABLE_ELEMENT_ARRAY.length,
\r
4208 _X = _mouseX -( _canvasX || canvasX),
\r
4209 _Y = _mouseY -( _canvasY || canvasY),
\r
4212 if( currentElement !== null && currentElement.busy() === true){
\r
4213 currentElement.onMouseMove( _X, _Y);
\r
4216 if( currentElement !== null){
\r
4217 _x = currentElement.hitareaX();
\r
4218 _y = currentElement.hitareaY();
\r
4219 if( _x <= _X && _y <= _Y && _x + currentElement.hitareaW() >= _X && _y +currentElement.hitareaH() >= _Y){
\r
4220 currentElement.onMouseMove( _X, _Y); // cursor
\r
4224 for( var i=0; i<l; i++){
\r
4225 _elm = DRAGGABLE_ELEMENT_ARRAY[ i];
\r
4226 _x = _elm.hitareaX();
\r
4227 _y = _elm.hitareaY();
\r
4229 if( _x <= _X && _y <= _Y && _x + _elm.hitareaW() >= _X && _y +_elm.hitareaH() >= _Y){
\r
4230 currentElement = _elm;
\r
4231 currentElement.onMouseMove( _X, _Y); // cursor
\r
4232 log.html( [ _X, _Y, _x, _y, i].join( ','));
\r
4236 currentElement = null;
\r
4237 COMIC_ELEMENT_OPERATOR.hide();
\r
4238 log.html( [ _X, _Y, _x, _y].join( ','));
\r
4241 onMouseUp: function( _mouseX, _mouseY){
\r
4242 var ret = currentElement !== null && currentElement.busy() === true;
\r
4243 ret === true && currentElement.onMouseUp( _mouseX -_canvasX || canvasX, _mouseY -_canvasY || canvasY);
\r
4244 _canvasX = _canvasY = NaN;
\r
4247 onMouseDown: function( _mouseX, _mouseY){
\r
4248 _canvasX = canvasX;
\r
4249 _canvasY = canvasY;
\r
4250 currentElement !== null && currentElement.onMouseDown( _mouseX -canvasX, _mouseY -canvasY);
\r
4251 return currentElement !== null;
\r
4253 onMouseClick: function( _mouseX, _mouseY){
\r
4254 return currentElement !== null &&
\r
4255 currentElement !== PANEL_RESIZER_TOP &&
\r
4256 currentElement !== PANEL_RESIZER_BOTTOM &&
\r
4257 COMIC_ELEMENT_OPERATOR.onMouseClick( _mouseX -canvasX, _mouseY -canvasY);
\r
4259 onMouseOut: function( _mouseX, _mouseY){
\r
4260 currentElement !== null && currentElement.busy() === true && currentElement.onMouseUp( _mouseX -canvasX, _mouseY -canvasY);
\r
4261 _canvasX = _canvasY = NaN;
\r
4262 currentElement = null;
\r
4263 COMIC_ELEMENT_OPERATOR.hide();
\r
4267 return currentElement !== null ? currentElement.busy() : false;
\r
4269 createImageElement: function( url, imagesetID, x, y, z, w, h){
\r
4270 w = w || 200; //ActualWidth
\r
4271 h = h || 150; //ActualHeight
\r
4272 x = x || Math.floor( canvasW /2 -w /2);
\r
4273 y = y || Math.floor( canvasH /2 -h /2);
\r
4274 IMAGE_GROUP_EXPROLER.show( function( _url, _w, _h){
\r
4275 var _comicElement = ImageElementClass.apply( {}, [ _url, imagesetID, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER]);
\r
4276 appendComicElement( _comicElement);
\r
4277 _comicElement.animate( undefined, undefined, _w, _h);
\r
4278 SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);
\r
4281 createTextElement: function( type, angle, text, x, y, z, w, h){
\r
4283 angle = angle || 0;
\r
4284 text = text || '';
\r
4287 x = x || Math.floor( canvasW /2 -w /2 +Math.random() *10);
\r
4288 y = y || Math.floor( canvasH /2 -h /2 +Math.random() *10);
\r
4289 var _comicElement = TextElementClass.apply( {}, [ type, angle, text, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER]);
\r
4290 TEXT_EDITOR_CONTROL.show( _comicElement, function( _comicElement){
\r
4291 appendComicElement( _comicElement);
\r
4292 SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);
\r
4295 getAsHTML: function( isAbsoluteUrl, isXHTML){
\r
4296 var HTML_ARRAY = [],
\r
4297 l = DRAGGABLE_ELEMENT_ARRAY.length,
\r
4301 while( HTML_ARRAY.length < l -NUM_RESIZER){
\r
4302 _comicElement = getComicElementByTiming();
\r
4303 if( _comicElement === null) break;
\r
4304 HTML_ARRAY.push( _comicElement.getAsHTML( isAbsoluteUrl, isXHTML));
\r
4306 function getComicElementByTiming(){
\r
4307 while( _timing < l *2){
\r
4308 for(var i=NUM_RESIZER; i<l; ++i){
\r
4309 if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){
\r
4311 return DRAGGABLE_ELEMENT_ARRAY[ i];
\r
4318 HTML_ARRAY.unshift(
\r
4320 '<div class="panel" ',
\r
4322 'height:', canvasH, 'px;',
\r
4323 'background-color:', ';',
\r
4328 HTML_ARRAY.push( '</div>');
\r
4330 return HTML_ARRAY.join( h2c.LINE_FEED_CODE_TEXTAREA);
\r
4332 getAsJsonString: function(){
\r
4333 var JSON_STRING_ARRAY = [],
\r
4335 BALLOON_ARRAY = [],
\r
4336 l = DRAGGABLE_ELEMENT_ARRAY.length,
\r
4339 cr = h2c.LINE_FEED_CODE_TEXTAREA;
\r
4341 while( IMAGE_ARRAY.length + BALLOON_ARRAY.length < l -NUM_RESIZER){
\r
4342 _comicElement = getComicElementByTiming();
\r
4343 if( _comicElement === null) break;
\r
4344 _comicElement.type === COMIC_ELEMENT_TYPE_IMAGE ?
\r
4345 IMAGE_ARRAY.push( _comicElement.getAsJsonString()) :
\r
4346 BALLOON_ARRAY.push( _comicElement.getAsJsonString());
\r
4348 function getComicElementByTiming(){
\r
4349 while( _timing < l *2){
\r
4350 for(var i=NUM_RESIZER; i<l; ++i){
\r
4351 if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){
\r
4353 return DRAGGABLE_ELEMENT_ARRAY[ i];
\r
4363 '"border": 1,', cr,
\r
4364 '"comic_id": 5,', cr,
\r
4365 '"resource_picture_id": 1,', cr,
\r
4366 '"width": ', canvasW, ',', cr,
\r
4367 '"height": ', canvasH, ',', cr,
\r
4368 '"panel_pictures_attributes": {', cr,
\r
4369 IMAGE_ARRAY.join( ',' +cr), cr,
\r
4371 '"balloons_attributes": {', cr,
\r
4372 BALLOON_ARRAY.join( ',' +cr), cr,
\r
4384 function resize( isResizerTopAction){
\r
4385 GRID_CONTROL.resize();
\r
4386 WHITE_GLASS_CONTROL.resize();
\r
4387 PANEL_BORDER_CONTROL.resize();
\r
4388 COMIC_ELEMENT_CONTROL.resize( isResizerTopAction);
\r
4391 init: function( _canvasW, _canvasH){
\r
4392 canvasW = _canvasW || DEFAULT_PANEL_WIDTH;
\r
4393 canvasH = _canvasH || DEFAULT_PANEL_HEIGHT;
\r
4394 canvasX = Math.floor( ( windowW -canvasW) /2);
\r
4395 canvasY = Math.floor( ( windowH -canvasH) /2);
\r
4397 GRID_CONTROL.init();
\r
4398 // WHITE_GLASS_CONTROL.init();
\r
4399 PANEL_BORDER_CONTROL.init();
\r
4400 COMIC_ELEMENT_CONTROL.init();
\r
4404 h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 32, false, false, function( e){
\r
4405 if( e.type === 'keyup'){
\r
4406 currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && updateMouseCursor( '');
\r
4407 isCanvasDraggble = false;
\r
4409 currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && updateMouseCursor( 'move');
\r
4410 isCanvasDraggble = true;
\r
4413 delete CANVAS_CONTROL.init;
\r
4415 x: function(){ return canvasX;},
\r
4416 y: function(){ return canvasY;},
\r
4417 onWindowResize: function( _windowW, _windowH){
\r
4418 canvasX = Math.floor(( _windowW - canvasW) / 2);
\r
4419 canvasY = Math.floor(( _windowH - canvasH) / 2);
\r
4422 onMouseMove: function( _mouseX, _mouseY){
\r
4423 if( currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && isCanvasDraggble === true && isDragging === true){
\r
4424 canvasX = startCanvasX +_mouseX -xOffset;
\r
4425 canvasY = startCanvasY +_mouseY -yOffset;
\r
4428 COMIC_ELEMENT_CONTROL.onMouseMove( _mouseX, _mouseY)
\r
4431 onMouseUp: function( _mouseX, _mouseY){
\r
4432 if( COMIC_ELEMENT_CONTROL.onMouseUp( _mouseX, _mouseY) === false && isCanvasDraggble === true){
\r
4433 isDragging = false;
\r
4434 updateMouseCursor( '');
\r
4437 onMouseDown: function( _mouseX, _mouseY){
\r
4438 if( COMIC_ELEMENT_CONTROL.onMouseDown( _mouseX, _mouseY) === false && isCanvasDraggble === true){
\r
4439 xOffset = _mouseX;
\r
4440 yOffset = _mouseY;
\r
4441 startCanvasX = canvasX;
\r
4442 startCanvasY = canvasY;
\r
4443 isDragging = true;
\r
4444 updateMouseCursor( 'move');
\r
4447 onMouseClick: function( _mouseX, _mouseY){
\r
4448 COMIC_ELEMENT_CONTROL.onMouseClick( _mouseX, _mouseY)
\r
4450 onMouseOut: function( _mouseX, _mouseY){
\r
4451 if( COMIC_ELEMENT_CONTROL.onMouseOut( _mouseX, _mouseY) === false){
\r
4456 return isDragging === true || COMIC_ELEMENT_CONTROL.busy();
\r
4458 createImageElement: function( url, imagesetID, x, y, z, w, h){
\r
4459 COMIC_ELEMENT_CONTROL.createImageElement( url, imagesetID, x, y, z, w, h);
\r
4461 createTextElement: function( type, angle, text, x, y, w, h, z){
\r
4462 COMIC_ELEMENT_CONTROL.createTextElement( type, angle, text, x, y, w, h, z);
\r
4464 getAsHTML: COMIC_ELEMENT_CONTROL.getAsHTML,
\r
4465 getAsJsonString: COMIC_ELEMENT_CONTROL.getAsJsonString
\r
4470 function updateMouseCursor( _cursor){
\r
4471 if( currentCursor !== _cursor){
\r
4472 currentCursor = _cursor;
\r
4475 ELM_MOUSE_EVENT_CHATCHER.style.cursor = _cursor;
\r
4480 function centering(){
\r
4481 h2c.editor.onWindowResize( windowW, windowH);
\r
4483 function mouseEventRellay( rellayMethod, e){
\r
4484 var _mouseX = e.pageX,
\r
4485 _mouseY = e.pageY;
\r
4486 if( currentListener !== null && currentListener.busy() === true){
\r
4487 currentListener[ rellayMethod]( _mouseX, _mouseY);
\r
4489 currentListener = null;
\r
4490 var l = MOUSE_LISTENER_ARRAY.length,
\r
4492 for( var i=0; i<l; ++i){
\r
4493 _listener = MOUSE_LISTENER_ARRAY[ i];
\r
4494 if( typeof _listener[ rellayMethod] === 'function' && _listener[ rellayMethod]( _mouseX, _mouseY) === true){
\r
4495 currentListener = _listener;
\r
4500 e.stopPropagation();
\r
4506 var jqWindow = h2c.jqWindow();
\r
4507 windowW = jqWindow.width();
\r
4508 windowH = jqWindow.height();
\r
4510 jqEditor = $( '#editor');
\r
4512 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 96, false, true, centering);
\r
4513 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 48, false, true, centering);
\r
4516 MENU_BAR_CONTROL.EDIT.createSelection( 'centering', 'ctrl + 0', centering, true, true, true);
\r
4518 WINDOWS_CONTROL.init();
\r
4519 CANVAS_CONTROL.init();
\r
4522 MENU_BAR_CONTROL.init();
\r
4524 TEXT_EDITOR_CONTROL.init();
\r
4525 IMAGE_GROUP_EXPROLER.init();
\r
4527 * jqMouseEventChacher は透明な要素で、
\r
4528 * マウスイベントをcurrentElement(currentElement)に伝えるのが仕事
\r
4529 * このような実装になるのは、ここの表示オブジェクトにイベントを設定した場合、表示が追いつかずマウスカーソルが外れたタイミングでイベントが終わってしまうため。
\r
4532 * MOUSE_LISTENER_ARRAY は、表示順に格納.手前の要素が最初
\r
4533 * MENU_BAR_CONTROL,
\r
4536 * .busy() === true なら、そのままonMouseMove()にイベントを流す.これはArrayの後ろから、奥の表示要素から
\r
4537 * onMouseMove()に流してみて、false が帰れば、次にリスナーにも流す.
\r
4539 MOUSE_LISTENER_ARRAY.push( MENU_BAR_CONTROL, WINDOWS_CONTROL, CANVAS_CONTROL);
\r
4541 jqMouseEventChacher = $( ELM_MOUSE_EVENT_CHATCHER)
\r
4542 .mousemove( function( e){
\r
4543 return mouseEventRellay( 'onMouseMove', e);
\r
4544 }).mousedown( function( e){
\r
4545 return mouseEventRellay( 'onMouseDown', e);
\r
4546 }).mouseup( function( e){
\r
4547 return mouseEventRellay( 'onMouseUp', e);
\r
4548 }).mouseout( function( e){
\r
4549 return mouseEventRellay( 'onMouseUp', e);
\r
4550 }).click( function( e){
\r
4551 var _mouseX = e.pageX,
\r
4552 _mouseY = e.pageY;
\r
4553 if( CANVAS_CONTROL.busy() === true || WINDOWS_CONTROL.onMouseClick( _mouseX, _mouseY) === false){
\r
4554 CANVAS_CONTROL.onMouseClick( _mouseX, _mouseY);
\r
4556 e.stopPropagation();
\r
4559 height: windowH // ie6
\r
4562 delete h2c.editor.init;
\r
4564 onWindowResize: function( _windowW, _windowH){
\r
4565 windowW = _windowW;
\r
4566 windowH = _windowH;
\r
4571 jqEditor.get( 0).style.height = _windowH +'px';
\r
4572 ELM_MOUSE_EVENT_CHATCHER.style.height = _windowH +'px';
\r
4574 WINDOWS_CONTROL.onWindowResize( _windowW, _windowH);
\r
4575 MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH);
\r
4576 CANVAS_CONTROL.onWindowResize( _windowW, _windowH);
\r
4583 h2c.log = ( function(){
\r
4585 init: function(){}
\r
4589 h2c.io = ( function(){
\r
4592 init: function(){}
\r
4599 * お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
\r
4600 * 最近アップロードされた画像 > images
\r
4601 * 最近使われた画像 > images
\r
4602 * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
\r
4609 h2c.file = ( function(){
\r
4610 var TREE_TYPE_IS_COMIC = 1,
\r
4611 TREE_TYPE_IS_IMAGE = 2,
\r
4612 TREE_TYPE_IS_SETTING = 3,
\r
4613 TREE_TYPE_IS_HELP = 4,
\r
4614 FILE_TYPE_IS_FOLDER = 1,
\r
4615 FILE_TYPE_IS_IMAGE = 2,
\r
4616 FILE_TYPE_IS_PANEL = 3,
\r
4617 FILE_TYPE_IS_SETTING = 4,
\r
4618 FILE_TYPE_IS_HTML = 5,
\r
4619 FILE_STATE_IS_UNKNOWN = 0,
\r
4620 FILE_STATE_IS_OK = 1,
\r
4621 FILE_STATE_IS_LOADING = 2,
\r
4622 FILE_STATE_IS_ERROR = 3,
\r
4623 FILE_STATE_IS_BROKEN = 4,
\r
4624 TREE_EVENT_UPDTE = 'onUpdate',
\r
4625 FILE_EVENT_UPDATED_ATTRIVUTE = 'onUpdate',
\r
4626 FILE_EVENT_GET_SEQENTIAL_FILES = 'gotSeqentilFiles',
\r
4627 ROLE_IS_SUPER_USER = 2^4,
\r
4628 ROLE_IS_OWNER = 2^3,
\r
4629 ROLE_IS_CREATOR = 2^2,
\r
4630 ROLE_IS_ARTIST = 2^1,
\r
4631 ROLE_IS_VISITOR = 2^0,
\r
4632 ROLE_IS_UNKROWN = 2^-1,
\r
4633 UPDATE_POLICY_SOCAV = 0x11111,// s: super user
\r
4634 UPDATE_POLICY_SOCA_ = 0x11110,// o: owner( comic || panel || picture )
\r
4635 UPDATE_POLICY_SOC__ = 0x11100,// c: creator
\r
4636 UPDATE_POLICY_SO_A_ = 0x11010,// a: artist
\r
4637 UPDATE_POLICY_SO___ = 0x11000,// v: visitor
\r
4638 UPDATE_POLICY__O___ = 0x01000,// l: lisence manager
\r
4639 UPDATE_POLICY_S____ = 0x10000,
\r
4640 UPDATE_POLICY______ = 0x00000,
\r
4641 FILEDATA_RESITER = [],
\r
4642 FILEDATA_ACCESS = [];
\r
4644 var REQUEST_CONTROLER = ( function(){
\r
4645 var REQUEST_TICKET_RESISTER = [],
\r
4648 var RequestTicketClass = ( function(){
\r
4654 delete REQUEST_CONTROLER.init;
\r
4656 getJson: function( _url, _onLoad, _onError){
\r
4657 REQUEST_TICKET_RESISTER.push( RequestTicketClass.apply( {}, [ _url, _onLoad, _onError]));
\r
4661 /* ----------------------
\r
4665 * ID( imgGroupID, comicID)
\r
4666 * ----------------------
\r
4668 * img-group(folder)
\r
4672 * author, licence,
\r
4678 * groupID - updateGropuID
\r
4679 * actualWidth, actualHeight,
\r
4680 * author, licence( 'by,no-resize'),
\r
4681 * create, update, tag,
\r
4682 * actualWidth, actualHeight
\r
4684 * ----------------------
\r
4707 * ----------------------
\r
4709 var FILE_CONTROLER = ( function(){
\r
4710 var FILE_EVENT_LISTENER_RESISTER = [],
\r
4713 var TreeClass = function( TREE_ROOTFILE){
\r
4714 var UID = TREE_ACCESS.length,
\r
4715 currentFile = TREE_ROOTFILE,
\r
4716 PARENT_FILE_RESITER = [],
\r
4718 fileEventChatcher: dispatchFileEvent,
\r
4719 destroy: onDestroy
\r
4722 function dispatchFileEvent( fileEvent){
\r
4725 function onDestroy(){
\r
4729 TREE_ACCESS.push( ACCESS);
\r
4731 FILE_CONTROLER.getSeqentialFiles( currentFile);
\r
4733 ROOT_FILE :function(){
\r
4734 return TREE_ROOTFILE;
\r
4736 currentFile: function(){
\r
4737 return currentFile;
\r
4739 hierarky: function(){
\r
4740 return PARENT_FILE_RESITER.length;
\r
4742 down: function( _index){
\r
4743 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
\r
4744 PARENT_FILE_RESITER.unshift( currentFile);
\r
4745 currentFile = currentFile.getChildFileByIndex( _index);
\r
4746 FILE_CONTROLER.getSeqentialFiles( currentFile);
\r
4747 return currentFile;
\r
4750 if( PARENT_FILE_RESITER.length === 0) return;
\r
4751 currentFile = PARENT_FILE_RESITER.shift();
\r
4752 FILE_CONTROLER.getSeqentialFiles( currentFile);
\r
4753 return currentFile;
\r
4755 addEventListener: function( UID, _eventType, _callback){
\r
4756 FILE_CONTROLER.addEventListener( UID, _eventType, _callback);
\r
4758 removeEventListener: function( UID, _eventType, _callback){
\r
4759 FILE_CONTROLER.removeEventListener( UID, _eventType, _callback);
\r
4761 createSearchResultFolder: function( _searchParam){
\r
4764 destroySearchResultFolder: function( _searchParam){
\r
4767 destroy: function(){
\r
4768 FILE_CONTROLER.destroyTree( UID);
\r
4773 var FileEventTicketClass = function( UID, _eventType, _callback){
\r
4776 eventType: _eventType,
\r
4777 callBack: _callback
\r
4781 var FileEventClass = function( eventType, file, key, value){
\r
4783 eventType: eventType,
\r
4785 updatedAttribute: key,
\r
4786 updatedValue: value
\r
4790 function disptchFileEvent( eventType, fileUID, key, value){
\r
4791 var _fileEvent = FileEventClass.apply( {}, [ eventType, fileUID, key, value]),
\r
4792 l = TREE_ACCESS.length,
\r
4794 for( var i=0; i<l; ++i){
\r
4795 _tree = TREE_ACCESS[ i];
\r
4796 _tree !== null && _tree.fileEventChatcher( _fileEvent);
\r
4799 function getFileDataAccess( UIDorFILE){
\r
4800 var l = FILEDATA_ACCESS.length,
\r
4801 i = typeof UIDorFILE === 'number' ?
\r
4802 ( UIDorFILE > 0 && UIDorFILE > l ? UIDorFILE : -1) :
\r
4804 for( var i=0; i<l; ++i){
\r
4805 if( FILEDATA_ACCESS[ i] === UIDorFILE) return i;
\r
4809 return i !== -1 ? FILEDATA_ACCESS[ i] : null;
\r
4814 delete FILE_CONTROLER.init;
\r
4816 createTree: function( _rootFileData){
\r
4817 return TreeClass.apply( {}, [ _rootFileData]);
\r
4819 getFileData: function( _file){
\r
4820 var _access = getFileDataAccess( _file);
\r
4821 return _access !== null ? _access.DATA : null;
\r
4823 getSeqentialFiles: function( _uid){
\r
4826 updateFileAttribute: function( _uid, key, _value, _opt_callback){
\r
4827 var _fileData = getFileDataAccess( _uid),
\r
4828 _type = _fileData.TYPE;
\r
4831 getFileAttribute: function( _uid, KEYorKEYARRAY){
\r
4832 var _fileData = getFileDataAccess( _uid),
\r
4833 _type = _fileData.TYPE;
\r
4835 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
\r
4836 var _parentData = getFileDataAccess( _prentUID),
\r
4837 _parentType = _parentData.TYPE,
\r
4838 _targetData = getFileDataAccess( _targetfile),
\r
4839 _targetType = _targetData.TYPE;
\r
4841 replace: function( _uid, _file, _newIndex){
\r
4848 * fileのdataはobjectで保持している。
\r
4849 * h2c.file.の外からファイルをみるときは、FileClassを通して操作する。
\r
4850 * fileの変更、それに付随して追加されたイベントは、treeで管理される。
\r
4851 * treeがdestryされると、fileのイベントリスナーも全て削除される。
\r
4854 var FileClass = function( TREE, PARENT_FILE, DATA){
\r
4855 var TYPE = DATA.type,
\r
4856 UID = FILEDATA_ACCESS.length,
\r
4857 CHILDREN = DATA.children;
\r
4859 FILEDATA_ACCESS.push(
\r
4863 CHILDREN: CHILDREN,
\r
4864 destroy: function(){
\r
4865 PARENT_FILE = DATA = CHILDREN = null;
\r
4866 delete this.destroy;
\r
4871 TYPE: function(){ return TYPE;},
\r
4872 state: function(){
\r
4873 return DATA.state !== undefined ? DATA.state : FILE_STATE_IS_OK;
\r
4875 childFileLength: function(){
\r
4876 return typeof CHILDREN === 'array' ? CHILDREN.length : 0;
\r
4878 getChildFileByIndex: function( _index){
\r
4879 if( typeof _index !== 'number' || _index < 0 || typeof CHILDREN !== 'array' || _index >= CHILDREN.length) return;
\r
4880 return FileClass.apply( {}, [ TREE, PARENT_FILE, this, CHILDREN[ _index]]);
\r
4882 getChildFileIndex: function( _FILEorFILEDATA){
\r
4883 if( typeof CHILDREN !== 'array') return -1;
\r
4884 var l = CHILDREN.length,
\r
4885 _fileData = ( function(){
\r
4886 var l = FILEDATA_RESITER.length;
\r
4887 for( var i=0; i<l; ++i){
\r
4888 if( _FILEorFILEDATA === FILEDATA_RESITER[ i]) return _FILEorFILEDATA;
\r
4890 return FILE_CONTROLER.getFileData( _FILEorFILEDATA);
\r
4892 if( _fileData === null) return -1;
\r
4893 for( var i=0; i<l; ++i){
\r
4894 if( CHILDREN[ i] === _fileData) return i;
\r
4898 isChildFile: function( _FILEorFILEDATA){
\r
4899 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
\r
4901 getAttribute: function( KEYorKEYARRAY){
\r
4902 return FILE_CONTROLER.getFileAttribute( UID, KEYorKEYARRAY);
\r
4904 getSeqentialFiles: function(){
\r
4905 FILE_CONTROLER.getSeqentialFiles( this);
\r
4907 updateAttribute: function( key, value, opt_callback){
\r
4908 TREE.updateFileAttribute( UID, key, value, opt_callback);
\r
4910 move: function( _newFolder, _newIndex, opt_callback){
\r
4911 TREE.move( PARENT_FILE, UID, _newFolder, _newIndex, opt_callback);
\r
4913 replace: function( _newIndex, opt_callback){
\r
4914 TREE.replace( PARENT_FILE, UID, _newIndex, opt_callback);
\r
4916 addEventListener: function( _eventType, _callback){
\r
4917 TREE.addEventListener( UID, _eventType, _callback);
\r
4919 removeEventListener: function( _eventType, _callback){
\r
4920 TREE.removeEventListener( UID, _eventType, _callback);
\r
4925 var ROOT_FILEDATA = {
\r
4927 type: FILE_TYPE_IS_FOLDER,
\r
4930 IMAGE_FILEDATA = {
\r
4931 name: 'image root',
\r
4932 type: FILE_TYPE_IS_FOLDER
\r
4934 COMIC_FILEDATA = {
\r
4935 name: 'comic root',
\r
4936 type: FILE_TYPE_IS_FOLDER
\r
4938 SETTING_FILEDATA = {
\r
4939 name: 'setting root',
\r
4940 type: FILE_TYPE_IS_FOLDER
\r
4943 name: 'help root',
\r
4944 type: FILE_TYPE_IS_FOLDER
\r
4946 FILEDATA_RESITER.push( ROOT_FILEDATA, IMAGE_FILEDATA, COMIC_FILEDATA, SETTING_FILEDATA, HELP_FILEDATA);
\r
4947 ROOT_FILEDATA.children.push( IMAGE_FILEDATA, COMIC_FILEDATA, SETTING_FILEDATA, HELP_FILEDATA);
\r
4949 var SYSTEM_TREE = FILE_CONTROLER.createTree( FileClass.apply( {}, [ null, null, ROOT_FILEDATA])),
\r
4950 ROOT_FILE = SYSTEM_TREE.ROOT_FILE(),
\r
4951 COMIC_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( COMIC_FILEDATA),
\r
4952 COMIC_ROOT_FILE = ROOT_FILE.getChildFileByIndex( COMIC_ROOT_INDEX),
\r
4953 IMAGE_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( IMAGE_FILEDATA),
\r
4954 IMAGE_ROOT_FILE = ROOT_FILE.getChildFileByIndex( IMAGE_ROOT_INDEX),
\r
4955 SETTING_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( SETTING_FILEDATA),
\r
4956 SETTING_ROOT_FILE = ROOT_FILE.getChildFileByIndex( SETTING_ROOT_INDEX),
\r
4957 HELP_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( HELP_FILEDATA),
\r
4958 HELP_ROOT_FILE = ROOT_FILE.getChildFileByIndex( HELP_ROOT_INDEX);
\r
4962 REQUEST_CONTROLER.init();
\r
4963 FILE_CONTROLER.init();
\r
4964 delete h2c.file.init;
\r
4966 createTree: function( _treeType){
\r
4968 if( _treeType === TREE_TYPE_IS_COMIC) _rootFile = COMIC_ROOT_FILE;
\r
4969 if( _treeType === TREE_TYPE_IS_IMAGE) _rootFile = IMAGE_ROOT_FILE;
\r
4970 if( _treeType === TREE_TYPE_IS_SETTING) _rootFile = SETTING_ROOT_FILE;
\r
4971 if( _treeType === TREE_TYPE_IS_HELP) _rootFile = HELP_ROOT_FILE;
\r
4972 if( _rootFile === undefined) return;
\r
4973 return FILE_CONTROLER.createTree( _rootFile);
\r
4975 TREE_TYPE_IS_COMIC: TREE_TYPE_IS_COMIC,
\r
4976 TREE_TYPE_IS_IMAGE: TREE_TYPE_IS_IMAGE,
\r
4977 TREE_TYPE_IS_SETTING: TREE_TYPE_IS_SETTING,
\r
4978 FILE_TYPE_IS_FOLDER: FILE_TYPE_IS_FOLDER,
\r
4979 FILE_TYPE_IS_IMAGE: FILE_TYPE_IS_IMAGE,
\r
4980 FILE_TYPE_IS_PANEL: FILE_TYPE_IS_PANEL,
\r
4981 FILE_TYPE_IS_SETTING: FILE_TYPE_IS_SETTING
\r
4989 h2c.fn( h2c.view);
\r
4990 h2c.fn( h2c.overlay);
\r
4992 h2c.fn( h2c.balloon);
\r
4993 h2c.fn( h2c.editor);
\r
4994 h2c.fn( h2c.file);
\r
4996 $(window).ready( h2c.init);
\r