2013-10-28 20:00:20 +00:00
// Copyright (C) 2013 Massachusetts Institute of Technology
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
'use strict' ;
var Reporter = function ( data ) {
this . cmd = data . cmd ;
this . color = data . color ;
this . isDiscrete = data . isDiscrete ;
this . mode = data . mode ;
this . param = data . param ;
this . sliderMin = data . sliderMin ;
this . sliderMax = data . sliderMax ;
this . target = data . target ;
this . visible = data . visible ;
this . x = data . x ;
this . y = data . y ;
this . z = io . getCount ( ) ;
2014-03-09 11:59:38 -06:00
//Set the label after hydrating the cmd and param variables
this . label = this . determineReporterLabel ( ) ;
2013-10-28 20:00:20 +00:00
this . el = null ; // jQuery Element for the outer box
this . valueEl = null ; // jQ element containing the reporter value
this . slider = null ; // slider jQ element
2013-11-01 22:44:51 -04:00
} ;
2013-10-28 20:00:20 +00:00
2014-03-08 00:46:59 -07:00
Reporter . prototype . determineReporterLabel = function ( ) {
2014-04-09 01:17:50 -07:00
if ( this . target === 'Stage' && this . cmd === "getVar:" ) return this . param ;
if ( this . target === 'Stage' && this . param === null ) return this . cmd ;
2014-03-08 00:46:59 -07:00
return this . target + ': ' + this . param ;
}
2013-10-28 20:00:20 +00:00
Reporter . prototype . attach = function ( scene ) {
switch ( this . mode ) {
case 1 : // Normal
case 3 : // Slider
2014-03-09 11:59:38 -06:00
this . el = $ ( '<div class="reporter-normal">' + this . label + '</div>' ) ;
2013-10-28 20:00:20 +00:00
this . valueEl = $ ( '<div class="reporter-inset">null</div>' ) ;
this . el . append ( this . valueEl ) ;
if ( this . mode == 3 ) {
// Slider-specific
// Temporarily, set the value to sliderMin until an update
this . slider = $ ( '<input type="range" min="' + this . sliderMin +
'" max="' + this . sliderMax + '" step="1" value="' +
2013-11-01 22:44:51 -04:00
this . sliderMin + '" data-target="' + this . target +
2013-10-28 20:00:20 +00:00
'" data-var="' + this . param + '">' ) ;
this . slider . change ( this . changeSlider ) ;
this . el . append ( '<br>' ) ;
this . el . append ( this . slider ) ;
}
break ;
case 2 : // Large
this . el = $ ( '<div class="reporter-large">null</div>' ) ;
this . valueEl = this . el ;
break ;
}
this . el . css ( 'left' , this . x ) ;
this . el . css ( 'top' , this . y ) ;
this . el . css ( 'z-index' , this . z ) ;
var cR = ( this . color >> 16 ) ;
var cG = ( this . color >> 8 & 255 ) ;
var cB = ( this . color & 255 ) ;
this . valueEl . css ( 'background-color' , 'rgb(' + cR + ',' + cG + ',' + cB + ')' ) ;
this . el . css ( 'display' , this . visible ? 'inline-block' : 'none' ) ;
scene . append ( this . el ) ;
2013-11-01 22:44:51 -04:00
} ;
2013-10-28 20:00:20 +00:00
Reporter . prototype . update = function ( ) {
this . el . css ( 'display' , this . visible ? 'inline-block' : 'none' ) ;
if ( ! this . visible ) return ;
2013-11-01 22:44:51 -04:00
var newValue = '' ;
2013-10-28 20:00:20 +00:00
var target = runtime . spriteNamed ( this . target ) ;
switch ( this . cmd ) {
2014-03-09 11:59:38 -06:00
case 'answer' :
newValue = target . askAnswer ;
break ;
2013-10-28 20:00:20 +00:00
case 'getVar:' :
newValue = target . variables [ this . param ] ;
break ;
case 'xpos' :
2013-11-14 23:02:16 -05:00
newValue = target . scratchX ;
2013-10-28 20:00:20 +00:00
break ;
case 'ypos' :
2013-11-14 23:02:16 -05:00
newValue = target . scratchY ;
2013-10-28 20:00:20 +00:00
break ;
case 'heading' :
newValue = target . direction ;
break ;
case 'scale' :
newValue = target . getSize ( ) ;
break ;
case 'sceneName' :
newValue = runtime . stage . costumes [ runtime . stage . currentCostumeIndex ] . costumeName ;
break ;
case 'costumeIndex' :
newValue = target . currentCostumeIndex + 1 ;
break ;
2013-10-30 15:50:29 +02:00
case 'timer' :
2014-04-09 19:26:25 -07:00
newValue = '' + Math . round ( interp . primitiveTable . timer ( ) * 10 ) / 10 ;
2013-10-30 15:50:29 +02:00
break ;
2013-10-28 20:00:20 +00:00
}
2013-11-14 23:02:16 -05:00
if ( typeof newValue === 'number' && Math . abs ( newValue ) > 0.001 ) {
newValue = Math . round ( newValue * 1000 ) / 1000 ;
}
2014-04-10 11:34:01 -07:00
newValue = '' + newValue ;
2013-10-28 20:00:20 +00:00
this . valueEl . html ( newValue ) ;
2013-11-01 22:44:51 -04:00
if ( this . mode == 3 ) {
2013-11-14 23:02:16 -05:00
this . slider . val ( Number ( newValue ) ) ;
2013-11-01 22:44:51 -04:00
}
} ;
2013-10-28 20:00:20 +00:00
Reporter . prototype . updateLayer = function ( ) {
this . el . css ( 'z-index' , this . z ) ;
2013-11-01 22:44:51 -04:00
} ;
2013-10-28 20:00:20 +00:00
Reporter . prototype . changeSlider = function ( ) {
2013-11-14 23:02:16 -05:00
var newValue = Number ( $ ( this ) . val ( ) ) ;
2013-10-28 20:00:20 +00:00
var target = runtime . spriteNamed ( $ ( this ) . attr ( 'data-target' ) ) ;
var variable = $ ( this ) . attr ( 'data-var' ) ;
target . variables [ variable ] = newValue ;
2013-11-01 22:44:51 -04:00
} ;
2013-10-30 21:16:15 +02:00
2013-11-04 22:28:23 +02:00
var List = function ( data , sprite ) {
2013-10-30 21:16:15 +02:00
this . contents = data . contents ;
this . listName = data . listName ;
this . height = data . height ;
this . width = data . width ;
this . x = data . x ;
this . y = data . y ;
this . z = io . getCount ( ) ;
this . visible = data . visible ;
2013-11-04 22:28:23 +02:00
this . target = sprite ;
2013-10-30 21:16:15 +02:00
// this.isPersistent = data.isPersistent;
this . el = null ; // jQuery element for list
this . containerEl = null ;
2013-10-31 10:24:34 +02:00
this . scrollbar = null ;
2013-10-30 21:16:15 +02:00
} ;
List . prototype . attach = function ( scene ) {
this . el = $ ( '<div class="list">' ) ;
2013-11-04 22:28:23 +02:00
this . el . append ( '<div class="list-title">' + ( this . target === 'Stage' ? '' : this . target + ' ' ) + this . listName ) ;
2013-11-04 23:06:54 +02:00
var c = this . containerEl = $ ( '<div style="overflow:hidden;float:left;position:relative">' ) . appendTo ( this . el ) . width ( this . width - 13 ) . height ( this . height - 34 ) ;
2013-10-31 10:24:34 +02:00
var s = this . scrollbar = $ ( '<div class="list-scrollbar-container"><div class="list-scrollbar">' ) . appendTo ( this . el ) ;
var sb = s . children ( '.list-scrollbar' ) ;
2014-04-09 01:17:50 -07:00
sb . mousedown ( function ( e ) {
2013-10-31 10:24:34 +02:00
if ( e . which === 1 ) $ ( this ) . data ( { scrolling : true , startY : e . pageY } ) ; // left button
} ) ;
2014-04-09 01:17:50 -07:00
$ ( 'body' ) . mousemove ( function ( e ) {
2013-10-31 10:24:34 +02:00
if ( sb . data ( 'scrolling' ) ) {
2013-11-03 17:47:32 +02:00
var offset = parseInt ( sb . css ( 'top' ) ) + e . pageY - sb . data ( 'startY' ) ;
if ( offset < 0 ) {
offset = 0 ;
2013-10-31 10:24:34 +02:00
}
2013-11-03 17:47:32 +02:00
if ( offset > c . height ( ) - sb . height ( ) ) {
offset = c . height ( ) - sb . height ( ) ;
}
sb . css ( 'top' , offset ) ;
c . scrollTop ( c . height ( ) / sb . height ( ) * offset ) ;
2013-10-31 10:24:34 +02:00
}
2014-04-09 01:17:50 -07:00
} ) . mouseup ( function ( ) {
2013-10-31 10:24:34 +02:00
if ( $ . hasData ( sb [ 0 ] , 'scrolling' ) ) sb . removeData ( [ 'scrolling' , 'startY' ] ) ;
} ) ;
// this.el.append('<div class="list-add">+'); // disabled because it doesn't do anything even in the original
2013-10-30 21:16:15 +02:00
this . el . append ( '<div class="list-length">length: ' + this . contents . length ) ;
scene . append ( this . el ) ;
this . update ( ) ;
this . el . css ( 'left' , this . x ) ;
this . el . css ( 'top' , this . y ) ;
this . el . width ( this . width ) ;
this . el . height ( this . height ) ;
this . el . css ( 'z-index' , this . z ) ;
this . el . css ( 'display' , this . visible ? 'inline-block' : 'none' ) ;
2013-11-03 18:01:50 +02:00
} ;
2013-10-30 21:16:15 +02:00
2014-04-09 01:17:50 -07:00
List . prototype . update = function ( ) {
2013-11-04 22:28:23 +02:00
this . contents = findList ( runtime . spriteNamed ( this . target ) , this . listName ) ;
2013-10-30 21:16:15 +02:00
this . el . css ( 'display' , this . visible ? 'inline-block' : 'none' ) ;
if ( ! this . visible ) return ;
var c = this . containerEl . html ( '' ) ; // so that it can be used inside the forEach
2014-04-09 01:17:50 -07:00
this . contents . forEach ( function ( val , i ) {
2013-10-30 21:16:15 +02:00
$ ( '<div style="clear:both">' ) . appendTo ( c ) . append ( '<div class="list-index">' + ( i + 1 ) , '<div class="list-item">' + val ) ;
} ) ;
2013-11-03 17:47:32 +02:00
c . find ( '.list-index' ) . width ( c . find ( '.list-index' ) . last ( ) . width ( ) ) ;
2013-11-04 23:06:54 +02:00
c . find ( '.list-item' ) . width ( c . width ( ) - c . find ( '.list-index' ) . width ( ) - 15 ) ;
var s = this . scrollbar . height ( c . height ( ) ) ;
2013-10-31 10:24:34 +02:00
s . children ( '.list-scrollbar' ) . height ( s . height ( ) / c [ 0 ] . scrollHeight * s . height ( ) ) . css ( 'display' , s . children ( '.list-scrollbar' ) . height ( ) === c . height ( ) ? 'none' : 'inline-block' ) ;
2013-10-30 21:16:15 +02:00
this . el . find ( '.list-length' ) . text ( 'length: ' + this . contents . length ) ;
} ;
List . prototype . updateLayer = function ( ) {
this . el . css ( 'z-index' , this . z ) ;
2013-11-03 18:01:50 +02:00
} ;
2013-11-04 23:06:54 +02:00