OSDN Git Service

fixed assets/ & views/layouts/
[pettanr/pettanr.git] / public / assets / work.js
1 /*\r
2  * pettanR work.js\r
3  *   version 0.4.2\r
4  *   \r
5  * author:\r
6  *   itozyun\r
7  * licence:\r
8  *   3-clause BSD\r
9  *\r
10  * \r
11  * ----------------------------------------\r
12  * naming rules\r
13  * \r
14  *  Class\r
15  *    ThisIsClass\r
16  *  \r
17  *  const\r
18  *    THIS_IS_CONST = 'this is const';\r
19  *  \r
20  *  var\r
21  *    thisIsVar\r
22  *   \r
23  *  value of jquery\r
24  *    jqWrapper, JQ_WRAPPER\r
25  *  \r
26  *  value of dom element\r
27  *    elmWrapper, ELM_WRAP\r
28  * \r
29  *      value of vml element\r
30  *    vmlImg, VML_SHAPE\r
31  * \r
32  */\r
33 \r
34 \r
35 /* ----------------------------------------\r
36  *   pettanr.editor\r
37  *    - MENU_BAR_CONTROL\r
38  *    - HISTORY\r
39  *    - SAVE_CONTROL\r
40  *    - TEXT_EDITOR_CONTROL\r
41  *    - IMAGE_GROUP_EXPROLER\r
42  *    - WINDOW_CONTROL\r
43  *       - WindowClass\r
44  *    - INFOMATION_WINDOW\r
45  *    - TOOL_BOX_WINDOW\r
46  *    - HELP_DOCUMENTS_WINDOW\r
47  *    - PANEL_CONTROL\r
48  *    - GRID_CONTROL\r
49  *    - WHITE_GLASS_CONTROL\r
50  *    - PANEL_CONTROL\r
51  *    \r
52  * \r
53  *    - PanelResizerClass\r
54  *    - PANEL_RESIZER_TOP\r
55  *    - PANEL_RESIZER_BOTTOM\r
56  *    - CONSOLE_CONTROLER\r
57  * \r
58  *    - TAIL_OPERATOR\r
59  *    - RESIZE_OPERATOR\r
60  *    - POSITION_OPERATOR\r
61  *    - COMIC_ELEMENT_OPERATION_MANAGER\r
62  *      \r
63  *    - ImageElementClass\r
64  *    - TextElementClass\r
65  * \r
66  *    - COMIC_ELEMENT_CONTROL\r
67  * \r
68  * \r
69  */\r
70 pettanr.editor = ( function(){\r
71 \r
72         var COMIC_ELEMENT_TYPE_IMAGE = 0,\r
73                 COMIC_ELEMENT_TYPE_TEXT = 1,\r
74                 MOUSE_LISTENER_ARRAY = [],\r
75                 COMIC_ELEMENT_ARRAY = [],\r
76                 ELM_MOUSE_EVENT_CHATCHER = document.getElementById( 'mouse-operation-catcher'),\r
77                 MIN_PANEL_HEIGHT = 20,\r
78                 MIN_ELEMENT_SIZE = 19,\r
79                 MOUSE_HIT_AREA = 10,\r
80                 jqMouseEventChacher,\r
81                 jqEditor,\r
82                 windowW, windowH,\r
83                 currentListener = null,\r
84                 currentCursor = '',\r
85                 option,\r
86                 log;\r
87 \r
88 /* ----------------------------------------\r
89  * MENU BAR\r
90  * div\r
91  *   div.title\r
92  *   ul\r
93  *     li\r
94  *        a\r
95  *          span\r
96  *          kbd shortcut\r
97  */\r
98         var MENU_BAR_CONTROL = ( function(){\r
99                 var ELM_BAR = document.getElementById( 'menu-bar'),\r
100                         ELM_ITEM_CLASSNAME = 'menu-bar-item',\r
101                         ELM_ITEM_ORIGN = ( function(){\r
102                                 var ret = document.createElement( 'div'),\r
103                                         div = document.createElement( 'div'),\r
104                                         ul = document.createElement( 'ul');\r
105                                 ret.className = ELM_ITEM_CLASSNAME;\r
106                                 ret.appendChild( div);\r
107                                 ret.appendChild( ul);\r
108                                 return ret;\r
109                         })(),\r
110                         ELM_SELECTION_ORIGN = ( function(){\r
111                                 var ret = document.createElement( 'li'),\r
112                                         a = document.createElement( 'a'),\r
113                                         span = document.createElement( 'span'),\r
114                                         key = document.createElement( 'kbd');\r
115                                 a.appendChild( span);\r
116                                 a.appendChild( key);\r
117                                 ret.appendChild( a);\r
118                                 a.href = '#';\r
119                                 return ret;\r
120                         })(),\r
121                         ITEM_ARRAY = [],\r
122                         barH = pettanr.util.getElementSize( ELM_BAR).height,\r
123                         itemW = pettanr.util.getElementSize( ELM_ITEM_ORIGN).width,\r
124                         selectionW = pettanr.util.getElementSize( ELM_ITEM_ORIGN.getElementsByTagName( 'ul')[ 0]).width,\r
125                         jqStage, jqBar;\r
126                 ELM_BAR.style.top = ( -barH) +'px';\r
127 \r
128                 var MenubarSelectionClass = function( container, title, shortcut, visible, separateAfter){\r
129                         var ELM_WRAPPER = ELM_SELECTION_ORIGN.cloneNode( true),\r
130                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'span')[ 0],\r
131                                 elmShortcut = ELM_WRAPPER.getElementsByTagName( 'kbd')[ 0];\r
132                                 \r
133                         if( shortcut){\r
134                                 elmShortcut.innerHTML = shortcut;\r
135                         } else {\r
136                                 elmShortcut.parentNode.removeChild( elmShortcut);\r
137                         }\r
138                         elmShortcut = null;\r
139                         \r
140                         container.appendChild( ELM_WRAPPER);\r
141                         \r
142                         updateTitle( title);\r
143                         updateVisible( visible);\r
144                         \r
145                         function updateTitle( _title){\r
146                                 ELM_TITLE.innerHTML = title = _title;\r
147                         }\r
148                         function updateVisible( _visible){\r
149                                 if( _visible !== undefined){\r
150                                         visible = !!_visible;\r
151                                         ELM_WRAPPER.className = visible === true ? '' : 'disabled';\r
152                                 };\r
153                         }\r
154                         return {\r
155                                 elm: ELM_WRAPPER,\r
156                                 title: function( _title){\r
157                                         _title !== undefined && updateTitle( _title);\r
158                                         return title;\r
159                                 },\r
160                                 visible: function( _visible){\r
161                                         visible !== !!_visible && updateVisible( _visible);\r
162                                         return visible;\r
163                                 },\r
164                                 separateAfter: separateAfter\r
165                         }\r
166                 }\r
167 \r
168                 var MenuBarItemClass = function( title){\r
169                         var ELM_WRAPPER = ELM_ITEM_ORIGN.cloneNode( true),\r
170                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'div')[ 0],\r
171                                 ELM_SELECTION = ELM_WRAPPER.getElementsByTagName( 'ul')[ 0],\r
172                                 INDEX = ITEM_ARRAY.length,\r
173                                 SELECTION_CALLBACK_ARRAY = [],\r
174                                 numSelection = 0,\r
175                                 visible = false;\r
176                         ELM_TITLE.innerHTML = title;\r
177                         \r
178                         ELM_WRAPPER.style.left = ( itemW * INDEX) +'px';\r
179                         ELM_BAR.appendChild( ELM_WRAPPER);\r
180                         \r
181                         function onClick( e){\r
182                                 var that = this,\r
183                                         i = ( function(){\r
184                                                 var parent = that.parentNode,\r
185                                                         children = parent.getElementsByTagName( 'li'),\r
186                                                         l = children.length;\r
187                                                 for(var i=0; i<l; ++i){\r
188                                                         if( children[ i] === that) return i;\r
189                                                 }\r
190                                                 return -1;\r
191                                         })();\r
192                                 i !== -1 && this.className !== 'disabled' && SELECTION_CALLBACK_ARRAY[ i]( i);\r
193                                 e.stopPropagation();\r
194                                 return false;\r
195                         }\r
196                         return {\r
197                                 elm: ELM_WRAPPER,\r
198                                 onClick: onClick,\r
199                                 init: function(){\r
200                                         $( ELM_SELECTION).children( 'li').click( onClick);\r
201                                         delete this.init;\r
202                                 },\r
203                                 show: function(){\r
204                                         if( visible === true) return;\r
205                                         jqStage.append( ELM_WRAPPER);\r
206                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME +'-focus';\r
207                                         this.onShow && setTimeout( this.onShow, 0);\r
208                                         visible = true;\r
209                                 },\r
210                                 hide: function(){\r
211                                         if( visible === false) return;\r
212                                         ELM_BAR.appendChild( ELM_WRAPPER);\r
213                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME;\r
214                                         this.onHide && setTimeout( this.onHide, 0);\r
215                                         visible = false;\r
216                                 },\r
217                                 createSelection: function( title, shortcut, callback, visible, separateBefore, separateAfter){\r
218                                         var ret = MenubarSelectionClass.apply( {}, [ ELM_SELECTION, title, shortcut, visible, separateAfter]),\r
219                                                 before = SELECTION_CALLBACK_ARRAY.length > 0 ? SELECTION_CALLBACK_ARRAY[ SELECTION_CALLBACK_ARRAY.length -1] : null;\r
220                                         SELECTION_CALLBACK_ARRAY.push( callback);\r
221                                         if( before !== null && ( separateBefore === true || before.separateAfter === true)){\r
222                                                 ret.elm.style.borderTop = '1px solid #ccc';\r
223                                         }\r
224                                         return ret;\r
225                                 }\r
226                         }\r
227                 }\r
228 \r
229                 \r
230                 function createMenubarItem( title){\r
231                         var _item = new MenuBarItemClass( title);\r
232                         ITEM_ARRAY.push( _item);\r
233                         return _item;\r
234                 }\r
235                 return {\r
236                         init: function(){\r
237                                 jqStage = jqEditor;\r
238                                 jqBar = $( ELM_BAR).animate( { top: 0});\r
239 \r
240                                 var l = ITEM_ARRAY.length;\r
241                                 for( var i=0; i<l; ++i){\r
242                                         ITEM_ARRAY[ i].init();\r
243                                 }\r
244 \r
245                                 delete MENU_BAR_CONTROL.init;\r
246                         },\r
247                         open: function(){\r
248                                 MENU_BAR_CONTROL.init && MENU_BAR_CONTROL.init();\r
249                                 // ELM_BAR.style.top = ( -barH) +'px';\r
250                                 // anime\r
251                         },\r
252                         close: function(){\r
253                                 var l = ITEM_ARRAY.length;\r
254                                 for( var i=0; i<l; ++i){\r
255                                         ITEM_ARRAY[ i].hide();\r
256                                 }\r
257                         },\r
258                         h: barH,\r
259                         onMouseMove: function( _mouseX, _mouseY){\r
260                                 if( barH >= _mouseY){\r
261                                         return true;\r
262                                 }\r
263                                 var l = ITEM_ARRAY.length;\r
264                                 for( var i=0; i<l; ++i){\r
265                                         ITEM_ARRAY[ i].hide();\r
266                                 }\r
267                                 return false;\r
268                         },\r
269                         onMouseUp: function( _mouseX, _mouseY){\r
270                                 return false;\r
271                         },\r
272                         onMouseDown: function( _mouseX, _mouseY){\r
273                                 var l = ITEM_ARRAY.length;\r
274                                 if( barH < _mouseY || itemW * l < _mouseX) return false;\r
275                                 for( var i=0; i<l; ++i){\r
276                                         if( i * itemW <= _mouseX && _mouseX < ( i +1) * itemW){\r
277                                                 ITEM_ARRAY[ i].show();\r
278                                         } else {\r
279                                                 ITEM_ARRAY[ i].hide();\r
280                                         }\r
281                                 }\r
282                                 return true;\r
283                         },\r
284                         busy: function( _busy){\r
285                                 return false;\r
286                         },\r
287                         onWindowResize: function( _windowW, _windowH){\r
288                                 \r
289                         },\r
290                         QUIT: createMenubarItem( 'Quit'),\r
291                         EDIT: createMenubarItem( 'Edit'),\r
292                         WINDOW: createMenubarItem( 'Window'),\r
293                         HELP: pettanr.util.extend( createMenubarItem( 'Help'), {\r
294                                         createAjaxSelection: function( callback){\r
295                                                 var elmLoading = document.createElement( 'li'),\r
296                                                         that = this,\r
297                                                         elmSelection = this.elm.getElementsByTagName( 'ul')[ 0];\r
298                                                 elmSelection.appendChild( elmLoading);\r
299                                                 elmLoading.className = 'loading';\r
300                                                 elmLoading.style.height = '90px';                                                       \r
301 \r
302                                                 this.onShow = callback;\r
303                                                 callback = null;\r
304                                                 \r
305                                                 delete this.createAjaxSelection;\r
306                                                 return function(){\r
307                                                         elmSelection.removeChild( elmLoading);\r
308                                                         $( elmSelection).children( 'li').click( that.onClick);\r
309                                                         elmLoading = elmSelection = null;\r
310                                                         delete that.onShow;\r
311                                                         that = null;\r
312                                                 }\r
313                                         }\r
314                                 })\r
315                 }\r
316         })();\r
317 \r
318 \r
319 /* ----------------------------------------\r
320  * HISTORY\r
321  */\r
322         var HISTORY = ( function() {\r
323                 var     STACK_BACK = [],\r
324                         STACK_FORWARD = [],\r
325                         MENUBAR_BACK = MENU_BAR_CONTROL.EDIT.createSelection( 'back', 'ctrl + z', back, false),\r
326                         MENUBAR_FORWARD = MENU_BAR_CONTROL.EDIT.createSelection( 'forward', 'ctrl + y', forward, false, false, true),\r
327                         log;\r
328                         \r
329                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 90, false, true, back);       // ctrl + Z\r
330                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 90, true, true, forward);     // ctrl + shift + Z\r
331                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 89, false, true, forward); // ctrl + Y\r
332 \r
333                 function back(){\r
334                         /*\r
335                          * currentを控えてSTACK_FORWARD.push(current)\r
336                          * STACK_BACK.pop()を実行してcurrentに\r
337                          */\r
338                         if( STACK_BACK.length === 0) return;\r
339 \r
340                         var state = STACK_BACK.pop();\r
341                         state && state.fn( state.argBack);\r
342                         MENUBAR_BACK.visible( STACK_BACK.length !== 0);\r
343                         SAVE_CONTROL.panelUpdated( STACK_BACK.length !== 0);\r
344                         \r
345                         STACK_FORWARD.push( state);\r
346                         MENUBAR_FORWARD.visible( true);\r
347                 }\r
348                 function forward(){\r
349                         if( STACK_FORWARD.length === 0) return;\r
350                         \r
351                         var state = STACK_FORWARD.pop();\r
352                         state.fn( state.argForword);\r
353                         MENUBAR_FORWARD.visible( STACK_FORWARD.length !== 0);\r
354                         \r
355                         STACK_BACK.push( state);\r
356                         MENUBAR_BACK.visible( true);\r
357                         SAVE_CONTROL.panelUpdated( true);\r
358                 }\r
359                 function destroyStack( _stack, _destroy){\r
360                         _stack.fn = null;\r
361                         \r
362                         var     _argBack = _stack.argBack,\r
363                                 _argForword = _stack.argForword,\r
364                                 _value;\r
365                         if( typeof _argBack.length === 'number'){ // isArray\r
366                                 while( _argBack.length > 0){\r
367                                         _value = _argBack.shift();\r
368                                         _destroy === true && typeof _value.destroy === 'function' && _value.destroy();\r
369                                 }\r
370                         }\r
371                         if( typeof _argForword.length === 'number'){\r
372                                 while( _argForword.length > 0){\r
373                                         _value = _argForword.shift();\r
374                                         _destroy === true && typeof _value.destroy === 'function' && _value.destroy();\r
375                                 }                                               \r
376                         }                       \r
377                 }\r
378                 return {\r
379                         init: function(){\r
380                                 log = $( '#history-log');\r
381                                 delete HISTORY.init;\r
382                         },\r
383                         open: function(){\r
384                                 HISTORY.init && HISTORY.init();\r
385                         },\r
386                         close: function(){\r
387                                 MENUBAR_BACK.visible( false);\r
388                                 MENUBAR_FORWARD.visible( false);\r
389                         while( STACK_BACK.length > 0){\r
390                                         destroyStack( STACK_BACK.shift(), true);\r
391                                 }\r
392                         while( STACK_FORWARD.length > 0){\r
393                                         destroyStack( STACK_FORWARD.shift(), true);\r
394                                 }\r
395                         },\r
396                     saveState: function( _function, _argBack, _argForword, _destroy) {\r
397                         STACK_BACK.push( {\r
398                                 fn:                     _function,\r
399                                 argBack:        _argBack,\r
400                                         argForword:     _argForword,\r
401                                         destroy:        _destroy\r
402                         });\r
403                         MENUBAR_BACK.visible( true);\r
404                                 SAVE_CONTROL.panelUpdated( true);\r
405                                 \r
406                                 var _stack;\r
407                         while( STACK_FORWARD.length > 0){\r
408                                         _stack = STACK_FORWARD.shift();\r
409                                         destroyStack( _stack, _stack.destroy);\r
410                                 }\r
411                                 MENUBAR_FORWARD.visible( false);\r
412                     }           \r
413                 }\r
414         })();\r
415 \r
416 \r
417 /* ----------------------------------------\r
418  *     Save Control\r
419  */\r
420 \r
421         var OUTPUT_CONSOLE = ( function(){\r
422                 var jqWrap, jqOutputArea,\r
423                         ID = 'outputConsole';\r
424                 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);\r
425                 \r
426                 function close(){\r
427                         jqWrap.hide();\r
428                         jqOutputArea.val('');\r
429                 }\r
430                 function clickOK(){\r
431                         pettanr.overlay.hide();\r
432                         close();                        \r
433                 }\r
434                 return {\r
435                         init: function(){\r
436                                 this.jqWrap = jqWrap = $( '#output-console-wrapper').hide();\r
437                                 jqOutputArea = $( '#output-area');\r
438                                 delete OUTPUT_CONSOLE.init;\r
439                         },\r
440                         jqWrap: null,\r
441                         show: function( _text){\r
442                                 jqWrap.show();\r
443 \r
444                                 \r
445                                 pettanr.overlay.show( this);\r
446                                 jqWrap.css(\r
447                                         {\r
448                                                 left:   Math.floor( ( windowW -jqWrap.width()) /2),\r
449                                                 top:    Math.floor( ( windowH -jqWrap.height()) /2)\r
450                                         }\r
451                                 );                              \r
452                                 \r
453                                 jqOutputArea.val( _text).focus();\r
454                         },\r
455                         onWindowResize: function(){\r
456                                 jqWrap.css(\r
457                                         {\r
458                                                 left:   Math.floor( ( windowW -jqWrap.width()) /2),\r
459                                                 top:    Math.floor( ( windowH -jqWrap.height()) /2)\r
460                                         }\r
461                                 );\r
462                         },\r
463                         onClose: close,\r
464                         ID: 'textEditor'\r
465                 }\r
466         })();\r
467 \r
468         var SAVE_CONTROL = ( function(){\r
469                 var SAVE = MENU_BAR_CONTROL.QUIT.createSelection( 'save', 'ctrl + S', quit, false),\r
470                         SAVE_AND_QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'save & quit', null, quit, false, false, true),\r
471                         SAVE_AS_HTML = MENU_BAR_CONTROL.QUIT.createSelection( 'get as html', null, outputAsHtml, true, false, true),\r
472                         SAVE_AS_JSON_STRING = MENU_BAR_CONTROL.QUIT.createSelection( 'get JsonStr', null, outputAsJsonString, true, false, true),\r
473                         OUTPUT = MENU_BAR_CONTROL.QUIT.createSelection( 'output', null, onOutputClick, true, false, true),\r
474                         QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'quit', null, quit, true, true),\r
475                         updated = false;\r
476                 \r
477                 function quit(){\r
478                 }\r
479                 \r
480                 function onOutputClick(){\r
481                         // OUTPUT_CONSOLE.show();\r
482                 }\r
483                 \r
484                 function outputAsHtml(){\r
485                         OUTPUT_CONSOLE.show( COMIC_ELEMENT_CONTROL.getAsHTML( true, false));\r
486                 }\r
487                 function outputAsJsonString(){\r
488                         OUTPUT_CONSOLE.show( COMIC_ELEMENT_CONTROL.getAsJsonString());\r
489                 }\r
490                 return {\r
491                         quit: quit,\r
492                         panelUpdated: function( _updated){\r
493                                 if( _updated !== undefined && updated !== _updated){\r
494                                         SAVE.visible( !!_updated);\r
495                                         SAVE_AND_QUIT.visible( !!_updated);\r
496                                         updated = !!_updated;\r
497                                 }\r
498                                 return updated;\r
499                         },\r
500                         save: function(){\r
501                                 \r
502                         }\r
503                 }\r
504         })();\r
505 \r
506 /* ----------------------------------------\r
507  *     Text Editor (Overlay)\r
508  */\r
509         \r
510         var TEXT_EDITOR_CONTROL = ( function(){\r
511                 var jqWrap, jqTextarea, jqButton,\r
512                         textElement, onUpdateFunction,\r
513                         ID = 'textEditor';\r
514                 //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);\r
515                 \r
516                 function close(){\r
517                         jqWrap.hide();\r
518                         textElement = onUpdateFunction = null;          \r
519                 }\r
520                 function clickOK(){\r
521                         pettanr.overlay.hide();\r
522                         textElement && textElement.text( jqTextarea.val());\r
523                         onUpdateFunction && onUpdateFunction( textElement);\r
524                         close();                        \r
525                 }\r
526                 return {\r
527                         init: function(){\r
528                                 this.jqWrap = jqWrap = $( '#speach-editor-wrapper').hide();\r
529                                 jqTextarea = $( '#speach-editor').keydown( function( e){\r
530                                         if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){\r
531                                                 clickOK();\r
532                                                 e.preventDefault();\r
533                                         e.keyCode = 0;\r
534                                         e.cancelBubble = true;\r
535                                         e.returnValue = false;\r
536                                                 return false;\r
537                                         }\r
538                                 });\r
539                                 jqButton = $( '#speach-edit-complete-button').click( clickOK);\r
540                                 delete TEXT_EDITOR_CONTROL.init;\r
541                         },\r
542                         jqWrap: null,\r
543                         show: function( _textElement, _onUpdateFunction){\r
544                                 textElement = _textElement;\r
545                                 onUpdateFunction = _onUpdateFunction || null;\r
546                                 pettanr.overlay.show( this);\r
547                                 var h = _textElement.h;\r
548                                 jqWrap.show().css( {\r
549                                         left:                   _textElement.x +PANEL_CONTROL.x(),\r
550                                         top:                    _textElement.y +PANEL_CONTROL.y(),\r
551                                         width:                  _textElement.w,\r
552                                         height:                 h\r
553                                 });\r
554                                 jqTextarea.val( _textElement.text()).focus();\r
555                                 \r
556                                 /*\r
557                                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。\r
558                                  */\r
559                                 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( function(){\r
560                                         var rows = 0;\r
561                                         while( jqTextarea.height() < h){\r
562                                                 rows++;\r
563                                                 jqTextarea.attr( 'rows', rows);\r
564                                         }\r
565                                         rows > 1 && jqTextarea.attr( 'rows', rows -1);\r
566                                 }, 0);\r
567                         },\r
568                         onWindowResize: function(){\r
569                                 textElement && this.show( textElement);\r
570                         },\r
571                         onClose: close,\r
572                         ID: ID\r
573                 }\r
574         })();\r
575 \r
576 /* ----------------------------------------\r
577  *     Image Group Exproler (Overlay)\r
578  */\r
579         var IMAGE_GROUP_EXPROLER = ( function(){\r
580                 var ICON_ARRAY = [],\r
581                         WHEEL_DELTA = 64,\r
582                         containerW, containerH, wrapX,\r
583                         jqWrap, jqContainer, jqItemOrigin,\r
584                         itemW, itemH,\r
585                         jqName, jqButton, buttonW,\r
586                         //onUpdateFunction,\r
587                         _g_onUpdateFunction,\r
588                         winW,\r
589                         onEnterInterval = null;\r
590                 \r
591                 var BASE_PATH = pettanr.LOCAL === false ? 'http://pettan.heroku.com/resource_pictures/' : 'resource_pictures/',\r
592                         THUMB_PATH = BASE_PATH, // + 'thumbnail/',\r
593                         LIMIT_FILESIZE = 1024 * 10; // 10KB\r
594                 var IMAGE_DATA = {\r
595                                 pen001: [\r
596                                     {\r
597                                         "created_at": "2011-11-13T08:57:39Z", \r
598                                         "ext": "png", \r
599                                         "filesize": 9969, \r
600                                         "height": 463, \r
601                                         "id": 1, \r
602                                         "updated_at": "2011-11-13T08:57:39Z", \r
603                                         "width": 441\r
604                                     }, \r
605                                     {\r
606                                         "created_at": "2011-11-13T08:57:54Z", \r
607                                         "ext": "gif", \r
608                                         "filesize": 5418, \r
609                                         "height": 500, \r
610                                         "id": 2, \r
611                                         "updated_at": "2011-11-13T08:57:54Z", \r
612                                         "width": 500\r
613                                     }, \r
614                                     {\r
615                                         "created_at": "2011-11-13T08:58:06Z", \r
616                                         "ext": "gif", \r
617                                         "filesize": 8758, \r
618                                         "height": 464, \r
619                                         "id": 3, \r
620                                         "updated_at": "2011-11-13T08:58:06Z", \r
621                                         "width": 366\r
622                                     }, \r
623                                     {\r
624                                         "created_at": "2011-11-13T08:58:23Z", \r
625                                         "ext": "gif", \r
626                                         "filesize": 9383, \r
627                                         "height": 480, \r
628                                         "id": 4, \r
629                                         "updated_at": "2011-11-13T08:58:23Z", \r
630                                         "width": 392\r
631                                     }, \r
632                                     {\r
633                                         "created_at": "2011-11-13T08:58:33Z", \r
634                                         "ext": "gif", \r
635                                         "filesize": 11061, \r
636                                         "height": 500, \r
637                                         "id": 5, \r
638                                         "updated_at": "2011-11-13T08:58:33Z", \r
639                                         "width": 500\r
640                                     }, \r
641                                     {\r
642                                         "created_at": "2011-11-20T09:50:43Z", \r
643                                         "ext": "gif", \r
644                                         "filesize": 1131, \r
645                                         "height": 126, \r
646                                         "id": 6, \r
647                                         "updated_at": "2011-11-20T09:50:43Z", \r
648                                         "width": 259\r
649                                     }, \r
650                                     {\r
651                                         "created_at": "2011-11-20T09:50:55Z", \r
652                                         "ext": "gif", \r
653                                         "filesize": 1125, \r
654                                         "height": 126, \r
655                                         "id": 7, \r
656                                         "updated_at": "2011-11-20T09:50:55Z", \r
657                                         "width": 259\r
658                                     }, \r
659                                     {\r
660                                         "created_at": "2011-11-20T11:33:12Z", \r
661                                         "ext": "gif", \r
662                                         "filesize": 17919, \r
663                                         "height": 600, \r
664                                         "id": 8, \r
665                                         "updated_at": "2011-11-20T11:33:12Z", \r
666                                         "width": 800\r
667                                     },\r
668                                     {\r
669                                         "created_at": "2011-11-20T11:33:12Z", \r
670                                         "ext": "gif", \r
671                                         "filesize": 17919, \r
672                                         "height": 600, \r
673                                         "id": 9, \r
674                                         "updated_at": "2011-11-20T11:33:12Z", \r
675                                         "width": 800\r
676                                     },\r
677                                     {\r
678                                         "created_at": "2011-11-20T11:33:12Z", \r
679                                         "ext": "gif", \r
680                                         "filesize": 17919, \r
681                                         "height": 600, \r
682                                         "id": 10, \r
683                                         "updated_at": "2011-11-20T11:33:12Z", \r
684                                         "width": 800\r
685                                     },\r
686                                     {\r
687                                         "created_at": "2011-11-20T11:33:12Z", \r
688                                         "ext": "gif", \r
689                                         "filesize": 17919, \r
690                                         "height": 600, \r
691                                         "id": 11, \r
692                                         "updated_at": "2011-11-20T11:33:12Z", \r
693                                         "width": 800\r
694                                     },\r
695                                     {\r
696                                         "created_at": "2011-11-22T09:17:20Z", \r
697                                         "ext": "gif", \r
698                                         "filesize": 9055, \r
699                                         "height": 473, \r
700                                         "id": 12, \r
701                                         "updated_at": "2011-11-22T09:17:20Z", \r
702                                         "width": 405\r
703                                     }, \r
704                                     {\r
705                                         "created_at": "2011-11-22T10:11:07Z", \r
706                                         "ext": "gif", \r
707                                         "filesize": 8758, \r
708                                         "height": 464, \r
709                                         "id": 13, \r
710                                         "updated_at": "2011-11-22T10:11:07Z", \r
711                                         "width": 366\r
712                                     }, \r
713                                     {\r
714                                         "created_at": "2011-11-24T09:05:12Z", \r
715                                         "ext": "gif", \r
716                                         "filesize": 6431, \r
717                                         "height": 386, \r
718                                         "id": 16, \r
719                                         "updated_at": "2011-11-24T09:05:12Z", \r
720                                         "width": 453\r
721                                     }, \r
722                                     {\r
723                                         "created_at": "2011-11-26T04:52:12Z",\r
724                                         "ext": "gif", \r
725                                         "filesize": 6421, \r
726                                         "height": 426, \r
727                                         "id": 17, \r
728                                         "updated_at": "2011-11-26T04:52:12Z", \r
729                                         "width": 306\r
730                                     }, \r
731                                     {\r
732                                         "created_at": "2011-11-26T04:52:12Z",\r
733                                         "ext": "gif", \r
734                                         "filesize": 6421, \r
735                                         "height": 426, \r
736                                         "id": 18, \r
737                                         "updated_at": "2011-11-26T04:52:12Z", \r
738                                         "width": 306\r
739                                     }, \r
740                                     {\r
741                                         "created_at": "2011-11-26T04:52:12Z",\r
742                                         "ext": "gif", \r
743                                         "filesize": 6421, \r
744                                         "height": 426, \r
745                                         "id": 19, \r
746                                         "updated_at": "2011-11-26T04:52:12Z", \r
747                                         "width": 306\r
748                                     }, \r
749                                     {\r
750                                         "created_at": "2011-11-26T04:52:12Z",\r
751                                         "ext": "gif", \r
752                                         "filesize": 6421, \r
753                                         "height": 426, \r
754                                         "id": 20, \r
755                                         "updated_at": "2011-11-26T04:52:12Z", \r
756                                         "width": 306\r
757                                     }, \r
758                                     {\r
759                                         "created_at": "2011-11-26T04:52:12Z",\r
760                                         "ext": "gif", \r
761                                         "filesize": 6421, \r
762                                         "height": 426, \r
763                                         "id": 21, \r
764                                         "updated_at": "2011-11-26T04:52:12Z",\r
765                                         "width": 306\r
766                                     }\r
767                                 ]\r
768                         }\r
769                 \r
770                 var ImageGroupIconClass = function( INDEX, data){\r
771                         var JQ_ICON_WRAP = jqItemOrigin.clone( true),\r
772                                 SRC = [ BASE_PATH, data.id, '.', data.ext].join( ''),\r
773                                 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext].join( '') : null,\r
774                                 reversibleImage = null,\r
775                                 onEnterFlag = false,\r
776                                 imgW, imgH;\r
777                         JQ_ICON_WRAP.children( 'div').eq( 0).html( data.filesize + 'bytes');\r
778                         jqContainer.append( JQ_ICON_WRAP.css( { left: INDEX * itemW}));\r
779                         \r
780                         function onImageLoad( url, _imgW, _imgH){\r
781                                 if( reversibleImage === null) {\r
782                                         alert( url);\r
783                                         return;\r
784                                 }\r
785                                 imgW = _imgW || data.width || 64;\r
786                                 imgH = _imgH || data.height || 64;\r
787                                 JQ_ICON_WRAP.children( 'div').eq( 1).html( imgW +'x' +imgH);\r
788                                 var zoom = 128 /( imgW > imgH ? imgW : imgH),\r
789                                         h = Math.floor( imgH *zoom),\r
790                                         w = Math.floor( imgW *zoom);\r
791                                 reversibleImage.elm.style.width = w +'px';\r
792                                 reversibleImage.elm.style.height = h +'px';\r
793                                 reversibleImage.elm.style.margin = Math.floor( itemH /2 -h /2)+'px 0 0';\r
794                                 reversibleImage.resize( w, h);\r
795                                 JQ_ICON_WRAP.click( onClick);\r
796                         }\r
797                         \r
798                         function onClick( e){\r
799                                 pettanr.overlay.hide();\r
800                                 if( _g_onUpdateFunction) {\r
801                                         if( LOW_SRC === null){\r
802                                                 window[ _g_onUpdateFunction]( SRC, imgW, imgH);\r
803                                                 window[ _g_onUpdateFunction] = null;\r
804                                         } else {\r
805                                                 var _onLoad = pettanr.util.createGlobalFunc( [\r
806                                                                 'function( url, w, h){',\r
807                                                                         'window["', _g_onUpdateFunction, '"]( url, w || ', data.width,',  h || ', data.height,');',\r
808                                                                         'window["', _g_onUpdateFunction, '"] = null;',\r
809                                                                 '}'\r
810                                                         ].join( '')),\r
811                                                         _onError = pettanr.util.createGlobalFunc( [\r
812                                                                 'function( url){',\r
813                                                                         'window["', _g_onUpdateFunction, '"]( url, ', data.width || 64 ,', ', data.height || 64,');',\r
814                                                                         'window["', _g_onUpdateFunction, '"] = null;',\r
815                                                                 '}'\r
816                                                         ].join( ''));\r
817                                                 pettanr.util.loadImage( SRC, window[ _onLoad], window[ _onError]);\r
818                                                 window[ _onLoad] = window[ _onError] = undefined;\r
819                                                 /*\r
820                                                 ( function( onUpdate){\r
821                                                         pettanr.util.loadImage( SRC,\r
822                                                                 function( _abspath, imgW, imgH){\r
823                                                                         onUpdate( SRC, imgW, imgH);\r
824                                                                         onUpdate = null;\r
825                                                                 },\r
826                                                                 function( _abspath){\r
827                                                                         onUpdate( SRC, data.width || 64, data.height || 64);\r
828                                                                         onUpdate = null;\r
829                                                                 }\r
830                                                         );                                                                              \r
831                                                 })( onUpdateFunction);*/ // close()で値が消えるので、クロージャに保持\r
832                                         }\r
833                                 }\r
834                                 close();\r
835                         }\r
836                         \r
837                         return {\r
838                                 onEnter: function(){\r
839                                         if( onEnterFlag === true) return;\r
840                                         reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad);\r
841                                         JQ_ICON_WRAP.children( 'img').replaceWith( reversibleImage.elm);\r
842                                         onEnterFlag = true;                                             \r
843                                 },\r
844                                 destroy: function(){\r
845                                         reversibleImage && reversibleImage.destroy();\r
846                                         JQ_ICON_WRAP.remove();\r
847                                         reversibleImage = JQ_ICON_WRAP = null;\r
848                                         delete this.destroy;\r
849                                 }\r
850                         }\r
851                 }\r
852                 \r
853                 function close(){\r
854                         jqContainer.stop().animate( {\r
855                                         height: 0,\r
856                                         top:    Math.floor( windowH /2)\r
857                                 }, function(){\r
858                                         jqWrap.hide()\r
859                                 });\r
860                         while( ICON_ARRAY.length > 0){\r
861                                 ICON_ARRAY.shift().destroy();\r
862                         }\r
863                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
864                         onEnterInterval = null;// onUpdateFunction = \r
865                 }\r
866                 function onEnterShowImage(){\r
867                         var l = ICON_ARRAY.length,\r
868                                 _start = -wrapX /itemW -1,\r
869                                 _end = _start + winW /itemW +1;\r
870                         for( var i=0; i<l; ++i){\r
871                                 _start < i && i < _end && ICON_ARRAY[ i].onEnter();\r
872                         }\r
873                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
874                         onEnterInterval = null;\r
875                 }\r
876                 function clickOK(){\r
877                         pettanr.overlay.hide();\r
878                         // onUpdateFunction && onUpdateFunction( textElement);\r
879                         close();\r
880                 }\r
881                 function onMouseWheel( e, delta){\r
882                         if( winW < containerW){\r
883                                 wrapX += delta *WHEEL_DELTA;\r
884                                 wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;\r
885                                 jqContainer.css( { left: wrapX});\r
886                                 \r
887                                 onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
888                                 onEnterInterval = window.setTimeout( onEnterShowImage, 500);\r
889                         }\r
890                         //e.stopPropagation();\r
891                         return false;                   \r
892                 }\r
893                 return {\r
894                         init: function(){\r
895                                 this.jqWrap = jqWrap = $( '#image-gruop-wrapper').hide();\r
896                                 jqContainer = $( '#image-icon-container').mousewheel( onMouseWheel);\r
897                                 containerH = pettanr.util.getElementSize( jqContainer.get( 0)).height;\r
898                                 jqItemOrigin = $( $( '#imageGruopItemTemplete').remove().html());\r
899                                 var itemSize = pettanr.util.getElementSize( jqItemOrigin.get( 0));\r
900                                 itemW = itemSize.width;\r
901                                 itemH = itemSize.height;\r
902                                 jqName = $( '#gruop-name-display');\r
903                                 jqButton = $( '#image-gruop-button').click( clickOK);\r
904                                 buttonW = pettanr.util.getElementSize( jqButton.get( 0)).width;\r
905                                 \r
906                                 delete IMAGE_GROUP_EXPROLER.init;\r
907                         },\r
908                         jqWrap: null,\r
909                         show: function( _onUpdateFunction){\r
910                                 //onUpdateFunction = _onUpdateFunction;\r
911                                 if( _onUpdateFunction){\r
912                                         _g_onUpdateFunction = pettanr.util.createGlobalFunction( _onUpdateFunction);\r
913                                 } else {\r
914                                         _g_onUpdateFunction = null;\r
915                                 }\r
916                                 pettanr.overlay.show( this);\r
917                                 \r
918                                 var CURRENT_GROUP_ARRAY = IMAGE_DATA[ 'pen001'] || [],\r
919                                         l = CURRENT_GROUP_ARRAY.length;\r
920                                 for( var i=0; i<l; ++i){\r
921                                         ICON_ARRAY.push( ImageGroupIconClass.apply( {}, [ i, CURRENT_GROUP_ARRAY[ i]]));\r
922                                 }\r
923                                 wrapX = 0;\r
924                                 containerW = l * itemW;\r
925                                 \r
926                                 winW = windowW;\r
927                                 var w = winW > containerW ? winW : containerW,\r
928                                         h = windowH > containerH ? containerH : windowH;\r
929                                 \r
930                                 jqWrap.show();\r
931                                 jqContainer.css( {\r
932                                         width:          w,\r
933                                         height:         0,\r
934                                         left:           0,\r
935                                         top:            Math.floor( windowH /2)\r
936                                 }).stop().animate( {\r
937                                         height:         h,\r
938                                         top:            Math.floor( windowH /2 -h /2)\r
939                                 });\r
940                                 \r
941                                 jqButton.css( {\r
942                                         left:           Math.floor( winW /2 -buttonW /2),\r
943                                         top:            Math.floor( windowH /2 +containerH /2 +10)\r
944                                 });\r
945                                 \r
946                                 onEnterShowImage();\r
947                         },\r
948                         onWindowResize: function( _windowW, _windowH){\r
949                                 var w = _windowW > containerW ? _windowW : containerW,\r
950                                         h = _windowH > containerH ? containerH : _windowH,\r
951                                         offsetW = Math.floor( _windowW /2 -winW /2);\r
952                                 winW = _windowW;\r
953                                 if( offsetW <= 0){ // smaller\r
954                                         jqContainer.css( {\r
955                                                 left:                           offsetW,\r
956                                                 width:                          w\r
957                                         }).animate( {\r
958                                                 left:                           0,\r
959                                                 top:                            Math.floor( _windowH /2 -h /2)\r
960                                         });                                     \r
961                                 } else {\r
962                                         jqContainer.css( { // bigger\r
963                                                 left:                           0,\r
964                                                 width:                          w,\r
965                                                 borderLeftWidth:        offsetW\r
966                                         }).animate( {\r
967                                                 top:                            Math.floor( _windowH /2 -h /2),\r
968                                                 borderLeftWidth:        0\r
969                                         });\r
970                                 }\r
971                                 jqButton.css( {\r
972                                         left:           Math.floor( _windowW /2 -buttonW /2),\r
973                                         top:            Math.floor( _windowH /2 +containerH /2 +10)\r
974                                 });\r
975                                 onEnterShowImage();\r
976                         },\r
977                         onClose: close,\r
978                         ID: 'imageGroupExproler'\r
979                 }\r
980         })();\r
981 \r
982 /* ----------------------------------------\r
983  * WINDOWS_CONTROL\r
984  */     \r
985         var WINDOWS_CONTROL = ( function(){\r
986                 /*\r
987                  *  表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。\r
988                  */\r
989                 var DEFAULT_MIN_WINDOW_WIDTH = 200,\r
990                         DEFAULT_MIN_WINDOW_HEIGHT = 200,\r
991                         WINDOW_ARRAY = [],\r
992                         WINDOW_BODY_BODER_SIZE = 1,\r
993                         jqContainer,\r
994                         currentWindow,\r
995                         currentWindowIndex = -1,\r
996                         log;\r
997 \r
998                 var jqWindowOrigin,\r
999                         closeButtonWidth;\r
1000                 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH){\r
1001                         var MOUSE_CURSOR = updateMouseCursor,\r
1002                                 MENUBAR_SELWCTION = MENU_BAR_CONTROL.WINDOW.createSelection( \r
1003                                         ( visible !== true ? 'show ' : 'hide ') +title,\r
1004                                         null, onMenuClick, true\r
1005                                 ),\r
1006                                 jqStage,\r
1007                                 jqWrapper, jqHeader, jqFooter = null,\r
1008                                 elmBody, elmBodyStyle,\r
1009                                 startX, startY, startW, startH,\r
1010                                 offsetX, offsetY,\r
1011                                 headerH, bodyH, footerH = 0,\r
1012                                 isDragging = false,\r
1013                                 isResizing = false,\r
1014                                 bodyIsTachable = false,\r
1015                                 instance;\r
1016 \r
1017                         function onMenuClick(){\r
1018                                 visible === true ? instance.close() : instance.open();\r
1019                         }\r
1020                         function update( _x, _y, _w, _h){\r
1021                                 _x = _x !== undefined ? _x : x;\r
1022                                 _y = _y !== undefined ? _y : y;\r
1023                                 _y = _y > MENU_BAR_CONTROL.h ? _y : MENU_BAR_CONTROL.h;\r
1024                                 _w = _w !== undefined ? _w : w;\r
1025                                 _h = _h !== undefined ? _h : h;\r
1026                                 jqWrapper.css( {\r
1027                                         left:           _x,\r
1028                                         top:            _y,\r
1029                                         width:          _w,\r
1030                                         height:         _h\r
1031                                 });\r
1032                                 bodyH = _h -headerH -footerH;\r
1033                                 elmBodyStyle.height = bodyH +'px';\r
1034                                 ( w !== _w || h !== _h) && instance.onResize && instance.onResize( _w, bodyH);\r
1035                                 x = _x;\r
1036                                 y = _y;\r
1037                                 w = _w;\r
1038                                 h = _h;\r
1039                         }\r
1040                         function bodyBackOrForward( isBack){\r
1041                                 if( !instance) return;\r
1042                                 if( bodyIsTachable === !isBack) return;\r
1043                                 elmBodyStyle.position = isBack === true ? 'relative' : 'absolute';\r
1044                                 elmBodyStyle.left =             isBack === true ? 0  : x +'px';\r
1045                                 elmBodyStyle.top =              isBack === true ? 0  : y +headerH +'px';\r
1046                                 elmBodyStyle.width =    isBack === true ? '' : ( w -WINDOW_BODY_BODER_SIZE *2) +'px';\r
1047                                 bodyIsTachable === isBack && isBack === true ? jqHeader.after( elmBody) : jqStage.append( elmBody);\r
1048                                 bodyIsTachable = !isBack;\r
1049                         }\r
1050                         function onWindowResize( e){\r
1051                                 bodyBackOrForward( true);\r
1052                                 isResizing = true;\r
1053                                 startX = x;\r
1054                                 startY = y;\r
1055                                 startW = w;\r
1056                                 startH = h;\r
1057                                 offsetX = e.pageX;\r
1058                                 offsetY = e.pageY;\r
1059                                 MOUSE_CURSOR( 'nw-resize');\r
1060                                 e.stopPropagation();\r
1061                                 return false;\r
1062                         }\r
1063                         return {\r
1064                                 init: function( jqContainer){\r
1065                                         /*\r
1066                                          * setTimeout で呼ばれるグローバルメソッド内では、this でなく instance を使う.\r
1067                                          */\r
1068                                         instance = this;\r
1069                                         \r
1070                                         jqWindowOrigin = jqWindowOrigin || ( function(){\r
1071                                                 return $( $( '#windowTemplete').remove().html());\r
1072                                         })();\r
1073                                         closeButtonWidth = closeButtonWidth || ( function(){\r
1074                                                 return pettanr.util.getElementSize( jqWindowOrigin.clone( true).find( '.window-close-button').get( 0)).width;\r
1075                                         })();\r
1076                                         \r
1077                                         jqStage = jqEditor;\r
1078                                         this.$ = jqWrapper = jqWindowOrigin.clone( true);\r
1079                                         jqHeader = jqWrapper.children( '.window-header').eq( 0).html( title);\r
1080                                         headerH = pettanr.util.getElementSize( jqHeader.get( 0)).height;\r
1081                                         elmBody = jqWrapper.children( '.window-body').get( 0);\r
1082                                         elmBodyStyle = elmBody.style;\r
1083                                         \r
1084                                         if( bodyTempleteID) {\r
1085                                                 jqWrapper.find( '.window-body-insert-position').replaceWith( $( $( '#' +bodyTempleteID).remove().html()));\r
1086                                         } else {\r
1087                                                 jqWrapper.find( '.window-body-insert-position').remove();\r
1088                                         }\r
1089                                         CLOSE_BUTTON_ENABLED !== true && jqWrapper.find( '.window-close-button').remove();\r
1090                                         \r
1091                                         this.onInit && this.onInit();\r
1092                                         delete this.init;\r
1093                                 },\r
1094                                 x: function(){ return x;},\r
1095                                 y: function(){ return y;},\r
1096                                 w: function(){ return w;},\r
1097                                 h: function(){ return h;},\r
1098                                 $: null,\r
1099                                 title: function( _title){\r
1100                                         typeof _title === 'string' && jqHeader.html( _title);\r
1101                                         title = typeof _title === 'string' ? _title : title;\r
1102                                         return title;\r
1103                                 },\r
1104                                 visible: visible,\r
1105                                 firstOpen: function(){\r
1106                                         if( RESIZE_BUTTON_ENABLED === true){\r
1107                                                 footerH = pettanr.util.getElementSize( jqWrapper.find( '.window-footer').get( 0)).height;\r
1108                                                 //jqWrapper.find( '.window-resize-button').eq( 0).mousedown( onWindowResize);\r
1109                                         } else {\r
1110                                                 jqWrapper.find( '.window-footer').remove();\r
1111                                         }\r
1112                                         this.onFirstOpen && this.onFirstOpen( w, h -headerH -footerH);\r
1113                                         \r
1114                                         update( x, y, w, h);\r
1115                                         \r
1116                                         delete this.firstOpen;\r
1117                                 },\r
1118                                 open: function(){\r
1119                                         if( visible === true) return;\r
1120                                         instance.visible = visible = true;\r
1121                                         openWindow( instance);\r
1122                                         MENUBAR_SELWCTION.title( 'hide ' +title);\r
1123                                         \r
1124                                         for( var i=0, l = WINDOW_ARRAY.length; i<l; ++i){\r
1125                                                 if( WINDOW_ARRAY[ i] === instance){\r
1126                                                         WINDOW_ARRAY.splice( i, 1);\r
1127                                                         WINDOW_ARRAY.unshift( instance);\r
1128                                                         currentWindow = null;\r
1129                                                         currentWindowIndex = -1;\r
1130                                                 }\r
1131                                         }\r
1132                                 },\r
1133                                 onFadeIn: function(){\r
1134                                         instance.firstOpen && instance.firstOpen();\r
1135                                         instance.onOpen && setTimeout( callOnOpen, 0);\r
1136                                         function callOnOpen(){\r
1137                                                 instance.onOpen( w, bodyH);\r
1138                                         }\r
1139                                 },\r
1140                                 onFadeOut: function(){\r
1141                                         var elmWrapper = jqWrapper.get(0);\r
1142                                         elmWrapper.parentNode.removeChild( elmWrapper);\r
1143                                         instance.onClose && setTimeout( instance.onClose, 0);\r
1144                                 },\r
1145                                 close: function(){\r
1146                                         if( visible === false) return;\r
1147                                         instance.visible = visible = false;\r
1148                                         jqWrapper.fadeOut( instance.onFadeOut);\r
1149                                         MENUBAR_SELWCTION.title( 'show ' +title);\r
1150                                 },\r
1151                                 bodyBackOrForward: bodyBackOrForward,\r
1152                                 onMouseDown: function( _mouseX, _mouseY){\r
1153                                         if( RESIZE_BUTTON_ENABLED === true && x +w -20 <= _mouseX && _mouseX < x +w && y +headerH +bodyH < _mouseY && _mouseY <= y +h){\r
1154                                                 bodyBackOrForward( true);\r
1155                                                 isResizing = true;\r
1156                                                 startX = x;\r
1157                                                 startY = y;\r
1158                                                 startW = w;\r
1159                                                 startH = h;\r
1160                                                 offsetX = _mouseX;\r
1161                                                 offsetY = _mouseY;\r
1162                                                 MOUSE_CURSOR( 'nw-resize');\r
1163                                                 return;\r
1164                                         }\r
1165                                         \r
1166                                         if( x > _mouseX || y > _mouseY || x +w < _mouseX || y +headerH < _mouseY ) return;\r
1167                                         if( CLOSE_BUTTON_ENABLED === true && x +w -closeButtonWidth < _mouseX){\r
1168                                                 instance.close();\r
1169                                                 return;\r
1170                                         }\r
1171                                         \r
1172                                         isDragging = true;\r
1173                                         MOUSE_CURSOR( 'move');                          \r
1174                                         startX = x;\r
1175                                         startY = y;\r
1176                                         startW = w;\r
1177                                         startH = h;\r
1178                                         offsetX = _mouseX;\r
1179                                         offsetY = _mouseY;\r
1180                                 },\r
1181                                 onMouseUp: function( _mouseX, _mouseY){\r
1182                                         isDragging = isResizing = false;\r
1183                                         MOUSE_CURSOR( '');\r
1184                                 },\r
1185                                 onMouseMove: function( _mouseX, _mouseY){\r
1186                                         var _updateX = _mouseX -offsetX,\r
1187                                                 _updateY = _mouseY -offsetY;\r
1188                                         \r
1189                                         if( isResizing === true){\r
1190                                                 var _w = startW +_updateX,\r
1191                                                         _h = startH +_updateY;\r
1192                                                 update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h);\r
1193                                                 return;\r
1194                                         } else\r
1195                                         if( isDragging === true) {\r
1196                                                 update( startX +_updateX, startY +_updateY);\r
1197                                                 return;\r
1198                                         } else\r
1199                                         if( x > _mouseX || x +w < _mouseX ) return;\r
1200         \r
1201                                         ( y <= _mouseY && y +headerH >= _mouseY ) ?\r
1202                                                 MOUSE_CURSOR( 'pointer') :      // hit to header\r
1203                                                 MOUSE_CURSOR( '');\r
1204                                         bodyBackOrForward( y +headerH > _mouseY || y +headerH +bodyH < _mouseY);\r
1205                                 },\r
1206                                 onMouseOut: function( _mouseX, _mouseY){\r
1207                                         bodyIsTachable === true && bodyBackOrForward( true);\r
1208                                         isDragging = false;\r
1209                                         MOUSE_CURSOR( '');\r
1210                                 },\r
1211                                 busy: function(){\r
1212                                         return isDragging === true || isResizing === true;\r
1213                                 },\r
1214                                 bodyHeight: function(){\r
1215                                         return  bodyH;\r
1216                                 }\r
1217                         }\r
1218                 };\r
1219                 \r
1220                 function getCurrentWindow( _mouseX, _mouseY){\r
1221                         if( currentWindow && currentWindow.busy() === true) return currentWindowIndex;\r
1222                         var l = WINDOW_ARRAY.length,\r
1223                                 _currentWindow = null,\r
1224                                 _win, _x, _y;\r
1225                         currentWindowIndex = -1;\r
1226                         for( var i=0; i<l; i++){\r
1227                                 _win = WINDOW_ARRAY[ i];\r
1228                                 if( _win.visible !== true) continue;\r
1229                                 _x = _win.x();\r
1230                                 _y = _win.y();\r
1231                                 if( _x <= _mouseX && _y <= _mouseY && _x +_win.w() >= _mouseX && _y +_win.h() >= _mouseY){\r
1232                                         _currentWindow = _win;\r
1233                                         currentWindowIndex = i;\r
1234                                         break;\r
1235                                 }\r
1236                         }\r
1237                         currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY);\r
1238                         currentWindow = _currentWindow;\r
1239                         return currentWindowIndex;\r
1240                 }\r
1241                 function openWindow( _window){\r
1242                         if( _window.visible !== true) return;\r
1243                         var _jqWindow = _window.$;\r
1244                         jqContainer.append( _jqWindow);// appendした後に fadeIn() しないと ie で filterが適用されない.\r
1245                         _jqWindow.fadeIn( _window.onFadeIn);\r
1246                         return;\r
1247                 }\r
1248                 \r
1249                 return {\r
1250                         init: function(){\r
1251                                 jqContainer = $( '#window-container');\r
1252                                 \r
1253                                 var l = WINDOW_ARRAY.length,\r
1254                                         _window;\r
1255                                 for( var i=l-1; i >= 0; --i){\r
1256                                         _window = WINDOW_ARRAY[ i];\r
1257                                         _window.init && _window.init( jqContainer);\r
1258                                         _window.visible === true && openWindow( _window);\r
1259                                 }\r
1260                                 log = $( '#window-log');\r
1261                                 \r
1262                                 delete WINDOWS_CONTROL.init;\r
1263                         },\r
1264                         onMouseMove: function( _mouseX, _mouseY){\r
1265                                 var _index = getCurrentWindow( _mouseX, _mouseY);\r
1266                                 if( _index === 0){\r
1267                                         currentWindow.onMouseMove( _mouseX, _mouseY);\r
1268                                         return true;\r
1269                                 } else\r
1270                                 if( _index !== -1){ // 先頭のクリックでない場合\r
1271                                 // Array を前に\r
1272                                         WINDOW_ARRAY.splice( currentWindowIndex, 1);\r
1273                                         WINDOW_ARRAY.unshift( currentWindow);\r
1274                                 // Domを最後に\r
1275                                         jqContainer.append( currentWindow.$);\r
1276                                         currentWindowIndex = 0;\r
1277                                         return true;\r
1278                                 }\r
1279                                 return false;\r
1280                         },\r
1281                         onMouseUp: function( _mouseX, _mouseY){\r
1282                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
1283                                         currentWindow.onMouseUp( _mouseX, _mouseY);\r
1284                                         return true;\r
1285                                 }\r
1286                                 return false;\r
1287                         },\r
1288                         onMouseDown: function( _mouseX, _mouseY){\r
1289                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
1290                                         currentWindow.onMouseDown( _mouseX, _mouseY);\r
1291                                         return true;\r
1292                                 }\r
1293                                 return false;\r
1294                         },\r
1295                         busy: function(){\r
1296                                 return currentWindow !== null;\r
1297                         },\r
1298                         onWindowResize: function( _windowW, _windowH){\r
1299                                 /*\r
1300                                  * 画面外に出るwindowの移動\r
1301                                  */\r
1302                         },\r
1303                         createWindow: function( scope, EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH){\r
1304                                 opt_visible = opt_visible !== false;\r
1305                                 opt_closeButtonEnabled = opt_closeButtonEnabled === true;\r
1306                                 opt_resizeButtonEnabled = opt_resizeButtonEnabled === true;\r
1307                                 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH) ? w : DEFAULT_MIN_WINDOW_WIDTH;\r
1308                                 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT) ? h : DEFAULT_MIN_WINDOW_HEIGHT;\r
1309                                 \r
1310                                 var _window = pettanr.util.extend(\r
1311                                         WindowClass.apply( scope, [ bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH]),\r
1312                                         EXTENDS\r
1313                                 );\r
1314                                 WINDOW_ARRAY.unshift( _window);\r
1315                                 WINDOWS_CONTROL.init === undefined && _window.init( jqContainer);\r
1316                                 WINDOWS_CONTROL.init === undefined && openWindow( _window);\r
1317                                 return _window;\r
1318                         }\r
1319                 }\r
1320         })();\r
1321 \r
1322 /* ----------------------------------------\r
1323  * TOOL_BOX_WINDOW\r
1324  */\r
1325         var TOOL_BOX_WINDOW = ( function(){\r
1326                 var addImageButton, addTextButton, editBgButton, switchGridButton, popupHelpButton, postButton,\r
1327                         instance;\r
1328                         \r
1329                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 73, false, true, addImage);\r
1330                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Image', 'ctrl + I', addImage, true, true, false);\r
1331                 \r
1332                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 84, false, true, addText);\r
1333                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Text', 'ctrl + T', addText, true, false, true);\r
1334 \r
1335                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 71, false, true, switchGrid);\r
1336                 MENU_BAR_CONTROL.EDIT.createSelection( 'show Grid', 'ctrl + G', switchGrid, true, true, true);\r
1337 \r
1338                 function addImage( e){\r
1339                         setTimeout( COMIC_ELEMENT_CONTROL.createImageElement, 0);\r
1340                         e && e.preventDefault();\r
1341                         return false;\r
1342                 }\r
1343                 function addText( e){\r
1344                         setTimeout( COMIC_ELEMENT_CONTROL.createTextElement, 0);\r
1345                         e && e.preventDefault();\r
1346                         return false;\r
1347                 }\r
1348                 function switchGrid( e){\r
1349                         setTimeout( GRID_CONTROL.update, 0);\r
1350                         e && e.preventDefault();\r
1351                         return false;\r
1352                 }\r
1353                 function popupHelp( e){\r
1354                         instance.bodyBackOrForward( true);\r
1355                         setTimeout( HELP_DOCUMENTS_WINDOW.open, 0);\r
1356                         e && e.preventDefault();\r
1357                         return false;\r
1358                 }\r
1359                 function editBG( e){\r
1360                         instance.bodyBackOrForward( true);\r
1361                         setTimeout( INFOMATION_WINDOW.open, 0); \r
1362                         e && e.preventDefault();\r
1363                         return false;\r
1364                 }\r
1365                 \r
1366                 return WINDOWS_CONTROL.createWindow(\r
1367                         this,\r
1368                         {\r
1369                                 onInit: function(){\r
1370                                         instance = this;\r
1371                                         delete this.onInit;\r
1372                                 },\r
1373                                 onFirstOpen: function(){\r
1374                                         addImageButton = $( '#toolbox-add-image-button').click( addImage);\r
1375                                         addTextButton = $( '#toolbox-add-text-button').click( addText);\r
1376                                         editBgButton = $( '#toolbox-edit-bg-button').click( editBG);\r
1377                                         switchGridButton = $( '#toolbox-switch-grid').click( switchGrid);\r
1378                                         popupHelpButton = $( '#toolbox-popup-help-button').click( popupHelp);\r
1379                                         \r
1380                                         postButton = $( '#toolbox-post-button');\r
1381                                         \r
1382                                         delete this.onFirstOpen;\r
1383                                 }\r
1384                         },\r
1385                         'toolbox-window', 'Tool box', 0, 215, 110, 290, true\r
1386                 );\r
1387         })();\r
1388         \r
1389         \r
1390 /* ----------------------------------------\r
1391  * IMAGE_EXPROLER\r
1392  */\r
1393         var IMAGE_EXPLORER_WINDOW = ( function(){\r
1394                 var instance, finder;\r
1395                 \r
1396                 return WINDOWS_CONTROL.createWindow(\r
1397                         this,\r
1398                         {\r
1399                                 onInit: function(){\r
1400                                         instance = this;\r
1401                                         delete this.onInit;\r
1402                                 },\r
1403                                 onFirstOpen: function( _w, _h){\r
1404                                         finder = pettanr.finder.createFinder( document.getElementById( 'image-exproler-container'), pettanr.file.TREE_TYPE_IS_IMAGE);\r
1405                                         delete this.onFirstOpen;\r
1406                                 },\r
1407                                 onOpen: function( _w, _h){\r
1408                                         finder.onOpen( _w, _h);\r
1409                                 },\r
1410                                 onResize: function( _w, _h){\r
1411                                         finder.onWindowResize( _w, _h);\r
1412                                 }\r
1413                         },\r
1414                         'image-exproler', 'Album', 0, 215, 400, 350, false, true, true, 300, 300\r
1415                 );\r
1416         })();\r
1417         \r
1418         \r
1419 /* ----------------------------------------\r
1420  * INFOMATION_WINDOW\r
1421  */                     \r
1422         var INFOMATION_WINDOW = ( function(){\r
1423                 var FADE_EFFECT_ENABLED = true, //pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 8,\r
1424                         FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show',\r
1425                         FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide',\r
1426                         backgroundInfomationElm,\r
1427                         jqComicElementInformation,\r
1428                         inputX, inputY, inputZ, inputA, inputW, inputH, inputAspectRatio,\r
1429                         inputPercentW, inputPercentH,\r
1430                         currentComicElement = null,\r
1431                         currentElementType = -1,\r
1432                         currentLock = false;\r
1433 \r
1434                 return WINDOWS_CONTROL.createWindow(\r
1435                         this,\r
1436                         {\r
1437                                 onFirstOpen: function( _w, _h){\r
1438                                         backgroundInfomationElm = $( '#panel-background-information');\r
1439                                         \r
1440                                         jqComicElementInformation = $( '#comic-element-infomation').hide().css( {\r
1441                                                 height:         _h\r
1442                                         });\r
1443                                         var TAB_GROUP_ID = 'comic-element-attribute';\r
1444                                         var CREATER = pettanr.form.createInputText;//pettanr.key.createEditableText;\r
1445                                         inputX = CREATER( document.getElementById( 'comic-element-x'), null, TAB_GROUP_ID);\r
1446                                         inputY = CREATER( document.getElementById( 'comic-element-y'), null, TAB_GROUP_ID);\r
1447                                         inputZ = CREATER( document.getElementById( 'comic-element-z'), null, TAB_GROUP_ID);\r
1448                                         inputA = CREATER( document.getElementById( 'comic-element-a'), null, TAB_GROUP_ID);\r
1449                                         inputW = CREATER( document.getElementById( 'comic-element-w'), null, TAB_GROUP_ID);\r
1450                                         inputH = CREATER( document.getElementById( 'comic-element-h'), null, TAB_GROUP_ID);\r
1451                                         inputPercentW = CREATER( document.getElementById( 'comic-element-w-percent'), null, TAB_GROUP_ID);\r
1452                                         inputPercentH = CREATER( document.getElementById( 'comic-element-h-percent'), null, TAB_GROUP_ID);\r
1453                                         inputAspectRatio = $( '#comic-element-keep-aspect');\r
1454                                         delete this.onFirstOpen;\r
1455                                 },\r
1456                                 onResize: function(  _w, _h){\r
1457                                         jqComicElementInformation.css( {\r
1458                                                 height: _h\r
1459                                         });\r
1460                                 },\r
1461                                 update: function( currentElement){\r
1462                                         \r
1463                                         if( currentLock === true && currentElement === null) return;\r
1464                                         \r
1465                                         var _elementType = currentElement === null ? -1 : currentElement.type,\r
1466                                                 x = currentElement !== null ? currentElement.x : 0,\r
1467                                                 y = currentElement !== null ? currentElement.y : 0,\r
1468                                                 z = currentElement !== null ? currentElement.z : 0,\r
1469                                                 a = _elementType === COMIC_ELEMENT_TYPE_TEXT ? Math.floor( currentElement.angle()) : 0,\r
1470                                                 w = currentElement !== null ? currentElement.w : 0,\r
1471                                                 h = currentElement !== null ? currentElement.h : 0,\r
1472                                                 actualW = _elementType === COMIC_ELEMENT_TYPE_IMAGE ? currentElement.actualW() : 1,\r
1473                                                 actualH = _elementType === COMIC_ELEMENT_TYPE_IMAGE ? currentElement.actualH() : 1,\r
1474                                                 wPercent = _elementType === COMIC_ELEMENT_TYPE_IMAGE ? Math.floor( w / actualW *100) : 0,\r
1475                                                 hPercent = _elementType === COMIC_ELEMENT_TYPE_IMAGE ? Math.floor( h / actualH *100) : 0,\r
1476                                                 keepAspect = currentElement !== null && currentElement.keepAspect === true;\r
1477                                         \r
1478                                         if( currentElementType !== _elementType){\r
1479                                                 if( _elementType !== -1){\r
1480                                                         if( _elementType === 1){\r
1481                                                                 inputA.visible( true);\r
1482                                                                 inputPercentW.visible( false);\r
1483                                                                 inputPercentH.visible( false);\r
1484                                                                 inputAspectRatio.hide();\r
1485                                                         } else {\r
1486                                                                 inputA.visible( false);\r
1487                                                                 inputPercentW.visible( true);\r
1488                                                                 inputPercentH.visible( true);\r
1489                                                                 inputAspectRatio.show();\r
1490                                                         }\r
1491                                                         currentElementType === -1 && jqComicElementInformation.stop().css( {\r
1492                                                                 filter:         '',\r
1493                                                                 opacity:        ''\r
1494                                                         })[ FADE_IN_EFFECT]();\r
1495                                                 } else {\r
1496                                                         currentElementType !== -1 && jqComicElementInformation.stop().css({\r
1497                                                                 filter:         '',\r
1498                                                                 opacity:        ''\r
1499                                                         })[ FADE_OUT_EFFECT]();\r
1500                                                 }\r
1501                                                 currentElementType = _elementType;\r
1502                                         }\r
1503                                         if( currentElementType !== -1){\r
1504                                                 inputX.update( x);\r
1505                                                 inputY.update( y);\r
1506                                                 inputZ.update( z);\r
1507                                                 _elementType === 1 && inputA.update( a);\r
1508                                                 inputW.update( w);\r
1509                                                 inputH.update( h);\r
1510                                                 _elementType === 0 && inputPercentW.update( wPercent);\r
1511                                                 _elementType === 0 && inputPercentH.update( hPercent);                                  \r
1512                                         } else {\r
1513                                                 \r
1514                                         }\r
1515                                 },\r
1516                                 lock: function( _currentLock){\r
1517                                         currentLock = !!_currentLock;\r
1518                                         this.bodyBackOrForward( !currentLock);\r
1519                                 }\r
1520                         },\r
1521                         'infomation-window', 'Infomation', 0, 30, 200, 180, true\r
1522                 );\r
1523         })();\r
1524 \r
1525 /* ----------------------------------------\r
1526  * HELP_WINDOW\r
1527  */\r
1528         var HELP_DOCUMENTS_WINDOW = ( function(){\r
1529                 var visible = true,\r
1530                         jqAjaxContents,\r
1531                         jqNaviItems,\r
1532                         jqPages,\r
1533                         currentPageIndex = 0,\r
1534                         HELP = MENU_BAR_CONTROL.HELP,\r
1535                         onLoadFunction = HELP.createAjaxSelection( onFirstOpen),\r
1536                         instance;\r
1537                 function jumpPage( _index){\r
1538                         \r
1539                 }\r
1540                 function onSelectionClick( _pageIndex){\r
1541                         currentPageIndex = _pageIndex || currentPageIndex;\r
1542                         HELP_DOCUMENTS_WINDOW.open();\r
1543                         onOpen();\r
1544                 }\r
1545                 function onOpen(){\r
1546                         jqNaviItems.removeClass( 'current').eq( currentPageIndex).addClass( 'current');\r
1547                         jqPages.hide().eq( currentPageIndex).show();\r
1548                 }\r
1549                 function onFirstOpen( _pageIndex){\r
1550                         currentPageIndex = _pageIndex || currentPageIndex;\r
1551                         if( onHelpLoad !== null){\r
1552                                 $.ajax({\r
1553                                         url:            'help/jp.xml',\r
1554                                         dataType:       'xml',\r
1555                                         success:        onHelpLoad\r
1556                                 });\r
1557                                 onHelpLoad = null;\r
1558                         }\r
1559                 }\r
1560                 var onHelpLoad = function( _xml){\r
1561                         var jqXML = $( _xml),\r
1562                                 helpTitle = jqXML.find( 'pages').eq( 0).attr( 'title'),\r
1563                                 elmNavi = document.createElement( 'div'),\r
1564                                 elmItemOrigin = document.createElement( 'a'),\r
1565                                 elmPages = document.createElement( 'div'),\r
1566                                 elmPageOrigin = document.createElement( 'div'),\r
1567                                 elmTitleOrigin = document.createElement( 'h2'),\r
1568                                 elmPage,\r
1569                                 numPage = 0;\r
1570                         elmNavi.className = 'sidenavi';\r
1571                         elmItemOrigin.className = 'sidenavi-item';\r
1572                         elmItemOrigin.href = '#';\r
1573                         elmPages.className = 'page-contents';\r
1574                         elmPageOrigin.className = 'page-content main';\r
1575                         elmPageOrigin.appendChild( elmTitleOrigin);\r
1576                         \r
1577                         // helpTitle && instance.title( helpTitle);\r
1578                         \r
1579                         jqXML.find( 'page').each( function(){\r
1580                                 var xmlPage = $( this),\r
1581                                         title = xmlPage.attr( 'title'),\r
1582                                         content = xmlPage.text();\r
1583                                 \r
1584                                 elmItemOrigin.innerHTML = title;\r
1585                                 elmNavi.appendChild( elmItemOrigin.cloneNode( true));\r
1586                                 \r
1587                                 elmTitleOrigin.innerHTML = title;\r
1588                                 elmPage = elmPageOrigin.cloneNode( true);\r
1589                                 elmPage.innerHTML = content;\r
1590                                 \r
1591                                 pettanr.util.cleanElement( elmPage);\r
1592                                 \r
1593                                 if( elmPage.childNodes.length > 0){\r
1594                                         elmPage.insertBefore( elmTitleOrigin.cloneNode( true), elmPage.childNodes[0]);\r
1595                                 } else {\r
1596                                         elmPage.appendChild( elmTitleOrigin.cloneNode( true));\r
1597                                 }\r
1598                                 elmPages.appendChild( elmPage);\r
1599                                 \r
1600                                 HELP.createSelection( title, null, onSelectionClick, true);\r
1601                                 ++numPage;\r
1602                         });\r
1603                         onLoadFunction();\r
1604                         onLoadFunction = null;\r
1605                         \r
1606                         jqAjaxContents.removeClass( 'loading').append( elmNavi, elmPages);\r
1607                         \r
1608                         jqNaviItems = jqAjaxContents.find( 'a.' +elmItemOrigin.className).click( onNaviClick);\r
1609                         jqAjaxContents.find( '.' +elmPageOrigin.className).find( 'a').click( onInnerLinkClick);\r
1610                         jqPages = jqAjaxContents.find( '.page-content');\r
1611                         setTimeout( onOpen, 0);\r
1612                 }\r
1613                 function onNaviClick( e){\r
1614                         // this は <a>\r
1615                         var children = this.parentNode.getElementsByTagName( 'a'),\r
1616                                 l = children.length;\r
1617                         for( var i=0; i<l; ++i){\r
1618                                 if( children[ i] === this) break;\r
1619                         }\r
1620                         e.stopPropagation();\r
1621                         if( i === l) return false;\r
1622                         jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
1623                         jqPages.hide().eq( i).show();\r
1624                         return false;\r
1625                 }\r
1626                 function onInnerLinkClick( e){\r
1627                         var jump = this.href.split( '#jump'),\r
1628                                 n = jump[1],\r
1629                                 i = ( n && '' +parseFloat( n) === n) ? parseFloat( n) : -1;\r
1630                         e.stopPropagation();\r
1631                         if( i === -1) return false;\r
1632                         jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
1633                         jqPages.hide().eq( i).show();\r
1634                         currentPageIndex = i;\r
1635                         return false;                           \r
1636                 }\r
1637                 return WINDOWS_CONTROL.createWindow(\r
1638                         this,\r
1639                         {\r
1640                                 onInit: function(){\r
1641                                         instance = this;\r
1642                                         jqAjaxContents = this.$.find( '.window-body').addClass( 'loading').css( { height: this.bodyHeight()});\r
1643                                         delete this.onInit;\r
1644                                 },\r
1645                                 onFirstOpen: function(){\r
1646                                         onFirstOpen();\r
1647                                 },\r
1648                                 onResize: function( w, h){\r
1649                                         jqAjaxContents && jqAjaxContents.css( { height: h});\r
1650                                 },\r
1651                                 setAjaxContent: function( html){\r
1652                                         \r
1653                                         delete this.onLoadAjaxContent;\r
1654                                 }\r
1655                         },\r
1656                         null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300\r
1657                 );\r
1658         })();\r
1659 \r
1660 /* ----------------------------------------\r
1661  * GRID_CONTROL\r
1662  */\r
1663         var GRID_CONTROL = ( function(){\r
1664                 var ELM_GRID = document.getElementById( 'grid'),\r
1665                         jqGrid,\r
1666                         visible = false;\r
1667 \r
1668                 return {\r
1669                         init: function(){\r
1670                                 jqGrid = $( ELM_GRID);\r
1671                                 delete GRID_CONTROL.init;\r
1672                         },\r
1673                         onPanelResize: function( _panelX, _panelY){\r
1674                                 ELM_GRID.style.backgroundPosition = [ _panelX % 10, 'px ', _panelY % 10, 'px'].join( '');\r
1675                                 ELM_GRID.style.height = windowH +'px';\r
1676                         },\r
1677                         enabled: function(){\r
1678                                 return visible;\r
1679                         },\r
1680                         update: function(){\r
1681                                 jqGrid.css( {\r
1682                                         opacity:        '',\r
1683                                         fliter:         ''\r
1684                                 }).stop()[ visible === true ? 'fadeOut' : 'fadeIn']();\r
1685                                 \r
1686                                 visible = !visible;\r
1687                                 \r
1688                                 if( visible === true && !ELM_GRID.style.backgroundImage){\r
1689                                         ELM_GRID.style.backgroundImage = "url('images/grid.gif')";\r
1690                                 }\r
1691                                 return visible;                         \r
1692                         }\r
1693                 }\r
1694         })();\r
1695                 \r
1696         /*\r
1697          *      WHITE_GLASS_CONTROL\r
1698          */     \r
1699         var WHITE_GLASS_CONTROL = ( function(){\r
1700                 var styleTop = document.getElementById( 'whiteGlass-top').style,\r
1701                         styleLeft = document.getElementById( 'whiteGlass-left').style,\r
1702                         styleRight = document.getElementById( 'whiteGlass-right').style,\r
1703                         styleBottom = document.getElementById( 'whiteGlass-bottom').style;\r
1704 \r
1705                 return {\r
1706                         onPanelResize: function( _panelX, _panelY, _panelW, _panelH){\r
1707                                 var     _w = _panelW,\r
1708                                         _h = _panelH,\r
1709                                         marginTop = _panelY,\r
1710                                         marginBottom = windowH -_h -marginTop,\r
1711                                         marginX = _panelX,\r
1712                                         rightWidth = windowW -_w -marginX;\r
1713                                 \r
1714                                 styleTop.height = ( marginTop < 0 ? 0 : marginTop) +'px';\r
1715                                 \r
1716                                 styleLeft.top = marginTop +'px';\r
1717                                 styleLeft.width = ( marginX < 0 ? 0 : marginX) +'px';\r
1718                                 styleLeft.height = ( _h + marginBottom) +'px';\r
1719                                 \r
1720                                 styleRight.top = marginTop +'px';\r
1721                                 styleRight.left = _w +marginX +'px';\r
1722                                 styleRight.width = ( rightWidth < 0 ? 0 : rightWidth) +'px';\r
1723                                 styleRight.height = ( _h + marginBottom) +'px';\r
1724                                 \r
1725                                 styleBottom.top = ( _h +marginTop) +'px';\r
1726                                 styleBottom.left = marginX +'px';\r
1727                                 styleBottom.width = _w +'px';\r
1728                                 styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom) +'px';\r
1729                         }\r
1730                 }\r
1731         })();\r
1732 \r
1733 \r
1734 /*\r
1735  * PANEL_CONTROL\r
1736  * panel-border の表示と onPanelResize の通知.\r
1737  * panel drag.\r
1738  * \r
1739  */\r
1740         var PANEL_CONTROL = ( function(){\r
1741                 var ELM_PANEL = document.getElementById('panel-tools-container'),\r
1742                         ELM_PANEL_STYLE = ELM_PANEL.style,\r
1743                         DEFAULT_PANEL_WIDTH = 400,\r
1744                         DEFAULT_PANEL_HEIGHT = 300,\r
1745                         borderSize = 2,\r
1746                         panelW, panelH, panelX, panelY,\r
1747                         offsetX, offsetY, startX, startY,\r
1748                         isDragging = false,\r
1749                         isDraggable = false;\r
1750                 \r
1751                 function onSpaceUpdate(e){\r
1752                         if( e.type === 'keyup'){\r
1753                                 currentListener === null && updateMouseCursor( '');\r
1754                                 isDraggable = false;\r
1755                         } else {\r
1756                                 currentListener === null && updateMouseCursor( 'move');\r
1757                                 isDraggable = true;\r
1758                         }\r
1759                 }\r
1760                 \r
1761                 return {\r
1762                         init: function( _panelW, _panelH, _borderSize){\r
1763                                 panelW = _panelW || DEFAULT_PANEL_WIDTH;\r
1764                                 panelH = _panelH || DEFAULT_PANEL_HEIGHT;\r
1765                                 panelX = Math.floor( ( windowW -panelW) /2);\r
1766                                 panelY = Math.floor( ( windowH -panelH) /2);\r
1767                                 borderSize = _borderSize !== undefined ? _borderSize : borderSize;\r
1768                                 \r
1769                                 pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 32, false, false, onSpaceUpdate);\r
1770                                 \r
1771                                 setTimeout( PANEL_CONTROL.resize, 0);\r
1772                                 \r
1773                                 delete PANEL_CONTROL.init;\r
1774                         },\r
1775                         x: function(){\r
1776                                 return panelX;\r
1777                         },\r
1778                         y: function(){\r
1779                                 return panelY;\r
1780                         },\r
1781                         resize: function( isResizerTopAction, _x, _y, _w, _h){\r
1782                                 panelX = _x !== undefined ? _x : panelX;\r
1783                                 panelY = _y !== undefined ? _y : panelY;\r
1784                                 panelW = _w !== undefined ? _w : panelW;\r
1785                                 panelH = _h !== undefined ? _h : panelH;\r
1786                                 \r
1787                                 ELM_PANEL_STYLE.left    = ( panelX -borderSize) +'px';\r
1788                                 ELM_PANEL_STYLE.top             = ( panelY -borderSize) +'px';\r
1789                                 ELM_PANEL_STYLE.width   = panelW +'px';\r
1790                                 ELM_PANEL_STYLE.height  = panelH +'px';\r
1791                                 \r
1792                                 PANEL_RESIZER_TOP.onPanelResize( panelX, panelY, panelW, panelH);\r
1793                                 PANEL_RESIZER_BOTTOM.onPanelResize( panelX, panelY, panelW, panelH);\r
1794                                 GRID_CONTROL.onPanelResize( panelX, panelY);\r
1795                                 WHITE_GLASS_CONTROL.onPanelResize( panelX, panelY, panelW, panelH);\r
1796                                 COMIC_ELEMENT_CONTROL.onPanelResize( panelX, panelY, panelW, panelH, isResizerTopAction === true);\r
1797                         },\r
1798                         onWindowResize: function( _windowW, _windowH){\r
1799                                 panelX = Math.floor(( _windowW - panelW) / 2);\r
1800                                 panelY = Math.floor(( _windowH - panelH) / 2);\r
1801                                 PANEL_CONTROL.resize();\r
1802                         },\r
1803                         onMouseMove: function( _mouseX, _mouseY){\r
1804                                 if( isDraggable === true && isDragging === true){\r
1805                                         PANEL_CONTROL.resize( false, startX +_mouseX -offsetX, startY +_mouseY -offsetY);\r
1806                                 }\r
1807                         },\r
1808                         onMouseUp: function( _mouseX, _mouseY){\r
1809                                 if( isDraggable === true){\r
1810                                         isDragging = false;\r
1811                                         updateMouseCursor( '');\r
1812                                 }\r
1813                         },\r
1814                         onMouseDown: function( _mouseX, _mouseY){\r
1815                                 if( isDraggable === true){\r
1816                                         offsetX = _mouseX;\r
1817                                         offsetY = _mouseY;\r
1818                                         startX = panelX;\r
1819                                         startY = panelY;\r
1820                                         isDragging = true;\r
1821                                         updateMouseCursor( 'move');\r
1822                                         return true;\r
1823                                 }\r
1824                         },\r
1825                         busy: function(){\r
1826                                 return isDragging === true;\r
1827                         }                               \r
1828                 }\r
1829         })();\r
1830 \r
1831 /*\r
1832  * --------------------------------------------------------------------------------------------\r
1833  * panel resizer\r
1834  */\r
1835         var PanelResizerClass = function( ID, isTop){\r
1836                 var ELM = document.getElementById( ID),\r
1837                         BORDER_WIDTH = 2,\r
1838                         RESIZER_HEIGHT = 30,\r
1839                         x = -BORDER_WIDTH /2,\r
1840                         y = isTop === true ? ( -5 -RESIZER_HEIGHT -BORDER_WIDTH) : 0,\r
1841                         w,\r
1842                         h = RESIZER_HEIGHT,\r
1843                         panelX, panelY, panelW, panelH,\r
1844                         offsetY, startY, startH,\r
1845                         isDragging = false,\r
1846                         MOUSE_CURSOR = updateMouseCursor;\r
1847                         \r
1848                 function restoreState( arg){\r
1849                         if( arg && arg.length > 3){\r
1850                                 PANEL_CONTROL.resize( isTop, arg[ 0] || panelX, arg[ 1] || panelY, arg[ 2] || panelW, arg[ 3] || panelH);\r
1851                         }\r
1852                 }\r
1853                         \r
1854                 return {\r
1855                         busy: function(){\r
1856                                 return isDragging;\r
1857                         },\r
1858                         onMouseDown: function( _mouseX, _mouseY){\r
1859                                 var _x = _mouseX -panelX,\r
1860                                         _y = _mouseY -panelY;\r
1861                                 if( _x < x || x + w < _x || _y < y || y + h < _y) return false;\r
1862                                 offsetY = _y;\r
1863                                 startY = panelY;\r
1864                                 startH = panelH;\r
1865                                 isDragging = true;\r
1866                                 MOUSE_CURSOR( 'n-resize');\r
1867                                 return true;\r
1868                         },\r
1869                         onMouseMove: function( _mouseX, _mouseY){\r
1870                                 var _x = _mouseX -panelX,\r
1871                                         _y = _mouseY -panelY;\r
1872                                 if( isDragging !== true){\r
1873                                         if( _x < x || x + w < _x || _y < y || y + h < _y) return false;\r
1874                                         COMIC_ELEMENT_OPERATION_MANAGER.hide();\r
1875                                         MOUSE_CURSOR( 'pointer');\r
1876                                         return true;\r
1877                                 } else {\r
1878                                         var move = _y -offsetY;\r
1879                                         if( isTop === true){\r
1880                                                 if( panelH - move < MIN_PANEL_HEIGHT){\r
1881                                                         move = panelH -MIN_PANEL_HEIGHT;\r
1882                                                 }\r
1883                                                 PANEL_CONTROL.resize( true, panelX, panelY + move, panelW, panelH - move);\r
1884                                         } else {\r
1885                                                 var _h = startH +move;\r
1886                                                 if( 0 < _h && _h < windowH -panelY -RESIZER_HEIGHT -5 -BORDER_WIDTH){\r
1887                                                         PANEL_CONTROL.resize( false, panelX, panelY, panelW, _h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : _h);\r
1888                                                 }\r
1889                                         }\r
1890                                 }\r
1891                                 return true;\r
1892                         },\r
1893                         onMouseUp: function( _mouseX, _mouseY){\r
1894                                 if( isDragging !== true) return;\r
1895                                 ( startY !== panelY || startH !== panelH) && HISTORY.saveState( restoreState, [ NaN, startY, NaN, startH], [ NaN, panelY, NaN, panelH]);\r
1896                                 isDragging = false;\r
1897                                 MOUSE_CURSOR( '');\r
1898                         },\r
1899                         busy: function(){\r
1900                                 return isDragging\r
1901                         },\r
1902                         onPanelResize: function( _x, _y, _w, _h){\r
1903                                 panelX = _x;\r
1904                                 panelY = _y;\r
1905                                 if( panelW !== _w){\r
1906                                         ELM.style.width = ( _w +2) +'px';\r
1907                                         panelW = _w;\r
1908                                 }\r
1909                                 panelH = _h;\r
1910                                 y = isTop === true ? y : ( panelH +5 +BORDER_WIDTH);\r
1911                                 w = panelW +2;\r
1912                         }\r
1913                 }\r
1914         };\r
1915         var     PANEL_RESIZER_TOP = new PanelResizerClass( 'panel-resizer-top', true),\r
1916                 PANEL_RESIZER_BOTTOM = new PanelResizerClass( 'panel-resizer-bottom', false);\r
1917                 \r
1918         PanelResizerClass = undefined;\r
1919 \r
1920 \r
1921         var CONSOLE_CONTROLER = ( function(){\r
1922                 var LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer back', 'ctrl + B', layerBack, false, true, false),\r
1923                         LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer forward', 'ctrl + F', layerForward, false, false, false),\r
1924                         DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'delete', 'ctrl + D', del, false, true, true),\r
1925                         EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'Edit Text', 'ctrl + E', edit, false, true, false),\r
1926                         CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'change', 'ctrl + U', change, false, false, true),\r
1927                         SAVE = HISTORY.saveState,\r
1928                         jqStage,\r
1929                         jqConsoleParent,\r
1930                         jqConsoleWrapper,\r
1931                         jqConsoleTail,\r
1932                         jqImgConsole, jqTextConsole,\r
1933                         currentElement = null,\r
1934                         currentType = -1,\r
1935                         visible = false,\r
1936                         imgConsoleWidth, imgConsoleHeight,\r
1937                         textConsoleWidth, textConsoleHeight,\r
1938                         consoleWidth, consoleHeight,\r
1939                         consoleX, consoleY,\r
1940                         tailSize = 10,\r
1941                         buttonClickable = false;\r
1942                 \r
1943                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 66, false, true, layerBack);\r
1944                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 70, false, true, layerForward);\r
1945                 \r
1946                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 68, false, true, del);\r
1947                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 69, false, true, edit);\r
1948                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 85, false, true, change);\r
1949                 \r
1950                 function buttonBackOrForward( isBack){\r
1951                         var     offest = jqConsoleWrapper.offset();\r
1952                         jqConsoleWrapper.css( {\r
1953                                 position:       isBack === true ? '' : 'absolute',\r
1954                                 left:           isBack === true ? consoleX  : offest.left,\r
1955                                 top:            isBack === true ? consoleY  : offest.top\r
1956                         });\r
1957                         buttonClickable === isBack && ( isBack === true ? jqConsoleParent : jqStage).append( jqConsoleWrapper);\r
1958                         buttonClickable = !isBack;\r
1959                 }\r
1960                 function layerBack(){\r
1961                         if( currentElement === null) return;\r
1962                         if( COMIC_ELEMENT_CONTROL.replace( currentElement, false) === false) return;\r
1963                         INFOMATION_WINDOW.update( currentElement);\r
1964                         SAVE( COMIC_ELEMENT_CONTROL.restoreReplace, [ currentElement, true], [ currentElement, false]);\r
1965                         var _z = currentElement.z;\r
1966                         LAYER_BACK_BUTTON.visible( _z > 0);\r
1967                         LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1);\r
1968                 }\r
1969                 function layerForward(){\r
1970                         if( currentElement === null) return;\r
1971                         if( COMIC_ELEMENT_CONTROL.replace( currentElement, true) === false) return;\r
1972                         INFOMATION_WINDOW.update( currentElement);\r
1973                         SAVE( COMIC_ELEMENT_CONTROL.restoreReplace, [ currentElement, false], [ currentElement, true]);\r
1974                         var _z = currentElement.z;\r
1975                         LAYER_BACK_BUTTON.visible( _z > 0);\r
1976                         LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1);\r
1977                 }\r
1978                 function del(){\r
1979                         if( currentElement === null) return;\r
1980                         buttonBackOrForward( true);\r
1981                         COMIC_ELEMENT_CONTROL.remove( currentElement);\r
1982                         SAVE( COMIC_ELEMENT_CONTROL.restore, [ true, currentElement], [ false, currentElement], true);\r
1983                         COMIC_ELEMENT_OPERATION_MANAGER.hide();\r
1984                 }\r
1985                 function edit(){\r
1986                         if( currentElement === null || currentElement.type !== COMIC_ELEMENT_TYPE_TEXT) return;\r
1987                         TEXT_EDITOR_CONTROL.show( currentElement);\r
1988                         buttonBackOrForward( true);\r
1989                 }\r
1990                 function change(){\r
1991                         if( currentElement === null) return;\r
1992                         buttonBackOrForward( true);\r
1993                         IMAGE_GROUP_EXPROLER.show( currentElement.url);\r
1994                 }\r
1995                 return {\r
1996                         init: function(){\r
1997                                 jqStage = jqEditor;\r
1998                                 jqConsoleTail = $( '#comic-element-consol-tail');\r
1999                                 jqImgConsole = $( '#image-element-consol').hide();\r
2000                                 var imgConsoleSize = pettanr.util.getElementSize( jqImgConsole.get( 0));\r
2001                                 imgConsoleWidth = imgConsoleSize.width;\r
2002                                 imgConsoleHeight = imgConsoleSize.height;\r
2003                                 \r
2004                                 jqTextConsole = $( '#text-element-consol').hide();\r
2005                                 var textConsoleSize = pettanr.util.getElementSize( jqTextConsole.get( 0));\r
2006                                 textConsoleWidth = textConsoleSize.width;\r
2007                                 textConsoleHeight = textConsoleSize.height;\r
2008                                 \r
2009                                 jqConsoleWrapper = $( '#comic-element-consol-wrapper').hide();\r
2010                                 jqConsoleParent = jqConsoleWrapper.parent();\r
2011                                 \r
2012                                 $( '#edit-text-button').click( edit);\r
2013                                 $( '#delete-image-button, #delete-text-button').click( del);\r
2014                                 $( '#change-image-button').click( change);\r
2015                                 $( '#layer-forward-button, #forward-text-button').click( layerForward);\r
2016                                 $( '#layer-back-button, #back-text-button').click( layerBack);\r
2017                                                                                         \r
2018                                 delete CONSOLE_CONTROLER.init;\r
2019                         },\r
2020                         show: function( _currentElement, _w, _h){\r
2021                                 visible === false && jqConsoleWrapper.show();\r
2022                                 visible = true;\r
2023                                 currentElement = _currentElement;\r
2024                                 var _currentType = _currentElement.type,\r
2025                                         _z = _currentElement.z;\r
2026                                 if( currentType !== _currentType){\r
2027                                         currentType = _currentType;\r
2028                                         jqImgConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_IMAGE);\r
2029                                         jqTextConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
2030                                         consoleWidth = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth;\r
2031                                         consoleHeight = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight;\r
2032                                 }\r
2033                                 consoleX = Math.floor( ( _w -consoleWidth) /2);\r
2034                                 \r
2035                                 LAYER_BACK_BUTTON.visible( _z > 0);\r
2036                                 LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1);\r
2037                                 DELETE_BUTTON.visible( true);\r
2038                                 EDIT_BUTTON.visible( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
2039                                 CHANGE_BUTTON.visible( false);\r
2040                                 \r
2041                                 if( _w > consoleWidth * 1.5 && _h > consoleHeight * 1.5){\r
2042                                         consoleY = Math.floor( ( _h -consoleHeight) /2);\r
2043                                         jqConsoleWrapper.css( {\r
2044                                                 left:                   consoleX,\r
2045                                                 top:                    consoleY\r
2046                                         }).removeClass( 'console-out');\r
2047                                 } else {\r
2048                                         consoleY = _h +tailSize;\r
2049                                         jqConsoleWrapper.css( {\r
2050                                                 left:                   consoleX,\r
2051                                                 top:                    consoleY\r
2052                                         }).addClass( 'console-out');\r
2053                                 }\r
2054                         },\r
2055                         hide: function (){\r
2056                                 visible === true && jqConsoleWrapper.hide();\r
2057                                 visible = false;\r
2058                                 currentElement = null;\r
2059                                 LAYER_BACK_BUTTON.visible( false);\r
2060                                 LAYER_FORWARD_BUTTON.visible( false);\r
2061                                 DELETE_BUTTON.visible( false);\r
2062                                 EDIT_BUTTON.visible( false);\r
2063                                 CHANGE_BUTTON.visible( false);\r
2064                         },\r
2065                         x: function(){ return consoleX;},\r
2066                         y: function(){ return consoleY;},\r
2067                         w: function(){ return consoleWidth;},\r
2068                         h: function(){ return consoleHeight;},\r
2069                         onMouseMove: function( _mouseX, _mouseY){\r
2070                                 if( consoleX > _mouseX || consoleY > _mouseY || consoleX +consoleWidth < _mouseX || consoleY +consoleHeight < _mouseY){\r
2071                                         buttonClickable === true && buttonBackOrForward( true);\r
2072                                         return false;\r
2073                                 }\r
2074                                 buttonClickable === false && buttonBackOrForward( false);\r
2075                                 return true;\r
2076                         },\r
2077                         onMouseOut: function( _mouseX, _mouseY){\r
2078                                 buttonClickable === true && buttonBackOrForward( true);\r
2079                         }\r
2080                 }\r
2081         })();\r
2082 \r
2083 \r
2084         var TAIL_OPERATOR = ( function(){\r
2085                 var     MOUSE_CURSOR = updateMouseCursor,\r
2086                         ELM_MOVER = document.getElementById( 'balloon-tail-mover'),\r
2087                         SIZE = pettanr.util.getElementSize( ELM_MOVER).width,\r
2088                         SIN = Math.sin,\r
2089                         COS = Math.cos,\r
2090                         ATAN = Math.atan,\r
2091                         FLOOR = Math.floor,\r
2092                         DEG_TO_RAD = Math.PI / 180,\r
2093                         RAD_TO_DEG = 1 /DEG_TO_RAD,\r
2094                         currentText = null,\r
2095                         tailX, tailY,\r
2096                         x, y, w, h,\r
2097                         balloonW, balloonH, balloonA, radA,\r
2098                         visible = false,\r
2099                         startA;\r
2100                 \r
2101                 return {\r
2102                         update: function ( _w, _h, _a){\r
2103                                 balloonW = _w !== undefined ? _w : balloonW;\r
2104                                 balloonH = _h !== undefined ? _h : balloonH;\r
2105                                 balloonA = _a !== undefined ? _a : balloonA;\r
2106                                 radA = balloonA *DEG_TO_RAD;\r
2107                                 tailX = FLOOR( ( ( COS( radA) /2 +0.5) *( balloonW +SIZE)) -SIZE /2);\r
2108                                 tailY = FLOOR( ( ( SIN( radA) /2 +0.5) *( balloonH +SIZE)) -SIZE /2);\r
2109                                 ELM_MOVER.style.left = tailX +'px';\r
2110                                 ELM_MOVER.style.top = tailY +'px';\r
2111                                 //log.html( [ balloonW, balloonH, balloonA].join());\r
2112                         },\r
2113                         show: function( _currentText){\r
2114                                 /*\r
2115                                  * visibilityのほうがいい, display:none だと ie で描画が狂う\r
2116                                  */\r
2117                                 ELM_MOVER.style.visibility = '';\r
2118                                 this.update( _currentText.w, _currentText.h, _currentText.angle());\r
2119                                 currentText = _currentText;\r
2120                         },\r
2121                         hitTest: function( _mouseX, _mouseY){\r
2122                                 var _x = tailX -SIZE /2,\r
2123                                         _y = tailY -SIZE /2;\r
2124                                         ret = _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY;\r
2125                                 ret === true && MOUSE_CURSOR( 'move');\r
2126                                 return ret;\r
2127                         },\r
2128                         hide: function(){\r
2129                                 ELM_MOVER.style.visibility = 'hidden';\r
2130                                 currentText = null;\r
2131                         },\r
2132                         onStart: function( _currentText, _mouseX, _mouseY){\r
2133                                 if( _currentText.type !== COMIC_ELEMENT_TYPE_TEXT) return false;\r
2134                                 x = _currentText.x;\r
2135                                 y = _currentText.y;\r
2136                                 if( this.hitTest( _mouseX -x, _mouseY -y) === true){\r
2137                                         w = _currentText.w;\r
2138                                         h = _currentText.h;\r
2139                                         currentText = _currentText;\r
2140                                         startA = _currentText.angle();\r
2141                                         return true;\r
2142                                 }\r
2143                                 return false;\r
2144                         },\r
2145                         onDrag: function( _mouseX, _mouseY){\r
2146                                 _mouseX = _mouseX -x -w /2;\r
2147                                 _mouseY = _mouseY -y -h /2; //Balloonの中心を0,0とする座標系に変換\r
2148                                 \r
2149                                 this.update( w, h,\r
2150                                         _mouseX !== 0 ?\r
2151                                                 ATAN( _mouseY /_mouseX) *RAD_TO_DEG +( _mouseX < 0 ? 180 : 0) :\r
2152                                                 _mouseY > 0 ? 90 : -90\r
2153                                 );\r
2154                                 currentText && currentText.angle( balloonA);\r
2155                                 INFOMATION_WINDOW.update( currentText);\r
2156                         },\r
2157                         onFinish: function(){\r
2158                                 startA !== currentText.angle() && COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( x, y, w, h, startA);\r
2159                                 startA !== currentText.angle() && COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, currentText.angle());\r
2160                                 currentText = null;\r
2161                         },\r
2162                         onCancel: function(){\r
2163                                 currentText.angle( startA);\r
2164                                 COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, startA);\r
2165                                 currentText = null;\r
2166                         }\r
2167                 }\r
2168         })();\r
2169         \r
2170         var RESIZE_OPERATOR = ( function(){\r
2171                 var     MOUSE_CURSOR = updateMouseCursor,\r
2172                         GRID_ENABLED = GRID_CONTROL.enabled;\r
2173                 \r
2174                 var     HIT_AREA = MOUSE_HIT_AREA,\r
2175                         POSITION_ARRAY = [],\r
2176                         FLOOR = Math.floor,\r
2177                         CURSOR_AND_FLIP = [\r
2178                                 { cursor:       'n-resize',             v: 3},\r
2179                                 { cursor:       'e-resize',             h: 2},\r
2180                                 { cursor:       'e-resize',             h: 1},\r
2181                                 { cursor:       'n-resize',             v: 0},\r
2182                                 { cursor:       'nw-resize',    h: 5, v: 6, vh: 7},\r
2183                                 { cursor:       'ne-resize',    h: 4, v: 7, vh: 6},\r
2184                                 { cursor:       'ne-resize',    h: 7, v: 4, vh: 5},\r
2185                                 { cursor:       'nw-resize',    h: 6, v: 5, vh: 4}\r
2186                         ],\r
2187                         elmResizerContainer = document.getElementById( 'comic-element-resizer-container'),\r
2188                         elmResizerContainerStyle = elmResizerContainer.style,\r
2189                         elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style,\r
2190                         elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style,\r
2191                         elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style,\r
2192                         elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style,\r
2193                         x, y, w, h,\r
2194                         currentIndex = -1,\r
2195                         currentElement,\r
2196                         currentIsTextElement = false;\r
2197                 \r
2198                 elmResizerContainerStyle.display = 'none';\r
2199                 \r
2200                 var RESIZE_WORK_ARRAY = [\r
2201                                 { x:    0, w:    0, y:  1, h:   -1}, //top\r
2202                                 { x:    1, w:   -1, y:  0, h:    0}, //left\r
2203                                 { x:    0, w:    1, y:  0, h:    0}, //right\r
2204                                 { x:    0, w:    0, y:  0, h:    1}, //bottom\r
2205                                 { x:    1, w:   -1, y:  1, h:   -1}, //top-left\r
2206                                 { x:    0, w:    1, y:  1, h:   -1}, //top-right\r
2207                                 { x:    1, w:   -1, y:  0, h:    1}, //bottom-left\r
2208                                 { x:    0, w:    1, y:  0, h:    1}  //bottom-right\r
2209                         ],\r
2210                         startX, startY, startW, startH, startFilpV, startFilpH, startAspect,\r
2211                         baseX, baseY, baseW, baseH,\r
2212                         currentX, currentY, currentW, currentH,\r
2213                         offsetX, offsetY,\r
2214                         lock = false,\r
2215                         error = 0;\r
2216                 \r
2217                 function draw( _x, _y, _w, _h){\r
2218                         x = _x !== undefined ? _x : x;\r
2219                         y = _y !== undefined ? _y : y;\r
2220                         w = _w !== undefined ? _w : w;\r
2221                         h = _h !== undefined ? _h : h;\r
2222                         try {\r
2223                                 elmResizerContainerStyle.left = x +'px';\r
2224                                 elmResizerContainerStyle.top = y +'px';\r
2225                                 elmResizerContainerStyle.width = w +'px';\r
2226                                 elmResizerContainerStyle.height = h +'px';\r
2227                                 elmResizerTopStyle.left = FLOOR( w /2 -10 /2) +'px';\r
2228                                 elmResizerLeftStyle.top = FLOOR( h /2 -10 /2) +'px';\r
2229                                 elmResizerRightStyle.top = FLOOR( h /2 -10 /2) +'px';\r
2230                                 elmResizerBottomStyle.left = FLOOR( w /2 -10 /2) +'px';                         \r
2231                         } catch(e){\r
2232                                 alert( [x, y, w, h].join( ','));\r
2233                                 return;\r
2234                         }\r
2235 \r
2236                         \r
2237                         POSITION_ARRAY.splice( 0, POSITION_ARRAY.length);\r
2238                         POSITION_ARRAY.push(\r
2239                                 {x:     x +5,                                   y:      y -HIT_AREA,            w:      w -5 *2,                h:      HIT_AREA +5},\r
2240                                 {x: x -HIT_AREA,                        y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
2241                                 {x: x +w -5,                            y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
2242                                 {x:     x +5,                                   y:      y +h -5,                        w:      w -5 *2,                h:      HIT_AREA +5},\r
2243                                 {x:     x -HIT_AREA,                    y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2244                                 {x: x +w -HIT_AREA,                     y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2245                                 {x:     x -HIT_AREA,                    y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2246                                 {x:     x +w -5,                                y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5}\r
2247                         );\r
2248                 }\r
2249                 \r
2250                 function update( _x, _y, _w, _h){\r
2251                         x = _x !== undefined ? _x : currentX;\r
2252                         y = _y !== undefined ? _y : currentY;\r
2253                         w = _w !== undefined ? _w : currentW;\r
2254                         h = _h !== undefined ? _h : currentH;\r
2255                         \r
2256                         if( currentIsTextElement === false && currentIndex > 3 && pettanr.key.shiftEnabled() === true){\r
2257                                 if( startAspect >= 1){\r
2258                                         _w = w;\r
2259                                         w = Math.floor( startAspect * h);\r
2260                                         x = x +( currentIndex % 2 === 0 ? _w -w : 0);\r
2261                                 } else {\r
2262                                         _h = h;\r
2263                                         h = Math.floor( w / startAspect);\r
2264                                         y = y + ( currentIndex <= 5 ? _h -h : 0);\r
2265                                 }\r
2266                         }\r
2267                         draw( x, y, w, h);\r
2268                         currentElement.resize( x, y, w, h);\r
2269                         currentIsTextElement === true && TAIL_OPERATOR.update( w, h);\r
2270                         CONSOLE_CONTROLER.show( currentElement, w, h);\r
2271                         INFOMATION_WINDOW.update( currentElement);\r
2272                 }\r
2273                 \r
2274                 function flip( _flipH, _flipV){\r
2275                         var p = CURSOR_AND_FLIP[ currentIndex];\r
2276                         currentIndex = _flipH === true || _flipV === true ? p[\r
2277                                         _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v')\r
2278                                 ] : currentIndex;\r
2279                         MOUSE_CURSOR( CURSOR_AND_FLIP[ currentIndex].cursor);\r
2280                         elmResizerContainer.className = 'current-resizer-is-' +currentIndex;\r
2281                         currentElement.flip( _flipH, _flipV);\r
2282                 }\r
2283                 return {\r
2284                         update: draw,\r
2285                         index: function( _mouseX, _mouseY){\r
2286                                 var     p;\r
2287                                 for( var i=4; i<8; i++){\r
2288                                         p = POSITION_ARRAY[ i];\r
2289                                         if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){\r
2290                                                 MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor);\r
2291                                                 elmResizerContainer.className = 'current-resizer-is-' +i;\r
2292                                                 return currentIndex = i;\r
2293                                         }\r
2294                                 }\r
2295                                 for( var i=0; i<4; i++){\r
2296                                         p = POSITION_ARRAY[ i];\r
2297                                         if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){\r
2298                                                 MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor);\r
2299                                                 elmResizerContainer.className = 'current-resizer-is-' +i;\r
2300                                                 return currentIndex = i;\r
2301                                         }\r
2302                                 }\r
2303                                 MOUSE_CURSOR( '');\r
2304                                 elmResizerContainer.className = '';\r
2305                                 return -1;\r
2306                         },\r
2307                         show: function( _currentElement){\r
2308                                 currentElement = _currentElement;\r
2309                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
2310                                 elmResizerContainerStyle.display = '';\r
2311                         },\r
2312                         hide: function(){\r
2313                                 currentElement = null;\r
2314                                 elmResizerContainerStyle.display = 'none';\r
2315                         },\r
2316                         onStart: function( _currentElement, _mouseX, _mouseY){\r
2317                                 currentElement = _currentElement;\r
2318                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
2319                                 if( _currentElement.keepSize === true) return false;\r
2320                                 currentIndex = this.index( _mouseX, _mouseY);\r
2321                                 if( currentIndex === -1) return false;\r
2322                                 offsetX = _mouseX;\r
2323                                 offsetY = _mouseY;\r
2324                                 startX = baseX = _currentElement.x;\r
2325                                 startY = baseY = _currentElement.y;\r
2326                                 startW = baseW = _currentElement.w;\r
2327                                 startH = baseH = _currentElement.h;\r
2328                                 if( _currentElement.type === COMIC_ELEMENT_TYPE_IMAGE){\r
2329                                         startFilpV = _currentElement.flipV();\r
2330                                         startFilpH = _currentElement.flipH();                                                   \r
2331                                 }\r
2332                                 startAspect = startW /startH;\r
2333                                 return true;\r
2334                         },\r
2335                         onDrag: function( _mouseX, _mouseY){\r
2336                                 var com = RESIZE_WORK_ARRAY[ currentIndex],\r
2337                                         moveX = _mouseX -offsetX,\r
2338                                         moveY = _mouseY -offsetY,\r
2339                                         _updated = moveX !== 0 || moveY !== 0,\r
2340                                         _x, _y, _w, _h,\r
2341                                         _thisError = 0;\r
2342                                         \r
2343                                 var _memoryX = 0,\r
2344                                         _memoryY = 0,\r
2345                                         _momoryW = 0,\r
2346                                         _momoryH = 0;\r
2347                                 /*\r
2348                                  * Opera 11+ often forget values, why ??\r
2349                                  */\r
2350                                 while( _x === undefined || _y === undefined || _w === undefined || _h === undefined){\r
2351                                         _x = _x !== undefined ? _x : baseX +moveX *com.x;\r
2352                                         _y = _y !== undefined ? _y : baseY +moveY *com.y;\r
2353                                         _w = _w !== undefined ? _w : baseW +moveX *com.w;\r
2354                                         _h = _h !== undefined ? _h : baseH +moveY *com.h;\r
2355                                         error += _thisError === 0 ? 0 : 1;\r
2356                                         ++_thisError;\r
2357                                         if( _thisError > 9999){\r
2358                                                 ++error\r
2359                                                 //alert( 'opera error' +error);\r
2360                                                 this.onCancel;\r
2361                                                 return;\r
2362                                         }\r
2363                                 }\r
2364                                 \r
2365                                 if( _w >= MIN_ELEMENT_SIZE && _h >= MIN_ELEMENT_SIZE){\r
2366                                         \r
2367                                 } else \r
2368                                 if( _w >= -MIN_ELEMENT_SIZE && _h >= -MIN_ELEMENT_SIZE){\r
2369                                         //return;\r
2370                                         if( _w < MIN_ELEMENT_SIZE){\r
2371                                                 //_x += Math.abs( MIN_ELEMENT_SIZE -_w);\r
2372                                                 _x = currentX;\r
2373                                                 _w = MIN_ELEMENT_SIZE;\r
2374                                         }\r
2375                                         if( _h < MIN_ELEMENT_SIZE){\r
2376                                                 //_y += Math.abs( MIN_ELEMENT_SIZE -_h);\r
2377                                                 _y = currentY;\r
2378                                                 _h = MIN_ELEMENT_SIZE;\r
2379                                         }\r
2380                                 } else \r
2381                                 if( currentElement.type === COMIC_ELEMENT_TYPE_TEXT){\r
2382                                         return;\r
2383                                 } else \r
2384                                 if( _w < -MIN_ELEMENT_SIZE || _h < -MIN_ELEMENT_SIZE){\r
2385 \r
2386                                         if( _w < -MIN_ELEMENT_SIZE && _h > MIN_ELEMENT_SIZE){\r
2387                                         // flipH\r
2388                                                 _memoryX = _x;\r
2389                                                 baseX = _x = _x +_w;\r
2390                                                 baseY = _y;\r
2391                                                 baseW = _w = _memoryX -_x;\r
2392                                                 baseH = _h;\r
2393                                                 flip( true, false);\r
2394                                                 flipV = currentElement.flipV();\r
2395                                         } else \r
2396                                         if( _w > MIN_ELEMENT_SIZE && _h < -MIN_ELEMENT_SIZE){\r
2397                                         // flipV\r
2398                                                 _memoryY = _y;\r
2399                                                 baseX = _x;\r
2400                                                 baseY = _y = _y +_h;\r
2401                                                 baseW = _w;\r
2402                                                 baseH = _h = _memoryY -_y;\r
2403                                                 flip( false, true);\r
2404                                                 flipH = currentElement.flipH();\r
2405                                         } else {\r
2406                                         // flipVH\r
2407                                                 _memoryX = _x;\r
2408                                                 _memoryY = _y;\r
2409                                                 baseX = _x = _x +_w;\r
2410                                                 baseY = _y = _y +_h;\r
2411                                                 baseW = _w = _memoryX -_x;\r
2412                                                 baseH = _h = _memoryY -_y;\r
2413                                                 flip( true, true);\r
2414                                                 flipV = currentElement.flipV();\r
2415                                                 flipH = currentElement.flipH();\r
2416                                         }\r
2417                                         _updated = true;\r
2418                                         offsetX = _mouseX;\r
2419                                         offsetY = _mouseY;      \r
2420                                 }\r
2421                                 currentX = _x;\r
2422                                 currentY = _y;\r
2423                                 currentW = _w;\r
2424                                 currentH = _h;\r
2425                                 _updated === true && update( _x, _y, _w, _h);\r
2426                                 \r
2427                                 log.html( [\r
2428                                                 'currentIndex:', currentIndex, \r
2429                                                 'baseW', baseW, 'baseH', baseH,'<br>',\r
2430                                                 'mouse', _mouseX, _mouseY,'<br>',\r
2431                                                 'move', moveX, moveY,'<br>',\r
2432                                                 'xy', _x, _y, 'wh',_w, _h,'<br>',\r
2433                                                 'com.w', com.w, 'com.h', com.h,'<br>',\r
2434                                                 'current',currentW, currentH,'<br>',\r
2435                                                 'result', y, h,\r
2436                                                 'err', error\r
2437                                 ].join( ' , '));\r
2438                         },\r
2439                         onFinish: function(){\r
2440                                 MOUSE_CURSOR( '');\r
2441                                 if( w === startW && h === startH && x === startX && y === startY) return;\r
2442                                 COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h);\r
2443                                 currentElement.resize( x, y, w, h);\r
2444                                 COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY, startW, startH, undefined, startFilpV, startFilpH);\r
2445                         },\r
2446                         onCancel: function(){\r
2447                                 MOUSE_CURSOR( '');\r
2448                                 COMIC_ELEMENT_OPERATION_MANAGER.resize( startX, startY, startW, startH);\r
2449                                 currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
2450                                         currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) :\r
2451                                         currentElement.animate( startX, startY, startW, startH, angle);\r
2452                         },\r
2453                         lock: function( _lock){\r
2454                                 if( _lock !== undefined){\r
2455                                         elmResizerContainerStyle.borderColor = _lock === true ? 'blue' : '';\r
2456                                         lock = _lock;\r
2457                                 }\r
2458                                 return lock;\r
2459                         },\r
2460                         onShiftUpdate: update,\r
2461                         onCtrlUpdate: update\r
2462                 }\r
2463         })();\r
2464         \r
2465         var POSITION_OPERATOR = ( function(){\r
2466                 var     MOUSE_CURSOR = updateMouseCursor,\r
2467                         GRID_ENABLED = GRID_CONTROL.enabled;\r
2468                 \r
2469                 var currentElement,\r
2470                         startX, startY,\r
2471                         x, y,\r
2472                         offsetX, offsetY,\r
2473                         isCopy = false;\r
2474                 \r
2475                 function update( _x, _y){\r
2476                         x = _x !== undefined ? _x : x;\r
2477                         y = _y !== undefined ? _y : y;\r
2478                         RESIZE_OPERATOR.update( x, y);\r
2479                         currentElement.resize( x, y);\r
2480                         INFOMATION_WINDOW.update( currentElement);\r
2481                 }\r
2482                 \r
2483                 return {\r
2484                         onStart: function( _currentElement, _mouseX, _mouseY){\r
2485                                 currentElement = _currentElement;\r
2486                                 offsetX = _mouseX;\r
2487                                 offsetY = _mouseY;\r
2488                                 startX = x = _currentElement.x;\r
2489                                 startY = y = _currentElement.y;\r
2490                                 MOUSE_CURSOR( 'move');\r
2491                         },\r
2492                         onDrag: function( _mouseX, _mouseY){\r
2493                                 var moveX = _mouseX -offsetX,\r
2494                                         moveY = _mouseY -offsetY,\r
2495                                         _x = startX +moveX,\r
2496                                         _y = startY +moveY;\r
2497                                 if( GRID_ENABLED() === true){\r
2498                                         _x = Math.floor( _x / 10) * 10;\r
2499                                         _y = Math.floor( _y / 10) * 10;\r
2500                                 }\r
2501                                 update( _x, _y);\r
2502                         },\r
2503                         onFinish: function(){\r
2504                                 MOUSE_CURSOR( '');\r
2505                                 if( x === startX && y === startY) return;\r
2506                                 COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y);\r
2507                                 currentElement.resize( x, y);\r
2508                                 COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY);\r
2509                         },\r
2510                         onCancel: function(){\r
2511                                 MOUSE_CURSOR( '');\r
2512                                 COMIC_ELEMENT_OPERATION_MANAGER.resize( startX, startY);\r
2513                                 currentElement.animate( startX, startY);\r
2514                         },\r
2515                         onShiftUpdate: update,\r
2516                         onCtrlUpdate: update\r
2517                 }\r
2518         })();\r
2519 \r
2520 \r
2521 /*\r
2522  * --------------------------------------------------------------------------------------------\r
2523  * COMIC_ELEMENT_OPERATION_MANAGER\r
2524  */\r
2525         var COMIC_ELEMENT_OPERATION_MANAGER = ( function(){\r
2526                 var     MOUSE_CURSOR = updateMouseCursor,\r
2527                         SAVE = HISTORY.saveState,\r
2528                         GRID_ENABLED = GRID_CONTROL.enabled,\r
2529                         HIT_AREA = MOUSE_HIT_AREA,\r
2530                         currentIsTextElement = false,\r
2531                         currentOperator = null,\r
2532                         currentElement = null,\r
2533                         currentx, currenty, currentw, currenth, angle, flipV, flipH;\r
2534 \r
2535                         function resize( _x, _y, _w, _h, _angle){\r
2536                                 currentx = _x !== undefined ? _x : currentx;\r
2537                                 currenty = _y !== undefined ? _y : currenty;\r
2538                                 currentw = _w !== undefined ? _w : currentw;\r
2539                                 currenth = _h !== undefined ? _h : currenth;\r
2540                                 angle = _angle !== undefined ? _angle : angle;\r
2541 \r
2542                                 RESIZE_OPERATOR.update( currentx, currenty, currentw, currenth);\r
2543                                 currentIsTextElement === true && TAIL_OPERATOR.update( currentw, currenth, angle);\r
2544                                 CONSOLE_CONTROLER.show( currentElement, currentw, currenth);\r
2545                                 INFOMATION_WINDOW.update( currentElement);\r
2546                         }\r
2547                         function show( _currentElement){\r
2548                                 currentElement === null && RESIZE_OPERATOR.show( _currentElement);\r
2549                                 if( currentElement !== _currentElement){\r
2550                                         currentElement = _currentElement;\r
2551                                         \r
2552                                         currentIsTextElement = ( _currentElement.type === COMIC_ELEMENT_TYPE_TEXT);\r
2553                                         currentIsTextElement === true ? TAIL_OPERATOR.show( _currentElement) : TAIL_OPERATOR.hide();\r
2554                                         \r
2555                                         flipV = currentIsTextElement === false ? _currentElement.flipV() : 0;\r
2556                                         flipH = currentIsTextElement === false ? _currentElement.flipH() : 0;\r
2557                                         \r
2558                                         resize(\r
2559                                                 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,\r
2560                                                 currentIsTextElement === true ? _currentElement.angle() : 0\r
2561                                         );\r
2562                                 }\r
2563                         }\r
2564                         function hide(){\r
2565                                 currentElement !== null && RESIZE_OPERATOR.hide();\r
2566                                 currentElement = null;\r
2567                                 MOUSE_CURSOR( '');\r
2568                                 TAIL_OPERATOR.hide();\r
2569                                 CONSOLE_CONTROLER.hide();\r
2570                                 INFOMATION_WINDOW.update( null);\r
2571                         }\r
2572                         function restoreState( arg){\r
2573                                 if( arg && arg.length !== 8) return;\r
2574                                 var _currentElement = arg[ 0],\r
2575                                         _x = arg[ 1], _y = arg[ 2], _w = arg[ 3], _h = arg[ 4],\r
2576                                         _a = arg[ 5],\r
2577                                         _flipV = arg[ 6], _flipH = arg[ 7];\r
2578                                 if( !_currentElement && !currentOperator) return;\r
2579                                 _currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
2580                                         _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH) :\r
2581                                         _currentElement.animate( _x, _y, _w, _h, _a);\r
2582                                 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();\r
2583                                 currentOperator = null;\r
2584                                 currentElement === _currentElement ? resize( _x, _y, _w, _h, _a) : show( _currentElement);\r
2585                         }\r
2586                         function saveComicElementStatus( startX, startY, startW, startH, startA, startFilpV, startFilpH){\r
2587                                 startX = startX !== undefined ? startX : currentx;\r
2588                                 startY = startY !== undefined ? startY : currenty;\r
2589                                 startW = startW !== undefined ? startW : currentw;\r
2590                                 startH = startH !== undefined ? startH : currenth;\r
2591                                 startA = startA !== undefined ? startA : angle;\r
2592                                 startFilpV = startFilpV !== undefined ? startFilpV : flipV;\r
2593                                 startFilpH = startFilpH !== undefined ? startFilpH : flipH;\r
2594                                 currentElement && SAVE( restoreState,\r
2595                                         [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH],\r
2596                                         [ currentElement, currentx, currenty, currentw, currenth, angle, flipV, flipH]\r
2597                                 );\r
2598                         }\r
2599                         pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 16, undefined, undefined, function( e){\r
2600                                 currentOperator !== null && currentOperator.onShiftUpdate && currentOperator.onShiftUpdate();\r
2601                         });\r
2602                         pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 17, undefined, undefined, function(){\r
2603                                 currentOperator !== null && currentOperator.onCtrlUpdate && currentOperator.onCtrlUpdate();\r
2604                         });\r
2605                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 27, false, false, function(){\r
2606                                 currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel();\r
2607                                 currentOperator = null;\r
2608                         });\r
2609                 return {\r
2610                         init: function(){\r
2611                                 hide();\r
2612                                 delete COMIC_ELEMENT_OPERATION_MANAGER.init;\r
2613                         },\r
2614                         hide: hide,\r
2615                         resize: resize,\r
2616                         restoreState: restoreState,\r
2617                         saveStatus: saveComicElementStatus,\r
2618                         busy: function(){\r
2619                                 return currentOperator !== null;\r
2620                         },\r
2621                         hitTest: function( _mouseX, _mouseY, _comicElement){\r
2622                                 var _x, _y, _w, _h;\r
2623                                 if( _comicElement === currentElement){\r
2624                                         var _consoleX = CONSOLE_CONTROLER.x();\r
2625                                         _x = currentx +( _consoleX < 0 ? _consoleX : 0) -HIT_AREA;\r
2626                                         _y = currenty -HIT_AREA;\r
2627                                         var _consoleW = CONSOLE_CONTROLER.w();\r
2628                                         _w = ( _consoleW < currentw ? currentw : _consoleW) +HIT_AREA *2;\r
2629                                         var _consoleY = CONSOLE_CONTROLER.y();\r
2630                                         _h = ( _consoleY < currenth ? currenth : _consoleY +CONSOLE_CONTROLER.h()) +HIT_AREA *2;\r
2631                                 } else {\r
2632                                         _x = _comicElement.x -HIT_AREA;\r
2633                                         _y = _comicElement.y -HIT_AREA;\r
2634                                         _w = _comicElement.w +HIT_AREA *2;\r
2635                                         _h = _comicElement.h +HIT_AREA *2;\r
2636                                 }\r
2637                                 return _x <= _mouseX && _mouseX <= _x + _w && _y <= _mouseY && _mouseY <= _y + _h;\r
2638                         },\r
2639                         onMouseDown: function( _currentElement, _mouseX, _mouseY){\r
2640                                 //show( _currentElement);\r
2641                                 if( currentIsTextElement === true && TAIL_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){\r
2642                                         currentOperator = TAIL_OPERATOR;\r
2643                                 } else\r
2644                                 if( RESIZE_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){\r
2645                                         currentOperator = RESIZE_OPERATOR;\r
2646                                 } else {\r
2647                                         POSITION_OPERATOR.onStart( _currentElement, _mouseX, _mouseY)\r
2648                                         currentOperator = POSITION_OPERATOR;\r
2649                                 }\r
2650                         },\r
2651                         onMouseMove: function( _currentElement, _mouseX, _mouseY){\r
2652                                 show( _currentElement);\r
2653                                 if( currentOperator !== null){\r
2654                                         currentOperator.onDrag( _mouseX, _mouseY);                                              \r
2655                                 } else\r
2656                                 if( currentElement !== null){\r
2657                                         CONSOLE_CONTROLER.onMouseMove( _mouseX -currentx, _mouseY -currenty);\r
2658                                         if( currentIsTextElement === false || TAIL_OPERATOR.hitTest( _mouseX -currentx, _mouseY -currenty) === false){\r
2659                                                 RESIZE_OPERATOR.index( _mouseX, _mouseY);\r
2660                                         }\r
2661                                 }\r
2662                         },\r
2663                         onMouseUp: function( _currentElement, _mouseX, _mouseY){\r
2664                                 currentOperator !== null && currentOperator.onFinish();\r
2665                                 currentOperator = null;\r
2666                         }\r
2667                 }\r
2668         })();\r
2669         /*\r
2670          *  // COMIC_ELEMENT_OPERATION_MANAGER\r
2671          */\r
2672 \r
2673         var AbstractComicElement = function( JQ_WAPPER, COMIC_ELM_TYPE, update, x, y, w, h, z, timing){\r
2674                 var OPERATOR = COMIC_ELEMENT_OPERATION_MANAGER;\r
2675                 return {\r
2676                         $: JQ_WAPPER,\r
2677                         type: COMIC_ELM_TYPE,\r
2678                         x: x,\r
2679                         y: y,\r
2680                         w: w,\r
2681                         h: h,                                   \r
2682                         z: z,\r
2683                         timing: timing,\r
2684                         hitTest: function( _mouseX, _mouseY){ return OPERATOR.hitTest(  _mouseX, _mouseY, this);},\r
2685                         shift: function( _shiftX, _shiftY){\r
2686                                 update( this.x +_shiftX, this.y +_shiftY);\r
2687                         },\r
2688                         busy: function(){\r
2689                                 return OPERATOR.busy();\r
2690                         },\r
2691                         onMouseMove: function( _mouseX, _mouseY){\r
2692                                 OPERATOR.onMouseMove( this, _mouseX, _mouseY);\r
2693                         },\r
2694                         onMouseUp: function( _mouseX, _mouseY){\r
2695                                 OPERATOR.onMouseUp( this, _mouseX, _mouseY);\r
2696                         },\r
2697                         onMouseDown: function( _mouseX, _mouseY){\r
2698                                 OPERATOR.onMouseDown( this, _mouseX, _mouseY);\r
2699                         }\r
2700                 }\r
2701         };\r
2702 /*\r
2703  * --------------------------------------------------------------------------------------------\r
2704  * ImageElementClass\r
2705  */\r
2706         var     jqImageElementOrigin;\r
2707         var ImageElementClass = function( url, IMAGE_SET_ID, x, y, z, w, h, timing){\r
2708                 jqImageElementOrigin = jqImageElementOrigin || $( $( '#imgElementTemplete').remove().html());\r
2709                 \r
2710                 var JQ_WRAPPER = jqImageElementOrigin.clone( true),\r
2711                         OPERATOR = COMIC_ELEMENT_OPERATION_MANAGER,\r
2712                         SAVE = HISTORY.saveState,\r
2713                         HIT_AREA = MOUSE_HIT_AREA,\r
2714                         reversibleImage = null,\r
2715                         actualW = 0, actualH = 0,\r
2716                         flipH = w < 0 ? -1 : 1,\r
2717                         flipV = h < 0 ? -1 : 1,\r
2718                         instance;\r
2719                 w = Math.floor( w);\r
2720                 h = Math.floor( h);\r
2721                 \r
2722                 function update( _x, _y, _w, _h, animate){\r
2723                         instance.x = x = _x !== undefined ? _x : x;\r
2724                         instance.y = y = _y !== undefined ? _y : y;\r
2725                         instance.w = w = _w !== undefined ? _w : w;\r
2726                         instance.h = h = _h !== undefined ? _h : h;\r
2727                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( { \r
2728                                 left:   x,\r
2729                                 top:    y,\r
2730                                 width:  w,\r
2731                                 height: h\r
2732                         }, 250, onAnimeComplete);\r
2733                         animate !== true && onAnimeComplete();\r
2734                 }\r
2735                 function onAnimeComplete(){\r
2736                         reversibleImage.resize( flipH * w, flipV * h);\r
2737                 }\r
2738                 \r
2739                 function updateUrl( _url){\r
2740                         if( url === _url) return;\r
2741                         url = _url || url;\r
2742                         var _reversibleImage = pettanr.image.createReversibleImage( url, flipH * w, flipV * h, function( _url, _actualW, _actualH){\r
2743                                 actualW = _actualW;\r
2744                                 actualH = _actualH;\r
2745                         });\r
2746                         if( reversibleImage !== null){\r
2747                                 JQ_WRAPPER.children( reversibleImage.elm).replaceWith( _reversibleImage.elm);\r
2748                                 reversibleImage.destroy();\r
2749                         } else {\r
2750                                 JQ_WRAPPER.append( _reversibleImage.elm);\r
2751                         }\r
2752                         reversibleImage = _reversibleImage;\r
2753                 }\r
2754                 return pettanr.util.extend(\r
2755                         new AbstractComicElement( JQ_WRAPPER, COMIC_ELEMENT_TYPE_IMAGE, update, x, y, w, h, z, timing),\r
2756                         {\r
2757                                 init: function(){\r
2758                                         instance = this;\r
2759                                         updateUrl();\r
2760                                         update();\r
2761                                         delete this.init;\r
2762                                 },\r
2763                                 flip: function( _flipH, _flipV){\r
2764                                         if( _flipH !== true && _flipV !== true) return;\r
2765                                         flipH = _flipH === true ? -flipH : flipH;\r
2766                                         flipV = _flipV === true ? -flipV : flipV;\r
2767                                         reversibleImage.resize( flipH * w, flipV * h);\r
2768                                 },\r
2769                                 flipV: function(){\r
2770                                         return flipV;\r
2771                                 },\r
2772                                 flipH: function(){\r
2773                                         return flipH;\r
2774                                 },\r
2775                                 url: function( _url, _actualW, _actualH){\r
2776                                         if( _url && _url !== url){\r
2777                                                 SAVE( updateUrl, url, _url);\r
2778                                                 actualW = _actualW;\r
2779                                                 actualH = _actualH;\r
2780                                                 updateUrl( _url);\r
2781                                         }\r
2782                                         return url;\r
2783                                 },\r
2784                                 actualW: function(){ return actualW;},\r
2785                                 actualH: function(){ return actualH;},\r
2786                                 keepSize: false,\r
2787                                 resize: update,\r
2788                                 animate: function ( _x, _y, _w, _h, _flipH, _flipV){\r
2789                                         flipH = _flipH !== undefined ? _flipH : flipH;\r
2790                                         flipV = _flipV !== undefined ? _flipV : flipV;\r
2791                                         update( _x, _y, _w, _h, true);\r
2792                                 },\r
2793                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
2794                                         return [\r
2795                                                 '<img ',\r
2796                                                         'src="', isAbsoluteUrl !== true ? url : pettanr.util.getAbsolutePath( url), '" ',\r
2797                                                         'width="', w, '" ',\r
2798                                                         'height="', h, '" ',\r
2799                                                         'style="',                                                                      \r
2800                                                                 'left:', x, 'px;',\r
2801                                                                 'top:', y, 'px;',\r
2802                                                                 'z-index:', this.z, ';',\r
2803                                                         '"',\r
2804                                                 isXHTML !== true ? '>' : ' \/>'\r
2805                                         ].join( '');\r
2806                                 },\r
2807                                 getAsJsonString: function(){\r
2808                                         var cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
2809                                         return [\r
2810                                                 '"new', this.timing, '": {', cr,\r
2811                                                         '"resource_picture_id": 1,', cr,\r
2812                                                         '"x": ', x, ',', cr,\r
2813                                                         '"y": ', y, ',', cr,\r
2814                                                         '"z": ', this.z, ',', cr,\r
2815                                                         '"width": ', w, ',', cr,\r
2816                                                         '"height": ', h, ',', cr,\r
2817                                                         '"flipv": ', flipV === true ? 1 : 0, ',', cr,\r
2818                                                         '"fliph": ', flipH === true ? 1 : 0, ',', cr,\r
2819                                                         '"t": ', this.timing, cr,\r
2820                                                 '}'\r
2821                                         ].join( '');\r
2822                                 },\r
2823                                 destroy: function(){\r
2824                                         reversibleImage.destroy();\r
2825                                         JQ_WRAPPER.remove();\r
2826                                         JQ_WRAPPER = reversibleImage = OPERATOR = null;\r
2827                                         delete this.destroy;\r
2828                                 }\r
2829                         }\r
2830                 );\r
2831         }\r
2832 /*\r
2833  * / ImageElementClass\r
2834  * --------------------------------------------------------------------------------------------\r
2835  */\r
2836 \r
2837 \r
2838 /*\r
2839  * --------------------------------------------------------------------------------------------\r
2840  * TextElementClass\r
2841  * \r
2842  * ELM はpettanr.domで書き出したものを突っ込むcreateの場合\r
2843  * \r
2844  * type\r
2845  * 0.none\r
2846  * 1.speach balloon\r
2847  * 2.think\r
2848  * 3.bom\r
2849  * 4.black-box( dq style)\r
2850  * 5.blue-box( ff style)\r
2851  * \r
2852  */\r
2853         var jqTextElementOrigin;\r
2854         var TextElementClass = function( type, a, text, x, y, z, w, h, timing){\r
2855                 jqTextElementOrigin = jqTextElementOrigin || ( function(){\r
2856                         var _OLD_IE = $( $( '#textElementTempleteForOldIE').remove().html()),\r
2857                                 _MODERN = $( $( '#textElementTemplete').remove().html());\r
2858                         return pettanr.ua.isIE === true && pettanr.ua.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;\r
2859                 })();\r
2860                 \r
2861                 var JQ_WRAPPER = jqTextElementOrigin.clone( true),\r
2862                         XBROWSER_BALLOON = pettanr.balloon.createBalloon( w, h, a, type),\r
2863                         TEXT_ELM = JQ_WRAPPER.find( 'td,.speach-inner').eq( 0),\r
2864                         OPERATOR = COMIC_ELEMENT_OPERATION_MANAGER,\r
2865                         HIT_AREA = MOUSE_HIT_AREA,\r
2866                         SAVE = HISTORY.saveState,\r
2867                         instance;\r
2868                         \r
2869                 JQ_WRAPPER.find( 'img').eq( 0).replaceWith( XBROWSER_BALLOON.elm);\r
2870                 \r
2871                 function update( _x, _y, _w, _h, _a, animate){\r
2872                         instance.x = x = _x !== undefined ? _x : x;\r
2873                         instance.y = y = _y !== undefined ? _y : y;\r
2874                         instance.w = w = _w !== undefined ? _w : w;\r
2875                         instance.h = h = _h !== undefined ? _h : h;\r
2876                         a = _a !== undefined ? _a : a;\r
2877                         \r
2878                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {\r
2879                                         left:           x,\r
2880                                         top:            y,\r
2881                                         width:          w,\r
2882                                         height:         h\r
2883                                 }, 250,\r
2884                                 function(){\r
2885                                         XBROWSER_BALLOON.resize( a, w, h);\r
2886                                 }\r
2887                         );              \r
2888                         animate !== true && XBROWSER_BALLOON.resize( a, w, h);\r
2889                 }\r
2890                 \r
2891                 function updateType( _type){\r
2892                         if( type !== _type){\r
2893                                 type = _type || type;\r
2894                                 XBROWSER_BALLOON.type( type);\r
2895                         }\r
2896                 }\r
2897                 function updateAngle( _a){\r
2898                         if( _a !== undefined && a !== _a){\r
2899                                 a = _a !== undefined ? _a : a;\r
2900                                 XBROWSER_BALLOON.angle( a);\r
2901                         }\r
2902                 }\r
2903                 function updateText( _text){\r
2904                         text = _text || text || '';\r
2905                         TEXT_ELM.html( text);\r
2906                 }\r
2907                 \r
2908                 return pettanr.util.extend(\r
2909                         new AbstractComicElement( JQ_WRAPPER, COMIC_ELEMENT_TYPE_TEXT, update, x, y, w, h, z, timing),\r
2910                         {\r
2911                                 init: function(){\r
2912                                         instance = this;\r
2913                                         updateText();\r
2914                                         update();\r
2915                                         delete this.init;\r
2916                                 },\r
2917                                 angle: function( _a){\r
2918                                         _a !== undefined && update( undefined, undefined, undefined, undefined, _a);\r
2919                                         return a;\r
2920                                 },\r
2921                                 text: function( _text){\r
2922                                         if( _text && text !== _text) {\r
2923                                                 SAVE( updateText, text || '', _text);\r
2924                                                 updateText( _text);\r
2925                                         }\r
2926                                         return text;\r
2927                                 },\r
2928                                 resize: update,\r
2929                                 animate: function ( _x, _y, _w, _h, _a){\r
2930                                         update( _x, _y, _w, _h, _a, true);\r
2931                                 },\r
2932                                 destroy: function(){\r
2933                                         JQ_WRAPPER.remove();\r
2934                                         XBROWSER_BALLOON.destroy();\r
2935                                         OPERATOR = null;\r
2936                                         delete this.destroy;\r
2937                                 },\r
2938                                 getAsJSON: function(){\r
2939                                         \r
2940                                 },\r
2941                                 getAsJsonString: function(){\r
2942                                         var cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
2943                                         return [\r
2944                                                 '"new', this.timing, '": {', cr,\r
2945                                                         '"balloon_template_id": ', 1, ',', cr,\r
2946                                                         '"system_picture_id": ', 1, ',', cr,\r
2947                                                         '"size": ', 1, ',', cr,\r
2948                                                         '"tail": ', a, ',', cr,\r
2949                                                         '"x": ', x, ',', cr,\r
2950                                                         '"y": ', y, ',', cr,\r
2951                                                         '"z": ', this.z, ',', cr,\r
2952                                                         '"t": ', this.timing, ',', cr,\r
2953                                                         '"width": ', w, ',', cr,\r
2954                                                         '"height": ', h, ',', cr,\r
2955                                                         '"speaches_attributes": {', cr,\r
2956                                                         '"newf', this.timing, '": {', cr,\r
2957                                                         '"content": "', text, '",', cr,\r
2958                                                                         '"x": ', x, ',', cr,\r
2959                                                                         '"y": ', y, ',', cr,\r
2960                                                                         '"t": ', 0, ',', cr,\r
2961                                                                         '"width": ', w, ',', cr,\r
2962                                                                         '"height": ', h, cr,\r
2963                                                                 '}', cr,\r
2964                                                         '}', cr,\r
2965                                                 '}'\r
2966                                         ].join( '');\r
2967                                 },\r
2968                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
2969                                         var url = XBROWSER_BALLOON.getURL();\r
2970                                         return [\r
2971                                                 '<img ',\r
2972                                                         'src="', isAbsoluteUrl !== true ? url : pettanr.util.getAbsolutePath( url), '" ',\r
2973                                                         'width="', w, '" ',\r
2974                                                         'height="', h, '" ',\r
2975                                                         'style="',                                                                      \r
2976                                                                 'left:', x, 'px;',\r
2977                                                                 'top:', y, 'px;',\r
2978                                                                 'z-index:', this.z, ';',\r
2979                                                         '"',\r
2980                                                 isXHTML !== true ? '>' : ' \/>',\r
2981                                                 pettanr.LINE_FEED_CODE_TEXTAREA,\r
2982                                                 '<div class="balloon" style="',\r
2983                                                         'left:', x, 'px;',\r
2984                                                         'top:', y, 'px;',\r
2985                                                         'width:', w, 'px;',\r
2986                                                         'height:', h, 'px;',\r
2987                                                         'z-index:', this.z,\r
2988                                                 '"><span>', text, '<\/span>', '<\/div>'\r
2989                                                         \r
2990                                         ].join( '');\r
2991                                 },\r
2992                                 getAsXML: function(){}\r
2993                                 \r
2994                         }\r
2995                 );\r
2996         }\r
2997 \r
2998 \r
2999         var COMIC_ELEMENT_CONTROL = ( function(){\r
3000                 var     SAVE = HISTORY.saveState,\r
3001                         ELM_CONTAINER = document.getElementById( 'comic-element-container'),\r
3002                         currentElement = null,\r
3003                         currentLockTest = false,\r
3004                         currentLock = false,\r
3005                         panelX, panelY, panelW, panelH,\r
3006                         startX, startY;\r
3007         \r
3008         /*\r
3009          * append, remove, replace\r
3010          * \r
3011          * comicElement には、z-position と dom-index がある。\r
3012          *   z-position は 表示上の位置。大きいほど前に表示される( z-index)\r
3013          *   dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。\r
3014          * \r
3015          * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。\r
3016          * dom-index は、数値のみ保持して、投稿時にcomicElementを適宜に並び替える。\r
3017          * \r
3018          * append comicElement\r
3019          * 1. 新しい comicElement の z-position を得る\r
3020          * 2. z の同じ comicElementを見つけ、その前に加える。または一番先頭へ。(COMIC_ELEMENT_ARRAY)\r
3021          *    zが大きいほど、COMIC_ELEMENT_ARRAYの先頭へ。\r
3022          * 3. dom位置は、COMIC_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。\r
3023          * \r
3024          * \r
3025          * remove comicElement\r
3026          * 1. remove\r
3027          * 2. renumber z\r
3028          */\r
3029                 function appendComicElement( _comicElement) {\r
3030                         _comicElement.init && _comicElement.init();\r
3031                         var z = _comicElement.z,\r
3032                                 l = COMIC_ELEMENT_ARRAY.length,\r
3033                                 _jqElm = _comicElement.$.stop().css( {\r
3034                                         filter:         '',\r
3035                                         opacity:        ''\r
3036                                 });\r
3037                         if( typeof z !== 'number' || z < 0 || z >= l){\r
3038                                 COMIC_ELEMENT_ARRAY.unshift( _comicElement);\r
3039                                 ELM_CONTAINER.appendChild( _jqElm.get( 0));\r
3040                                 _jqElm.fadeIn();\r
3041                         } else {\r
3042                                 var insertIndex = 0;\r
3043                                 for( var i = 0; i < l; ++i){\r
3044                                         if( COMIC_ELEMENT_ARRAY[ i].z <= z){\r
3045                                                 insertIndex = i;\r
3046                                                 break;\r
3047                                         }\r
3048                                 }\r
3049                                 COMIC_ELEMENT_ARRAY[ insertIndex].$.before( _jqElm.fadeIn());\r
3050                                 COMIC_ELEMENT_ARRAY.splice( insertIndex, 0, _comicElement);\r
3051                         }\r
3052                         renumber();\r
3053                 }\r
3054                 function removeComicElement( _comicElement) {\r
3055                         var l = COMIC_ELEMENT_ARRAY.length;\r
3056                         for( var i=0; i<l; ++i){\r
3057                                 if( COMIC_ELEMENT_ARRAY[ i] === _comicElement){\r
3058                                         COMIC_ELEMENT_ARRAY.splice( i, 1);\r
3059                                         renumber();\r
3060                                         _comicElement.$.stop().css( {\r
3061                                                 filter:         '',\r
3062                                                 opacity:        ''\r
3063                                         }).fadeOut( onFadeOut);\r
3064                                         currentElement = currentElement === _comicElement ? null : currentElement;\r
3065                                         return;\r
3066                                 }\r
3067                         }\r
3068                         function onFadeOut(){\r
3069                                 this.parentNode.removeChild( this);\r
3070                         }\r
3071                 }\r
3072                 function restoreComicElement( arg){\r
3073                         var isAppend = arg[ 0],\r
3074                                 comicElement = arg[ 1];\r
3075                         isAppend === true ? appendComicElement( comicElement) : removeComicElement( comicElement);\r
3076                 }\r
3077                 /*\r
3078                  * COMIC_ELEMENT_ARRAY の順番を基準に、zの再計算\r
3079                  * jqElmの並び替え。\r
3080                  */\r
3081                 function renumber(){\r
3082                         var l = COMIC_ELEMENT_ARRAY.length,\r
3083                                 _comicElement, jqElm, jqNext;\r
3084                         for( var i=0; i < l; ++i){\r
3085                                 _comicElement = COMIC_ELEMENT_ARRAY[ i];\r
3086                                 jqElm = _comicElement.$;\r
3087                                 jqNext && jqNext.before( jqElm);\r
3088                                 _comicElement.z = l -i -1;\r
3089                                 jqNext = jqElm;\r
3090                         }\r
3091                 }\r
3092                 function replaceComicElement( _comicElement, goForward){\r
3093                         // COMIC_ELEMENT_ARRAYの再構築\r
3094                         var l = COMIC_ELEMENT_ARRAY.length,\r
3095                                 i = ( function(){\r
3096                                         for( var ret = 0; ret < l; ++ret){\r
3097                                                 if( COMIC_ELEMENT_ARRAY[ ret] === _comicElement) return ret;\r
3098                                         }\r
3099                                         return -1;\r
3100                                 })();\r
3101                         if( i === -1) return false;\r
3102                         if( goForward === true){\r
3103                                 if( i === 0) return false;\r
3104                                 COMIC_ELEMENT_ARRAY.splice( i, 1);\r
3105                                 COMIC_ELEMENT_ARRAY.splice( i -1, 0, _comicElement);\r
3106                         } else {\r
3107                                 if( i === l -1) return false;\r
3108                                 COMIC_ELEMENT_ARRAY.splice( i, 1);\r
3109                                 COMIC_ELEMENT_ARRAY.splice( i +1, 0, _comicElement);\r
3110                         }\r
3111                         renumber();\r
3112                         return true;\r
3113                 }\r
3114                 function restoreReplaceElement( arg){\r
3115                         replaceComicElement( arg[ 0], arg[ 1]);\r
3116                 }\r
3117                 \r
3118                 return {\r
3119                         init: function(){\r
3120                                 \r
3121                                 appendComicElement( ImageElementClass.apply( {}, [ 'resource_pictures/13.gif', 'penchan', 10, 10, 0, 100, 140, 0]));\r
3122                                 appendComicElement( TextElementClass.apply( {}, [ 0, 270, 'Hello', 50, 70, 1, 200, 160, 1]));\r
3123                         /*\r
3124                          * \r
3125                          */\r
3126                                 log = $( '#operation-catcher-log');\r
3127                                 \r
3128                                 delete COMIC_ELEMENT_CONTROL.init;\r
3129                         },\r
3130                         remove: removeComicElement,\r
3131                         restore: restoreComicElement,\r
3132                         replace: replaceComicElement,\r
3133                         restoreReplace: restoreReplaceElement,\r
3134                         onPanelResize : function ( _panelX, _panelY, _panelW, _panelH, isResizerTopAction){\r
3135                         /*\r
3136                          * リサイズが、ResizerTopによって行われた場合、comicElementのyを動かして見かけ上動かないようにする。\r
3137                          */                                     \r
3138                                 if( isResizerTopAction === true){\r
3139                                         var     _shiftX = _panelW -panelW,\r
3140                                                 _shiftY = _panelH -panelH,\r
3141                                                 l = COMIC_ELEMENT_ARRAY.length;\r
3142                                         for( var i = 0; i < l; i++){\r
3143                                                 COMIC_ELEMENT_ARRAY[ i].shift( _shiftX, _shiftY);\r
3144                                         }\r
3145                                 }\r
3146                                 panelX = _panelX;\r
3147                                 panelY = _panelY;\r
3148                                 panelW = _panelW;\r
3149                                 panelH = _panelH;\r
3150                                 \r
3151                                 ELM_CONTAINER.style.width       = _panelW +'px';\r
3152                                 ELM_CONTAINER.style.height      = _panelH +'px';\r
3153                                 ELM_CONTAINER.style.left        = _panelX +'px';\r
3154                                 ELM_CONTAINER.style.top         = _panelY +'px';\r
3155                         },\r
3156                         onMouseMove: function( _mouseX, _mouseY){\r
3157                                 var l = COMIC_ELEMENT_ARRAY.length,\r
3158                                         _x = _mouseX -panelX,\r
3159                                         _y = _mouseY -panelY,\r
3160                                         _elm = currentElement;\r
3161                                         \r
3162                                 if( _elm !== null){\r
3163                                         currentLockTest = currentLockTest === true && _x === 0 && _y === 0;\r
3164                                         if( _elm.busy() === true){\r
3165                                                 _elm.onMouseMove( _x, _y);\r
3166                                                 return true;\r
3167                                         }\r
3168                                         if( _elm.hitTest( _x, _y) === true){\r
3169                                                 _elm.onMouseMove( _x, _y); // cursor\r
3170                                                 return true;\r
3171                                         }\r
3172                                         if( currentLock === true){\r
3173                                                 currentLockTest = true;\r
3174                                                 return true;\r
3175                                         }\r
3176                                 }\r
3177                                 for( var i=0; i<l; i++){\r
3178                                         _elm = COMIC_ELEMENT_ARRAY[ i];\r
3179                                         // hitTest\r
3180                                         if( _elm.hitTest( _x, _y) === true){\r
3181                                                 _elm.onMouseMove( _x, _y); // cursor\r
3182                                                 log.html( [ _x, _y, i].join( ','));\r
3183                                                 currentElement = _elm;\r
3184                                                 return true;\r
3185                                         }\r
3186                                 }\r
3187                                 currentElement = null;                                                  \r
3188                                 COMIC_ELEMENT_OPERATION_MANAGER.hide();\r
3189                                 log.html( [ _x, _y].join( ','));\r
3190                                 return false;\r
3191                         },\r
3192                         onMouseUp: function( _mouseX, _mouseY){\r
3193                                 var ret = currentElement !== null && currentElement.busy() === true;\r
3194                                 ret === true && currentElement.onMouseUp( _mouseX -startX || panelX, _mouseY -startY || panelY);\r
3195                                 currentLock = currentLockTest === true && currentElement.hitTest( _mouseX -panelX, _mouseY -panelY) === true;\r
3196                                 RESIZE_OPERATOR.lock( currentLock);\r
3197                                 INFOMATION_WINDOW.lock( currentLock);\r
3198                                 return ret;\r
3199                         },\r
3200                         onMouseDown: function( _mouseX, _mouseY){\r
3201                                 startX = panelX;\r
3202                                 startY = panelY;\r
3203                                 if( currentElement === null) return false\r
3204                                 currentElement.onMouseDown( _mouseX -startX, _mouseY -startY);\r
3205                                 currentLockTest = true;\r
3206                                 return true;\r
3207                         },\r
3208                         busy: function(){\r
3209                                 return currentElement !== null;\r
3210                         },\r
3211                         createImageElement: function( url, imagesetID, x, y, z, w, h){\r
3212                                 w = w || 200; //ActualWidth\r
3213                                 h = h || 150; //ActualHeight\r
3214                                 x = x || Math.floor( panelW /2 -w /2);\r
3215                                 y = y || Math.floor( panelH /2 -h /2);\r
3216                                 function onImageSelect( _url, _w, _h){\r
3217                                         var _comicElement = new ImageElementClass( _url, imagesetID, x, y, z || -1, _w, _h, COMIC_ELEMENT_ARRAY.length);\r
3218                                         appendComicElement( _comicElement);\r
3219                                         _comicElement.animate( undefined, undefined, _w, _h);\r
3220                                         SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);                                      \r
3221                                 }\r
3222                                 IMAGE_GROUP_EXPROLER.show( onImageSelect);\r
3223                         },\r
3224                         createTextElement: function( type, angle, text, x, y, z, w, h){\r
3225                                 type = type || 0;\r
3226                                 angle = angle || 0;\r
3227                                 text = text || '';\r
3228                                 w = w || 200;\r
3229                                 h = h || 150;\r
3230                                 x = x || Math.floor( panelW /2 -w /2 +Math.random() *10);\r
3231                                 y = y || Math.floor( panelH /2 -h /2 +Math.random() *10);\r
3232                                 var _comicElement = TextElementClass.apply( {}, [ type, angle, text, x, y, z || -1, w, h, COMIC_ELEMENT_ARRAY.length]);\r
3233                                 TEXT_EDITOR_CONTROL.show( _comicElement, function( _comicElement){\r
3234                                         appendComicElement( _comicElement);\r
3235                                         SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);\r
3236                                 });\r
3237                         },\r
3238                         getAsHTML: function( isAbsoluteUrl, isXHTML){\r
3239                                 var HTML_ARRAY = [],\r
3240                                         l = COMIC_ELEMENT_ARRAY.length,\r
3241                                         _timing = 0,\r
3242                                         _comicElement;\r
3243 \r
3244                                 while( HTML_ARRAY.length < l){\r
3245                                         _comicElement = getComicElementByTiming();\r
3246                                         if( _comicElement === null) break;\r
3247                                         HTML_ARRAY.push( _comicElement.getAsHTML( isAbsoluteUrl, isXHTML));\r
3248                                 }\r
3249                                 function getComicElementByTiming(){\r
3250                                         while( _timing < l *2){\r
3251                                                 for(var i=0; i<l; ++i){\r
3252                                                         if( _timing === COMIC_ELEMENT_ARRAY[ i].timing){\r
3253                                                                 ++_timing;\r
3254                                                                 return COMIC_ELEMENT_ARRAY[ i];\r
3255                                                         }\r
3256                                                 }\r
3257                                                 ++_timing;\r
3258                                         }\r
3259                                         return null;\r
3260                                 }\r
3261                                 HTML_ARRAY.unshift(\r
3262                                         [\r
3263                                                 '<div class="panel" ',\r
3264                                                         'style="',\r
3265                                                                 'height:', panelH, 'px;',\r
3266                                                                 'background-color:', ';',\r
3267                                                         '"',\r
3268                                                 '>'\r
3269                                         ].join( '')\r
3270                                 );              \r
3271                                 HTML_ARRAY.push( '</div>');\r
3272                                 \r
3273                                 return HTML_ARRAY.join( pettanr.LINE_FEED_CODE_TEXTAREA);\r
3274                         },\r
3275                         getAsJsonString: function(){\r
3276                                 var JSON_STRING_ARRAY = [],\r
3277                                         IMAGE_ARRAY = [],\r
3278                                         BALLOON_ARRAY = [],\r
3279                                         l = COMIC_ELEMENT_ARRAY.length,\r
3280                                         _timing = 0,\r
3281                                         _comicElement,\r
3282                                         cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
3283                                         \r
3284                                 while( IMAGE_ARRAY.length + BALLOON_ARRAY.length < l){\r
3285                                         _comicElement = getComicElementByTiming();\r
3286                                         if( _comicElement === null) break;\r
3287                                         _comicElement.type === COMIC_ELEMENT_TYPE_IMAGE ? \r
3288                                                 IMAGE_ARRAY.push( _comicElement.getAsJsonString()) :\r
3289                                                 BALLOON_ARRAY.push( _comicElement.getAsJsonString());\r
3290                                 }\r
3291                                 function getComicElementByTiming(){\r
3292                                         while( _timing < l *2){\r
3293                                                 for(var i=0; i<l; ++i){\r
3294                                                         if( _timing === COMIC_ELEMENT_ARRAY[ i].timing){\r
3295                                                                 ++_timing;\r
3296                                                                 return COMIC_ELEMENT_ARRAY[ i];\r
3297                                                         }\r
3298                                                 }\r
3299                                                 ++_timing;\r
3300                                         }\r
3301                                         return null;\r
3302                                 }\r
3303                                 return [\r
3304                                         '{', cr,\r
3305                                                 '"panel": {', cr,\r
3306                                                     '"border": 1,', cr,\r
3307                                                     '"comic_id": 5,', cr,\r
3308                                                     '"resource_picture_id": 1,', cr,\r
3309                                                         '"x": ', 0, ',', cr,\r
3310                                                         '"y": ', 0, ',', cr,\r
3311                                                         '"z": ', 0, ',', cr,\r
3312                                                         '"t": ', 0, ',', cr,\r
3313                                                     '"width": ', panelW, ',', cr,\r
3314                                                     '"height": ', panelH, ',', cr,\r
3315                                                     '"panel_pictures_attributes": {', cr,\r
3316                                                         IMAGE_ARRAY.join( ',' +cr), cr,\r
3317                                                     '},', cr,\r
3318                                                     '"balloons_attributes": {', cr,\r
3319                                                         BALLOON_ARRAY.join( ',' +cr), cr,\r
3320                                                     '}', cr,\r
3321                                                 '}', cr,\r
3322                                         '}'\r
3323                                 ].join( '');\r
3324                         }\r
3325                 }\r
3326         })();\r
3327         \r
3328         /*\r
3329          * end of COMIC_ELEMENT_CONTROL\r
3330          */\r
3331 \r
3332 \r
3333 \r
3334         function updateMouseCursor( _cursor){\r
3335                 if( currentCursor !== _cursor){\r
3336                         currentCursor = _cursor;\r
3337                         setTimeout( update, 0);\r
3338                 }\r
3339                 function update(){\r
3340                         ELM_MOUSE_EVENT_CHATCHER.style.cursor = currentCursor;\r
3341                 }\r
3342         }\r
3343         function centering(){\r
3344                 pettanr.editor.onWindowResize( windowW, windowH);\r
3345         }       \r
3346         function mouseEventRellay( e){\r
3347                 var _mouseX = e.pageX,\r
3348                         _mouseY = e.pageY,\r
3349                         rellayMethod = e.type === 'mousedown' ?\r
3350                                         'onMouseDown' :\r
3351                                         ( e.type === 'mousemove' ? 'onMouseMove' : 'onMouseUp');\r
3352                 if( currentListener !== null && currentListener.busy() === true){\r
3353                         currentListener[ rellayMethod]( _mouseX, _mouseY);\r
3354                 } else {\r
3355                         currentListener = null;\r
3356                         var l = MOUSE_LISTENER_ARRAY.length,\r
3357                                 _listener;\r
3358                         for( var i=0; i<l; ++i){\r
3359                                 _listener = MOUSE_LISTENER_ARRAY[ i];\r
3360                                 if( _listener[ rellayMethod]( _mouseX, _mouseY) === true){\r
3361                                         currentListener = _listener;\r
3362                                         break;\r
3363                                 }\r
3364                         }\r
3365                 }\r
3366                 // 文字選択の禁止\r
3367                 //!document.selection && window.getSelection().removeAllRanges();\r
3368                 e.stopPropagation();\r
3369                 return false;\r
3370         }\r
3371 \r
3372         return {\r
3373                 init: function( _option){\r
3374                         option = _option;\r
3375                 },\r
3376                 firstOpen: function(){\r
3377                         var jqWindow = pettanr.jqWindow();\r
3378                         windowW = jqWindow.width();\r
3379                         windowH = jqWindow.height();\r
3380                         \r
3381                         jqEditor = $( '#editor');\r
3382 \r
3383                 /*\r
3384                  * MOUSE_LISTENER_ARRAY は、表示順に格納.手前の要素が最初\r
3385                  * MENU_BAR_CONTROL,\r
3386                  * WINDOW_CONTROL,\r
3387                  * COMIC_ELEMENT_CONTROL,\r
3388                  * PANEL_CONTROL\r
3389                  * .busy() === true なら、そのままonMouseMove()にイベントを流す.これはArrayの後ろから、奥の表示要素から\r
3390                  * onMouseMove()に流してみて、false が帰れば、次にリスナーにも流す.\r
3391                  */\r
3392                         MOUSE_LISTENER_ARRAY.push( MENU_BAR_CONTROL, WINDOWS_CONTROL, PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM, COMIC_ELEMENT_CONTROL, PANEL_CONTROL);\r
3393 \r
3394                         HISTORY.init();\r
3395                         \r
3396                         WINDOWS_CONTROL.init();\r
3397                         \r
3398                         GRID_CONTROL.init();\r
3399                         PANEL_CONTROL.init();\r
3400                         CONSOLE_CONTROLER.init();\r
3401                         COMIC_ELEMENT_OPERATION_MANAGER.init();\r
3402                         COMIC_ELEMENT_CONTROL.init();\r
3403                         \r
3404                         // last\r
3405                         MENU_BAR_CONTROL.init();\r
3406                         \r
3407                         OUTPUT_CONSOLE.init();\r
3408                         TEXT_EDITOR_CONTROL.init();\r
3409                         IMAGE_GROUP_EXPROLER.init();\r
3410 \r
3411                 /*\r
3412                  * centering\r
3413                  */\r
3414                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 96, false, true, centering);  // ctrl + 0\r
3415                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 48, false, true, centering);  // ctrl + 0\r
3416                         MENU_BAR_CONTROL.EDIT.createSelection( 'centering', 'ctrl + 0', centering, true, true, true);\r
3417                 /*\r
3418                  * jqMouseEventChacher は透明な要素で、\r
3419                  * マウスイベントをcurrentElement(currentElement)に伝えるのが仕事\r
3420                  * このような実装になるのは、ここの表示オブジェクトにイベントを設定した場合、表示が追いつかずマウスカーソルが外れたタイミングでイベントが終わってしまうため。\r
3421                  */                     \r
3422                         jqMouseEventChacher = $( ELM_MOUSE_EVENT_CHATCHER)\r
3423                                 .mousemove( mouseEventRellay)\r
3424                                 .mousedown( mouseEventRellay)\r
3425                                 .mouseup( mouseEventRellay)\r
3426                                 .mouseout( mouseEventRellay);\r
3427                         \r
3428                         delete pettanr.editor.firstOpen;\r
3429                 },\r
3430                 onOpen: function( _option){\r
3431                         pettanr.editor.firstOpen !== undefined && pettanr.editor.firstOpen();\r
3432 \r
3433                         // HISTORY.onOpen();\r
3434                         // WINDOWS_CONTROL.onOpen();\r
3435                         // COMIC_ELEMENT_CONTROL.onOpen();\r
3436                         // MENU_BAR_CONTROL.onOpen();\r
3437                         // TEXT_EDITOR_CONTROL.onOpen();\r
3438                         // IMAGE_GROUP_EXPROLER.onOpen();\r
3439                 },\r
3440                 onClose: function(){\r
3441                 },\r
3442                 onWindowResize: function( _windowW, _windowH){\r
3443                         windowW = _windowW;\r
3444                         windowH = _windowH;\r
3445                         if( pettanr.editor.firstOpen) return;\r
3446                         /*\r
3447                          * ieは +'px'が不要みたい\r
3448                          */\r
3449                         jqEditor.get( 0).style.height = _windowH +'px';\r
3450                         ELM_MOUSE_EVENT_CHATCHER.style.height = _windowH +'px';\r
3451                         \r
3452                         WINDOWS_CONTROL.onWindowResize( _windowW, _windowH);\r
3453                         MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH);\r
3454                         PANEL_CONTROL.onWindowResize( _windowW, _windowH);\r
3455                 },\r
3456                 MIN_WIDTH:      320,\r
3457                 MIN_HEIGHT:     320\r
3458         }\r
3459 })();\r