rsence-pre 2.2.0.12 → 2.2.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0.12.pre
1
+ 2.2.0.13.pre
@@ -173,7 +173,9 @@ HWindow = HDynControl.extend({
173
173
  }
174
174
  return _rect;
175
175
  },
176
-
176
+
177
+ hasWindowFocus: false,
178
+
177
179
  /** Reports to HSystem that this window has the focus and the
178
180
  * previously active window needs to blur
179
181
  **/
@@ -184,6 +186,7 @@ HWindow = HDynControl.extend({
184
186
  /** HSystem calls this method, whenever this window is allowed to be focused
185
187
  **/
186
188
  windowFocus: function(){
189
+ this.hasWindowFocus = true;
187
190
  this.toggleCSSClass(this.elemId, 'inactive', false);
188
191
  },
189
192
 
@@ -191,6 +194,7 @@ HWindow = HDynControl.extend({
191
194
  * focus (another window focused)
192
195
  **/
193
196
  windowBlur: function(){
197
+ this.hasWindowFocus = false;
194
198
  this.toggleCSSClass(this.elemId, 'inactive', true);
195
199
  this.setStyle('cursor','default');
196
200
  },
@@ -24,6 +24,7 @@
24
24
 
25
25
  .timesheet_timeline {
26
26
  left: 0px; top: 0px; right: 0px; bottom: 0px;
27
+ cursor: move;
27
28
  }
28
29
 
29
30
  .timesheet_timeline_hour {
@@ -160,6 +160,7 @@ HTimeSheet = HControl.extend({
160
160
 
161
161
  },
162
162
 
163
+ // extra hook for refreshing; updates label and hours before doing common things
163
164
  refresh: function(){
164
165
  if( this.drawn ){
165
166
  if( this.options.autoLabel ){
@@ -170,21 +171,25 @@ HTimeSheet = HControl.extend({
170
171
  this.base();
171
172
  },
172
173
 
174
+ // set the timezone offset (in seconds)
173
175
  setTzOffset: function( _tzOffset ){
174
176
  this.options.tzOffset = _tzOffset;
175
177
  this.refresh();
176
178
  },
177
179
 
180
+ // set the start timestamp of the timesheet
178
181
  setTimeStart: function( _timeStart ){
179
182
  this.options.timeStart = _timeStart;
180
183
  this.refresh();
181
184
  },
182
185
 
186
+ // set the end timestamp of the timesheet
183
187
  setTimeEnd: function( _timeEnd ){
184
188
  this.options.timeEnd = _timeEnd;
185
189
  this.refresh();
186
190
  },
187
191
 
192
+ // sets the range of timestams of the timesheet
188
193
  setTimeRange: function( _timeRange ){
189
194
  if( (_timeRange instanceof Array) && (_timeRange.length === 2) ){
190
195
  this.setTimeStart( _timeRange[0] );
@@ -200,6 +205,7 @@ HTimeSheet = HControl.extend({
200
205
  }
201
206
  },
202
207
 
208
+ // sets the timestamp of the timesheet
203
209
  setDate: function( _date ){
204
210
  var
205
211
  _range = (this.options.timeEnd - this.options.timeStart),
@@ -211,6 +217,7 @@ HTimeSheet = HControl.extend({
211
217
  this.refresh();
212
218
  },
213
219
 
220
+ // draw decorations
214
221
  drawSubviews: function(){
215
222
  this.drawHours();
216
223
  var
@@ -237,6 +244,7 @@ HTimeSheet = HControl.extend({
237
244
  this.dragPreview.setStyleOfPart('state','color','#fff');
238
245
  },
239
246
 
247
+ // event listener for clicks, cancels event if a drag event mistakenly triggered it
240
248
  click: function( x, y, b ){
241
249
  if( !this.startDragTime ){
242
250
  this.clickCreate( x,y );
@@ -245,11 +253,11 @@ HTimeSheet = HControl.extend({
245
253
  this.clickCreated = false;
246
254
  },
247
255
 
256
+ // creates an item on click
248
257
  clickCreate: function(x,y){
249
258
  var
250
259
  _startTime = this.pxToTime( y-this.pageY() ),
251
260
  _endTime = _startTime + this.minDuration;
252
- // console.log('start:',(new Date(_startTime*1000)).toUTCString(),', end:',(new Date(_endTime*1000)).toUTCString());
253
261
  this.refreshDragPreview( _startTime, _endTime );
254
262
  this.dragPreview.bringToFront();
255
263
  this.dragPreview.show();
@@ -261,6 +269,7 @@ HTimeSheet = HControl.extend({
261
269
  }
262
270
  },
263
271
 
272
+ // event listener for double clicks, simulates two sequential clicks
264
273
  doubleClick: function(x,y){
265
274
  if( !this.clickCreated ){
266
275
  this.click(x,y);
@@ -268,6 +277,7 @@ HTimeSheet = HControl.extend({
268
277
  this.clickCreated = false;
269
278
  },
270
279
 
280
+ // update the preview area
271
281
  refreshDragPreview: function( _startTime, _endTime ){
272
282
  this.dragPreviewRect.setTop( this.timeToPx( _startTime, true ) );
273
283
  this.dragPreviewRect.setBottom( this.timeToPx( _endTime, true ) );
@@ -280,9 +290,9 @@ HTimeSheet = HControl.extend({
280
290
  this.dragPreview.refreshValue();
281
291
  },
282
292
 
293
+ // drag & drop event listeners, used for dragging new timesheet items
283
294
  startDrag: function( x, y, b ){
284
295
  this.startDragTime = this.pxToTime( y-this.pageY() );
285
- // y -= this.pageY();
286
296
  this.refreshDragPreview( this.startDragTime, this.startDragTime + this.minDuration );
287
297
  this.dragPreview.bringToFront();
288
298
  this.dragPreview.show();
@@ -322,15 +332,13 @@ HTimeSheet = HControl.extend({
322
332
  return false;
323
333
  },
324
334
 
335
+ // a resize triggers refresh, of which the important part is refreshValue, which triggers redraw of the time sheet items
325
336
  resize: function(){
326
337
  this.base();
327
338
  this.refresh();
328
339
  },
329
- debugPos: function( _px, color ){
330
- var _debugPosId = ELEM.make(this.elemId,'div');
331
- ELEM.setCSS(_debugPosId,'position:absolute;left:0px;top:'+_px+'px;right:0px;background-color:'+color+';height:1px;');
332
- setTimeout( function(){ ELEM.del( _debugPosId ); }, 1000 );
333
- },
340
+
341
+ // snaps the time to grid
334
342
  snapTime: function( _timeSecs ){
335
343
  var
336
344
  _options = this.options,
@@ -347,12 +355,16 @@ HTimeSheet = HControl.extend({
347
355
  }
348
356
  return _timeSecs;
349
357
  },
358
+
359
+ // snaps the pixel to grid
350
360
  snapPx: function( _px ){
351
361
  var
352
362
  _timeSecs = this.pxToTime( _px );
353
363
  _timeSecs = this.snapTime( _timeSecs );
354
364
  return this.timeToPx( _timeSecs );
355
365
  },
366
+
367
+ // activates the editor; _item is the timesheet item to edit
356
368
  activateEditor: function( _item ){
357
369
  if( this['editor'] ){
358
370
  var _editor = this.editor;
@@ -375,6 +387,7 @@ HTimeSheet = HControl.extend({
375
387
  setEditor: function( _editor ){
376
388
  this.editor = _editor;
377
389
  },
390
+
378
391
  /** = Description
379
392
  * Destructor; destroys the editor first and commences inherited die.
380
393
  *
@@ -385,6 +398,7 @@ HTimeSheet = HControl.extend({
385
398
  this.base();
386
399
  },
387
400
 
401
+ // converts pixels to time
388
402
  pxToTime: function( _px, _noSnap ){
389
403
  var
390
404
  _options = this.options,
@@ -409,6 +423,8 @@ HTimeSheet = HControl.extend({
409
423
  }
410
424
  return Math.round( _timeSecs );
411
425
  },
426
+
427
+ // converts time to pixels
412
428
  timeToPx: function( _time, _snap ){
413
429
 
414
430
  if( _snap ){
@@ -422,13 +438,9 @@ HTimeSheet = HControl.extend({
422
438
 
423
439
  if( _time < _timeStart ){
424
440
  _time = _timeStart;
425
- // this.debug && console.log('time:',_time,' is less than timeStart:',_timeStart);
426
- // return 'underflow';
427
441
  }
428
442
  if( _time > _timeEnd ){
429
443
  _time = _timeEnd;
430
- // this.debug && console.log('time:',_time,' is more than timeEnd:',_timeEnd);
431
- // return 'overflow';
432
444
  }
433
445
 
434
446
  var
@@ -441,6 +453,8 @@ HTimeSheet = HControl.extend({
441
453
  _px = _top + ( _timeSecs * _pxPerSec );
442
454
  return Math.round( _px );
443
455
  },
456
+
457
+ // converts time to pixels for the rect
444
458
  rectFromValue: function( _value ){
445
459
  var
446
460
  _topPx = this.timeToPx( _value.start ),
@@ -452,11 +466,9 @@ HTimeSheet = HControl.extend({
452
466
  _topPx = _itemOptions.offsetTop;
453
467
  }
454
468
  else if( _topPx === 'overflow' ){
455
- this.debug && console.log('item out of range:',_value);
456
469
  return false;
457
470
  }
458
471
  if( _bottomPx === 'underflow' ){
459
- this.debug && console.log('item out of range:',_value);
460
472
  return false;
461
473
  }
462
474
  else if( _bottomPx === 'overflow' ){
@@ -468,12 +480,13 @@ HTimeSheet = HControl.extend({
468
480
  }
469
481
  return _rect;
470
482
  },
483
+
484
+ // creates a single time sheet item component
471
485
  createTimeSheetItem: function( _value ){
472
486
  var
473
487
  _rect = this.rectFromValue( _value ),
474
488
  _item;
475
489
  if( _rect === false ){
476
- this.debug && console.log('invalid item:',_value);
477
490
  return false;
478
491
  }
479
492
  _item = HTimeSheetItem.nu(
@@ -490,6 +503,274 @@ HTimeSheet = HControl.extend({
490
503
  );
491
504
  return _item;
492
505
  },
506
+
507
+ // calls createTimeSheetItem with each value of the timesheet value array
508
+ drawTimeSheetItems: function(){
509
+
510
+ var
511
+ _data = this.value,
512
+ i = 0,
513
+ _value,
514
+ _item,
515
+ _items = this.timeSheetItems;
516
+
517
+ if((_data instanceof Array) && (_data.length > 0)){
518
+ for( ; i < _data.length; i++){
519
+ _value = _data[i];
520
+ _item = this.createTimeSheetItem( _value );
521
+ if(_item){
522
+ _items.push( _item );
523
+ }
524
+ }
525
+ }
526
+ },
527
+
528
+
529
+ /** =Description
530
+ * Create a new timeSheetItems if it hasn't been done already,
531
+ * otherwise destroy the items of the old one before proceeding.
532
+ **/
533
+ _initTimeSheetItems: function(){
534
+ if(this.timeSheetItems === undefined){
535
+ this.timeSheetItems = [];
536
+ }
537
+ else if(this.timeSheetItems.length > 0){
538
+ for( var i=0; i<this.timeSheetItems.length; i++){
539
+ this.timeSheetItems[i].die();
540
+ }
541
+ this.timeSheetItems = [];
542
+ }
543
+ },
544
+
545
+ // checks if i overlaps j
546
+ // todo: refactor, it's a bit messy
547
+ _doesOverlap: function( i, j, _overlaps, _rectSelf, _items ){
548
+ if( _rectSelf === undefined ) {
549
+ _rectSelf = this.timeSheetItems[i].rect;
550
+ }
551
+ if( _items === undefined ){
552
+ _items = this.timeSheetItems;
553
+ }
554
+ var
555
+ _isntSame = (i !== j),
556
+ _isntListedSelf = (_overlaps.indexOf(i)===-1),
557
+ _isntListedOther = (_overlaps.indexOf(j)===-1),
558
+ _rectOther = _items[j].rect;
559
+ if( !_isntSame ){ return false; }
560
+ if( !_isntListedSelf ){ return false; }
561
+ if( _isntListedOther ){
562
+ if( _rectOther.intersects( _rectSelf, 1, 1 ) || _rectSelf.intersects( _rectOther, 1, 1 ) ){
563
+ return true;
564
+ }
565
+ }
566
+ return false;
567
+ },
568
+
569
+
570
+ // finds the index in the array which contains most sequential items
571
+ _findLargestSequence: function( _arr ){
572
+ var
573
+ i = 1,
574
+ _index = 0,
575
+ _length = 1,
576
+ _maxLength = 1,
577
+ _bestIndex = 0;
578
+ for( ; i < _arr.length; i++ ){
579
+ // grow:
580
+ if( ( _arr[i] - _arr[i-1] === 1 ) && ( _index === i-_length ) ){
581
+ _length += 1;
582
+ }
583
+ // reset:
584
+ else {
585
+ _index = i;
586
+ _length = 1;
587
+ }
588
+ if( _length > _maxLength ){
589
+ _bestIndex = _index;
590
+ _maxLength = _length;
591
+ }
592
+ }
593
+ return [ _bestIndex, _maxLength ];
594
+ },
595
+
596
+ // find the amount of overlapping time sheet items
597
+ _findOverlapCount: function(){
598
+ var
599
+ _overlapCount,
600
+ _items = this._sortedTimeSheetItems(),
601
+ _overlaps = [],
602
+ _maxOverlapCount = 0,
603
+ i = 0,
604
+ j;
605
+ for( ; i < _items.length; i++ ){
606
+ _overlapCount = 0;
607
+ for( j = 0; j < _items.length; j++ ){
608
+ if( this._doesOverlap( i, j, _overlaps, _items[i].rect, _items ) ){
609
+ _overlapCount++;
610
+ _overlaps.push( j );
611
+ }
612
+ }
613
+ if( _overlapCount !== 0 ){
614
+ _overlaps.push( i );
615
+ if( _overlapCount > _maxOverlapCount ){
616
+ _maxOverlapCount = _overlapCount;
617
+ }
618
+ }
619
+ }
620
+ return _maxOverlapCount;
621
+ },
622
+
623
+ // returns a sorted copy of the timeSheetItems array
624
+ _sortedTimeSheetItems: function( _sortFn ){
625
+ if( _sortFn === undefined ){
626
+ _sortFn = function(a,b){
627
+ return ( b.rect.height - a.rect.height);
628
+ };
629
+ }
630
+ var
631
+ i = 0,
632
+ _arr = [],
633
+ _items = this.timeSheetItems;
634
+ for( ; i < _items.length; i++ ){
635
+ _arr.push( _items[i] );
636
+ }
637
+ _arr = _arr.sort(_sortFn);
638
+ return _arr;
639
+ },
640
+
641
+
642
+ // Optimizes the left and right position of each timesheet item to fit
643
+ _updateTimelineRects: function(){
644
+ var
645
+ // loop indexes:
646
+ i, j, k, l,
647
+ // amount of items ovelapping (max, actual number might be smaller after optimization)
648
+ _options = this.options,
649
+ _rect = this.rect,
650
+ _overlapCount = this._findOverlapCount(),
651
+ _availWidth = ( _rect.width - _options.itemOffsetRight - _options.itemOffsetLeft ),
652
+ _left = _options.itemOffsetLeft,
653
+ _width = Math.floor( _availWidth / (_overlapCount+1) ),
654
+ // get a list of timesheet items sorted by height (larger to smaller order)
655
+ _items = this._sortedTimeSheetItems(),
656
+ _itemCount = _items.length,
657
+ _itemRect,
658
+ _testRect,
659
+ _leftPos,
660
+ _rightPos,
661
+ _maxCol = 0,
662
+ _origCol,
663
+ _origColById = [],
664
+ _overlapCols,
665
+ _vacantCols,
666
+ _optimalColAndLength,
667
+ _col,
668
+ _colWidth,
669
+ _overlaps;
670
+
671
+ // No overlapping; nothing to do
672
+ if(_overlapCount === 0 ){
673
+ return false;
674
+ }
675
+
676
+ // move all items initially to one column right of the max overlaps
677
+ _leftPos = _left+(_width*(_overlapCount+1));
678
+ for( i = 0; i < _itemCount; i++ ){
679
+ _itemRect = _items[i].rect;
680
+ _itemRect.setLeft( _leftPos );
681
+ _itemRect.setRight( _leftPos+_width );
682
+ }
683
+
684
+ // optimize gaps by traversing each combination
685
+ // and finding the first column with no gaps
686
+ // the top-level loops three times in the following modes:
687
+ // 0: place items into the first vacant column and find the actual max columns
688
+ // 1: stretch columns to final column width
689
+ // 2: stretch columns to fit multiple columns, if space is vacant
690
+ for( l = 0; l < 3; l++ ){
691
+ for( i = 0; i < _itemCount; i++){
692
+ _itemRect = _items[i].rect;
693
+ // in mode 1, just the column widths are changed
694
+ if( l === 1 ){
695
+ _leftPos = _left + (_origColById[i]*_width);
696
+ _itemRect.setLeft( _leftPos );
697
+ _itemRect.setRight( _leftPos + _width );
698
+ continue;
699
+ }
700
+ _testRect = HRect.nu( _itemRect );
701
+
702
+ _overlapCols = [];
703
+ _vacantCols = [];
704
+
705
+ // test each column position (modes 0 and 2)
706
+ for( k = 0; k < _overlapCount+1; k++ ){
707
+ _leftPos = _left + (k*_width);
708
+ _testRect.setLeft( _leftPos );
709
+ _testRect.setRight( _leftPos + _width );
710
+ _overlaps = [];
711
+ for( j = 0; j < _itemCount; j++){
712
+ if( this._doesOverlap( i, j, _overlaps, _testRect, _items ) ){
713
+ if( _overlapCols.indexOf( k ) === -1 ){
714
+ _overlapCols.push( k );
715
+ }
716
+ }
717
+ }
718
+ if( _vacantCols.indexOf( k ) === -1 && _overlapCols.indexOf( k ) === -1 ){
719
+ _vacantCols.push( k );
720
+ }
721
+ }
722
+
723
+ // on the first run (mode 0) place items into the first column:
724
+ if( l === 0 ){
725
+ _origCol = _vacantCols[0];
726
+ _origColById.push( _origCol );
727
+ _leftPos = _left+(_origCol*_width);
728
+ _rightPos = _leftPos + _width;
729
+ if( _maxCol < _origCol ){
730
+ _maxCol = _origCol;
731
+ }
732
+ }
733
+ else {
734
+ // on mode 2: stretch to fill multiple column widths,
735
+ // because no item moving is done anymore at this stage, so we know what's free and what's not
736
+ if( _vacantCols.length > 0 ){
737
+ _optimalColAndLength = this._findLargestSequence( _vacantCols );
738
+ _col = _vacantCols[ _optimalColAndLength[0] ];
739
+ _colWidth = _optimalColAndLength[1];
740
+ }
741
+ else {
742
+ _origCol = _origColById[i];
743
+ _col = _origCol;
744
+ _colWidth = 1;
745
+ }
746
+ _leftPos = _left+(_col*_width);
747
+ _rightPos = _leftPos+(_colWidth*_width);
748
+ }
749
+ _itemRect.setLeft( _leftPos );
750
+ _itemRect.setRight( _rightPos );
751
+ }
752
+ // afther the first run (mode 0) we know the actual amount of columns, so adjust column width accordingly
753
+ if( l === 0 ){
754
+ _overlapCount = _maxCol;
755
+ _width = Math.floor( _availWidth / (_maxCol+1) );
756
+ }
757
+ }
758
+ return true;
759
+ },
760
+
761
+ // draws the timeline (sub-routine of refreshValue)
762
+ drawTimeline: function(){
763
+ this._initTimeSheetItems();
764
+ this.drawTimeSheetItems();
765
+ this._updateTimelineRects();
766
+ // use the dimensions of the views
767
+ for( var i = 0; i < this.timeSheetItems.length; i++){
768
+ this.timeSheetItems[i].drawRect();
769
+ }
770
+ },
771
+
772
+ _sha: SHA.nu(8),
773
+
493
774
  /*
494
775
 
495
776
  Each item looks like this, any extra attributes are allowed,
@@ -512,66 +793,22 @@ but not used and not guaranteed to be preserved:
512
793
  *
513
794
  **/
514
795
  refreshValue: function(){
796
+
515
797
  if(!this.itemOptions){
516
798
  return;
517
799
  }
518
- this.dragPreview.hide();
519
- var
520
- _data = this.value,
521
- i;
522
- if(this.listItemViews === undefined){
523
- this.listItemViews = [];
524
- }
525
- else if(this.listItemViews.length > 0){
526
- for( i=0; i<this.listItemViews.length; i++){
527
- this.listItemViews[i].die();
528
- }
529
- this.listItemViews = [];
530
- }
531
- if((_data instanceof Array) && (_data.length > 0)){
532
- var
533
- _value,
534
- _item;
535
- for( i=0; i<_data.length; i++){
536
- _value = _data[i];
537
- _item = this.createTimeSheetItem( _value );
538
- if(_item){
539
- this.listItemViews.push( _item );
540
- }
541
- }
542
- }
543
- var
544
- _overlaps = [],
545
- j;
546
- for(i=0;i<this.listItemViews.length;i++){
547
- for(j=0;j<this.listItemViews.length;j++){
548
- if((i !== j) && (_overlaps.indexOf(i)===-1) && (_overlaps.indexOf(j)===-1)){
549
- if(this.listItemViews[i].rect.intersects(this.listItemViews[j].rect)){
550
- _overlaps.push(i);
551
- }
552
- }
553
- }
554
- }
800
+
801
+ // optimization that ensures the rect and previous value are different before redrawing
555
802
  var
556
- _overlapCount = _overlaps.length+1,
557
- _overlapLefts = {},
558
- _itemWidth = ( this.rect.width - this.options.itemOffsetRight - this.options.itemOffsetLeft ),
559
- _width = Math.floor( _itemWidth / _overlapCount),
560
- _left = this.options.itemOffsetLeft;
561
- for(j=0;j<_overlapCount;j++){
562
- _overlapLefts[_overlaps[j]] = _left + (j*_width) + _width;
563
- }
564
- for(i=0;i<this.listItemViews.length;i++){
565
- if(_overlaps.indexOf(i)===-1){
566
- this.listItemViews[i].rect.setLeft(_left);
567
- }
568
- else {
569
- this.listItemViews[i].rect.setLeft(_overlapLefts[i]);
570
- }
571
- this.listItemViews[i].rect.setWidth(_width);
572
- }
573
- for(i=0;i<this.listItemViews.length;i++){
574
- this.listItemViews[i].drawRect();
803
+ _valueStr = COMM.Values.encode( this.value ),
804
+ _rectStr = this.rect.toString(),
805
+ _timeRangeStr = this.options.timeStart+':'+this.options.timeEnd,
806
+ _shaSum = this._sha.strSHA1( _valueStr+_rectStr+_timeRangeStr );
807
+ if( this._prevSum !== _shaSum ){
808
+ // the preview timesheet item is hidden when new data arrives (including what it created)
809
+ this.dragPreview.hide();
810
+ this._prevSum = _shaSum;
811
+ this.drawTimeline();
575
812
  }
576
813
  }
577
814
 
@@ -390,18 +390,34 @@ HRect = HClass.extend({
390
390
  * of a side in common with rect, and false if it doesn't.
391
391
  *
392
392
  * = Parameters
393
- * +_rect+:: A HRect instance to intersect this rect with
393
+ * +_rect+:: A HRect instance to intersect this rect with
394
+ * +_insetByX+:: Insets +_rect+ by +_insetBy+ pixels, optional
395
+ * +_insetByY+:: Insets +_rect+ by +_insetBy+ pixels, optional. If omitted, but +_insetByX+ is defined, then +_insetByY+ equals +_insetByX+.
394
396
  *
395
397
  * = Returns
396
398
  * A Boolean (true/false) depending on the result.
397
399
  *
398
400
  **/
399
- intersects: function(_rect) {
401
+ intersects: function( _rect, _insetByX, _insetByY ) {
402
+ if( _insetByX !== undefined ){
403
+ _rect = HRect.nu( _rect );
404
+ if( _insetByY === undefined ){
405
+ _insetByY = _insetByX;
406
+ }
407
+ _rect.insetBy( _insetByX, _insetByY );
408
+ }
400
409
  return (
401
- ((_rect.left >= this.left && _rect.left <= this.right) ||
402
- (_rect.right >= this.left && _rect.right <= this.right)) &&
403
- ((_rect.top >= this.top && _rect.top <= this.bottom) ||
404
- (_rect.bottom >= this.top && _rect.bottom <= this.bottom)));
410
+ ( ( _rect.left >= this.left && _rect.left <= this.right ) ||
411
+ ( _rect.right >= this.left && _rect.right <= this.right )
412
+ ) &&
413
+ ( ( _rect.top >= this.top && _rect.top <= this.bottom) ||
414
+ ( _rect.bottom >= this.top && _rect.bottom <= this.bottom)
415
+ )
416
+ );
417
+ },
418
+
419
+ overlaps: function( _rect, _insetbyX, _insetByY ){
420
+ return this.intersects( _rect, _insetbyX, _insetByY );
405
421
  },
406
422
 
407
423
  /** = Description
@@ -651,6 +667,10 @@ HRect = HClass.extend({
651
667
  _viewId = this.viewIds[i];
652
668
  HSystem.views[_viewId].drawRect();
653
669
  }
670
+ },
671
+
672
+ toString: function(){
673
+ return ('[object Rect left='+this.left+' top='+this.top+' width='+this.width+' height='+this.height+' right='+this.right+' bottom='+this.bottom+']');
654
674
  }
655
675
 
656
676
  });
@@ -228,7 +228,7 @@ COMM.JSONRenderer = HClass.extend({
228
228
  }
229
229
  }
230
230
  catch(e){
231
- console.log('renderNode error:',e,', rect:',_rect,', class:',_dataNode['class'],', options:', _options);
231
+ console.log('renderNode error:',e.toString()+', rect:',_rect,', class:',_dataNode['class'],', options:', _options);
232
232
  }
233
233
  // Iterates recursively through all subviews, if specified.
234
234
  if(_hasSubviews){
@@ -1810,7 +1810,7 @@ HView = HClass.extend({
1810
1810
  **/
1811
1811
  invalidatePositionCache: function() {
1812
1812
  for(var i=0; i<this.views.length; i++) {
1813
- HSystem.views[this.views[i]].invalidatePositionCache();
1813
+ HSystem.views[this.views[i]]['invalidatePositionCache'] && HSystem.views[this.views[i]].invalidatePositionCache();
1814
1814
  }
1815
1815
  return this;
1816
1816
  },
@@ -332,7 +332,6 @@ module RSence
332
332
  # @private Returns a sanitized copy of a single responder specification.
333
333
  def sanitize_value_responders( responders_dirty )
334
334
  if responders_dirty.class != Array
335
- warn "Unsupported responders type: #{responders_dirty.inspect} (expected Array or Hash). Trying work-around.." if responders_dirty.class != Hash and RSence.args[:debug]
336
335
  responders_dirty = [ responders_dirty ]
337
336
  end
338
337
  responders_clean = []
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsence-pre
3
3
  version: !ruby/object:Gem::Version
4
- hash: 103
4
+ hash: 101
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
9
  - 0
10
- - 12
11
- version: 2.2.0.12
10
+ - 13
11
+ version: 2.2.0.13
12
12
  platform: ruby
13
13
  authors:
14
14
  - Riassence Inc.
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-07-13 00:00:00 Z
19
+ date: 2011-07-23 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rsence-deps