API  0.9.9
CPView.j
Go to the documentation of this file.
1 /*
2  * CPView.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 
26 @global appkit_tag_dom_elements
27 
28 @typedef _CPViewFullScreenModeState
29 
30 #if PLATFORM(DOM)
31 
32 if (typeof(appkit_tag_dom_elements) !== "undefined" && appkit_tag_dom_elements)
33 {
34  AppKitTagDOMElement = function(owner, element)
35  {
36  element.setAttribute("data-cappuccino-view", [owner className]);
37  element.setAttribute("data-cappuccino-uid", [owner UID]);
38  }
39 }
40 else
41 {
42  AppKitTagDOMElement = function(owner, element)
43  {
44  // By default, do nothing.
45  }
46 }
47 
48 #endif
49 
50 /*
51  @global
52  @group CPViewAutoresizingMasks
53  The default resizingMask, the view will not resize or reposition itself.
54 */
56 /*
57  @global
58  @group CPViewAutoresizingMasks
59  Allow for flexible space on the left hand side of the view.
60 */
62 /*
63  @global
64  @group CPViewAutoresizingMasks
65  The view should grow and shrink horizontally with its parent view.
66 */
68 /*
69  @global
70  @group CPViewAutoresizingMasks
71  Allow for flexible space to the right hand side of the view.
72 */
74 /*
75  @global
76  @group CPViewAutoresizingMasks
77  Allow for flexible space above the view.
78 */
80 /*
81  @global
82  @group CPViewAutoresizingMasks
83  The view should grow and shrink vertically with its parent view.
84 */
86 /*
87  @global
88  @group CPViewAutoresizingMasks
89  Allow for flexible space below the view.
90 */
92 
93 CPViewBoundsDidChangeNotification = @"CPViewBoundsDidChangeNotification";
94 CPViewFrameDidChangeNotification = @"CPViewFrameDidChangeNotification";
95 
97 
98 #if PLATFORM(DOM)
99 var DOMElementPrototype = nil,
100 
101  BackgroundTrivialColor = 0,
102  BackgroundVerticalThreePartImage = 1,
103  BackgroundHorizontalThreePartImage = 2,
104  BackgroundNinePartImage = 3,
105  BackgroundTransparentColor = 4;
106 #endif
107 
108 var CPViewFlags = { },
112 
114 
131 @implementation CPView : CPResponder <CPTheme>
132 {
133  CPWindow _window;
134 
135  CPView _superview;
136  CPArray _subviews;
137 
138  CPGraphicsContext _graphicsContext;
139 
140  int _tag;
141  CPString _identifier;
142 
143  CGRect _frame;
144  CGRect _bounds;
145  CGAffineTransform _boundsTransform;
146  CGAffineTransform _inverseBoundsTransform;
147 
148  CPSet _registeredDraggedTypes;
149  CPArray _registeredDraggedTypesArray;
150 
151  BOOL _isHidden;
152  BOOL _hitTests;
153  BOOL _clipsToBounds;
154 
155  BOOL _postsFrameChangedNotifications;
156  BOOL _postsBoundsChangedNotifications;
157  BOOL _inhibitFrameAndBoundsChangedNotifications;
158  BOOL _inLiveResize;
159  BOOL _isSuperviewAClipView;
160 
161 #if PLATFORM(DOM)
162  DOMElement _DOMElement;
163  DOMElement _DOMContentsElement;
164 
165  CPArray _DOMImageParts;
166  CPArray _DOMImageSizes;
167 
168  unsigned _backgroundType;
169 #endif
170 
171  CGRect _dirtyRect;
172 
173  float _opacity;
174  CPColor _backgroundColor;
175 
176  BOOL _autoresizesSubviews;
177  unsigned _autoresizingMask;
178 
179  CALayer _layer;
180  BOOL _wantsLayer;
181 
182  // Full Screen State
183  BOOL _isInFullScreenMode;
184 
185  _CPViewFullScreenModeState _fullScreenModeState;
186 
187  // Zoom Support
188  BOOL _isScaled;
189  CGSize _hierarchyScaleSize;
190  CGSize _scaleSize;
191 
192  // Drawing high DPI
193  BOOL _needToSetTransformMatrix;
194  float _highDPIRatio;
195 
196  // Layout Support
197  BOOL _needsLayout;
198  JSObject _ephemeralSubviews;
199 
200  JSObject _ephemeralSubviewsForNames;
201  CPSet _ephereralSubviews;
202 
203  // Key View Support
204  CPView _nextKeyView;
205  CPView _previousKeyView;
206 
207  unsigned _viewClassFlags;
208 
209  // ToolTips
210  CPString _toolTip;
211  Function _toolTipFunctionIn;
212  Function _toolTipFunctionOut;
213  BOOL _toolTipInstalled;
214 
215  BOOL _isObserving;
216 
217  BOOL _allowsVibrancy;
218  CPAppearance _appearance;
219  CPAppearance _effectiveAppearance;
220 
221  CPMutableArray _trackingAreas;
222  BOOL _inhibitUpdateTrackingAreas;
223 }
224 
225 /*
226  Private method for Objective-J.
227  @ignore
228 */
229 + (void)initialize
230 {
231  if (self !== [CPView class])
232  return;
233 
234 #if PLATFORM(DOM)
235  DOMElementPrototype = document.createElement("div");
236 
237  var style = DOMElementPrototype.style;
238 
239  style.overflow = "hidden";
240  style.position = "absolute";
241  style.visibility = "visible";
242  style.zIndex = 0;
243 #endif
244 
245  CachedNotificationCenter = [CPNotificationCenter defaultCenter];
246 }
247 
248 + (Class)_binderClassForBinding:(CPString)aBinding
249 {
250  if ([aBinding hasPrefix:CPHiddenBinding])
251  return [CPMultipleValueOrBinding class];
252 
253  return [super _binderClassForBinding:aBinding];
254 }
255 
260 + (void)setHighDPIDrawingEnabled:(BOOL)isEnabled
261 {
262  CPViewHighDPIDrawingEnabled = isEnabled;
263 }
264 
270 {
272 }
273 
275 {
276  return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
277 }
278 
280 {
281  return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"];
282 }
283 
285 {
286  return nil;
287 }
288 
289 - (void)_setupViewFlags
290 {
291  var theClass = [self class],
292  classUID = [theClass UID];
293 
294  if (CPViewFlags[classUID] === undefined)
295  {
296  var flags = 0;
297 
298  if ([theClass instanceMethodForSelector:@selector(drawRect:)] !== [CPView instanceMethodForSelector:@selector(drawRect:)]
299  || [theClass instanceMethodForSelector:@selector(viewWillDraw)] !== [CPView instanceMethodForSelector:@selector(viewWillDraw)])
300  flags |= CPViewHasCustomDrawRect;
301 
302  if ([theClass instanceMethodForSelector:@selector(viewWillLayout)] !== [CPView instanceMethodForSelector:@selector(viewWillLayout)])
304 
305  if ([theClass instanceMethodForSelector:@selector(layoutSubviews)] !== [CPView instanceMethodForSelector:@selector(layoutSubviews)])
307 
308  CPViewFlags[classUID] = flags;
309  }
310 
311  _viewClassFlags = CPViewFlags[classUID];
312 }
313 
314 - (id)init
315 {
316  return [self initWithFrame:CGRectMakeZero()];
317 }
318 
323 - (id)initWithFrame:(CGRect)aFrame
324 {
325  self = [super init];
326 
327  if (self)
328  {
329  var width = CGRectGetWidth(aFrame),
330  height = CGRectGetHeight(aFrame);
331 
332  _subviews = [];
333  _registeredDraggedTypes = [CPSet set];
334  _registeredDraggedTypesArray = [];
335 
336  _trackingAreas = [];
337 
338  _tag = -1;
339 
340  _frame = CGRectMakeCopy(aFrame);
341  _bounds = CGRectMake(0.0, 0.0, width, height);
342 
343  _autoresizingMask = CPViewNotSizable;
344  _autoresizesSubviews = YES;
345  _clipsToBounds = YES;
346 
347  _opacity = 1.0;
348  _isHidden = NO;
349  _hitTests = YES;
350 
351  _hierarchyScaleSize = CGSizeMake(1.0 , 1.0);
352  _scaleSize = CGSizeMake(1.0, 1.0);
353  _isScaled = NO;
354 
355  _theme = [CPTheme defaultTheme];
356  _themeState = CPThemeStateNormal;
357 
358 #if PLATFORM(DOM)
359  _DOMElement = DOMElementPrototype.cloneNode(false);
360  AppKitTagDOMElement(self, _DOMElement);
361 
362  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, CGRectGetMinX(aFrame), CGRectGetMinY(aFrame));
363  CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
364 
365  _DOMImageParts = [];
366  _DOMImageSizes = [];
367 #endif
368 
369  [self _setupViewFlags];
370  [self _loadThemeAttributes];
371  }
372 
373  return self;
374 }
375 
376 
382 - (void)setToolTip:(CPString)aToolTip
383 {
384  if (_toolTip == aToolTip)
385  return;
386 
387  if (aToolTip && ![aToolTip isKindOfClass:CPString])
388  aToolTip = [aToolTip description];
389 
390  _toolTip = aToolTip;
391 
392  [self _manageToolTipInstallation];
393 }
394 
395 - (void)_manageToolTipInstallation
396 {
397  if ([self window] && _toolTip)
398  [self _installToolTipEventHandlers];
399  else
400  [self _uninstallToolTipEventHandlers];
401 }
406 - (void)_installToolTipEventHandlers
407 {
408  if (_toolTipInstalled)
409  return;
410 
411  if (!_toolTipFunctionIn)
412  _toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
413 
414  if (!_toolTipFunctionOut)
415  _toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
416 
417 #if PLATFORM(DOM)
418  if (_DOMElement.addEventListener)
419  {
420  _DOMElement.addEventListener("mouseover", _toolTipFunctionIn, YES);
421  _DOMElement.addEventListener("keypress", _toolTipFunctionOut, YES);
422  _DOMElement.addEventListener("mouseout", _toolTipFunctionOut, YES);
423  }
424  else if (_DOMElement.attachEvent)
425  {
426  _DOMElement.attachEvent("onmouseover", _toolTipFunctionIn);
427  _DOMElement.attachEvent("onkeypress", _toolTipFunctionOut);
428  _DOMElement.attachEvent("onmouseout", _toolTipFunctionOut);
429  }
430 #endif
431 
432  _toolTipInstalled = YES;
433 }
434 
439 - (void)_uninstallToolTipEventHandlers
440 {
441  if (!_toolTipInstalled)
442  return;
443 
444 #if PLATFORM(DOM)
445  if (_DOMElement.removeEventListener)
446  {
447  _DOMElement.removeEventListener("mouseover", _toolTipFunctionIn, YES);
448  _DOMElement.removeEventListener("keypress", _toolTipFunctionOut, YES);
449  _DOMElement.removeEventListener("mouseout", _toolTipFunctionOut, YES);
450  }
451  else if (_DOMElement.detachEvent)
452  {
453  _DOMElement.detachEvent("onmouseover", _toolTipFunctionIn);
454  _DOMElement.detachEvent("onkeypress", _toolTipFunctionOut);
455  _DOMElement.detachEvent("onmouseout", _toolTipFunctionOut);
456  }
457 #endif
458 
459  _toolTipFunctionIn = nil;
460  _toolTipFunctionOut = nil;
461 
462  _toolTipInstalled = NO;
463 }
464 
470 {
471  return _superview;
472 }
473 
478 - (CPArray)subviews
479 {
480  return [_subviews copy];
481 }
482 
487 {
488  return _window;
489 }
490 
495 - (void)addSubview:(CPView)aSubview
496 {
497  [self _insertSubview:aSubview atIndex:CPNotFound];
498 }
499 
506 - (void)addSubview:(CPView)aSubview positioned:(CPWindowOrderingMode)anOrderingMode relativeTo:(CPView)anotherView
507 {
508  var index = anotherView ? [_subviews indexOfObjectIdenticalTo:anotherView] : CPNotFound;
509 
510  // In other words, if no view, then either all the way at the bottom or all the way at the top.
511  if (index === CPNotFound)
512  index = (anOrderingMode === CPWindowAbove) ? [_subviews count] : 0;
513 
514  // else, if we have a view, above if above.
515  else if (anOrderingMode === CPWindowAbove)
516  ++index;
517 
518  [self _insertSubview:aSubview atIndex:index];
519 }
520 
521 /* @ignore */
522 - (void)_insertSubview:(CPView)aSubview atIndex:(int)anIndex
523 {
524  if (aSubview === self)
525  [CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
526 #if DEBUG
527  if (!aSubview._superview && _subviews.indexOf(aSubview) !== CPNotFound)
528  [CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
529 #endif
530 
531  // Notify the subview that it will be moving.
532  [aSubview viewWillMoveToSuperview:self];
533 
534  // We will have to adjust the z-index of all views starting at this index.
535  var count = _subviews.length,
536  lastWindow;
537 
538  // Dirty the key view loop, in case the window wants to auto recalculate it
539  [[self window] _dirtyKeyViewLoop];
540 
541  // If this is already one of our subviews, remove it.
542  if (aSubview._superview == self)
543  {
544  var index = [_subviews indexOfObjectIdenticalTo:aSubview];
545 
546  // FIXME: should this be anIndex >= count? (last one)
547  if (index === anIndex || index === count - 1 && anIndex === count)
548  return;
549 
550  [_subviews removeObjectAtIndex:index];
551 
552 #if PLATFORM(DOM)
553  CPDOMDisplayServerRemoveChild(_DOMElement, aSubview._DOMElement);
554 #endif
555 
556  if (anIndex > index)
557  --anIndex;
558 
559  //We've effectively made the subviews array shorter, so represent that.
560  --count;
561  }
562  else
563  {
564  var superview = aSubview._superview;
565 
566  lastWindow = [superview window];
567 
568  // Remove the view from its previous superview.
569  [aSubview _removeFromSuperview];
570 
571  // Set ourselves as the superview.
572  aSubview._superview = self;
573  }
574 
575  if (anIndex === CPNotFound || anIndex >= count)
576  {
577  _subviews.push(aSubview);
578 
579 #if PLATFORM(DOM)
580  // Attach the actual node.
581  CPDOMDisplayServerAppendChild(_DOMElement, aSubview._DOMElement);
582 #endif
583  }
584  else
585  {
586  _subviews.splice(anIndex, 0, aSubview);
587 
588 #if PLATFORM(DOM)
589  // Attach the actual node.
590  CPDOMDisplayServerInsertBefore(_DOMElement, aSubview._DOMElement, _subviews[anIndex + 1]._DOMElement);
591 #endif
592  }
593 
594  [aSubview setNextResponder:self];
595  [aSubview _scaleSizeUnitSquareToSize:[self _hierarchyScaleSize]];
596 
597  // If the subview is not hidden and one of its ancestors is hidden,
598  // notify the subview that it is now hidden.
599  if (![aSubview isHidden] && [self isHiddenOrHasHiddenAncestor])
600  [aSubview _notifyViewDidHide];
601 
602  [aSubview viewDidMoveToSuperview];
603 
604  // Set the subview's window to our own.
605  if (_window)
606  [aSubview _setWindow:_window];
607 
608  if (!_window && lastWindow)
609  [aSubview _setWindow:nil];
610 
611  // This method might be called before we are fully unarchived, in which case the theme state isn't set up yet
612  // and none of the below matters anyhow.
613  if (_themeState)
614  {
615  if ([self hasThemeState:CPThemeStateFirstResponder])
616  [aSubview _notifyViewDidBecomeFirstResponder];
617  else
618  [aSubview _notifyViewDidResignFirstResponder];
619 
620  if ([self hasThemeState:CPThemeStateKeyWindow])
621  [aSubview _notifyWindowDidBecomeKey];
622  else
623  [aSubview _notifyWindowDidResignKey];
624  }
625 
626  [self didAddSubview:aSubview];
627 }
628 
633 - (void)didAddSubview:(CPView)aSubview
634 {
635 }
636 
642 {
643  var superview = _superview;
644 
645  [self viewWillMoveToSuperview:nil];
646  [self _removeFromSuperview];
647  [self viewDidMoveToSuperview];
648 
649  if (superview)
650  [self _setWindow:nil];
651 }
652 
653 - (void)_removeFromSuperview
654 {
655  if (!_superview)
656  return;
657 
658  // Dirty the key view loop, in case the window wants to auto recalculate it
659  [[self window] _dirtyKeyViewLoop];
660 
661  [_superview willRemoveSubview:self];
662 
663  [_superview._subviews removeObjectIdenticalTo:self];
664 
665 #if PLATFORM(DOM)
666  CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
667 #endif
668 
669  // If the view is not hidden and one of its ancestors is hidden,
670  // notify the view that it is now unhidden.
671  if (!_isHidden && [_superview isHiddenOrHasHiddenAncestor])
672  [self _notifyViewDidUnhide];
673 
674  [self _notifyWindowDidResignKey];
675  [self _notifyViewDidResignFirstResponder];
676 
677  _superview = nil;
678 }
679 
685 - (void)replaceSubview:(CPView)aSubview with:(CPView)aView
686 {
687  if (aSubview._superview !== self || aSubview === aView)
688  return;
689 
690  var index = [_subviews indexOfObjectIdenticalTo:aSubview];
691 
692  [self _insertSubview:aView atIndex:index];
693 
694  [aSubview removeFromSuperview];
695 }
696 
697 - (void)setSubviews:(CPArray)newSubviews
698 {
699  if (!newSubviews)
700  [CPException raise:CPInvalidArgumentException reason:"newSubviews cannot be nil in -[CPView setSubviews:]"];
701 
702  // Trivial Case 0: Same array somehow
703  if ([_subviews isEqual:newSubviews])
704  return;
705 
706  // Trivial Case 1: No current subviews, simply add all new subviews.
707  if ([_subviews count] === 0)
708  {
709  var index = 0,
710  count = [newSubviews count];
711 
712  for (; index < count; ++index)
713  [self addSubview:newSubviews[index]];
714 
715  return;
716  }
717 
718  // Trivial Case 2: No new subviews, simply remove all current subviews.
719  if ([newSubviews count] === 0)
720  {
721  var count = [_subviews count];
722 
723  while (count--)
724  [_subviews[count] removeFromSuperview];
725 
726  return;
727  }
728 
729  // Find out the views that were removed.
730  var removedSubviews = [CPMutableSet setWithArray:_subviews];
731 
732  [removedSubviews removeObjectsInArray:newSubviews];
733  [removedSubviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
734 
735  // Find out which views need to be added.
736  var addedSubviews = [CPMutableSet setWithArray:newSubviews];
737 
738  [addedSubviews removeObjectsInArray:_subviews];
739 
740  var addedSubview = nil,
741  addedSubviewEnumerator = [addedSubviews objectEnumerator];
742 
743  while ((addedSubview = [addedSubviewEnumerator nextObject]) !== nil)
744  [self addSubview:addedSubview];
745 
746  // If the order is fine, no need to reorder.
747  if ([_subviews isEqual:newSubviews])
748  return;
749 
750  _subviews = [newSubviews copy];
751 
752 #if PLATFORM(DOM)
753  var index = 0,
754  count = [_subviews count];
755 
756  for (; index < count; ++index)
757  {
758  var subview = _subviews[index];
759 
760  CPDOMDisplayServerRemoveChild(_DOMElement, subview._DOMElement);
761  CPDOMDisplayServerAppendChild(_DOMElement, subview._DOMElement);
762  }
763 #endif
764 }
765 
766 /* @ignore */
767 - (void)_setWindow:(CPWindow)aWindow
768 {
769  [[self window] _dirtyKeyViewLoop];
770 
771  // Clear out first responder if we're the first responder and leaving.
772  if ([_window firstResponder] === self && _window != aWindow)
773  [_window makeFirstResponder:nil];
774 
775  // Notify the view and its subviews
776  [self viewWillMoveToWindow:aWindow];
777 
778  // Unregister the drag events from the current window and register
779  // them in the new window.
780  if (_registeredDraggedTypes)
781  {
782  [_window _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
783  [aWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
784  }
785 
786  // View must be removed from the current window viewsWithTrackingAreas
787  if (_window && (_trackingAreas.length > 0))
788  [_window _removeTrackingAreaView:self];
789 
790  _window = aWindow;
791 
792  if (_window)
793  {
794  var owners;
795 
796  if (_trackingAreas.length > 0)
797  {
798  // View must be added to the new window viewsWithTrackingAreas
799  [_window _addTrackingAreaView:self];
800  owners = [self _calcTrackingAreaOwners];
801  }
802  else
803  owners = [self];
804 
805  // Notify that view tracking areas should be updated
806  // Cocoa doesn't notify on leaving a window
807  [self _updateTrackingAreasForOwners:owners];
808  }
809 
810  var count = [_subviews count];
811 
812  while (count--)
813  [_subviews[count] _setWindow:aWindow];
814 
815  if ([_window isKeyWindow])
816  [self setThemeState:CPThemeStateKeyWindow];
817  else
818  [self unsetThemeState:CPThemeStateKeyWindow];
819 
820  [self viewDidMoveToWindow];
821 
822  [self _manageToolTipInstallation];
823 
824  [[self window] _dirtyKeyViewLoop];
825 }
826 
831 - (BOOL)isDescendantOf:(CPView)aView
832 {
833  var view = self;
834 
835  do
836  {
837  if (view == aView)
838  return YES;
839  } while(view = [view superview])
840 
841  return NO;
842 }
843 
848 {
849  [self setNeedsLayout:YES];
850  [self setNeedsDisplay:YES];
851 }
852 
857 {
858 }
859 
864 - (void)viewWillMoveToSuperview:(CPView)aView
865 {
866  _isSuperviewAClipView = [aView isKindOfClass:[CPClipView class]];
867 
868  [self _removeObservers];
869 
870  if (aView)
871  [self _addObservers];
872 }
873 
878 - (void)viewWillMoveToWindow:(CPWindow)aWindow
879 {
880 }
881 
886 - (void)willRemoveSubview:(CPView)aView
887 {
888 }
889 
890 - (void)_removeObservers
891 {
892  if (!_isObserving)
893  return;
894 
895  var count = [_subviews count];
896 
897  while (count--)
898  [_subviews[count] _removeObservers];
899 
900  _isObserving = NO;
901 }
902 
903 - (void)_addObservers
904 {
905  if (_isObserving)
906  return;
907 
908  var count = [_subviews count];
909 
910  while (count--)
911  [_subviews[count] _addObservers];
912 
913  _isObserving = YES;
914 }
915 
921 {
922  var view = self;
923 
924  while (view && ![view isKindOfClass:[_CPMenuItemView class]])
925  view = [view superview];
926 
927  if (view)
928  return view._menuItem;
929 
930  return nil;
931 /* var view = self,
932  enclosingMenuItem = _enclosingMenuItem;
933 
934  while (!enclosingMenuItem && (view = view._enclosingMenuItem))
935  view = [view superview];
936 
937  return enclosingMenuItem;*/
938 }
939 
940 - (void)setTag:(CPInteger)aTag
941 {
942  _tag = aTag;
943 }
944 
945 - (CPInteger)tag
946 {
947  return _tag;
948 }
949 
950 - (CPView)viewWithTag:(CPInteger)aTag
951 {
952  if ([self tag] == aTag)
953  return self;
954 
955  var index = 0,
956  count = _subviews.length;
957 
958  for (; index < count; ++index)
959  {
960  var view = [_subviews[index] viewWithTag:aTag];
961 
962  if (view)
963  return view;
964  }
965 
966  return nil;
967 }
968 
973 - (BOOL)isFlipped
974 {
975  return YES;
976 }
977 
985 - (void)setFrame:(CGRect)aFrame
986 {
987  if (CGRectEqualToRect(_frame, aFrame))
988  return;
989 
990  _inhibitFrameAndBoundsChangedNotifications = YES;
991 
992  [self setFrameOrigin:aFrame.origin];
993  [self setFrameSize:aFrame.size];
994 
995  _inhibitFrameAndBoundsChangedNotifications = NO;
996 
997  if (_postsFrameChangedNotifications)
998  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
999 
1000  if (_isSuperviewAClipView)
1001  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1002 
1003  if (!_inhibitUpdateTrackingAreas)
1004  [self _updateTrackingAreas];
1005 }
1006 
1011 - (CGRect)frame
1012 {
1013  return CGRectMakeCopy(_frame);
1014 }
1015 
1016 - (CGPoint)frameOrigin
1017 {
1018  return CGPointMakeCopy(_frame.origin);
1019 }
1020 
1021 - (CGSize)frameSize
1022 {
1023  return CGSizeMakeCopy(_frame.size);
1024 }
1025 
1033 - (void)setCenter:(CGPoint)aPoint
1034 {
1035  [self setFrameOrigin:CGPointMake(aPoint.x - _frame.size.width / 2.0, aPoint.y - _frame.size.height / 2.0)];
1036 }
1037 
1042 - (CGPoint)center
1043 {
1044  return CGPointMake(_frame.size.width / 2.0 + _frame.origin.x, _frame.size.height / 2.0 + _frame.origin.y);
1045 }
1046 
1054 - (void)setFrameOrigin:(CGPoint)aPoint
1055 {
1056  var origin = _frame.origin;
1057 
1058  if (!aPoint || CGPointEqualToPoint(origin, aPoint))
1059  return;
1060 
1061  origin.x = aPoint.x;
1062  origin.y = aPoint.y;
1063 
1064  if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1065  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
1066 
1067  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1068  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1069 
1070 #if PLATFORM(DOM)
1071  var transform = _superview ? _superview._boundsTransform : NULL;
1072 
1073  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, transform, origin.x, origin.y);
1074 #endif
1075 
1076  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1077  [self _updateTrackingAreas];
1078 }
1079 
1086 - (void)setFrameSize:(CGSize)aSize
1087 {
1088  var size = _frame.size;
1089 
1090  if (!aSize || CGSizeEqualToSize(size, aSize))
1091  return;
1092 
1093  var oldSize = CGSizeMakeCopy(size);
1094 
1095  size.width = aSize.width;
1096  size.height = aSize.height;
1097 
1098  if (YES)
1099  {
1100  _bounds.size.width = aSize.width * 1 / _scaleSize.width;
1101  _bounds.size.height = aSize.height * 1 / _scaleSize.height;
1102  }
1103 
1104  if (_layer)
1105  [_layer _owningViewBoundsChanged];
1106 
1107  if (_autoresizesSubviews)
1108  [self resizeSubviewsWithOldSize:oldSize];
1109 
1110  [self setNeedsLayout];
1111  [self setNeedsDisplay:YES];
1112 
1113 #if PLATFORM(DOM)
1114  [self _setDisplayServerSetStyleSize:size];
1115 
1116  if (_backgroundType !== BackgroundTrivialColor)
1117  {
1118  if (_backgroundType === BackgroundTransparentColor)
1119  {
1120  CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
1121  }
1122  else
1123  {
1124  var images = [[_backgroundColor patternImage] imageSlices],
1125  partIndex = 0,
1126  frameSize = aSize;
1127 
1128  if (_backgroundType === BackgroundVerticalThreePartImage)
1129  {
1130  var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
1131  bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
1132 
1133  // Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
1134  if (top)
1135  {
1136  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
1137  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
1138  partIndex++;
1139  }
1140  if (_DOMImageSizes[1])
1141  {
1142  var height = frameSize.height - top - bottom;
1143 
1144  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
1145  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
1146  partIndex++;
1147  }
1148  if (bottom)
1149  {
1150  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
1151  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
1152  }
1153  }
1154  else if (_backgroundType === BackgroundHorizontalThreePartImage)
1155  {
1156  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
1157  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
1158 
1159  // Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
1160  if (left)
1161  {
1162  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
1163  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
1164  partIndex++;
1165  }
1166  if (_DOMImageSizes[1])
1167  {
1168  var width = (frameSize.width - left - right);
1169 
1170  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
1171  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
1172  partIndex++;
1173  }
1174  if (right)
1175  {
1176  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
1177  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
1178  }
1179  }
1180  else if (_backgroundType === BackgroundNinePartImage)
1181  {
1182  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
1183  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
1184  top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
1185  bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
1186  width = size.width - left - right,
1187  height = size.height - top - bottom;
1188 
1189  if (_DOMImageSizes[0])
1190  partIndex++;
1191  if (_DOMImageSizes[1])
1192  {
1193  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, top);
1194  partIndex++;
1195  }
1196  if (_DOMImageSizes[2])
1197  partIndex++;
1198  if (_DOMImageSizes[3])
1199  {
1200  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
1201  partIndex++;
1202  }
1203  if (_DOMImageSizes[4])
1204  {
1205  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
1206  partIndex++;
1207  }
1208  if (_DOMImageSizes[5])
1209  {
1210  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
1211  partIndex++;
1212  }
1213  if (_DOMImageSizes[6])
1214  partIndex++;
1215  if (_DOMImageSizes[7])
1216  {
1217  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
1218  }
1219  }
1220  }
1221  }
1222 #endif
1223 
1224  if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1225  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
1226 
1227  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1228  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1229 
1230  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1231  [self _updateTrackingAreas];
1232 }
1233 
1239 - (void)_setDisplayServerSetStyleSize:(CGSize)aSize
1240 {
1241 #if PLATFORM(DOM)
1242  var scale = [self scaleSize];
1243 
1244  CPDOMDisplayServerSetStyleSize(_DOMElement, aSize.width * 1 / scale.width, aSize.height * 1 / scale.height);
1245 
1246  if (_DOMContentsElement)
1247  {
1248  CPDOMDisplayServerSetSize(_DOMContentsElement, aSize.width * _highDPIRatio * 1 / scale.width, aSize.height * _highDPIRatio * 1 / scale.height);
1249  CPDOMDisplayServerSetStyleSize(_DOMContentsElement, aSize.width * 1 / scale.width, aSize.height * 1 / scale.height);
1250 
1251  _needToSetTransformMatrix = YES;
1252  }
1253 #endif
1254 }
1255 
1261 - (void)setBounds:(CGRect)bounds
1262 {
1263  if (CGRectEqualToRect(_bounds, bounds))
1264  return;
1265 
1266  _inhibitFrameAndBoundsChangedNotifications = YES;
1267 
1268  [self setBoundsOrigin:bounds.origin];
1269  [self setBoundsSize:bounds.size];
1270 
1271  _inhibitFrameAndBoundsChangedNotifications = NO;
1272 
1273  if (_postsBoundsChangedNotifications)
1274  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1275 
1276  if (_isSuperviewAClipView)
1277  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1278 
1279  if (!_inhibitUpdateTrackingAreas)
1280  [self _updateTrackingAreas];
1281 }
1282 
1287 - (CGRect)bounds
1288 {
1289  return CGRectMakeCopy(_bounds);
1290 }
1291 
1292 - (CGPoint)boundsOrigin
1293 {
1294  return CGPointMakeCopy(_bounds.origin);
1295 }
1296 
1297 - (CGSize)boundsSize
1298 {
1299  return CGSizeMakeCopy(_bounds.size);
1300 }
1301 
1308 - (void)setBoundsOrigin:(CGPoint)aPoint
1309 {
1310  var origin = _bounds.origin;
1311 
1312  if (CGPointEqualToPoint(origin, aPoint))
1313  return;
1314 
1315  origin.x = aPoint.x;
1316  origin.y = aPoint.y;
1317 
1318  if (origin.x != 0 || origin.y != 0)
1319  {
1320  _boundsTransform = CGAffineTransformMakeTranslation(-origin.x, -origin.y);
1321  _inverseBoundsTransform = CGAffineTransformInvert(_boundsTransform);
1322  }
1323  else
1324  {
1325  _boundsTransform = nil;
1326  _inverseBoundsTransform = nil;
1327  }
1328 
1329 #if PLATFORM(DOM)
1330  var index = _subviews.length;
1331 
1332  while (index--)
1333  {
1334  var view = _subviews[index],
1335  origin = view._frame.origin;
1336 
1337  CPDOMDisplayServerSetStyleLeftTop(view._DOMElement, _boundsTransform, origin.x, origin.y);
1338  }
1339 #endif
1340 
1341  if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1342  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1343 
1344  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1345  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1346 
1347  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1348  [self _updateTrackingAreas];
1349 }
1350 
1357 - (void)setBoundsSize:(CGSize)aSize
1358 {
1359  var size = _bounds.size;
1360 
1361  if (CGSizeEqualToSize(size, aSize))
1362  return;
1363 
1364  var frameSize = _frame.size;
1365 
1366  if (!CGSizeEqualToSize(size, frameSize))
1367  {
1368  var origin = _bounds.origin;
1369 
1370  origin.x /= size.width / frameSize.width;
1371  origin.y /= size.height / frameSize.height;
1372  }
1373 
1374  size.width = aSize.width;
1375  size.height = aSize.height;
1376 
1377  if (!CGSizeEqualToSize(size, frameSize))
1378  {
1379  var origin = _bounds.origin;
1380 
1381  origin.x *= size.width / frameSize.width;
1382  origin.y *= size.height / frameSize.height;
1383  }
1384 
1385  if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1386  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1387 
1388  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1389  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1390 
1391  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1392  [self _updateTrackingAreas];
1393 }
1394 
1395 
1400 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
1401 {
1402  var mask = [self autoresizingMask];
1403 
1404  if (mask == CPViewNotSizable)
1405  return;
1406 
1407  var frame = _superview._frame,
1408  newFrame = CGRectMakeCopy(_frame),
1409  dX = frame.size.width - aSize.width,
1410  dY = frame.size.height - aSize.height,
1411  evenFractionX = 1.0 / ((mask & CPViewMinXMargin ? 1 : 0) + (mask & CPViewWidthSizable ? 1 : 0) + (mask & CPViewMaxXMargin ? 1 : 0)),
1412  evenFractionY = 1.0 / ((mask & CPViewMinYMargin ? 1 : 0) + (mask & CPViewHeightSizable ? 1 : 0) + (mask & CPViewMaxYMargin ? 1 : 0)),
1413  baseX = (mask & CPViewMinXMargin ? _frame.origin.x : 0) +
1414  (mask & CPViewWidthSizable ? _frame.size.width : 0) +
1415  (mask & CPViewMaxXMargin ? aSize.width - _frame.size.width - _frame.origin.x : 0),
1416  baseY = (mask & CPViewMinYMargin ? _frame.origin.y : 0) +
1417  (mask & CPViewHeightSizable ? _frame.size.height : 0) +
1418  (mask & CPViewMaxYMargin ? aSize.height - _frame.size.height - _frame.origin.y : 0);
1419 
1420  if (mask & CPViewMinXMargin)
1421  newFrame.origin.x += dX * (baseX > 0 ? _frame.origin.x / baseX : evenFractionX);
1422 
1423  if (mask & CPViewWidthSizable)
1424  newFrame.size.width += dX * (baseX > 0 ? _frame.size.width / baseX : evenFractionX);
1425 
1426  if (mask & CPViewMinYMargin)
1427  newFrame.origin.y += dY * (baseY > 0 ? _frame.origin.y / baseY : evenFractionY);
1428 
1429  if (mask & CPViewHeightSizable)
1430  newFrame.size.height += dY * (baseY > 0 ? _frame.size.height / baseY : evenFractionY);
1431 
1432  [self setFrame:newFrame];
1433 }
1434 
1439 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
1440 {
1441  var count = _subviews.length;
1442 
1443  while (count--)
1444  [_subviews[count] resizeWithOldSuperviewSize:aSize];
1445 }
1446 
1454 - (void)setAutoresizesSubviews:(BOOL)aFlag
1455 {
1456  _autoresizesSubviews = !!aFlag;
1457 }
1458 
1464 {
1465  return _autoresizesSubviews;
1466 }
1467 
1472 - (void)setAutoresizingMask:(unsigned)aMask
1473 {
1474  _autoresizingMask = aMask;
1475 }
1476 
1480 - (unsigned)autoresizingMask
1481 {
1482  return _autoresizingMask;
1483 }
1484 
1485 // Fullscreen Mode
1486 
1491 {
1492  return [self enterFullScreenMode:nil withOptions:nil];
1493 }
1494 
1500 - (BOOL)enterFullScreenMode:(CPScreen)aScreen withOptions:(CPDictionary)options
1501 {
1502  _fullScreenModeState = _CPViewFullScreenModeStateMake(self);
1503 
1504  var fullScreenWindow = [[CPWindow alloc] initWithContentRect:[[CPPlatformWindow primaryPlatformWindow] contentBounds] styleMask:CPBorderlessWindowMask];
1505 
1506  [fullScreenWindow setLevel:CPScreenSaverWindowLevel];
1507  [fullScreenWindow setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
1508 
1509  var contentView = [fullScreenWindow contentView];
1510 
1511  [contentView setBackgroundColor:[CPColor blackColor]];
1512  [contentView addSubview:self];
1513 
1514  [self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
1515  [self setFrame:CGRectMakeCopy([contentView bounds])];
1516 
1517  [fullScreenWindow makeKeyAndOrderFront:self];
1518 
1519  [fullScreenWindow makeFirstResponder:self];
1520 
1521  _isInFullScreenMode = YES;
1522 
1523  return YES;
1524 }
1525 
1530 {
1531  [self exitFullScreenModeWithOptions:nil];
1532 }
1533 
1538 - (void)exitFullScreenModeWithOptions:(CPDictionary)options
1539 {
1540  if (!_isInFullScreenMode)
1541  return;
1542 
1543  _isInFullScreenMode = NO;
1544 
1545  [self setFrame:_fullScreenModeState.frame];
1546  [self setAutoresizingMask:_fullScreenModeState.autoresizingMask];
1547  [_fullScreenModeState.superview _insertSubview:self atIndex:_fullScreenModeState.index];
1548 
1549  [[self window] orderOut:self];
1550 }
1551 
1556 {
1557  return _isInFullScreenMode;
1558 }
1559 
1564 - (void)setHidden:(BOOL)aFlag
1565 {
1566  aFlag = !!aFlag;
1567 
1568  if (_isHidden === aFlag)
1569  return;
1570 
1571 // FIXME: Should we return to visibility? This breaks in FireFox, Opera, and IE.
1572 // _DOMElement.style.visibility = (_isHidden = aFlag) ? "hidden" : "visible";
1573  _isHidden = aFlag;
1574 
1575 #if PLATFORM(DOM)
1576  _DOMElement.style.display = _isHidden ? "none" : "block";
1577 #endif
1578 
1579  if (aFlag)
1580  {
1581  var view = [_window firstResponder];
1582 
1583  if ([view isKindOfClass:[CPView class]])
1584  {
1585  do
1586  {
1587  if (self == view)
1588  {
1589  [_window makeFirstResponder:[self nextValidKeyView]];
1590  break;
1591  }
1592  }
1593  while (view = [view superview]);
1594  }
1595 
1596  [self _notifyViewDidHide];
1597  }
1598  else
1599  {
1600  [self setNeedsDisplay:YES];
1601  [self _notifyViewDidUnhide];
1602  }
1603 }
1604 
1605 - (void)_notifyViewDidHide
1606 {
1607  [self viewDidHide];
1608 
1609  var count = [_subviews count];
1610 
1611  while (count--)
1612  [_subviews[count] _notifyViewDidHide];
1613 }
1614 
1615 - (void)_notifyViewDidUnhide
1616 {
1617  [self viewDidUnhide];
1618 
1619  var count = [_subviews count];
1620 
1621  while (count--)
1622  [_subviews[count] _notifyViewDidUnhide];
1623 }
1624 
1628 - (BOOL)isHidden
1629 {
1630  return _isHidden;
1631 }
1632 
1633 - (void)setClipsToBounds:(BOOL)shouldClip
1634 {
1635  if (_clipsToBounds === shouldClip)
1636  return;
1637 
1638  _clipsToBounds = shouldClip;
1639 
1640 #if PLATFORM(DOM)
1641  _DOMElement.style.overflow = _clipsToBounds ? "hidden" : "visible";
1642 #endif
1643 }
1644 
1646 {
1647  return _clipsToBounds;
1648 }
1649 
1655 - (void)setAlphaValue:(float)anAlphaValue
1656 {
1657  if (_opacity == anAlphaValue)
1658  return;
1659 
1660  _opacity = anAlphaValue;
1661 
1662 #if PLATFORM(DOM)
1663 
1665  {
1666  if (anAlphaValue === 1.0)
1667  try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
1668  else
1669  _DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
1670  }
1671  else
1672  _DOMElement.style.opacity = anAlphaValue;
1673 
1674 #endif
1675 }
1676 
1681 - (float)alphaValue
1682 {
1683  return _opacity;
1684 }
1685 
1691 {
1692  var view = self;
1693 
1694  while (view && ![view isHidden])
1695  view = [view superview];
1696 
1697  return view !== nil;
1698 }
1699 
1703 - (BOOL)_isVisible
1704 {
1705  return ![self isHiddenOrHasHiddenAncestor] && [[self window] isVisible];
1706 }
1707 
1718 {
1719 
1720 }
1721 
1732 {
1733 
1734 }
1735 
1741 - (BOOL)acceptsFirstMouse:(CPEvent)anEvent
1742 {
1743  return NO;
1744 }
1745 
1750 - (BOOL)hitTests
1751 {
1752  return _hitTests;
1753 }
1754 
1759 - (void)setHitTests:(BOOL)shouldHitTest
1760 {
1761  _hitTests = !!shouldHitTest;
1762 }
1763 
1769 - (CPView)hitTest:(CGPoint)aPoint
1770 {
1771  if (_isHidden || !_hitTests)
1772  return nil;
1773 
1774  var frame = _frame,
1775  sizeScale = [self _hierarchyScaleSize];
1776 
1777  if (_isScaled)
1778  frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale([_superview _hierarchyScaleSize].width, [_superview _hierarchyScaleSize].height));
1779  else
1780  frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale(sizeScale.width, sizeScale.height));
1781 
1782  if (!CGRectContainsPoint(frame, aPoint))
1783  return nil;
1784 
1785  var view = nil,
1786  i = _subviews.length,
1787  adjustedPoint = CGPointMake(aPoint.x - CGRectGetMinX(frame), aPoint.y - CGRectGetMinY(frame));
1788 
1789  if (_inverseBoundsTransform)
1790  {
1791  var affineTransform = CGAffineTransformMakeCopy(_inverseBoundsTransform);
1792 
1793  if (_isScaled)
1794  {
1795  affineTransform.tx *= [_superview _hierarchyScaleSize].width;
1796  affineTransform.ty *= [_superview _hierarchyScaleSize].height;
1797  }
1798  else
1799  {
1800  affineTransform.tx *= sizeScale.width;
1801  affineTransform.ty *= sizeScale.height;
1802  }
1803 
1804  adjustedPoint = CGPointApplyAffineTransform(adjustedPoint, affineTransform);
1805  }
1806 
1807 
1808  while (i--)
1809  if (view = [_subviews[i] hitTest:adjustedPoint])
1810  return view;
1811 
1812  return self;
1813 }
1814 
1819 {
1820  return NO;
1821 }
1822 
1828 {
1829  return ![self isOpaque];
1830 }
1831 
1832 - (void)mouseDown:(CPEvent)anEvent
1833 {
1834  if ([self mouseDownCanMoveWindow])
1835  [super mouseDown:anEvent];
1836 }
1837 
1838 - (void)rightMouseDown:(CPEvent)anEvent
1839 {
1840  var menu = [self menuForEvent:anEvent];
1841 
1842  if (menu)
1843  [CPMenu popUpContextMenu:menu withEvent:anEvent forView:self];
1844  else if ([[self nextResponder] isKindOfClass:CPView])
1845  [super rightMouseDown:anEvent];
1846  else
1847  [[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:NO];
1848 }
1849 
1850 - (CPMenu)menuForEvent:(CPEvent)anEvent
1851 {
1852  return [self menu] || [[self class] defaultMenu];
1853 }
1854 
1859 - (void)setBackgroundColor:(CPColor)aColor
1860 {
1861  if (_backgroundColor == aColor)
1862  return;
1863 
1864  if (aColor == [CPNull null])
1865  aColor = nil;
1866 
1867  _backgroundColor = aColor;
1868 
1869 #if PLATFORM(DOM)
1870  var patternImage = [_backgroundColor patternImage],
1871  colorExists = _backgroundColor && ([_backgroundColor patternImage] || [_backgroundColor alphaComponent] > 0.0),
1872  colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
1873  supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
1874  colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
1875  amount = 0,
1876  slices;
1877 
1878  if ([patternImage isThreePartImage])
1879  {
1880  _backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
1881  amount = 3;
1882  }
1883  else if ([patternImage isNinePartImage])
1884  {
1885  _backgroundType = BackgroundNinePartImage;
1886  amount = 9;
1887  }
1888  else
1889  {
1890  _backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
1891  amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
1892  }
1893 
1894  // Prepare multipart image data and reduce number of required DOM parts by number of empty slices in the multipart image to save needless DOM elements.
1895  if (_backgroundType === BackgroundVerticalThreePartImage || _backgroundType === BackgroundHorizontalThreePartImage || _backgroundType === BackgroundNinePartImage)
1896  {
1897  slices = [patternImage imageSlices];
1898 
1899  // We won't need more divs than there are slices.
1900  amount = MIN(amount, slices.length);
1901 
1902  for (var i = 0, count = slices.length; i < count; i++)
1903  {
1904  var image = slices[i],
1905  size = [image size];
1906 
1907  if (!size || (size.width == 0 && size.height == 0))
1908  size = nil;
1909 
1910  _DOMImageSizes[i] = size;
1911 
1912  // If there's a nil slice or a slice with no size, it won't need a div.
1913  if (!size)
1914  amount--;
1915  }
1916 
1917  // Now that we know how many divs we really need, compare that to number we actually have.
1918  amount -= _DOMImageParts.length;
1919  }
1920 
1921  // Make sure the number of divs we have match our needs.
1922  if (amount > 0)
1923  {
1924  while (amount--)
1925  {
1926  var DOMElement = DOMElementPrototype.cloneNode(false);
1927 
1928  DOMElement.style.zIndex = -1000;
1929 
1930  _DOMImageParts.push(DOMElement);
1931  _DOMElement.appendChild(DOMElement);
1932  }
1933  }
1934  else
1935  {
1936  amount = -amount;
1937  while (amount--)
1938  _DOMElement.removeChild(_DOMImageParts.pop());
1939  }
1940 
1941  if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
1942  {
1943  var colorCSS = colorExists ? [_backgroundColor cssString] : "";
1944 
1945  if (colorNeedsDOMElement)
1946  {
1947  _DOMElement.style.background = "";
1948  _DOMImageParts[0].style.background = [_backgroundColor cssString];
1949 
1950  if (patternImage)
1951  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[0], [patternImage size].width + "px", [patternImage size].height + "px");
1952 
1954  _DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
1955  else
1956  _DOMImageParts[0].style.opacity = [_backgroundColor alphaComponent];
1957 
1958  var size = [self bounds].size;
1959  CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
1960  }
1961  else
1962  _DOMElement.style.background = colorCSS;
1963 
1964  if (patternImage)
1965  CPDOMDisplayServerSetStyleBackgroundSize(_DOMElement, [patternImage size].width + "px", [patternImage size].height + "px");
1966  }
1967  else
1968  {
1969  var frameSize = _frame.size,
1970  partIndex = 0;
1971 
1972  for (var i = 0; i < slices.length; i++)
1973  {
1974  var size = _DOMImageSizes[i];
1975 
1976  if (!size)
1977  continue;
1978 
1979  var image = slices[i];
1980 
1981  // // If image was nil, size should have been nil too.
1982  // assert(image != nil);
1983 
1984  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height);
1985 
1986  _DOMImageParts[partIndex].style.background = "url(\"" + [image filename] + "\")";
1987 
1988  if (!supportsRGBA)
1989  {
1991  try { _DOMImageParts[partIndex].style.removeAttribute("filter") } catch (anException) { }
1992  else
1993  _DOMImageParts[partIndex].style.opacity = 1.0;
1994  }
1995 
1996  partIndex++;
1997  }
1998 
1999  if (_backgroundType == BackgroundNinePartImage)
2000  {
2001  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
2002  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
2003  top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
2004  bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
2005  width = frameSize.width - left - right,
2006  height = frameSize.height - top - bottom;
2007 
2008  partIndex = 0;
2009 
2010  if (_DOMImageSizes[0])
2011  {
2012  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2013  partIndex++;
2014  }
2015  if (_DOMImageSizes[1])
2016  {
2017  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
2018  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[1].height);
2019  partIndex++;
2020  }
2021  if (_DOMImageSizes[2])
2022  {
2023  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2024  partIndex++;
2025  }
2026  if (_DOMImageSizes[3])
2027  {
2028  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2029  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
2030  partIndex++;
2031  }
2032  if (_DOMImageSizes[4])
2033  {
2034  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, top);
2035  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
2036  partIndex++;
2037  }
2038  if (_DOMImageSizes[5])
2039  {
2040  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2041  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
2042  partIndex++;
2043  }
2044  if (_DOMImageSizes[6])
2045  {
2046  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2047  partIndex++;
2048  }
2049  if (_DOMImageSizes[7])
2050  {
2051  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, left, 0.0);
2052  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
2053  partIndex++;
2054  }
2055  if (_DOMImageSizes[8])
2056  {
2057  CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2058  }
2059  }
2060  else if (_backgroundType == BackgroundVerticalThreePartImage)
2061  {
2062  var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
2063  bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
2064 
2065  partIndex = 0;
2066 
2067  // Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
2068  if (top)
2069  {
2070  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
2071  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2072  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
2073  partIndex++;
2074  }
2075  if (_DOMImageSizes[1])
2076  {
2077  var height = frameSize.height - top - bottom;
2078 
2079  //_DOMImageParts[partIndex].style.backgroundSize = frameSize.width + "px " + height + "px";
2080  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
2081  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2082  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, height);
2083  partIndex++;
2084  }
2085  if (bottom)
2086  {
2087  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
2088  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2089  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
2090  }
2091  }
2092  else if (_backgroundType == BackgroundHorizontalThreePartImage)
2093  {
2094  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
2095  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
2096 
2097  partIndex = 0;
2098 
2099  // Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
2100  if (left)
2101  {
2102  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
2103  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2104  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
2105  partIndex++;
2106  }
2107  if (_DOMImageSizes[1])
2108  {
2109  var width = (frameSize.width - left - right);
2110 
2111  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
2112  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
2113  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, frameSize.height);
2114  partIndex++;
2115  }
2116  if (right)
2117  {
2118  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
2119  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2120  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
2121  }
2122  }
2123  }
2124 #endif
2125 }
2126 
2131 {
2132  return _backgroundColor;
2133 }
2134 
2135 // Converting Coordinates
2142 - (CGPoint)convertPoint:(CGPoint)aPoint fromView:(CPView)aView
2143 {
2144  if (aView === self)
2145  return aPoint;
2146 
2147  return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
2148 }
2149 
2155 - (CGPoint)convertPointFromBase:(CGPoint)aPoint
2156 {
2157  return [self convertPoint:aPoint fromView:nil];
2158 }
2159 
2166 - (CGPoint)convertPoint:(CGPoint)aPoint toView:(CPView)aView
2167 {
2168  if (aView === self)
2169  return aPoint;
2170 
2171  return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
2172 }
2173 
2174 
2180 - (CGPoint)convertPointToBase:(CGPoint)aPoint
2181 {
2182  return [self convertPoint:aPoint toView:nil];
2183 }
2184 
2191 - (CGSize)convertSize:(CGSize)aSize fromView:(CPView)aView
2192 {
2193  if (aView === self)
2194  return aSize;
2195 
2196  return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(aView, self));
2197 }
2198 
2205 - (CGSize)convertSize:(CGSize)aSize toView:(CPView)aView
2206 {
2207  if (aView === self)
2208  return aSize;
2209 
2210  return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(self, aView));
2211 }
2212 
2219 - (CGRect)convertRect:(CGRect)aRect fromView:(CPView)aView
2220 {
2221  if (self === aView)
2222  return aRect;
2223 
2224  return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
2225 }
2226 
2232 - (CGRect)convertRectFromBase:(CGRect)aRect
2233 {
2234  return [self convertRect:aRect fromView:nil];
2235 }
2236 
2243 - (CGRect)convertRect:(CGRect)aRect toView:(CPView)aView
2244 {
2245  if (self === aView)
2246  return aRect;
2247 
2248  return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
2249 }
2250 
2256 - (CGRect)convertRectToBase:(CGRect)aRect
2257 {
2258  return [self convertRect:aRect toView:nil];
2259 }
2260 
2273 - (void)setPostsFrameChangedNotifications:(BOOL)shouldPostFrameChangedNotifications
2274 {
2275  shouldPostFrameChangedNotifications = !!shouldPostFrameChangedNotifications;
2276 
2277  if (_postsFrameChangedNotifications === shouldPostFrameChangedNotifications)
2278  return;
2279 
2280  _postsFrameChangedNotifications = shouldPostFrameChangedNotifications;
2281 }
2282 
2287 {
2288  return _postsFrameChangedNotifications;
2289 }
2290 
2303 - (void)setPostsBoundsChangedNotifications:(BOOL)shouldPostBoundsChangedNotifications
2304 {
2305  shouldPostBoundsChangedNotifications = !!shouldPostBoundsChangedNotifications;
2306 
2307  if (_postsBoundsChangedNotifications === shouldPostBoundsChangedNotifications)
2308  return;
2309 
2310  _postsBoundsChangedNotifications = shouldPostBoundsChangedNotifications;
2311 }
2312 
2319 {
2320  return _postsBoundsChangedNotifications;
2321 }
2322 
2333 - (void)dragImage:(CPImage)anImage at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
2334 {
2335  [_window dragImage:anImage at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
2336 }
2337 
2348 - (void)dragView:(CPView)aView at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
2349 {
2350  [_window dragView:aView at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
2351 }
2352 
2357 - (void)registerForDraggedTypes:(CPArray)pasteboardTypes
2358 {
2359  if (!pasteboardTypes || ![pasteboardTypes count])
2360  return;
2361 
2362  var theWindow = [self window];
2363 
2364  [theWindow _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
2365  [_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
2366  [theWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
2367 
2368  _registeredDraggedTypesArray = nil;
2369 }
2370 
2376 {
2377  if (!_registeredDraggedTypesArray)
2378  _registeredDraggedTypesArray = [_registeredDraggedTypes allObjects];
2379 
2380  return _registeredDraggedTypesArray;
2381 }
2382 
2387 {
2388  [[self window] _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
2389 
2390  _registeredDraggedTypes = [CPSet set];
2391  _registeredDraggedTypesArray = [];
2392 }
2393 
2398 - (void)drawRect:(CGRect)aRect
2399 {
2400 
2401 }
2402 
2403 // Scaling
2404 
2411 - (void)scaleUnitSquareToSize:(CGSize)aSize
2412 {
2413  if (!aSize)
2414  return;
2415 
2416  // Reset the bounds
2417  var bounds = CGRectMakeCopy([self bounds]);
2418  bounds.size.width *= _scaleSize.width;
2419  bounds.size.height *= _scaleSize.height;
2420 
2421  [self willChangeValueForKey:@"scaleSize"];
2422  _scaleSize = CGSizeMakeCopy([self scaleSize]);
2423  _scaleSize.height *= aSize.height;
2424  _scaleSize.width *= aSize.width;
2425  [self didChangeValueForKey:@"scaleSize"];
2426  _isScaled = YES;
2427 
2428  _hierarchyScaleSize = CGSizeMakeCopy([self _hierarchyScaleSize]);
2429  _hierarchyScaleSize.height *= aSize.height;
2430  _hierarchyScaleSize.width *= aSize.width;
2431 
2432  var scaleAffine = CGAffineTransformMakeScale(1.0 / _scaleSize.width, 1.0 / _scaleSize.height),
2433  newBounds = CGRectApplyAffineTransform(CGRectMakeCopy(bounds), scaleAffine);
2434 
2435  [self setBounds:newBounds];
2436 
2437  [_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
2438 }
2439 
2444 - (void)_scaleSizeUnitSquareToSize:(CGSize)aSize
2445 {
2446  _hierarchyScaleSize = CGSizeMakeCopy([_superview _hierarchyScaleSize]);
2447 
2448  if (_isScaled)
2449  {
2450  _hierarchyScaleSize.width *= _scaleSize.width;
2451  _hierarchyScaleSize.height *= _scaleSize.height;
2452  }
2453 
2454  [_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
2455 }
2456 
2460 - (CGSize)_hierarchyScaleSize
2461 {
2462  return _hierarchyScaleSize || CGSizeMake(1.0, 1.0);
2463 }
2464 
2468 - (void)_applyCSSScalingTranformations
2469 {
2470 #if PLATFORM(DOM)
2471  if (_isScaled)
2472  {
2473  var scale = [self scaleSize],
2474  browserPropertyTransform = CPBrowserStyleProperty(@"transform"),
2475  browserPropertyTransformOrigin = CPBrowserStyleProperty(@"transformOrigin");
2476 
2477  self._DOMElement.style[browserPropertyTransform] = 'scale(' + scale.width + ', ' + scale.height + ')';
2478  self._DOMElement.style[browserPropertyTransformOrigin] = '0 0';
2479 
2480  [self _setDisplayServerSetStyleSize:[self frameSize]];
2481  }
2482 #endif
2483 }
2484 
2485 // Displaying
2486 
2490 - (void)setNeedsDisplay:(BOOL)aFlag
2491 {
2492  if (aFlag)
2493  {
2494  [self _applyCSSScalingTranformations];
2495  [self setNeedsDisplayInRect:[self bounds]];
2496  }
2497 }
2498 
2503 - (void)setNeedsDisplayInRect:(CGRect)aRect
2504 {
2505  if (!(_viewClassFlags & CPViewHasCustomDrawRect))
2506  return;
2507 
2508  if (CGRectIsEmpty(aRect))
2509  return;
2510 
2511  if (_dirtyRect && !CGRectIsEmpty(_dirtyRect))
2512  _dirtyRect = CGRectUnion(aRect, _dirtyRect);
2513  else
2514  _dirtyRect = CGRectMakeCopy(aRect);
2515 
2516  _CPDisplayServerAddDisplayObject(self);
2517 }
2518 
2520 {
2521  return _dirtyRect && !CGRectIsEmpty(_dirtyRect);
2522 }
2523 
2528 {
2529  if ([self needsDisplay])
2530  [self displayRect:_dirtyRect];
2531 }
2532 
2536 - (void)display
2537 {
2538  [self displayRect:[self visibleRect]];
2539 }
2540 
2541 - (void)displayIfNeededInRect:(CGRect)aRect
2542 {
2543  if ([self needsDisplay])
2544  [self displayRect:aRect];
2545 }
2546 
2551 - (void)displayRect:(CGRect)aRect
2552 {
2553  [self viewWillDraw];
2554 
2555  [self displayRectIgnoringOpacity:aRect inContext:nil];
2556 
2557  _dirtyRect = NULL;
2558 }
2559 
2560 - (void)displayRectIgnoringOpacity:(CGRect)aRect inContext:(CPGraphicsContext)aGraphicsContext
2561 {
2562  if ([self isHidden])
2563  return;
2564 
2565 #if PLATFORM(DOM)
2566  [self lockFocus];
2567 
2568  CGContextClearRect([[CPGraphicsContext currentContext] graphicsPort], aRect);
2569 
2570  [self drawRect:aRect];
2571  [self unlockFocus];
2572 #endif
2573 }
2574 
2576 {
2577 }
2578 
2582 - (void)lockFocus
2583 {
2584  if (!_graphicsContext)
2585  {
2586  var graphicsPort = CGBitmapGraphicsContextCreate();
2587 
2588 #if PLATFORM(DOM)
2589  var width = CGRectGetWidth(_frame),
2590  height = CGRectGetHeight(_frame),
2591  devicePixelRatio = window.devicePixelRatio || 1,
2592  backingStoreRatio = CPBrowserBackingStorePixelRatio(graphicsPort);
2593 
2594  _highDPIRatio = CPViewHighDPIDrawingEnabled ? (devicePixelRatio / backingStoreRatio) : 1;
2595 
2596  _DOMContentsElement = graphicsPort.DOMElement;
2597 
2598  _DOMContentsElement.style.zIndex = -100;
2599 
2600  _DOMContentsElement.style.overflow = "hidden";
2601  _DOMContentsElement.style.position = "absolute";
2602  _DOMContentsElement.style.visibility = "visible";
2603 
2604  CPDOMDisplayServerSetSize(_DOMContentsElement, width * _highDPIRatio, height * _highDPIRatio);
2605 
2606  CPDOMDisplayServerSetStyleLeftTop(_DOMContentsElement, NULL, 0.0, 0.0);
2607  CPDOMDisplayServerSetStyleSize(_DOMContentsElement, width, height);
2608 
2609  // The performance implications of this aren't clear, but without this subviews might not be redrawn when this
2610  // view moves.
2612  _DOMElement.style.webkitTransform = 'translateX(0)';
2613 
2614  CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
2615 #endif
2616  _graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
2617  _needToSetTransformMatrix = YES;
2618  }
2619 
2620 #if PLATFORM(DOM)
2621  if (_needToSetTransformMatrix && _highDPIRatio !== 1)
2622  [_graphicsContext graphicsPort].setTransform(_highDPIRatio, 0, 0 , _highDPIRatio, 0, 0);
2623 #endif
2624 
2625  _needToSetTransformMatrix = NO;
2626  [CPGraphicsContext setCurrentContext:_graphicsContext];
2627 
2628  CGContextSaveGState([_graphicsContext graphicsPort]);
2629 }
2630 
2635 {
2636  CGContextRestoreGState([_graphicsContext graphicsPort]);
2637 
2639 }
2640 
2642 {
2643  [self setNeedsLayout:YES];
2644 }
2645 
2646 - (void)setNeedsLayout:(BOOL)needLayout
2647 {
2648  if (!needLayout)
2649  {
2650  _needsLayout = NO;
2651  return;
2652  }
2653 
2654  _needsLayout = YES;
2655 
2656  _CPDisplayServerAddLayoutObject(self);
2657 }
2658 
2660 {
2661  return _needsLayout;
2662 }
2663 
2664 - (void)layout
2665 {
2666  _needsLayout = NO;
2667 
2668  if (_viewClassFlags & CPViewHasCustomViewWillLayout)
2669  [self viewWillLayout];
2670 
2671  if (_viewClassFlags & CPViewHasCustomLayoutSubviews)
2672  [self layoutSubviews];
2673 
2674  [self viewDidLayout];
2675 }
2676 
2678 {
2679  if (_needsLayout)
2680  [self layout];
2681 }
2682 
2687 {
2688 
2689 }
2690 
2695 {
2696  [self _recomputeAppearance];
2697 }
2698 
2700 {
2701 
2702 }
2703 
2707 - (BOOL)isOpaque
2708 {
2709  return NO;
2710 }
2711 
2715 - (CGRect)visibleRect
2716 {
2717  if (!_superview)
2718  return _bounds;
2719 
2720  return CGRectIntersection([self convertRect:[_superview visibleRect] fromView:_superview], _bounds);
2721 }
2722 
2723 // Scrolling
2724 /* @ignore */
2725 - (CPScrollView)_enclosingClipView
2726 {
2727  var superview = _superview,
2728  clipViewClass = [CPClipView class];
2729 
2730  while (superview && ![superview isKindOfClass:clipViewClass])
2731  superview = superview._superview;
2732 
2733  return superview;
2734 }
2735 
2740 - (void)scrollPoint:(CGPoint)aPoint
2741 {
2742  var clipView = [self _enclosingClipView];
2743 
2744  if (!clipView)
2745  return;
2746 
2747  [clipView scrollToPoint:[self convertPoint:aPoint toView:clipView]];
2748 }
2749 
2755 - (BOOL)scrollRectToVisible:(CGRect)aRect
2756 {
2757  // Make sure we have a rect that exists.
2758  aRect = CGRectIntersection(aRect, _bounds);
2759 
2760  // If aRect is empty no scrolling required.
2761  if (CGRectIsEmpty(aRect))
2762  return NO;
2763 
2764  var enclosingClipView = [self _enclosingClipView];
2765 
2766  // If we're not in a clip view, then there isn't much we can do.
2767  if (!enclosingClipView)
2768  return NO;
2769 
2770  var documentView = [enclosingClipView documentView];
2771 
2772  // If the clip view doesn't have a document view, then there isn't much we can do.
2773  if (!documentView)
2774  return NO;
2775 
2776  // Get the document view visible rect and convert aRect to the document view's coordinate system
2777  var documentViewVisibleRect = [documentView visibleRect],
2778  rectInDocumentView = [self convertRect:aRect toView:documentView];
2779 
2780  // If already visible then no scrolling required.
2781  if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
2782  return NO;
2783 
2784  var currentScrollPoint = documentViewVisibleRect.origin,
2785  scrollPoint = CGPointMakeCopy(currentScrollPoint),
2786  rectInDocumentViewMinX = CGRectGetMinX(rectInDocumentView),
2787  documentViewVisibleRectMinX = CGRectGetMinX(documentViewVisibleRect),
2788  doesItFitForWidth = documentViewVisibleRect.size.width >= rectInDocumentView.size.width;
2789 
2790  // One of the following has to be true since our current visible rect didn't contain aRect.
2791  if (rectInDocumentViewMinX < documentViewVisibleRectMinX && doesItFitForWidth)
2792  // Scroll to left edge of aRect as it is to the left of the visible rect and it fit inside
2793  scrollPoint.x = rectInDocumentViewMinX;
2794  else if (CGRectGetMaxX(rectInDocumentView) > CGRectGetMaxX(documentViewVisibleRect) && doesItFitForWidth)
2795  // Scroll to right edge of aRect as it is to the right of the visible rect and it fit inside
2796  scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
2797  else if (rectInDocumentViewMinX > documentViewVisibleRectMinX)
2798  // Scroll to left edge of aRect as it is to the right of the visible rect and it doesn't fit inside
2799  scrollPoint.x = rectInDocumentViewMinX;
2800  else if (CGRectGetMaxX(rectInDocumentView) < CGRectGetMaxX(documentViewVisibleRect))
2801  // Scroll to right edge of aRect as it is to the left of the visible rect and it doesn't fit inside
2802  scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
2803 
2804  var rectInDocumentViewMinY = CGRectGetMinY(rectInDocumentView),
2805  documentViewVisibleRectMinY = CGRectGetMinY(documentViewVisibleRect),
2806  doesItFitForHeight = documentViewVisibleRect.size.height >= rectInDocumentView.size.height;
2807 
2808  if (rectInDocumentViewMinY < documentViewVisibleRectMinY && doesItFitForHeight)
2809  // Scroll to top edge of aRect as it is above the visible rect and it fit inside
2810  scrollPoint.y = rectInDocumentViewMinY;
2811  else if (CGRectGetMaxY(rectInDocumentView) > CGRectGetMaxY(documentViewVisibleRect) && doesItFitForHeight)
2812  // Scroll to bottom edge of aRect as it is below the visible rect and it fit inside
2813  scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
2814  else if (rectInDocumentViewMinY > documentViewVisibleRectMinY)
2815  // Scroll to top edge of aRect as it is below the visible rect and it doesn't fit inside
2816  scrollPoint.y = rectInDocumentViewMinY;
2817  else if (CGRectGetMaxY(rectInDocumentView) < CGRectGetMaxY(documentViewVisibleRect))
2818  // Scroll to bottom edge of aRect as it is above the visible rect and it doesn't fit inside
2819  scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
2820 
2821  // Don't scroll if aRect contains the whole visible rect as it is already as visible as possible.
2822  // We check this by comparing to new scrollPoint to the current.
2823  if (CGPointEqualToPoint(scrollPoint, currentScrollPoint))
2824  return NO;
2825 
2826  [enclosingClipView scrollToPoint:scrollPoint];
2827 
2828  return YES;
2829 }
2830 
2831 /*
2832  FIXME Not yet implemented
2833 */
2834 - (BOOL)autoscroll:(CPEvent)anEvent
2835 {
2836  return [[self superview] autoscroll:anEvent];
2837 }
2838 
2845 - (CGRect)adjustScroll:(CGRect)proposedVisibleRect
2846 {
2847  return proposedVisibleRect;
2848 }
2849 
2853 - (void)scrollRect:(CGRect)aRect by:(float)anAmount
2854 {
2855 
2856 }
2857 
2863 {
2864  var superview = _superview,
2865  scrollViewClass = [CPScrollView class];
2866 
2867  while (superview && ![superview isKindOfClass:scrollViewClass])
2868  superview = superview._superview;
2869 
2870  return superview;
2871 }
2872 
2878 - (void)scrollClipView:(CPClipView)aClipView toPoint:(CGPoint)aPoint
2879 {
2880  [aClipView scrollToPoint:aPoint];
2881 }
2882 
2888 - (void)reflectScrolledClipView:(CPClipView)aClipView
2889 {
2890 }
2891 
2896 {
2897  return _inLiveResize;
2898 }
2899 
2910 {
2911  _inLiveResize = YES;
2912 }
2913 
2925 {
2926  _inLiveResize = NO;
2927 }
2928 
2929 @end
2930 
2931 @implementation CPView (KeyView)
2932 
2947 - (BOOL)performKeyEquivalent:(CPEvent)anEvent
2948 {
2949  var count = [_subviews count];
2950 
2951  // Is reverse iteration correct here? It matches the other (correct) code like hit testing.
2952  while (count--)
2953  if ([_subviews[count] performKeyEquivalent:anEvent])
2954  return YES;
2955 
2956  return NO;
2957 }
2958 
2960 {
2961  return [self acceptsFirstResponder] && ![self isHiddenOrHasHiddenAncestor];
2962 }
2963 
2965 {
2966  return _nextKeyView;
2967 }
2968 
2970 {
2971  var result = [self nextKeyView],
2972  resultUID = [result UID],
2973  unsuitableResults = {};
2974 
2975  while (result && ![result canBecomeKeyView])
2976  {
2977  unsuitableResults[resultUID] = 1;
2978  result = [result nextKeyView];
2979 
2980  resultUID = [result UID];
2981 
2982  // Did we get back to a key view we already ruled out due to ![result canBecomeKeyView]?
2983  if (unsuitableResults[resultUID])
2984  return nil;
2985  }
2986 
2987  return result;
2988 }
2989 
2991 {
2992  return _previousKeyView;
2993 }
2994 
2996 {
2997  var result = [self previousKeyView],
2998  firstResult = result;
2999 
3000  while (result && ![result canBecomeKeyView])
3001  {
3002  result = [result previousKeyView];
3003 
3004  // Cycled.
3005  if (result === firstResult)
3006  return nil;
3007  }
3008 
3009  return result;
3010 }
3011 
3012 - (void)_setPreviousKeyView:(CPView)previous
3013 {
3014  if (![previous isEqual:self])
3015  {
3016  var previousWindow = [previous window];
3017 
3018  if (!previousWindow || previousWindow === _window)
3019  {
3020  _previousKeyView = previous;
3021  return;
3022  }
3023  }
3024 
3025  _previousKeyView = nil;
3026 }
3027 
3028 - (void)setNextKeyView:(CPView)next
3029 {
3030  if (![next isEqual:self])
3031  {
3032  var nextWindow = [next window];
3033 
3034  if (!nextWindow || nextWindow === _window)
3035  {
3036  _nextKeyView = next;
3037  [_nextKeyView _setPreviousKeyView:self];
3038  return;
3039  }
3040  }
3041 
3042  _nextKeyView = nil;
3043 }
3044 
3045 @end
3046 
3048 
3052 - (void)setLayer:(CALayer)aLayer
3053 {
3054  if (_layer == aLayer)
3055  return;
3056 
3057  if (_layer)
3058  {
3059  _layer._owningView = nil;
3060 #if PLATFORM(DOM)
3061  _DOMElement.removeChild(_layer._DOMElement);
3062 #endif
3063  }
3064 
3065  _layer = aLayer;
3066 
3067  if (_layer)
3068  {
3069  var bounds = CGRectMakeCopy([self bounds]);
3070 
3071  [_layer _setOwningView:self];
3072 
3073 #if PLATFORM(DOM)
3074  _layer._DOMElement.style.zIndex = 100;
3075 
3076  _DOMElement.appendChild(_layer._DOMElement);
3077 #endif
3078  }
3079 }
3080 
3085 {
3086  return _layer;
3087 }
3088 
3093 - (void)setWantsLayer:(BOOL)aFlag
3094 {
3095  _wantsLayer = !!aFlag;
3096 }
3097 
3102 - (BOOL)wantsLayer
3103 {
3104  return _wantsLayer;
3105 }
3106 
3107 @end
3108 
3109 
3110 @implementation CPView (Scaling)
3111 
3117 - (void)setScaleSize:(CGSize)aSize
3118 {
3119  if (CGSizeEqualToSize(_scaleSize, aSize))
3120  return;
3121 
3122  var size = CGSizeMakeZero(),
3123  scale = CGSizeMakeCopy([self scaleSize]);
3124 
3125  size.height = aSize.height / scale.height;
3126  size.width = aSize.width / scale.width;
3127 
3128  [self scaleUnitSquareToSize:size];
3129  [self setNeedsDisplay:YES];
3130 }
3131 
3132 
3136 - (CGSize)scaleSize
3137 {
3138  return _scaleSize || CGSizeMake(1.0, 1.0);
3139 }
3140 
3141 @end
3142 
3143 
3144 @implementation CPView (Theming)
3145 
3146 #pragma mark Override
3147 
3148 - (BOOL)setThemeState:(ThemeState)aState
3149 {
3150  var shouldLayout = [super setThemeState:aState];
3151 
3152  if (!shouldLayout)
3153  return NO;
3154 
3155  [self setNeedsLayout:YES];
3156  [self setNeedsDisplay:YES];
3157 
3158  return YES;
3159 }
3160 
3161 - (BOOL)unsetThemeState:(ThemeState)aState
3162 {
3163  var shouldLayout = [super unsetThemeState:aState];
3164 
3165  if (!shouldLayout)
3166  return NO;
3167 
3168  [self setNeedsLayout:YES];
3169  [self setNeedsDisplay:YES];
3170 
3171  return YES;
3172 }
3173 
3174 - (void)setThemeClass:(CPString)theClass
3175 {
3176  [super setThemeClass:theClass];
3177 
3178  [self setNeedsLayout];
3179  [self setNeedsDisplay:YES];
3180 }
3181 
3182 
3183 #pragma mark First responder
3184 
3186 {
3187  var r = [super becomeFirstResponder];
3188 
3189  if (r)
3190  [self _notifyViewDidBecomeFirstResponder];
3191 
3192  return r;
3193 }
3194 
3195 - (void)_notifyViewDidBecomeFirstResponder
3196 {
3197  [self setThemeState:CPThemeStateFirstResponder];
3198 
3199  var count = [_subviews count];
3200 
3201  while (count--)
3202  [_subviews[count] _notifyViewDidBecomeFirstResponder];
3203 }
3204 
3206 {
3207  var r = [super resignFirstResponder];
3208 
3209  if (r)
3210  [self _notifyViewDidResignFirstResponder];
3211 
3212  return r;
3213 }
3214 
3215 - (void)_notifyViewDidResignFirstResponder
3216 {
3217  [self unsetThemeState:CPThemeStateFirstResponder];
3218 
3219  var count = [_subviews count];
3220 
3221  while (count--)
3222  [_subviews[count] _notifyViewDidResignFirstResponder];
3223 }
3224 
3225 - (void)_notifyWindowDidBecomeKey
3226 {
3227  [self setThemeState:CPThemeStateKeyWindow];
3228 
3229  var count = [_subviews count];
3230 
3231  while (count--)
3232  [_subviews[count] _notifyWindowDidBecomeKey];
3233 }
3234 
3235 - (void)_notifyWindowDidResignKey
3236 {
3237  [self unsetThemeState:CPThemeStateKeyWindow];
3238 
3239  var count = [_subviews count];
3240 
3241  while (count--)
3242  [_subviews[count] _notifyWindowDidResignKey];
3243 }
3244 
3245 #pragma mark Theme Attributes
3246 
3247 - (void)_setThemeIncludingDescendants:(CPTheme)aTheme
3248 {
3249  [self setTheme:aTheme];
3250  [[self subviews] makeObjectsPerformSelector:@selector(_setThemeIncludingDescendants:) withObject:aTheme];
3251 }
3252 
3254 {
3255  if (!_themeAttributes)
3256  return;
3257 
3258  [super objectDidChangeTheme];
3259 
3260  [self setNeedsLayout];
3261  [self setNeedsDisplay:YES];
3262 }
3263 
3264 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
3265 {
3266  var currentValue = [self currentValueForThemeAttribute:aName];
3267 
3268  [super setValue:aValue forThemeAttribute:aName inState:aState];
3269 
3270  if ([self currentValueForThemeAttribute:aName] === currentValue)
3271  return;
3272 
3273  [self setNeedsDisplay:YES];
3274  [self setNeedsLayout];
3275 }
3276 
3277 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
3278 {
3279  var currentValue = [self currentValueForThemeAttribute:aName];
3280 
3281  [super setValue:aValue forThemeAttribute:aName ];
3282 
3283  if ([self currentValueForThemeAttribute:aName] === currentValue)
3284  return;
3285 
3286  [self setNeedsDisplay:YES];
3287  [self setNeedsLayout];
3288 }
3289 
3290 - (CPView)createEphemeralSubviewNamed:(CPString)aViewName
3291 {
3292  return nil;
3293 }
3294 
3295 - (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
3296 {
3297  return CGRectMakeZero();
3298 }
3299 
3300 - (CPView)layoutEphemeralSubviewNamed:(CPString)aViewName
3301  positioned:(CPWindowOrderingMode)anOrderingMode
3302  relativeToEphemeralSubviewNamed:(CPString)relativeToViewName
3303 {
3304  if (!_ephemeralSubviewsForNames)
3305  {
3306  _ephemeralSubviewsForNames = {};
3307  _ephemeralSubviews = [CPSet set];
3308  }
3309 
3310  var frame = [self rectForEphemeralSubviewNamed:aViewName];
3311 
3312  if (frame)
3313  {
3314  if (!_ephemeralSubviewsForNames[aViewName])
3315  {
3316  _ephemeralSubviewsForNames[aViewName] = [self createEphemeralSubviewNamed:aViewName];
3317 
3318  [_ephemeralSubviews addObject:_ephemeralSubviewsForNames[aViewName]];
3319 
3320  if (_ephemeralSubviewsForNames[aViewName])
3321  [self addSubview:_ephemeralSubviewsForNames[aViewName] positioned:anOrderingMode relativeTo:_ephemeralSubviewsForNames[relativeToViewName]];
3322  }
3323 
3324  if (_ephemeralSubviewsForNames[aViewName])
3325  [_ephemeralSubviewsForNames[aViewName] setFrame:frame];
3326  }
3327  else if (_ephemeralSubviewsForNames[aViewName])
3328  {
3329  [_ephemeralSubviewsForNames[aViewName] removeFromSuperview];
3330 
3331  [_ephemeralSubviews removeObject:_ephemeralSubviewsForNames[aViewName]];
3332  delete _ephemeralSubviewsForNames[aViewName];
3333  }
3334 
3335  return _ephemeralSubviewsForNames[aViewName];
3336 }
3337 
3338 - (CPView)ephemeralSubviewNamed:(CPString)aViewName
3339 {
3340  if (!_ephemeralSubviewsForNames)
3341  return nil;
3342 
3343  return (_ephemeralSubviewsForNames[aViewName] || nil);
3344 }
3345 
3346 @end
3347 
3348 
3349 @implementation CPView (Appearance)
3350 
3354 {
3355  if (_appearance)
3356  return _appearance;
3357 
3358  return [_superview effectiveAppearance];
3359 }
3360 
3361 - (void)setAppearance:(CPAppearance)anAppearance
3362 {
3363  if ([_appearance isEqual:anAppearance])
3364  return;
3365 
3366  [self willChangeValueForKey:@"appearance"];
3367  _appearance = anAppearance;
3368  [self didChangeValueForKey:@"appearance"];
3369 
3370  [self setNeedsLayout:YES];
3371 }
3372 
3375 - (void)_recomputeAppearance
3376 {
3378 
3379  if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameAqua]])
3380  {
3381  [self setThemeState:CPThemeStateAppearanceAqua];
3382  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3383  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3384  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3385  }
3386  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameLightContent]])
3387  {
3388  [self unsetThemeState:CPThemeStateAppearanceAqua];
3389  [self setThemeState:CPThemeStateAppearanceLightContent];
3390  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3391  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3392  }
3393  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
3394  {
3395  [self unsetThemeState:CPThemeStateAppearanceAqua];
3396  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3397  [self setThemeState:CPThemeStateAppearanceVibrantLight];
3398  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3399  }
3400  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]])
3401  {
3402  [self unsetThemeState:CPThemeStateAppearanceAqua];
3403  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3404  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3405  [self setThemeState:CPThemeStateAppearanceVibrantDark];
3406  }
3407  else
3408  {
3409  [self unsetThemeState:CPThemeStateAppearanceAqua];
3410  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3411  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3412  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3413  }
3414 
3415 // var start = [CPDate new];
3416 
3417  for (var i = 0, size = [_subviews count]; i < size; i++)
3418  {
3419  [[_subviews objectAtIndex:i] _recomputeAppearance];
3420  }
3421 // [_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
3422 
3423 /* var now = [CPDate new];
3424  var elapsedSeconds = [now timeIntervalSinceReferenceDate] - [start timeIntervalSinceReferenceDate];
3425 
3426  CPLog.trace(@"_recomputeAppearance " + [_subviews count] + " subviews in " + elapsedSeconds + @" seconds");
3427 */}
3428 
3429 
3430 @end
3431 
3433 
3434 - (void)addTrackingArea:(CPTrackingArea)trackingArea
3435 {
3436  // Consistency check
3437  if (!trackingArea || [_trackingAreas containsObjectIdenticalTo:trackingArea])
3438  return;
3439 
3440  if ([trackingArea view])
3441  [CPException raise:CPInternalInconsistencyException reason:"Tracking area has already been added to another view."];
3442 
3443  [_trackingAreas addObject:trackingArea];
3444  [trackingArea setView:self];
3445 
3446  if (_window)
3447  [_window _addTrackingArea:trackingArea];
3448 
3449  [trackingArea _updateWindowRect];
3450 }
3451 
3452 - (void)removeTrackingArea:(CPTrackingArea)trackingArea
3453 {
3454  // Consistency check
3455  if (!trackingArea)
3456  return;
3457 
3458  if (![_trackingAreas containsObjectIdenticalTo:trackingArea])
3459  [CPException raise:CPInternalInconsistencyException reason:"Trying to remove unreferenced trackingArea"];
3460 
3461  [self _removeTrackingArea:trackingArea];
3462 }
3463 
3481 {
3482 
3483 }
3484 
3499 {
3500  while (_trackingAreas.length > 0)
3501  [self _removeTrackingArea:_trackingAreas[0]];
3502 }
3503 
3504 // Internal methods
3505 
3506 - (void)_removeTrackingArea:(CPTrackingArea)trackingArea
3507 {
3508  if (_window)
3509  [_window _removeTrackingArea:trackingArea];
3510 
3511  [trackingArea setView:nil];
3512  [_trackingAreas removeObjectIdenticalTo:trackingArea];
3513 }
3514 
3515 - (void)_updateTrackingAreas
3516 {
3517  _inhibitUpdateTrackingAreas = YES;
3518 
3519  [self _recursivelyUpdateTrackingAreas];
3520 
3521  _inhibitUpdateTrackingAreas = NO;
3522 }
3523 
3524 - (void)_recursivelyUpdateTrackingAreas
3525 {
3526  [self _updateTrackingAreasForOwners:[self _calcTrackingAreaOwners]];
3527 
3528  for (var i = 0; i < _subviews.length; i++)
3529  [_subviews[i] _recursivelyUpdateTrackingAreas];
3530 }
3531 
3532 - (CPArray)_calcTrackingAreaOwners
3533 {
3534  // First search all owners that must be notified
3535  // Remark: 99.99% of time, the only owner will be the view itself
3536  // In the same time, update the rects of InVisibleRect tracking areas
3537 
3538  var owners = [];
3539 
3540  for (var i = 0; i < _trackingAreas.length; i++)
3541  {
3542  var trackingArea = _trackingAreas[i];
3543 
3544  if ([trackingArea options] & CPTrackingInVisibleRect)
3545  [trackingArea _updateWindowRect];
3546 
3547  else
3548  {
3549  var owner = [trackingArea owner];
3550 
3551  if (![owners containsObjectIdenticalTo:owner])
3552  [owners addObject:owner];
3553  }
3554  }
3555 
3556  return owners;
3557 }
3558 
3559 - (void)_updateTrackingAreasForOwners:(CPArray)owners
3560 {
3561  for (var i = 0; i < owners.length; i++)
3562  [owners[i] updateTrackingAreas];
3563 }
3564 
3565 @end
3566 
3567 var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
3568  CPViewAutoresizesSubviewsKey = @"CPViewAutoresizesSubviews",
3569  CPViewBackgroundColorKey = @"CPViewBackgroundColor",
3570  CPViewBoundsKey = @"CPViewBoundsKey",
3571  CPViewFrameKey = @"CPViewFrameKey",
3572  CPViewHitTestsKey = @"CPViewHitTestsKey",
3573  CPViewToolTipKey = @"CPViewToolTipKey",
3574  CPViewIsHiddenKey = @"CPViewIsHiddenKey",
3575  CPViewOpacityKey = @"CPViewOpacityKey",
3576  CPViewSubviewsKey = @"CPViewSubviewsKey",
3577  CPViewSuperviewKey = @"CPViewSuperviewKey",
3578  CPViewTagKey = @"CPViewTagKey",
3579  CPViewWindowKey = @"CPViewWindowKey",
3580  CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
3581  CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey",
3582  CPReuseIdentifierKey = @"CPReuseIdentifierKey",
3583  CPViewScaleKey = @"CPViewScaleKey",
3584  CPViewSizeScaleKey = @"CPViewSizeScaleKey",
3585  CPViewIsScaledKey = @"CPViewIsScaledKey",
3586  CPViewAppearanceKey = @"CPViewAppearanceKey",
3587  CPViewTrackingAreasKey = @"CPViewTrackingAreasKey";
3588 
3589 @implementation CPView (CPCoding)
3590 
3596 - (id)initWithCoder:(CPCoder)aCoder
3597 {
3598  // We create the DOMElement "early" because there is a chance that we
3599  // will decode our superview before we are done decoding, at which point
3600  // we have to have an element to place in the tree. Perhaps there is
3601  // a more "elegant" way to do this...?
3602 #if PLATFORM(DOM)
3603  _DOMElement = DOMElementPrototype.cloneNode(false);
3604  AppKitTagDOMElement(self, _DOMElement);
3605 #endif
3606 
3607  // Also decode these "early".
3608  _frame = [aCoder decodeRectForKey:CPViewFrameKey];
3609  _bounds = [aCoder decodeRectForKey:CPViewBoundsKey];
3610 
3611  self = [super initWithCoder:aCoder];
3612 
3613  if (self)
3614  {
3615  _trackingAreas = [aCoder decodeObjectForKey:CPViewTrackingAreasKey];
3616 
3617  if (!_trackingAreas)
3618  _trackingAreas = [];
3619 
3620  // We have to manually check because it may be 0, so we can't use ||
3621  _tag = [aCoder containsValueForKey:CPViewTagKey] ? [aCoder decodeIntForKey:CPViewTagKey] : -1;
3622  _identifier = [aCoder decodeObjectForKey:CPReuseIdentifierKey];
3623 
3624  _window = [aCoder decodeObjectForKey:CPViewWindowKey];
3625  _superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
3626 
3627  // We have to manually add the subviews so that they will receive
3628  // viewWillMoveToSuperview: and viewDidMoveToSuperview:
3629  _subviews = [];
3630 
3631  var subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
3632 
3633  for (var i = 0, count = [subviews count]; i < count; ++i)
3634  {
3635  // addSubview won't do anything if the superview is already self, so clear it
3636  subviews[i]._superview = nil;
3637  [self addSubview:subviews[i]];
3638  }
3639 
3640  // FIXME: Should we encode/decode this?
3641  _registeredDraggedTypes = [CPSet set];
3642  _registeredDraggedTypesArray = [];
3643 
3644  // Other views (CPBox) might set an autoresizes mask on their subviews before it is actually decoded.
3645  // We make sure we don't override the value by checking if it was already set.
3646  if (_autoresizingMask === nil)
3647  _autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey] || CPViewNotSizable;
3648 
3649  _autoresizesSubviews = ![aCoder containsValueForKey:CPViewAutoresizesSubviewsKey] || [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
3650 
3651  _hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeBoolForKey:CPViewHitTestsKey];
3652 
3653  _toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
3654 
3655  if (_toolTip)
3656  [self _installToolTipEventHandlers];
3657 
3658  _scaleSize = [aCoder containsValueForKey:CPViewScaleKey] ? [aCoder decodeSizeForKey:CPViewScaleKey] : CGSizeMake(1.0, 1.0);
3659  _hierarchyScaleSize = [aCoder containsValueForKey:CPViewSizeScaleKey] ? [aCoder decodeSizeForKey:CPViewSizeScaleKey] : CGSizeMake(1.0, 1.0);
3660  _isScaled = [aCoder containsValueForKey:CPViewIsScaledKey] ? [aCoder decodeBoolForKey:CPViewIsScaledKey] : NO;
3661 
3662  // DOM SETUP
3663 #if PLATFORM(DOM)
3664  _DOMImageParts = [];
3665  _DOMImageSizes = [];
3666 
3667  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, CGRectGetMinX(_frame), CGRectGetMinY(_frame));
3668  [self _setDisplayServerSetStyleSize:_frame.size];
3669 
3670  var index = 0,
3671  count = _subviews.length;
3672 
3673  for (; index < count; ++index)
3674  {
3675  CPDOMDisplayServerAppendChild(_DOMElement, _subviews[index]._DOMElement);
3676  //_subviews[index]._superview = self;
3677  }
3678 #endif
3679 
3680  [self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
3681 
3682  if ([aCoder containsValueForKey:CPViewOpacityKey])
3683  [self setAlphaValue:[aCoder decodeIntForKey:CPViewOpacityKey]];
3684  else
3685  _opacity = 1.0;
3686 
3687  [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
3688  [self _setupViewFlags];
3689  [self _decodeThemeObjectsWithCoder:aCoder];
3690 
3691  [self setAppearance:[aCoder decodeObjectForKey:CPViewAppearanceKey]];
3692 
3693  [self setNeedsDisplay:YES];
3694  [self setNeedsLayout];
3695  }
3696 
3697  return self;
3698 }
3699 
3704 - (void)encodeWithCoder:(CPCoder)aCoder
3705 {
3706  [super encodeWithCoder:aCoder];
3707 
3708  if (_tag !== -1)
3709  [aCoder encodeInt:_tag forKey:CPViewTagKey];
3710 
3711  [aCoder encodeRect:_frame forKey:CPViewFrameKey];
3712  [aCoder encodeRect:_bounds forKey:CPViewBoundsKey];
3713 
3714  // This will come out nil on the other side with decodeObjectForKey:
3715  if (_window !== nil)
3716  [aCoder encodeConditionalObject:_window forKey:CPViewWindowKey];
3717 
3718  var count = [_subviews count],
3719  encodedSubviews = _subviews;
3720 
3721  if (count > 0 && [_ephemeralSubviews count] > 0)
3722  {
3723  encodedSubviews = [encodedSubviews copy];
3724 
3725  while (count--)
3726  if ([_ephemeralSubviews containsObject:encodedSubviews[count]])
3727  encodedSubviews.splice(count, 1);
3728  }
3729 
3730  if (encodedSubviews.length > 0)
3731  [aCoder encodeObject:encodedSubviews forKey:CPViewSubviewsKey];
3732 
3733  // This will come out nil on the other side with decodeObjectForKey:
3734  if (_superview !== nil)
3735  [aCoder encodeConditionalObject:_superview forKey:CPViewSuperviewKey];
3736 
3737  if (_autoresizingMask !== CPViewNotSizable)
3738  [aCoder encodeInt:_autoresizingMask forKey:CPViewAutoresizingMaskKey];
3739 
3740  if (!_autoresizesSubviews)
3741  [aCoder encodeBool:_autoresizesSubviews forKey:CPViewAutoresizesSubviewsKey];
3742 
3743  if (_backgroundColor !== nil)
3744  [aCoder encodeObject:_backgroundColor forKey:CPViewBackgroundColorKey];
3745 
3746  if (_hitTests !== YES)
3747  [aCoder encodeBool:_hitTests forKey:CPViewHitTestsKey];
3748 
3749  if (_opacity !== 1.0)
3750  [aCoder encodeFloat:_opacity forKey:CPViewOpacityKey];
3751 
3752  if (_isHidden)
3753  [aCoder encodeBool:_isHidden forKey:CPViewIsHiddenKey];
3754 
3755  if (_toolTip)
3756  [aCoder encodeObject:_toolTip forKey:CPViewToolTipKey];
3757 
3758  var nextKeyView = [self nextKeyView];
3759 
3760  if (nextKeyView !== nil && ![nextKeyView isEqual:self])
3761  [aCoder encodeConditionalObject:nextKeyView forKey:CPViewNextKeyViewKey];
3762 
3763  var previousKeyView = [self previousKeyView];
3764 
3765  if (previousKeyView !== nil && ![previousKeyView isEqual:self])
3766  [aCoder encodeConditionalObject:previousKeyView forKey:CPViewPreviousKeyViewKey];
3767 
3768  [self _encodeThemeObjectsWithCoder:aCoder];
3769 
3770  if (_identifier)
3771  [aCoder encodeObject:_identifier forKey:CPReuseIdentifierKey];
3772 
3773  [aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
3774  [aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
3775  [aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
3776  [aCoder encodeObject:_appearance forKey:CPViewAppearanceKey];
3777  [aCoder encodeObject:_trackingAreas forKey:CPViewTrackingAreasKey];
3778 }
3779 
3780 @end
3781 
3782 var _CPViewFullScreenModeStateMake = function(aView)
3783 {
3784  var superview = aView._superview;
3785 
3786  return { autoresizingMask:aView._autoresizingMask, frame:CGRectMakeCopy(aView._frame), index:(superview ? [superview._subviews indexOfObjectIdenticalTo:aView] : 0), superview:superview };
3787 };
3788 
3789 var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
3790 {
3791  var transform = CGAffineTransformMakeIdentity(),
3792  sameWindow = YES,
3793  fromWindow = nil,
3794  toWindow = nil;
3795 
3796  if (fromView)
3797  {
3798  var view = fromView;
3799 
3800  // FIXME: This doesn't handle the case when the outside views are equal.
3801  // If we have a fromView, "climb up" the view tree until
3802  // we hit the root node or we hit the toLayer.
3803  while (view && view != toView)
3804  {
3805  var frame = view._frame;
3806 
3807  if (view._isScaled)
3808  {
3809  var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
3810  CGAffineTransformConcatTo(transform, affineZoom, transform);
3811  }
3812 
3813  transform.tx += CGRectGetMinX(frame);
3814  transform.ty += CGRectGetMinY(frame);
3815 
3816  if (view._boundsTransform)
3817  {
3818  var inverseBoundsTransform = CGAffineTransformMakeCopy(view._boundsTransform);
3819 
3820  if (view._isScaled)
3821  {
3822  var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
3823  CGAffineTransformConcatTo(inverseBoundsTransform, affineZoom, inverseBoundsTransform);
3824  }
3825 
3826  CGAffineTransformConcatTo(transform, inverseBoundsTransform, transform);
3827  }
3828 
3829  view = view._superview;
3830  }
3831 
3832  // If we hit toView, then we're done.
3833  if (view === toView)
3834  {
3835  return transform;
3836  }
3837  else if (fromView && toView)
3838  {
3839  fromWindow = [fromView window];
3840  toWindow = [toView window];
3841 
3842  if (fromWindow && toWindow && fromWindow !== toWindow)
3843  sameWindow = NO;
3844  }
3845  }
3846 
3847  // FIXME: For now we can do things this way, but eventually we need to do them the "hard" way.
3848  var view = toView,
3849  transform2 = CGAffineTransformMakeIdentity();
3850 
3851  while (view && view != fromView)
3852  {
3853  var frame = CGRectMakeCopy(view._frame);
3854 
3855  // FIXME : For now we don't care about rotate transform and so on
3856  if (view._isScaled)
3857  {
3858  transform2.a *= 1 / view._scaleSize.width;
3859  transform2.d *= 1 / view._scaleSize.height;
3860  }
3861 
3862  transform2.tx += CGRectGetMinX(frame) * transform2.a;
3863  transform2.ty += CGRectGetMinY(frame) * transform2.d;
3864 
3865  if (view._boundsTransform)
3866  {
3867  var inverseBoundsTransform = CGAffineTransformMakeIdentity();
3868  inverseBoundsTransform.tx -= view._inverseBoundsTransform.tx * transform2.a;
3869  inverseBoundsTransform.ty -= view._inverseBoundsTransform.ty * transform2.d;
3870 
3871  CGAffineTransformConcatTo(transform2, inverseBoundsTransform, transform2);
3872  }
3873 
3874  view = view._superview;
3875  }
3876 
3877  transform2.tx = -transform2.tx;
3878  transform2.ty = -transform2.ty;
3879 
3880  if (view === fromView)
3881  {
3882  // toView is inside of fromView
3883  return transform2;
3884  }
3885 
3886  CGAffineTransformConcatTo(transform, transform2, transform);
3887 
3888  return transform;
3889 
3890 
3891 
3892 /* var views = [],
3893  view = toView;
3894 
3895  while (view)
3896  {
3897  views.push(view);
3898  view = view._superview;
3899  }
3900 
3901  var index = views.length;
3902 
3903  while (index--)
3904  {
3905  var frame = views[index]._frame;
3906 
3907  transform.tx -= CGRectGetMinX(frame);
3908  transform.ty -= CGRectGetMinY(frame);
3909  }*/
3910 
3911  return transform;
3912 };
id initWithFrame:(CGRect aFrame)
Definition: CPView.j:323
Used to implement exception handling (creating & raising).
Definition: CPException.h:2
void viewDidMoveToSuperview()
Definition: CPView.j:847
void lockFocus()
Definition: CPView.j:2582
BOOL postsBoundsChangedNotifications()
Definition: CPView.j:2318
void viewWillLayout()
Definition: CPView.j:2686
BOOL canBecomeKeyView()
Definition: CPView.j:2959
Definition: CPMenu.h:2
void addSubview:(CPView aSubview)
Definition: CPView.j:495
void drawRect:(CGRect aRect)
Definition: CPView.j:2398
void layoutSubviews()
Definition: CPView.j:2699
CGPoint frameOrigin()
Definition: CPView.j:1016
void setAppearance:(CPAppearance anAppearance)
Definition: CPView.j:3361
void layoutIfNeeded()
Definition: CPView.j:2677
BOOL setThemeState:(ThemeState aState)
Definition: CPView.j:3148
CPCSSRGBAFeature
CPView nextValidKeyView()
Definition: CPView.j:2969
function CGAffineTransformMakeIdentity()
var isEqual
void scrollToPoint:(CGPoint aPoint)
Definition: CPClipView.j:102
BOOL clipsToBounds()
Definition: CPView.j:1645
An object representation of nil.
Definition: CPNull.h:2
var CPReuseIdentifierKey
Definition: CPView.j:3582
BOOL needsDisplay()
Definition: CPView.j:2519
CPViewWidthSizable
Definition: CPView.j:67
void layout()
Definition: CPView.j:2664
function CGAffineTransformMakeScale(sx, sy)
CPViewMaxYMargin
Definition: CPView.j:91
var CPViewIsHiddenKey
Definition: CPView.j:3574
var CPViewSubviewsKey
Definition: CPView.j:3576
BOOL hitTests()
Definition: CPView.j:1750
CGPoint center()
Definition: CPView.j:1042
BOOL inLiveResize()
Definition: CPView.j:2895
CPView previousKeyView()
Definition: CPView.j:2990
void setView:(CPView aValue)
BOOL isFlipped()
Definition: CPView.j:973
BOOL autoscroll:(CPEvent anEvent)
Definition: CPView.j:2834
function CPBrowserBackingStorePixelRatio(context)
var CPViewHasCustomLayoutSubviews
Definition: CPView.j:110
var CPViewPreviousKeyViewKey
Definition: CPView.j:3581
CGSize boundsSize()
Definition: CPView.j:1297
void setFrame:(CGRect aFrame)
Definition: CPView.j:985
void viewDidHide()
Definition: CPView.j:1717
function CGContextRestoreGState(aContext)
Definition: CGContext.j:156
function CGAffineTransformMakeCopy(anAffineTransform)
var CPViewFrameKey
Definition: CPView.j:3571
var CPViewBoundsKey
Definition: CPView.j:3570
void setCurrentContext:(CPGraphicsContext aGraphicsContext)
void viewWillDraw()
Definition: CPView.j:2575
int width
CGRect bounds()
Definition: CPView.j:1287
void raise:reason:(CPString aName, [reason] CPString aReason)
Definition: CPException.j:66
CPArray registeredDraggedTypes()
Definition: CPView.j:2375
CPInteger tag()
Definition: CPView.j:945
void removeFromSuperview()
Definition: CPView.j:641
var CPViewOpacityKey
Definition: CPView.j:3575
void viewWillMoveToWindow:(CPWindow aWindow)
Definition: CPView.j:878
Definition: CALayer.h:2
BOOL enterFullScreenMode:withOptions:(CPScreen aScreen, [withOptions] CPDictionary options)
Definition: CPView.j:1500
BOOL postsFrameChangedNotifications()
Definition: CPView.j:2286
CPColor backgroundColor()
Definition: CPView.j:2130
void initialize()
Definition: CPView.j:229
var CPViewHasCustomDrawRect
Definition: CPView.j:109
void viewDidLayout()
Definition: CPView.j:2694
void setNeedsDisplayInRect:(CGRect aRect)
Definition: CPView.j:2503
var CPViewTagKey
Definition: CPView.j:3578
var CPViewAppearanceKey
Definition: CPView.j:3586
CPNotificationCenter defaultCenter()
CPInvalidArgumentException
Definition: CPException.j:25
A mutable key-value pair collection.
Definition: CPDictionary.h:2
CPScrollView enclosingScrollView()
Definition: CPView.j:2862
BOOL isInFullScreenMode()
Definition: CPView.j:1555
var CPViewSizeScaleKey
Definition: CPView.j:3584
BOOL enterFullScreenMode()
Definition: CPView.j:1490
function ThemeState(stateNames)
Definition: CPTheme.j:314
void setNeedsDisplay()
Definition: CALayer.j:830
void displayRectIgnoringOpacity:inContext:(CGRect aRect, [inContext] CPGraphicsContext aGraphicsContext)
Definition: CPView.j:2560
void setBoundsOrigin:(CGPoint aPoint)
Definition: CPView.j:1308
void displayRect:(CGRect aRect)
Definition: CPView.j:2551
var CPViewWindowKey
Definition: CPView.j:3579
CPHiddenBinding
CPWindow window()
Definition: CPView.j:486
CGSize frameSize()
Definition: CPView.j:1021
CGPoint boundsOrigin()
Definition: CPView.j:1292
void setNeedsLayout:(BOOL needLayout)
Definition: CPView.j:2646
CPColor blackColor()
Definition: CPColor.j:281
id initWithContentRect:styleMask:(CGRect aContentRect, [styleMask] unsigned aStyleMask)
Definition: CPWindow.j:263
void viewWillMoveToSuperview:(CPView aView)
Definition: CPView.j:864
BOOL resignFirstResponder()
Definition: CPView.j:3205
var CPViewAutoresizingMaskKey
Definition: CPView.j:3567
CPView previousValidKeyView()
Definition: CPView.j:2995
CPView createEphemeralSubviewNamed:(CPString aViewName)
Definition: CPView.j:3290
id initWithName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
var CPViewTrackingAreasKey
Definition: CPView.j:3587
An immutable string (collection of characters).
Definition: CPString.h:2
CGPoint convertPoint:fromView:(CGPoint aPoint, [fromView] CPView aView)
Definition: CPView.j:2142
var CPViewBackgroundColorKey
Definition: CPView.j:3569
var CPViewIsScaledKey
Definition: CPView.j:3585
Definition: CPImage.h:2
CPSet keyPathsForValuesAffectingFrame()
Definition: CPView.j:274
void addSubview:positioned:relativeTo:(CPView aSubview, [positioned] CPWindowOrderingMode anOrderingMode, [relativeTo] CPView anotherView)
Definition: CPView.j:506
function CPFeatureIsCompatible(aFeature)
id init()
Definition: CPView.j:314
BOOL mouseDownCanMoveWindow()
Definition: CPView.j:1827
var CachedNotificationCenter
Definition: CPView.j:96
CPSet keyPathsForValuesAffectingBounds()
Definition: CPView.j:279
CGRect convertRect:toView:(CGRect aRect, [toView] CPView aView)
Definition: CPView.j:2243
CPViewMinXMargin
Definition: CPView.j:61
CPView nextValidKeyView()
Definition: CPView.j:2969
void viewDidMoveToWindow()
Definition: CPView.j:856
void setHidden:(BOOL aFlag)
Definition: CPView.j:1564
CPView previousKeyView()
Definition: CPView.j:2990
void setAutoresizingMask:(unsigned aMask)
Definition: CPView.j:1472
void exitFullScreenMode()
Definition: CPView.j:1529
BOOL isOpaque()
Definition: CPView.j:2707
void setNeedsDisplay:(BOOL aFlag)
Definition: CPView.j:2490
CPGraphicsContext graphicsContextWithGraphicsPort:flipped:(CGContext aContext, [flipped] BOOL aFlag)
void viewDidEndLiveResize()
Definition: CPView.j:2924
CPMenu menuForEvent:(CPEvent anEvent)
Definition: CPView.j:1850
BOOL isHidden()
Definition: CPView.j:1628
CPAppearanceNameAqua
Definition: CPAppearance.j:24
CGPoint convertPoint:toView:(CGPoint aPoint, [toView] CPView aView)
Definition: CPView.j:2166
CPViewBoundsDidChangeNotification
Definition: CPView.j:93
BOOL isVisible()
Definition: CPWindow.j:1094
CPWindow window()
Definition: CPEvent.j:330
function CGAffineTransformMakeTranslation(tx, ty)
var CPViewSuperviewKey
Definition: CPView.j:3577
function CGRectApplyAffineTransform(aRect, anAffineTransform)
function CGAffineTransformInvert(aTransform)
var CPViewScaleKey
Definition: CPView.j:3583
function CGContextClearRect(aContext, aRect)
Definition: CGContextVML.j:51
var CPViewToolTipKey
Definition: CPView.j:3573
A notification that can be posted to a CPNotificationCenter.
Definition: CPNotification.h:2
var CPViewHitTestsKey
Definition: CPView.j:3572
function CGAffineTransformConcatTo(lhs, rhs, to)
CPTheme defaultTheme()
Definition: CPTheme.j:44
CPArray subviews()
Definition: CPView.j:478
void setAlphaValue:(float anAlphaValue)
Definition: CPView.j:1655
BOOL isHighDPIDrawingEnabled()
Definition: CPView.j:269
void orderOut:(id aSender)
Definition: CPWindow.j:1006
void setNeedsLayout()
Definition: CPView.j:2641
void objectDidChangeTheme()
Definition: CPView.j:3253
CGRect convertRect:fromView:(CGRect aRect, [fromView] CPView aView)
Definition: CPView.j:2219
void scaleUnitSquareToSize:(CGSize aSize)
Definition: CPView.j:2411
function CGSizeApplyAffineTransform(aSize, aTransform)
CPViewMaxXMargin
Definition: CPView.j:73
BOOL needsLayout()
Definition: CPView.j:2659
CPAppearanceNameLightContent
Definition: CPAppearance.j:25
CPMenuItem enclosingMenuItem()
Definition: CPView.j:920
CPAppearanceNameVibrantDark
Definition: CPAppearance.j:26
global appkit_tag_dom_elements typedef _CPViewFullScreenModeState CPViewNotSizable
Definition: CPView.j:55
var CPViewFlags
Definition: CPView.j:108
function CPBrowserStyleProperty(aProperty)
Defines methods for use when archiving & restoring (enc/decoding).
Definition: CPCoder.h:2
BOOL becomeFirstResponder()
Definition: CPView.j:3185
CPAppearance effectiveAppearance()
Definition: CPView.j:3353
CPNotFound
Definition: CPObjJRuntime.j:62
var CPViewHighDPIDrawingEnabled
Definition: CPView.j:113
CPThemeStateFirstResponder
Definition: CPTheme.j:560
BOOL unsetThemeState:(ThemeState aState)
Definition: CPView.j:3161
function CGContextSaveGState(aContext)
Definition: CGContext.j:146
Sends messages (CPNotification) between objects.
BOOL needsPanelToBecomeKey()
Definition: CPView.j:1818
CPViewHeightSizable
Definition: CPView.j:85
Definition: CPTheme.h:2
CGSize scaleSize()
Definition: CPView.j:3136
CGSize scaleSize()
Definition: CPView.j:3136
void didAddSubview:(CPView aSubview)
Definition: CPView.j:633
CPView nextKeyView()
Definition: CPView.j:2964
void setBounds:(CGRect bounds)
Definition: CPView.j:1261
CPString description()
Definition: CPString.j:178
CGAffineTransform affineTransform()
Definition: CALayer.j:293
var CPViewNextKeyViewKey
Definition: CPView.j:3580
void setBackgroundColor:(CPColor aColor)
Definition: CPView.j:1859
void setBoundsSize:(CGSize aSize)
Definition: CPView.j:1357
CPAppearance effectiveAppearance()
Definition: CPView.j:3353
float alphaValue()
Definition: CPView.j:1681
CPViewMinYMargin
Definition: CPView.j:79
var CPViewAutoresizesSubviewsKey
Definition: CPView.j:3568
void setFrameSize:(CGSize aSize)
Definition: CPView.j:1086
CPOpacityRequiresFilterFeature
Definition: CPEvent.h:2
void viewWillStartLiveResize()
Definition: CPView.j:2909
void unlockFocus()
Definition: CPView.j:2634
CPView superview()
Definition: CPView.j:469
CPAppearanceNameVibrantLight
Definition: CPAppearance.j:27
var CPViewHasCustomViewWillLayout
Definition: CPView.j:111
CPView nextKeyView()
Definition: CPView.j:2964
unsigned autoresizingMask()
Definition: CPView.j:1480
CPPlatformWindow platformWindow()
Definition: CPWindow.j:384
CGRect frame()
Definition: CPView.j:1011
function CGPointApplyAffineTransform(aPoint, aTransform)
function CPPlatformHasBug(aBug)
void exitFullScreenModeWithOptions:(CPDictionary options)
Definition: CPView.j:1538
void displayIfNeeded()
Definition: CPView.j:2527
function CGBitmapGraphicsContextCreate()
Definition: CGContext.j:136
BOOL autoresizesSubviews()
Definition: CPView.j:1463
CPWindowOrderingMode CPWindowAbove
CGRect visibleRect()
Definition: CPView.j:2715
void viewDidUnhide()
Definition: CPView.j:1731
void setFrameOrigin:(CGPoint aPoint)
Definition: CPView.j:1054
CPTrackingInVisibleRect
CPMenu defaultMenu()
Definition: CPView.j:284
void resizeSubviewsWithOldSize:(CGSize aSize)
Definition: CPView.j:1439
void display()
Definition: CPView.j:2536
void popUpContextMenu:withEvent:forView:(CPMenu aMenu, [withEvent] CPEvent anEvent, [forView] CPView aView)
Definition: CPMenu.j:857
void unregisterDraggedTypes()
Definition: CPView.j:2386
CPPlatformWindow primaryPlatformWindow()
CPMenu menu
id alloc()
Definition: CPObject.j:130
CPViewFrameDidChangeNotification
Definition: CPView.j:94
CGRect rectForEphemeralSubviewNamed:(CPString aViewName)
Definition: CPView.j:3295
Definition: CPView.j:131
CPThemeStateKeyWindow
Definition: CPTheme.j:562
BOOL isHiddenOrHasHiddenAncestor()
Definition: CPView.j:1690
CPCanvasParentDrawErrorsOnMovementBug