API  0.9.10
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 _CPViewWillAppearNotification = @"CPViewWillAppearNotification";
94 _CPViewDidAppearNotification = @"CPViewDidAppearNotification";
95 _CPViewWillDisappearNotification = @"CPViewWillDisappearNotification";
96 _CPViewDidDisappearNotification = @"CPViewDidDisappearNotification";
97 
98 CPViewBoundsDidChangeNotification = @"CPViewBoundsDidChangeNotification";
99 CPViewFrameDidChangeNotification = @"CPViewFrameDidChangeNotification";
100 
102 
103 #if PLATFORM(DOM)
104 var DOMElementPrototype = nil,
105 
106  BackgroundTrivialColor = 0,
107  BackgroundVerticalThreePartImage = 1,
108  BackgroundHorizontalThreePartImage = 2,
109  BackgroundNinePartImage = 3,
110  BackgroundTransparentColor = 4;
111 #endif
112 
113 var CPViewFlags = { },
117 
119 
136 @implementation CPView : CPResponder <CPTheme>
137 {
138  CPWindow _window;
139 
140  CPView _superview;
141  CPArray _subviews;
142 
143  CPGraphicsContext _graphicsContext;
144 
145  int _tag;
146  CPString _identifier;
147 
148  CGRect _frame;
149  CGRect _bounds;
150  CGAffineTransform _boundsTransform;
151  CGAffineTransform _inverseBoundsTransform;
152 
153  CPSet _registeredDraggedTypes;
154  CPArray _registeredDraggedTypesArray;
155 
156  BOOL _isHidden;
157  BOOL _isHiddenOrHasHiddenAncestor;
158  BOOL _hitTests;
159  BOOL _clipsToBounds;
160 
161  BOOL _postsFrameChangedNotifications;
162  BOOL _postsBoundsChangedNotifications;
163  BOOL _inhibitFrameAndBoundsChangedNotifications;
164  BOOL _inLiveResize;
165  BOOL _isSuperviewAClipView;
166 
167 #if PLATFORM(DOM)
168  DOMElement _DOMElement;
169  DOMElement _DOMContentsElement;
170 
171  CPArray _DOMImageParts;
172  CPArray _DOMImageSizes;
173 
174  unsigned _backgroundType;
175 #endif
176 
177  CGRect _dirtyRect;
178 
179  float _opacity;
180  CPColor _backgroundColor;
181 
182  BOOL _autoresizesSubviews;
183  unsigned _autoresizingMask;
184 
185  CALayer _layer;
186  BOOL _wantsLayer;
187 
188  // Full Screen State
189  BOOL _isInFullScreenMode;
190 
191  _CPViewFullScreenModeState _fullScreenModeState;
192 
193  // Zoom Support
194  BOOL _isScaled;
195  CGSize _hierarchyScaleSize;
196  CGSize _scaleSize;
197 
198  // Drawing high DPI
199  BOOL _needToSetTransformMatrix;
200  float _highDPIRatio;
201 
202  // Layout Support
203  BOOL _needsLayout;
204  JSObject _ephemeralSubviews;
205 
206  JSObject _ephemeralSubviewsForNames;
207  CPSet _ephereralSubviews;
208 
209  // Key View Support
210  CPView _nextKeyView;
211  CPView _previousKeyView;
212 
213  unsigned _viewClassFlags;
214 
215  // ToolTips
216  CPString _toolTip;
217  Function _toolTipFunctionIn;
218  Function _toolTipFunctionOut;
219  BOOL _toolTipInstalled;
220 
221  BOOL _isObserving;
222 
223  BOOL _allowsVibrancy;
224  CPAppearance _appearance;
225  CPAppearance _effectiveAppearance;
226 
227  CPMutableArray _trackingAreas;
228  BOOL _inhibitUpdateTrackingAreas;
229 
230  id _animator;
231  CPDictionary _animationsDictionary;
232  BOOL _inhibitDOMUpdates;
233  BOOL _forceUpdates;
234 }
235 
236 /*
237  Private method for Objective-J.
238  @ignore
239 */
240 + (void)initialize
241 {
242  if (self !== [CPView class])
243  return;
244 
245 #if PLATFORM(DOM)
246  DOMElementPrototype = document.createElement("div");
247 
248  var style = DOMElementPrototype.style;
249 
250  style.overflow = "hidden";
251  style.position = "absolute";
252  style.visibility = "visible";
253  style.zIndex = 0;
254 #endif
255 
256  CachedNotificationCenter = [CPNotificationCenter defaultCenter];
257 }
258 
259 + (Class)_binderClassForBinding:(CPString)aBinding
260 {
261  if ([aBinding hasPrefix:CPHiddenBinding])
262  return [CPMultipleValueOrBinding class];
263 
264  return [super _binderClassForBinding:aBinding];
265 }
266 
271 + (void)setHighDPIDrawingEnabled:(BOOL)isEnabled
272 {
273  CPViewHighDPIDrawingEnabled = isEnabled;
274 }
275 
281 {
283 }
284 
286 {
287  return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
288 }
289 
291 {
292  return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"];
293 }
294 
296 {
297  return nil;
298 }
299 
300 - (void)_setupViewFlags
301 {
302  var theClass = [self class],
303  classUID = [theClass UID];
304 
305  if (CPViewFlags[classUID] === undefined)
306  {
307  var flags = 0;
308 
309  if ([theClass instanceMethodForSelector:@selector(drawRect:)] !== [CPView instanceMethodForSelector:@selector(drawRect:)]
310  || [theClass instanceMethodForSelector:@selector(viewWillDraw)] !== [CPView instanceMethodForSelector:@selector(viewWillDraw)])
311  flags |= CPViewHasCustomDrawRect;
312 
313  if ([theClass instanceMethodForSelector:@selector(viewWillLayout)] !== [CPView instanceMethodForSelector:@selector(viewWillLayout)])
315 
316  if ([theClass instanceMethodForSelector:@selector(layoutSubviews)] !== [CPView instanceMethodForSelector:@selector(layoutSubviews)])
318 
319  CPViewFlags[classUID] = flags;
320  }
321 
322  _viewClassFlags = CPViewFlags[classUID];
323 }
324 
325 - (id)init
326 {
327  return [self initWithFrame:CGRectMakeZero()];
328 }
329 
334 - (id)initWithFrame:(CGRect)aFrame
335 {
336  self = [super init];
337 
338  if (self)
339  {
340  var width = CGRectGetWidth(aFrame),
341  height = CGRectGetHeight(aFrame);
342 
343  _subviews = [];
344  _registeredDraggedTypes = [CPSet set];
345  _registeredDraggedTypesArray = [];
346 
347  _trackingAreas = [];
348 
349  _tag = -1;
350 
351  _frame = CGRectMakeCopy(aFrame);
352  _bounds = CGRectMake(0.0, 0.0, width, height);
353 
354  _autoresizingMask = CPViewNotSizable;
355  _autoresizesSubviews = YES;
356  _clipsToBounds = YES;
357 
358  _opacity = 1.0;
359  _isHidden = NO;
360  _isHiddenOrHasHiddenAncestor = NO;
361  _hitTests = YES;
362 
363  _hierarchyScaleSize = CGSizeMake(1.0 , 1.0);
364  _scaleSize = CGSizeMake(1.0, 1.0);
365  _isScaled = NO;
366 
367  _theme = [CPTheme defaultTheme];
368  _themeState = CPThemeStateNormal;
369 
370 #if PLATFORM(DOM)
371  _DOMElement = DOMElementPrototype.cloneNode(false);
372  AppKitTagDOMElement(self, _DOMElement);
373 
374  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, CGRectGetMinX(aFrame), CGRectGetMinY(aFrame));
375  CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
376 
377  _DOMImageParts = [];
378  _DOMImageSizes = [];
379 #endif
380 
381  _animator = nil;
382  _animationsDictionary = @{};
383 
384  [self _setupViewFlags];
385  [self _loadThemeAttributes];
386 
387  _inhibitDOMUpdates = NO;
388  _forceUpdates = NO;
389  }
390 
391  return self;
392 }
393 
399 - (void)setToolTip:(CPString)aToolTip
400 {
401  if (_toolTip === aToolTip)
402  return;
403 
404  if (aToolTip && ![aToolTip isKindOfClass:CPString])
405  aToolTip = [aToolTip description];
406 
407  _toolTip = aToolTip;
408 
409  [self _manageToolTipInstallation];
410 }
411 
412 - (void)_manageToolTipInstallation
413 {
414  if ([self window] && _toolTip)
415  [self _installToolTipEventHandlers];
416  else
417  [self _uninstallToolTipEventHandlers];
418 }
423 - (void)_installToolTipEventHandlers
424 {
425  if (_toolTipInstalled)
426  return;
427 
428  if (!_toolTipFunctionIn)
429  _toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
430 
431  if (!_toolTipFunctionOut)
432  _toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
433 
434 #if PLATFORM(DOM)
435  if (_DOMElement.addEventListener)
436  {
437  _DOMElement.addEventListener("mouseover", _toolTipFunctionIn, YES);
438  _DOMElement.addEventListener("keypress", _toolTipFunctionOut, YES);
439  _DOMElement.addEventListener("mouseout", _toolTipFunctionOut, YES);
440  }
441  else if (_DOMElement.attachEvent)
442  {
443  _DOMElement.attachEvent("onmouseover", _toolTipFunctionIn);
444  _DOMElement.attachEvent("onkeypress", _toolTipFunctionOut);
445  _DOMElement.attachEvent("onmouseout", _toolTipFunctionOut);
446  }
447 #endif
448 
449  _toolTipInstalled = YES;
450 }
451 
456 - (void)_uninstallToolTipEventHandlers
457 {
458  if (!_toolTipInstalled)
459  return;
460 
461 #if PLATFORM(DOM)
462  if (_DOMElement.removeEventListener)
463  {
464  _DOMElement.removeEventListener("mouseover", _toolTipFunctionIn, YES);
465  _DOMElement.removeEventListener("keypress", _toolTipFunctionOut, YES);
466  _DOMElement.removeEventListener("mouseout", _toolTipFunctionOut, YES);
467  }
468  else if (_DOMElement.detachEvent)
469  {
470  _DOMElement.detachEvent("onmouseover", _toolTipFunctionIn);
471  _DOMElement.detachEvent("onkeypress", _toolTipFunctionOut);
472  _DOMElement.detachEvent("onmouseout", _toolTipFunctionOut);
473  }
474 #endif
475 
476  _toolTipFunctionIn = nil;
477  _toolTipFunctionOut = nil;
478 
479  _toolTipInstalled = NO;
480 }
481 
487 {
488  return _superview;
489 }
490 
495 - (CPArray)subviews
496 {
497  return [_subviews copy];
498 }
499 
504 {
505  return _window;
506 }
507 
512 - (void)addSubview:(CPView)aSubview
513 {
514  [self _insertSubview:aSubview atIndex:CPNotFound];
515 }
516 
523 - (void)addSubview:(CPView)aSubview positioned:(CPWindowOrderingMode)anOrderingMode relativeTo:(CPView)anotherView
524 {
525  var index = anotherView ? [_subviews indexOfObjectIdenticalTo:anotherView] : CPNotFound;
526 
527  // In other words, if no view, then either all the way at the bottom or all the way at the top.
528  if (index === CPNotFound)
529  index = (anOrderingMode === CPWindowAbove) ? [_subviews count] : 0;
530 
531  // else, if we have a view, above if above.
532  else if (anOrderingMode === CPWindowAbove)
533  ++index;
534 
535  [self _insertSubview:aSubview atIndex:index];
536 }
537 
538 /* @ignore */
539 - (void)_insertSubview:(CPView)aSubview atIndex:(int)anIndex
540 {
541  if (aSubview === self)
542  [CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
543 #if DEBUG
544  if (!aSubview._superview && _subviews.indexOf(aSubview) !== CPNotFound)
545  [CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
546 #endif
547 
548  // Notify the subview that it will be moving.
549  [aSubview viewWillMoveToSuperview:self];
550 
551  // We will have to adjust the z-index of all views starting at this index.
552  var count = _subviews.length,
553  lastWindow;
554 
555  // Dirty the key view loop, in case the window wants to auto recalculate it
556  [[self window] _dirtyKeyViewLoop];
557 
558  // If this is already one of our subviews, remove it.
559  if (aSubview._superview === self)
560  {
561  var index = [_subviews indexOfObjectIdenticalTo:aSubview];
562 
563  // FIXME: should this be anIndex >= count? (last one)
564  if (index === anIndex || index === count - 1 && anIndex === count)
565  return;
566 
567  [_subviews removeObjectAtIndex:index];
568 
569 #if PLATFORM(DOM)
570  CPDOMDisplayServerRemoveChild(_DOMElement, aSubview._DOMElement);
571 #endif
572 
573  if (anIndex > index)
574  --anIndex;
575 
576  //We've effectively made the subviews array shorter, so represent that.
577  --count;
578  }
579  else
580  {
581  var superview = aSubview._superview;
582 
583  lastWindow = [superview window];
584 
585  // Remove the view from its previous superview.
586  [aSubview _removeFromSuperview];
587 
588  [aSubview _postViewWillAppearNotification];
589  // Set ourselves as the superview.
590  [aSubview _setSuperview:self];
591  }
592 
593  if (anIndex === CPNotFound || anIndex >= count)
594  {
595  _subviews.push(aSubview);
596 
597 #if PLATFORM(DOM)
598  // Attach the actual node.
599  CPDOMDisplayServerAppendChild(_DOMElement, aSubview._DOMElement);
600 #endif
601  }
602  else
603  {
604  _subviews.splice(anIndex, 0, aSubview);
605 
606 #if PLATFORM(DOM)
607  // Attach the actual node.
608  CPDOMDisplayServerInsertBefore(_DOMElement, aSubview._DOMElement, _subviews[anIndex + 1]._DOMElement);
609 #endif
610  }
611 
612  [aSubview setNextResponder:self];
613  [aSubview _scaleSizeUnitSquareToSize:[self _hierarchyScaleSize]];
614 
615  [aSubview viewDidMoveToSuperview];
616 
617  // Set the subview's window to our own.
618  if (_window)
619  [aSubview _setWindow:_window];
620 
621  if (!_window && lastWindow)
622  [aSubview _setWindow:nil];
623 
624  // This method might be called before we are fully unarchived, in which case the theme state isn't set up yet
625  // and none of the below matters anyhow.
626  if (_themeState)
627  {
628  if ([self hasThemeState:CPThemeStateFirstResponder])
629  [aSubview _notifyViewDidBecomeFirstResponder];
630  else
631  [aSubview _notifyViewDidResignFirstResponder];
632 
633  if ([self hasThemeState:CPThemeStateKeyWindow])
634  [aSubview _notifyWindowDidBecomeKey];
635  else
636  [aSubview _notifyWindowDidResignKey];
637  }
638 
639  [self didAddSubview:aSubview];
640 }
641 
646 - (void)didAddSubview:(CPView)aSubview
647 {
648 }
649 
655 {
656  var superview = _superview;
657 
658  [self viewWillMoveToSuperview:nil];
659  [self _removeFromSuperview];
660  [self viewDidMoveToSuperview];
661 
662  if (superview)
663  [self _setWindow:nil];
664 }
665 
666 - (void)_removeFromSuperview
667 {
668  if (!_superview)
669  return;
670 
671  // Dirty the key view loop, in case the window wants to auto recalculate it
672  [[self window] _dirtyKeyViewLoop];
673 
674  [_superview willRemoveSubview:self];
675  [self _postViewWillDisappearNotification];
676 
677  [_superview._subviews removeObjectIdenticalTo:self];
678 
679 #if PLATFORM(DOM)
680  CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
681 #endif
682 
683  // If the view is not hidden and one of its ancestors is hidden,
684  // notify the view that it is now unhidden.
685  [self _setSuperview:nil];
686 
687  [self _notifyWindowDidResignKey];
688  [self _notifyViewDidResignFirstResponder];
689 }
690 
696 - (void)replaceSubview:(CPView)aSubview with:(CPView)aView
697 {
698  if (aSubview._superview !== self || aSubview === aView)
699  return;
700 
701  var index = [_subviews indexOfObjectIdenticalTo:aSubview];
702 
703  [self _insertSubview:aView atIndex:index];
704 
705  [aSubview removeFromSuperview];
706 }
707 
708 - (void)setSubviews:(CPArray)newSubviews
709 {
710  if (!newSubviews)
711  [CPException raise:CPInvalidArgumentException reason:"newSubviews cannot be nil in -[CPView setSubviews:]"];
712 
713  // Trivial Case 0: Same array somehow
714  if ([_subviews isEqual:newSubviews])
715  return;
716 
717  // Trivial Case 1: No current subviews, simply add all new subviews.
718  if ([_subviews count] === 0)
719  {
720  var index = 0,
721  count = [newSubviews count];
722 
723  for (; index < count; ++index)
724  [self addSubview:newSubviews[index]];
725 
726  return;
727  }
728 
729  // Trivial Case 2: No new subviews, simply remove all current subviews.
730  if ([newSubviews count] === 0)
731  {
732  var count = [_subviews count];
733 
734  while (count--)
735  [_subviews[count] removeFromSuperview];
736 
737  return;
738  }
739 
740  // Find out the views that were removed.
741  var removedSubviews = [CPMutableSet setWithArray:_subviews];
742 
743  [removedSubviews removeObjectsInArray:newSubviews];
744  [removedSubviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
745 
746  // Find out which views need to be added.
747  var addedSubviews = [CPMutableSet setWithArray:newSubviews];
748 
749  [addedSubviews removeObjectsInArray:_subviews];
750 
751  var addedSubview = nil,
752  addedSubviewEnumerator = [addedSubviews objectEnumerator];
753 
754  while ((addedSubview = [addedSubviewEnumerator nextObject]) !== nil)
755  [self addSubview:addedSubview];
756 
757  // If the order is fine, no need to reorder.
758  if ([_subviews isEqual:newSubviews])
759  return;
760 
761  _subviews = [newSubviews copy];
762 
763 #if PLATFORM(DOM)
764  var index = 0,
765  count = [_subviews count];
766 
767  for (; index < count; ++index)
768  {
769  var subview = _subviews[index];
770 
771  CPDOMDisplayServerRemoveChild(_DOMElement, subview._DOMElement);
772  CPDOMDisplayServerAppendChild(_DOMElement, subview._DOMElement);
773  }
774 #endif
775 }
776 
777 /* @ignore */
778 - (void)_setWindow:(CPWindow)aWindow
779 {
780  [[self window] _dirtyKeyViewLoop];
781 
782  // Clear out first responder if we're the first responder and leaving.
783  if ([_window firstResponder] === self && _window != aWindow)
784  [_window makeFirstResponder:nil];
785 
786  // Notify the view and its subviews
787  [self viewWillMoveToWindow:aWindow];
788 
789  // Unregister the drag events from the current window and register
790  // them in the new window.
791  if (_registeredDraggedTypes)
792  {
793  [_window _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
794  [aWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
795  }
796 
797  // View must be removed from the current window viewsWithTrackingAreas
798  if (_window && (_trackingAreas.length > 0))
799  [_window _removeTrackingAreaView:self];
800 
801  _window = aWindow;
802 
803  if (_window)
804  {
805  var owners;
806 
807  if (_trackingAreas.length > 0)
808  {
809  // View must be added to the new window viewsWithTrackingAreas
810  [_window _addTrackingAreaView:self];
811  owners = [self _calcTrackingAreaOwners];
812  }
813  else
814  owners = [self];
815 
816  // Notify that view tracking areas should be updated
817  // Cocoa doesn't notify on leaving a window
818  [self _updateTrackingAreasForOwners:owners];
819  }
820 
821  var count = [_subviews count];
822 
823  while (count--)
824  [_subviews[count] _setWindow:aWindow];
825 
826  if ([_window isKeyWindow])
827  [self setThemeState:CPThemeStateKeyWindow];
828  else
829  [self unsetThemeState:CPThemeStateKeyWindow];
830 
831  [self viewDidMoveToWindow];
832 
833  [self _manageToolTipInstallation];
834 
835  [[self window] _dirtyKeyViewLoop];
836 }
837 
842 - (BOOL)isDescendantOf:(CPView)aView
843 {
844  var view = self;
845 
846  do
847  {
848  if (view === aView)
849  return YES;
850  } while(view = [view superview])
851 
852  return NO;
853 }
854 
859 {
860  [self setNeedsLayout:YES];
861  [self setNeedsDisplay:YES];
862 }
863 
868 {
869 }
870 
875 - (void)viewWillMoveToSuperview:(CPView)aView
876 {
877  _isSuperviewAClipView = [aView isKindOfClass:[CPClipView class]];
878 
879  [self _removeObservers];
880 
881  if (aView)
882  [self _addObservers];
883 }
884 
889 - (void)viewWillMoveToWindow:(CPWindow)aWindow
890 {
891 }
892 
897 - (void)willRemoveSubview:(CPView)aView
898 {
899 }
900 
901 - (void)_removeObservers
902 {
903  if (!_isObserving)
904  return;
905 
906  var count = [_subviews count];
907 
908  while (count--)
909  [_subviews[count] _removeObservers];
910 
911  _isObserving = NO;
912 }
913 
914 - (void)_addObservers
915 {
916  if (_isObserving)
917  return;
918 
919  var count = [_subviews count];
920 
921  while (count--)
922  [_subviews[count] _addObservers];
923 
924  _isObserving = YES;
925 }
926 
932 {
933  var view = self;
934 
935  while (view && ![view isKindOfClass:[_CPMenuItemView class]])
936  view = [view superview];
937 
938  if (view)
939  return view._menuItem;
940 
941  return nil;
942 /* var view = self,
943  enclosingMenuItem = _enclosingMenuItem;
944 
945  while (!enclosingMenuItem && (view = view._enclosingMenuItem))
946  view = [view superview];
947 
948  return enclosingMenuItem;*/
949 }
950 
951 - (void)setTag:(CPInteger)aTag
952 {
953  _tag = aTag;
954 }
955 
956 - (CPInteger)tag
957 {
958  return _tag;
959 }
960 
961 - (CPView)viewWithTag:(CPInteger)aTag
962 {
963  if ([self tag] === aTag)
964  return self;
965 
966  var index = 0,
967  count = _subviews.length;
968 
969  for (; index < count; ++index)
970  {
971  var view = [_subviews[index] viewWithTag:aTag];
972 
973  if (view)
974  return view;
975  }
976 
977  return nil;
978 }
979 
984 - (BOOL)isFlipped
985 {
986  return YES;
987 }
988 
996 - (void)setFrame:(CGRect)aFrame
997 {
998  if (CGRectEqualToRect(_frame, aFrame) && !_forceUpdates)
999  return;
1000 
1001  _inhibitFrameAndBoundsChangedNotifications = YES;
1002 
1003  [self setFrameOrigin:aFrame.origin];
1004  [self setFrameSize:aFrame.size];
1005 
1006  _inhibitFrameAndBoundsChangedNotifications = NO;
1007 
1008  if (_postsFrameChangedNotifications)
1009  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
1010 
1011  if (_isSuperviewAClipView)
1012  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1013 
1014  if (!_inhibitUpdateTrackingAreas)
1015  [self _updateTrackingAreasWithRecursion:YES];
1016 }
1017 
1022 - (CGRect)frame
1023 {
1024  return CGRectMakeCopy(_frame);
1025 }
1026 
1027 - (CGPoint)frameOrigin
1028 {
1029  return CGPointMakeCopy(_frame.origin);
1030 }
1031 
1032 - (CGSize)frameSize
1033 {
1034  return CGSizeMakeCopy(_frame.size);
1035 }
1036 
1044 - (void)setCenter:(CGPoint)aPoint
1045 {
1046  [self setFrameOrigin:CGPointMake(aPoint.x - _frame.size.width / 2.0, aPoint.y - _frame.size.height / 2.0)];
1047 }
1048 
1053 - (CGPoint)center
1054 {
1055  return CGPointMake(_frame.size.width / 2.0 + _frame.origin.x, _frame.size.height / 2.0 + _frame.origin.y);
1056 }
1057 
1065 - (void)setFrameOrigin:(CGPoint)aPoint
1066 {
1067  var origin = _frame.origin;
1068 
1069  if (!aPoint || (CGPointEqualToPoint(origin, aPoint) && !_forceUpdates))
1070  return;
1071 
1072  origin.x = aPoint.x;
1073  origin.y = aPoint.y;
1074 
1075  if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1076  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
1077 
1078  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1079  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1080 
1081 #if PLATFORM(DOM)
1082  if (!_inhibitDOMUpdates)
1083  {
1084  var transform = _superview ? _superview._boundsTransform : NULL;
1085 
1086  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, transform, origin.x, origin.y);
1087  }
1088 #endif
1089 
1090  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1091  [self _updateTrackingAreasWithRecursion:YES];
1092 }
1093 
1100 - (void)setFrameSize:(CGSize)aSize
1101 {
1102  var size = _frame.size;
1103 
1104  if (!aSize || (CGSizeEqualToSize(size, aSize) && !_forceUpdates))
1105  return;
1106 
1107  var oldSize = CGSizeMakeCopy(size);
1108 
1109  size.width = aSize.width;
1110  size.height = aSize.height;
1111 
1112  if (YES)
1113  {
1114  _bounds.size.width = aSize.width * 1 / _scaleSize.width;
1115  _bounds.size.height = aSize.height * 1 / _scaleSize.height;
1116  }
1117 
1118  if (_layer)
1119  [_layer _owningViewBoundsChanged];
1120 
1121  if (_autoresizesSubviews)
1122  [self resizeSubviewsWithOldSize:oldSize];
1123 
1124  [self setNeedsLayout];
1125  [self setNeedsDisplay:YES];
1126 
1127 #if PLATFORM(DOM)
1128  [self _setDisplayServerSetStyleSize:size];
1129 
1130  if (_backgroundType !== BackgroundTrivialColor)
1131  {
1132  if (_backgroundType === BackgroundTransparentColor)
1133  {
1134  CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
1135  }
1136  else
1137  {
1138  var images = [[_backgroundColor patternImage] imageSlices],
1139  partIndex = 0,
1140  frameSize = aSize;
1141 
1142  if (_backgroundType === BackgroundVerticalThreePartImage)
1143  {
1144  var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
1145  bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
1146 
1147  // Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
1148  if (top)
1149  {
1150  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
1151  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
1152  partIndex++;
1153  }
1154  if (_DOMImageSizes[1])
1155  {
1156  var height = frameSize.height - top - bottom;
1157 
1158  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
1159  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
1160  partIndex++;
1161  }
1162  if (bottom)
1163  {
1164  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
1165  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
1166  }
1167  }
1168  else if (_backgroundType === BackgroundHorizontalThreePartImage)
1169  {
1170  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
1171  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
1172 
1173  // Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
1174  if (left)
1175  {
1176  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
1177  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
1178  partIndex++;
1179  }
1180  if (_DOMImageSizes[1])
1181  {
1182  var width = (frameSize.width - left - right);
1183 
1184  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
1185  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
1186  partIndex++;
1187  }
1188  if (right)
1189  {
1190  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
1191  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
1192  }
1193  }
1194  else if (_backgroundType === BackgroundNinePartImage)
1195  {
1196  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
1197  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
1198  top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
1199  bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
1200  width = size.width - left - right,
1201  height = size.height - top - bottom;
1202 
1203  if (_DOMImageSizes[0])
1204  partIndex++;
1205  if (_DOMImageSizes[1])
1206  {
1207  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, top);
1208  partIndex++;
1209  }
1210  if (_DOMImageSizes[2])
1211  partIndex++;
1212  if (_DOMImageSizes[3])
1213  {
1214  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
1215  partIndex++;
1216  }
1217  if (_DOMImageSizes[4])
1218  {
1219  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
1220  partIndex++;
1221  }
1222  if (_DOMImageSizes[5])
1223  {
1224  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
1225  partIndex++;
1226  }
1227  if (_DOMImageSizes[6])
1228  partIndex++;
1229  if (_DOMImageSizes[7])
1230  {
1231  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
1232  }
1233  }
1234  }
1235  }
1236 #endif
1237 
1238  if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1239  [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
1240 
1241  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1242  [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
1243 
1244  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1245  [self _updateTrackingAreasWithRecursion:!_autoresizesSubviews];
1246 }
1247 
1253 - (void)_setDisplayServerSetStyleSize:(CGSize)aSize
1254 {
1255 #if PLATFORM(DOM)
1256  var scale = [self scaleSize];
1257 
1258  if (!_inhibitDOMUpdates)
1259  CPDOMDisplayServerSetStyleSize(_DOMElement, aSize.width * 1 / scale.width, aSize.height * 1 / scale.height);
1260 
1261  if (_DOMContentsElement)
1262  {
1263  CPDOMDisplayServerSetSize(_DOMContentsElement, aSize.width * _highDPIRatio * 1 / scale.width, aSize.height * _highDPIRatio * 1 / scale.height);
1264  CPDOMDisplayServerSetStyleSize(_DOMContentsElement, aSize.width * 1 / scale.width, aSize.height * 1 / scale.height);
1265 
1266  _needToSetTransformMatrix = YES;
1267  }
1268 #endif
1269 }
1270 
1276 - (void)setBounds:(CGRect)bounds
1277 {
1278  if (CGRectEqualToRect(_bounds, bounds))
1279  return;
1280 
1281  _inhibitFrameAndBoundsChangedNotifications = YES;
1282 
1283  [self setBoundsOrigin:bounds.origin];
1284  [self setBoundsSize:bounds.size];
1285 
1286  _inhibitFrameAndBoundsChangedNotifications = NO;
1287 
1288  if (_postsBoundsChangedNotifications)
1289  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1290 
1291  if (_isSuperviewAClipView)
1292  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1293 
1294  if (!_inhibitUpdateTrackingAreas)
1295  [self _updateTrackingAreasWithRecursion:YES];
1296 }
1297 
1302 - (CGRect)bounds
1303 {
1304  return CGRectMakeCopy(_bounds);
1305 }
1306 
1307 - (CGPoint)boundsOrigin
1308 {
1309  return CGPointMakeCopy(_bounds.origin);
1310 }
1311 
1312 - (CGSize)boundsSize
1313 {
1314  return CGSizeMakeCopy(_bounds.size);
1315 }
1316 
1323 - (void)setBoundsOrigin:(CGPoint)aPoint
1324 {
1325  var origin = _bounds.origin;
1326 
1327  if (CGPointEqualToPoint(origin, aPoint))
1328  return;
1329 
1330  origin.x = aPoint.x;
1331  origin.y = aPoint.y;
1332 
1333  if (origin.x != 0 || origin.y != 0)
1334  {
1335  _boundsTransform = CGAffineTransformMakeTranslation(-origin.x, -origin.y);
1336  _inverseBoundsTransform = CGAffineTransformInvert(_boundsTransform);
1337  }
1338  else
1339  {
1340  _boundsTransform = nil;
1341  _inverseBoundsTransform = nil;
1342  }
1343 
1344 #if PLATFORM(DOM)
1345  var index = _subviews.length;
1346 
1347  while (index--)
1348  {
1349  var view = _subviews[index],
1350  origin = view._frame.origin;
1351 
1352  CPDOMDisplayServerSetStyleLeftTop(view._DOMElement, _boundsTransform, origin.x, origin.y);
1353  }
1354 #endif
1355 
1356  if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1357  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1358 
1359  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1360  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1361 
1362  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1363  [self _updateTrackingAreasWithRecursion:YES];
1364 }
1365 
1372 - (void)setBoundsSize:(CGSize)aSize
1373 {
1374  var size = _bounds.size;
1375 
1376  if (CGSizeEqualToSize(size, aSize))
1377  return;
1378 
1379  var frameSize = _frame.size;
1380 
1381  if (!CGSizeEqualToSize(size, frameSize))
1382  {
1383  var origin = _bounds.origin;
1384 
1385  origin.x /= size.width / frameSize.width;
1386  origin.y /= size.height / frameSize.height;
1387  }
1388 
1389  size.width = aSize.width;
1390  size.height = aSize.height;
1391 
1392  if (!CGSizeEqualToSize(size, frameSize))
1393  {
1394  var origin = _bounds.origin;
1395 
1396  origin.x *= size.width / frameSize.width;
1397  origin.y *= size.height / frameSize.height;
1398  }
1399 
1400  if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
1401  [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
1402 
1403  if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
1404  [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
1405 
1406  if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
1407  [self _updateTrackingAreasWithRecursion:YES];
1408 }
1409 
1410 
1415 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
1416 {
1417  var mask = [self autoresizingMask];
1418 
1419  if (mask === CPViewNotSizable)
1420  return;
1421 
1422  var frame = _superview._frame,
1423  newFrame = CGRectMakeCopy(_frame),
1424  dX = frame.size.width - aSize.width,
1425  dY = frame.size.height - aSize.height,
1426  evenFractionX = 1.0 / ((mask & CPViewMinXMargin ? 1 : 0) + (mask & CPViewWidthSizable ? 1 : 0) + (mask & CPViewMaxXMargin ? 1 : 0)),
1427  evenFractionY = 1.0 / ((mask & CPViewMinYMargin ? 1 : 0) + (mask & CPViewHeightSizable ? 1 : 0) + (mask & CPViewMaxYMargin ? 1 : 0)),
1428  baseX = (mask & CPViewMinXMargin ? _frame.origin.x : 0) +
1429  (mask & CPViewWidthSizable ? _frame.size.width : 0) +
1430  (mask & CPViewMaxXMargin ? aSize.width - _frame.size.width - _frame.origin.x : 0),
1431  baseY = (mask & CPViewMinYMargin ? _frame.origin.y : 0) +
1432  (mask & CPViewHeightSizable ? _frame.size.height : 0) +
1433  (mask & CPViewMaxYMargin ? aSize.height - _frame.size.height - _frame.origin.y : 0);
1434 
1435  if (mask & CPViewMinXMargin)
1436  newFrame.origin.x += dX * (baseX > 0 ? _frame.origin.x / baseX : evenFractionX);
1437 
1438  if (mask & CPViewWidthSizable)
1439  newFrame.size.width += dX * (baseX > 0 ? _frame.size.width / baseX : evenFractionX);
1440 
1441  if (mask & CPViewMinYMargin)
1442  newFrame.origin.y += dY * (baseY > 0 ? _frame.origin.y / baseY : evenFractionY);
1443 
1444  if (mask & CPViewHeightSizable)
1445  newFrame.size.height += dY * (baseY > 0 ? _frame.size.height / baseY : evenFractionY);
1446 
1447  [self setFrame:newFrame];
1448 }
1449 
1454 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
1455 {
1456  var count = _subviews.length;
1457 
1458  while (count--)
1459  [_subviews[count] resizeWithOldSuperviewSize:aSize];
1460 }
1461 
1469 - (void)setAutoresizesSubviews:(BOOL)aFlag
1470 {
1471  _autoresizesSubviews = !!aFlag;
1472 }
1473 
1479 {
1480  return _autoresizesSubviews;
1481 }
1482 
1487 - (void)setAutoresizingMask:(unsigned)aMask
1488 {
1489  _autoresizingMask = aMask;
1490 }
1491 
1495 - (unsigned)autoresizingMask
1496 {
1497  return _autoresizingMask;
1498 }
1499 
1500 // Fullscreen Mode
1501 
1506 {
1507  return [self enterFullScreenMode:nil withOptions:nil];
1508 }
1509 
1515 - (BOOL)enterFullScreenMode:(CPScreen)aScreen withOptions:(CPDictionary)options
1516 {
1517  _fullScreenModeState = _CPViewFullScreenModeStateMake(self);
1518 
1519  var fullScreenWindow = [[CPWindow alloc] initWithContentRect:[[CPPlatformWindow primaryPlatformWindow] contentBounds] styleMask:CPBorderlessWindowMask];
1520 
1521  [fullScreenWindow setLevel:CPScreenSaverWindowLevel];
1522  [fullScreenWindow setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
1523 
1524  var contentView = [fullScreenWindow contentView];
1525 
1526  [contentView setBackgroundColor:[CPColor blackColor]];
1527  [contentView addSubview:self];
1528 
1529  [self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
1530  [self setFrame:CGRectMakeCopy([contentView bounds])];
1531 
1532  [fullScreenWindow makeKeyAndOrderFront:self];
1533 
1534  [fullScreenWindow makeFirstResponder:self];
1535 
1536  _isInFullScreenMode = YES;
1537 
1538  return YES;
1539 }
1540 
1545 {
1546  [self exitFullScreenModeWithOptions:nil];
1547 }
1548 
1553 - (void)exitFullScreenModeWithOptions:(CPDictionary)options
1554 {
1555  if (!_isInFullScreenMode)
1556  return;
1557 
1558  _isInFullScreenMode = NO;
1559 
1560  [self setFrame:_fullScreenModeState.frame];
1561  [self setAutoresizingMask:_fullScreenModeState.autoresizingMask];
1562  [_fullScreenModeState.superview _insertSubview:self atIndex:_fullScreenModeState.index];
1563 
1564  [[self window] orderOut:self];
1565 }
1566 
1571 {
1572  return _isInFullScreenMode;
1573 }
1574 
1579 - (void)setHidden:(BOOL)aFlag
1580 {
1581  aFlag = !!aFlag;
1582 
1583  if (_isHidden === aFlag)
1584  return;
1585 
1586 // FIXME: Should we return to visibility? This breaks in FireFox, Opera, and IE.
1587 // _DOMElement.style.visibility = (_isHidden = aFlag) ? "hidden" : "visible";
1588 #if PLATFORM(DOM)
1589  _DOMElement.style.display = aFlag ? "none" : "block";
1590 #endif
1591 
1592  if (aFlag)
1593  {
1594  var view = [_window firstResponder];
1595 
1596  if ([view isKindOfClass:[CPView class]])
1597  {
1598  do
1599  {
1600  if (self === view)
1601  {
1602  [_window makeFirstResponder:[self nextValidKeyView]];
1603  break;
1604  }
1605  }
1606  while (view = [view superview]);
1607  }
1608 
1609  [self _postViewWillDisappearNotification];
1610  [self _recursiveGainedHiddenAncestor];
1611  }
1612  else
1613  {
1614  [self setNeedsDisplay:YES];
1615 
1616  [self _postViewWillAppearNotification];
1617  [self _recursiveLostHiddenAncestor];
1618  }
1619 
1620  _isHidden = aFlag;
1621 }
1622 
1623 - (void)_postViewWillAppearNotification
1624 {
1625  [[CPNotificationCenter defaultCenter] postNotificationName:_CPViewWillAppearNotification object:self userInfo:nil];
1626 }
1627 
1628 - (void)_postViewDidAppearNotification
1629 {
1630  [[CPNotificationCenter defaultCenter] postNotificationName:_CPViewDidAppearNotification object:self userInfo:nil];
1631 }
1632 
1633 - (void)_postViewWillDisappearNotification
1634 {
1635  [[CPNotificationCenter defaultCenter] postNotificationName:_CPViewWillDisappearNotification object:self userInfo:nil];
1636 }
1637 
1638 - (void)_postViewDidDisappearNotification
1639 {
1640  [[CPNotificationCenter defaultCenter] postNotificationName:_CPViewDidDisappearNotification object:self userInfo:nil];
1641 }
1642 
1643 - (void)_setSuperview:(CPView)aSuperview
1644 {
1645  var hasOldSuperview = (_superview !== nil),
1646  hasNewSuperview = (aSuperview !== nil),
1647  oldSuperviewIsHidden = hasOldSuperview && [_superview isHiddenOrHasHiddenAncestor],
1648  newSuperviewIsHidden = hasNewSuperview && [aSuperview isHiddenOrHasHiddenAncestor];
1649 
1650  if (!newSuperviewIsHidden && oldSuperviewIsHidden)
1651  [self _recursiveLostHiddenAncestor];
1652 
1653  if (newSuperviewIsHidden && !oldSuperviewIsHidden)
1654  [self _recursiveGainedHiddenAncestor];
1655 
1656  _superview = aSuperview;
1657 
1658  if (hasOldSuperview)
1659  [self _postViewDidDisappearNotification];
1660 
1661  if (hasNewSuperview)
1662  [self _postViewDidAppearNotification];
1663 }
1664 
1665 - (void)_recursiveLostHiddenAncestor
1666 {
1667  if (_isHiddenOrHasHiddenAncestor)
1668  {
1669  _isHiddenOrHasHiddenAncestor = NO;
1670  [self viewDidUnhide];
1671  }
1672 
1673  [_subviews enumerateObjectsUsingBlock:function(view, idx, stop)
1674  {
1675  [view _recursiveLostHiddenAncestor];
1676  }];
1677 }
1678 
1679 - (void)_recursiveGainedHiddenAncestor
1680 {
1681  if (!_isHidden)
1682  {
1683  [self viewDidHide];
1684  }
1685 
1686  _isHiddenOrHasHiddenAncestor = YES;
1687 
1688  [_subviews enumerateObjectsUsingBlock:function(view, idx, stop)
1689  {
1690  [view _recursiveGainedHiddenAncestor];
1691  }];
1692 }
1693 
1697 - (BOOL)isHidden
1698 {
1699  return _isHidden;
1700 }
1701 
1702 - (void)setClipsToBounds:(BOOL)shouldClip
1703 {
1704  if (_clipsToBounds === shouldClip)
1705  return;
1706 
1707  _clipsToBounds = shouldClip;
1708 
1709 #if PLATFORM(DOM)
1710  _DOMElement.style.overflow = _clipsToBounds ? "hidden" : "visible";
1711 #endif
1712 }
1713 
1715 {
1716  return _clipsToBounds;
1717 }
1718 
1724 - (void)setAlphaValue:(float)anAlphaValue
1725 {
1726  if (_opacity === anAlphaValue)
1727  return;
1728 
1729  _opacity = anAlphaValue;
1730 
1731 #if PLATFORM(DOM)
1732 
1734  {
1735  if (anAlphaValue === 1.0)
1736  try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
1737  else
1738  _DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
1739  }
1740  else
1741  _DOMElement.style.opacity = anAlphaValue;
1742 
1743 #endif
1744 }
1745 
1750 - (float)alphaValue
1751 {
1752  return _opacity;
1753 }
1754 
1760 {
1761  return _isHiddenOrHasHiddenAncestor;
1762 }
1763 
1767 - (BOOL)_isVisible
1768 {
1769  return ![self isHiddenOrHasHiddenAncestor] && [[self window] isVisible];
1770 }
1771 
1782 {
1783 
1784 }
1785 
1796 {
1797 
1798 }
1799 
1805 - (BOOL)acceptsFirstMouse:(CPEvent)anEvent
1806 {
1807  return NO;
1808 }
1809 
1814 - (BOOL)hitTests
1815 {
1816  return _hitTests;
1817 }
1818 
1823 - (void)setHitTests:(BOOL)shouldHitTest
1824 {
1825  _hitTests = !!shouldHitTest;
1826 }
1827 
1833 - (CPView)hitTest:(CGPoint)aPoint
1834 {
1835  if (_isHidden || !_hitTests)
1836  return nil;
1837 
1838  var frame = _frame,
1839  sizeScale = [self _hierarchyScaleSize];
1840 
1841  if (_isScaled)
1842  frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale([_superview _hierarchyScaleSize].width, [_superview _hierarchyScaleSize].height));
1843  else
1844  frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale(sizeScale.width, sizeScale.height));
1845 
1846  if (!CGRectContainsPoint(frame, aPoint))
1847  return nil;
1848 
1849  var view = nil,
1850  i = _subviews.length,
1851  adjustedPoint = CGPointMake(aPoint.x - CGRectGetMinX(frame), aPoint.y - CGRectGetMinY(frame));
1852 
1853  if (_inverseBoundsTransform)
1854  {
1855  var affineTransform = CGAffineTransformMakeCopy(_inverseBoundsTransform);
1856 
1857  if (_isScaled)
1858  {
1859  affineTransform.tx *= [_superview _hierarchyScaleSize].width;
1860  affineTransform.ty *= [_superview _hierarchyScaleSize].height;
1861  }
1862  else
1863  {
1864  affineTransform.tx *= sizeScale.width;
1865  affineTransform.ty *= sizeScale.height;
1866  }
1867 
1868  adjustedPoint = CGPointApplyAffineTransform(adjustedPoint, affineTransform);
1869  }
1870 
1871 
1872  while (i--)
1873  if (view = [_subviews[i] hitTest:adjustedPoint])
1874  return view;
1875 
1876  return self;
1877 }
1878 
1883 {
1884  return NO;
1885 }
1886 
1892 {
1893  return ![self isOpaque];
1894 }
1895 
1896 - (void)mouseDown:(CPEvent)anEvent
1897 {
1898  if ([self mouseDownCanMoveWindow])
1899  [super mouseDown:anEvent];
1900 }
1901 
1902 - (void)rightMouseDown:(CPEvent)anEvent
1903 {
1904  var menu = [self menuForEvent:anEvent];
1905 
1906  if (menu)
1907  [CPMenu popUpContextMenu:menu withEvent:anEvent forView:self];
1908  else if ([[self nextResponder] isKindOfClass:CPView])
1909  [super rightMouseDown:anEvent];
1910  else
1911  [[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:NO];
1912 }
1913 
1914 - (CPMenu)menuForEvent:(CPEvent)anEvent
1915 {
1916  return [self menu] || [[self class] defaultMenu];
1917 }
1918 
1923 - (void)setBackgroundColor:(CPColor)aColor
1924 {
1925  if (_backgroundColor === aColor)
1926  return;
1927 
1928  if (aColor === [CPNull null])
1929  aColor = nil;
1930 
1931  _backgroundColor = aColor;
1932 
1933 #if PLATFORM(DOM)
1934  var patternImage = [_backgroundColor patternImage],
1935  colorExists = _backgroundColor && ([_backgroundColor patternImage] || [_backgroundColor alphaComponent] > 0.0),
1936  colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
1937  supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
1938  colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
1939  amount = 0,
1940  slices;
1941 
1942  if ([patternImage isThreePartImage])
1943  {
1944  _backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
1945  amount = 3;
1946  }
1947  else if ([patternImage isNinePartImage])
1948  {
1949  _backgroundType = BackgroundNinePartImage;
1950  amount = 9;
1951  }
1952  else
1953  {
1954  _backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
1955  amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
1956  }
1957 
1958  // 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.
1959  if (_backgroundType === BackgroundVerticalThreePartImage || _backgroundType === BackgroundHorizontalThreePartImage || _backgroundType === BackgroundNinePartImage)
1960  {
1961  slices = [patternImage imageSlices];
1962 
1963  // We won't need more divs than there are slices.
1964  amount = MIN(amount, slices.length);
1965 
1966  for (var i = 0, count = slices.length; i < count; i++)
1967  {
1968  var image = slices[i],
1969  size = [image size];
1970 
1971  if (!size || (size.width === 0 && size.height === 0))
1972  size = nil;
1973 
1974  _DOMImageSizes[i] = size;
1975 
1976  // If there's a nil slice or a slice with no size, it won't need a div.
1977  if (!size)
1978  amount--;
1979  }
1980 
1981  // Now that we know how many divs we really need, compare that to number we actually have.
1982  amount -= _DOMImageParts.length;
1983  }
1984 
1985  // Make sure the number of divs we have match our needs.
1986  if (amount > 0)
1987  {
1988  while (amount--)
1989  {
1990  var DOMElement = DOMElementPrototype.cloneNode(false);
1991 
1992  DOMElement.style.zIndex = -1000;
1993 
1994  _DOMImageParts.push(DOMElement);
1995  _DOMElement.appendChild(DOMElement);
1996  }
1997  }
1998  else
1999  {
2000  amount = -amount;
2001  while (amount--)
2002  _DOMElement.removeChild(_DOMImageParts.pop());
2003  }
2004 
2005  if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
2006  {
2007  var colorCSS = colorExists ? [_backgroundColor cssString] : "";
2008 
2009  if (colorNeedsDOMElement)
2010  {
2011  _DOMElement.style.background = "";
2012  _DOMImageParts[0].style.background = [_backgroundColor cssString];
2013 
2014  if (patternImage)
2015  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[0], [patternImage size].width + "px", [patternImage size].height + "px");
2016 
2018  _DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
2019  else
2020  _DOMImageParts[0].style.opacity = [_backgroundColor alphaComponent];
2021 
2022  var size = [self bounds].size;
2023  CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
2024  }
2025  else
2026  {
2027  _DOMElement.style.background = colorCSS;
2028 
2029  if (patternImage)
2030  CPDOMDisplayServerSetStyleBackgroundSize(_DOMElement, [patternImage size].width + "px", [patternImage size].height + "px");
2031  }
2032  }
2033  else
2034  {
2035  var frameSize = _frame.size,
2036  partIndex = 0;
2037 
2038  for (var i = 0; i < slices.length; i++)
2039  {
2040  var size = _DOMImageSizes[i];
2041 
2042  if (!size)
2043  continue;
2044 
2045  var image = slices[i];
2046 
2047  // // If image was nil, size should have been nil too.
2048  // assert(image != nil);
2049 
2050  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height);
2051 
2052  _DOMImageParts[partIndex].style.background = "url(\"" + [image filename] + "\")";
2053 
2054  if (!supportsRGBA)
2055  {
2057  try { _DOMImageParts[partIndex].style.removeAttribute("filter") } catch (anException) { }
2058  else
2059  _DOMImageParts[partIndex].style.opacity = 1.0;
2060  }
2061 
2062  partIndex++;
2063  }
2064 
2065  if (_backgroundType === BackgroundNinePartImage)
2066  {
2067  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
2068  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
2069  top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
2070  bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
2071  width = frameSize.width - left - right,
2072  height = frameSize.height - top - bottom;
2073 
2074  partIndex = 0;
2075 
2076  if (_DOMImageSizes[0])
2077  {
2078  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2079  partIndex++;
2080  }
2081  if (_DOMImageSizes[1])
2082  {
2083  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
2084  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[1].height);
2085  partIndex++;
2086  }
2087  if (_DOMImageSizes[2])
2088  {
2089  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2090  partIndex++;
2091  }
2092  if (_DOMImageSizes[3])
2093  {
2094  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2095  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
2096  partIndex++;
2097  }
2098  if (_DOMImageSizes[4])
2099  {
2100  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, top);
2101  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
2102  partIndex++;
2103  }
2104  if (_DOMImageSizes[5])
2105  {
2106  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2107  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
2108  partIndex++;
2109  }
2110  if (_DOMImageSizes[6])
2111  {
2112  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2113  partIndex++;
2114  }
2115  if (_DOMImageSizes[7])
2116  {
2117  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, left, 0.0);
2118  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
2119  partIndex++;
2120  }
2121  if (_DOMImageSizes[8])
2122  {
2123  CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2124  }
2125  }
2126  else if (_backgroundType === BackgroundVerticalThreePartImage)
2127  {
2128  var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
2129  bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
2130 
2131  partIndex = 0;
2132 
2133  // Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
2134  if (top)
2135  {
2136  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
2137  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2138  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
2139  partIndex++;
2140  }
2141  if (_DOMImageSizes[1])
2142  {
2143  var height = frameSize.height - top - bottom;
2144 
2145  //_DOMImageParts[partIndex].style.backgroundSize = frameSize.width + "px " + height + "px";
2146  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
2147  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
2148  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, height);
2149  partIndex++;
2150  }
2151  if (bottom)
2152  {
2153  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
2154  CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2155  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
2156  }
2157  }
2158  else if (_backgroundType === BackgroundHorizontalThreePartImage)
2159  {
2160  var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
2161  right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
2162 
2163  partIndex = 0;
2164 
2165  // Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
2166  if (left)
2167  {
2168  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
2169  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2170  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
2171  partIndex++;
2172  }
2173  if (_DOMImageSizes[1])
2174  {
2175  var width = (frameSize.width - left - right);
2176 
2177  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
2178  CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
2179  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, frameSize.height);
2180  partIndex++;
2181  }
2182  if (right)
2183  {
2184  CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
2185  CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
2186  CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
2187  }
2188  }
2189  }
2190 #endif
2191 }
2192 
2197 {
2198  return _backgroundColor;
2199 }
2200 
2201 // Converting Coordinates
2208 - (CGPoint)convertPoint:(CGPoint)aPoint fromView:(CPView)aView
2209 {
2210  if (aView === self)
2211  return aPoint;
2212 
2213  return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
2214 }
2215 
2221 - (CGPoint)convertPointFromBase:(CGPoint)aPoint
2222 {
2223  return [self convertPoint:aPoint fromView:nil];
2224 }
2225 
2232 - (CGPoint)convertPoint:(CGPoint)aPoint toView:(CPView)aView
2233 {
2234  if (aView === self)
2235  return aPoint;
2236 
2237  return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
2238 }
2239 
2240 
2246 - (CGPoint)convertPointToBase:(CGPoint)aPoint
2247 {
2248  return [self convertPoint:aPoint toView:nil];
2249 }
2250 
2257 - (CGSize)convertSize:(CGSize)aSize fromView:(CPView)aView
2258 {
2259  if (aView === self)
2260  return aSize;
2261 
2262  return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(aView, self));
2263 }
2264 
2271 - (CGSize)convertSize:(CGSize)aSize toView:(CPView)aView
2272 {
2273  if (aView === self)
2274  return aSize;
2275 
2276  return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(self, aView));
2277 }
2278 
2285 - (CGRect)convertRect:(CGRect)aRect fromView:(CPView)aView
2286 {
2287  if (self === aView)
2288  return aRect;
2289 
2290  return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
2291 }
2292 
2298 - (CGRect)convertRectFromBase:(CGRect)aRect
2299 {
2300  return [self convertRect:aRect fromView:nil];
2301 }
2302 
2309 - (CGRect)convertRect:(CGRect)aRect toView:(CPView)aView
2310 {
2311  if (self === aView)
2312  return aRect;
2313 
2314  return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
2315 }
2316 
2322 - (CGRect)convertRectToBase:(CGRect)aRect
2323 {
2324  return [self convertRect:aRect toView:nil];
2325 }
2326 
2339 - (void)setPostsFrameChangedNotifications:(BOOL)shouldPostFrameChangedNotifications
2340 {
2341  shouldPostFrameChangedNotifications = !!shouldPostFrameChangedNotifications;
2342 
2343  if (_postsFrameChangedNotifications === shouldPostFrameChangedNotifications)
2344  return;
2345 
2346  _postsFrameChangedNotifications = shouldPostFrameChangedNotifications;
2347 }
2348 
2353 {
2354  return _postsFrameChangedNotifications;
2355 }
2356 
2369 - (void)setPostsBoundsChangedNotifications:(BOOL)shouldPostBoundsChangedNotifications
2370 {
2371  shouldPostBoundsChangedNotifications = !!shouldPostBoundsChangedNotifications;
2372 
2373  if (_postsBoundsChangedNotifications === shouldPostBoundsChangedNotifications)
2374  return;
2375 
2376  _postsBoundsChangedNotifications = shouldPostBoundsChangedNotifications;
2377 }
2378 
2385 {
2386  return _postsBoundsChangedNotifications;
2387 }
2388 
2399 - (void)dragImage:(CPImage)anImage at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
2400 {
2401  [_window dragImage:anImage at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
2402 }
2403 
2414 - (void)dragView:(CPView)aView at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
2415 {
2416  [_window dragView:aView at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
2417 }
2418 
2423 - (void)registerForDraggedTypes:(CPArray)pasteboardTypes
2424 {
2425  if (!pasteboardTypes || ![pasteboardTypes count])
2426  return;
2427 
2428  var theWindow = [self window];
2429 
2430  [theWindow _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
2431  [_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
2432  [theWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
2433 
2434  _registeredDraggedTypesArray = nil;
2435 }
2436 
2442 {
2443  if (!_registeredDraggedTypesArray)
2444  _registeredDraggedTypesArray = [_registeredDraggedTypes allObjects];
2445 
2446  return _registeredDraggedTypesArray;
2447 }
2448 
2453 {
2454  [[self window] _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
2455 
2456  _registeredDraggedTypes = [CPSet set];
2457  _registeredDraggedTypesArray = [];
2458 }
2459 
2464 - (void)drawRect:(CGRect)aRect
2465 {
2466 
2467 }
2468 
2469 // Scaling
2470 
2477 - (void)scaleUnitSquareToSize:(CGSize)aSize
2478 {
2479  if (!aSize)
2480  return;
2481 
2482  // Reset the bounds
2483  var bounds = CGRectMakeCopy([self bounds]);
2484  bounds.size.width *= _scaleSize.width;
2485  bounds.size.height *= _scaleSize.height;
2486 
2487  [self willChangeValueForKey:@"scaleSize"];
2488  _scaleSize = CGSizeMakeCopy([self scaleSize]);
2489  _scaleSize.height *= aSize.height;
2490  _scaleSize.width *= aSize.width;
2491  [self didChangeValueForKey:@"scaleSize"];
2492  _isScaled = YES;
2493 
2494  _hierarchyScaleSize = CGSizeMakeCopy([self _hierarchyScaleSize]);
2495  _hierarchyScaleSize.height *= aSize.height;
2496  _hierarchyScaleSize.width *= aSize.width;
2497 
2498  var scaleAffine = CGAffineTransformMakeScale(1.0 / _scaleSize.width, 1.0 / _scaleSize.height),
2499  newBounds = CGRectApplyAffineTransform(CGRectMakeCopy(bounds), scaleAffine);
2500 
2501  [self setBounds:newBounds];
2502 
2503  [_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
2504 }
2505 
2510 - (void)_scaleSizeUnitSquareToSize:(CGSize)aSize
2511 {
2512  _hierarchyScaleSize = CGSizeMakeCopy([_superview _hierarchyScaleSize]);
2513 
2514  if (_isScaled)
2515  {
2516  _hierarchyScaleSize.width *= _scaleSize.width;
2517  _hierarchyScaleSize.height *= _scaleSize.height;
2518  }
2519 
2520  [_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
2521 }
2522 
2526 - (CGSize)_hierarchyScaleSize
2527 {
2528  return _hierarchyScaleSize || CGSizeMake(1.0, 1.0);
2529 }
2530 
2534 - (void)_applyCSSScalingTranformations
2535 {
2536 #if PLATFORM(DOM)
2537  if (_isScaled)
2538  {
2539  var scale = [self scaleSize],
2540  browserPropertyTransform = CPBrowserStyleProperty(@"transform"),
2541  browserPropertyTransformOrigin = CPBrowserStyleProperty(@"transformOrigin");
2542 
2543  self._DOMElement.style[browserPropertyTransform] = 'scale(' + scale.width + ', ' + scale.height + ')';
2544  self._DOMElement.style[browserPropertyTransformOrigin] = '0 0';
2545 
2546  [self _setDisplayServerSetStyleSize:[self frameSize]];
2547  }
2548 #endif
2549 }
2550 
2551 // Displaying
2552 
2556 - (void)setNeedsDisplay:(BOOL)aFlag
2557 {
2558  if (aFlag)
2559  {
2560  [self _applyCSSScalingTranformations];
2561  [self setNeedsDisplayInRect:[self bounds]];
2562  }
2563 }
2564 
2569 - (void)setNeedsDisplayInRect:(CGRect)aRect
2570 {
2571  if (!(_viewClassFlags & CPViewHasCustomDrawRect))
2572  return;
2573 
2574  if (CGRectIsEmpty(aRect))
2575  return;
2576 
2577  if (_dirtyRect && !CGRectIsEmpty(_dirtyRect))
2578  _dirtyRect = CGRectUnion(aRect, _dirtyRect);
2579  else
2580  _dirtyRect = CGRectMakeCopy(aRect);
2581 
2582  _CPDisplayServerAddDisplayObject(self);
2583 }
2584 
2586 {
2587  return _dirtyRect && !CGRectIsEmpty(_dirtyRect);
2588 }
2589 
2594 {
2595  if ([self needsDisplay])
2596  [self displayRect:_dirtyRect];
2597 }
2598 
2602 - (void)display
2603 {
2604  [self displayRect:[self visibleRect]];
2605 }
2606 
2607 - (void)displayIfNeededInRect:(CGRect)aRect
2608 {
2609  if ([self needsDisplay])
2610  [self displayRect:aRect];
2611 }
2612 
2617 - (void)displayRect:(CGRect)aRect
2618 {
2619  [self viewWillDraw];
2620 
2621  [self displayRectIgnoringOpacity:aRect inContext:nil];
2622 
2623  _dirtyRect = NULL;
2624 }
2625 
2626 - (void)displayRectIgnoringOpacity:(CGRect)aRect inContext:(CPGraphicsContext)aGraphicsContext
2627 {
2628  if ([self isHidden])
2629  return;
2630 
2631 #if PLATFORM(DOM)
2632  [self lockFocus];
2633 
2634  CGContextClearRect([[CPGraphicsContext currentContext] graphicsPort], aRect);
2635 
2636  [self drawRect:aRect];
2637  [self unlockFocus];
2638 #endif
2639 }
2640 
2642 {
2643 }
2644 
2648 - (void)lockFocus
2649 {
2650  if (!_graphicsContext)
2651  {
2652  var graphicsPort = CGBitmapGraphicsContextCreate();
2653 
2654 #if PLATFORM(DOM)
2655  var width = CGRectGetWidth(_frame),
2656  height = CGRectGetHeight(_frame),
2657  devicePixelRatio = window.devicePixelRatio || 1,
2658  backingStoreRatio = CPBrowserBackingStorePixelRatio(graphicsPort);
2659 
2660  _highDPIRatio = CPViewHighDPIDrawingEnabled ? (devicePixelRatio / backingStoreRatio) : 1;
2661 
2662  _DOMContentsElement = graphicsPort.DOMElement;
2663 
2664  _DOMContentsElement.style.zIndex = -100;
2665 
2666  _DOMContentsElement.style.overflow = "hidden";
2667  _DOMContentsElement.style.position = "absolute";
2668  _DOMContentsElement.style.visibility = "visible";
2669 
2670  CPDOMDisplayServerSetSize(_DOMContentsElement, width * _highDPIRatio, height * _highDPIRatio);
2671 
2672  CPDOMDisplayServerSetStyleLeftTop(_DOMContentsElement, NULL, 0.0, 0.0);
2673  CPDOMDisplayServerSetStyleSize(_DOMContentsElement, width, height);
2674 
2675  // The performance implications of this aren't clear, but without this subviews might not be redrawn when this
2676  // view moves.
2678  _DOMElement.style.webkitTransform = 'translateX(0)';
2679 
2680  CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
2681 #endif
2682  _graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
2683  _needToSetTransformMatrix = YES;
2684  }
2685 
2686 #if PLATFORM(DOM)
2687  if (_needToSetTransformMatrix && _highDPIRatio !== 1)
2688  [_graphicsContext graphicsPort].setTransform(_highDPIRatio, 0, 0 , _highDPIRatio, 0, 0);
2689 #endif
2690 
2691  _needToSetTransformMatrix = NO;
2692  [CPGraphicsContext setCurrentContext:_graphicsContext];
2693 
2694  CGContextSaveGState([_graphicsContext graphicsPort]);
2695 }
2696 
2701 {
2702  CGContextRestoreGState([_graphicsContext graphicsPort]);
2703 
2705 }
2706 
2708 {
2709  [self setNeedsLayout:YES];
2710 }
2711 
2712 - (void)setNeedsLayout:(BOOL)needLayout
2713 {
2714  if (!needLayout)
2715  {
2716  _needsLayout = NO;
2717  return;
2718  }
2719 
2720  _needsLayout = YES;
2721 
2722  _CPDisplayServerAddLayoutObject(self);
2723 }
2724 
2726 {
2727  return _needsLayout;
2728 }
2729 
2730 - (void)layout
2731 {
2732  _needsLayout = NO;
2733 
2734  if (_viewClassFlags & CPViewHasCustomViewWillLayout)
2735  [self viewWillLayout];
2736 
2737  if (_viewClassFlags & CPViewHasCustomLayoutSubviews)
2738  [self layoutSubviews];
2739 
2740  [self viewDidLayout];
2741 }
2742 
2744 {
2745  if (_needsLayout)
2746  [self layout];
2747 }
2748 
2753 {
2754 
2755 }
2756 
2761 {
2762  [self _recomputeAppearance];
2763 }
2764 
2766 {
2767 
2768 }
2769 
2773 - (BOOL)isOpaque
2774 {
2775  return NO;
2776 }
2777 
2781 - (CGRect)visibleRect
2782 {
2783  if (!_superview)
2784  return _bounds;
2785 
2786  return CGRectIntersection([self convertRect:[_superview visibleRect] fromView:_superview], _bounds);
2787 }
2788 
2789 // Scrolling
2790 /* @ignore */
2791 - (CPScrollView)_enclosingClipView
2792 {
2793  var superview = _superview,
2794  clipViewClass = [CPClipView class];
2795 
2796  while (superview && ![superview isKindOfClass:clipViewClass])
2797  superview = superview._superview;
2798 
2799  return superview;
2800 }
2801 
2806 - (void)scrollPoint:(CGPoint)aPoint
2807 {
2808  var clipView = [self _enclosingClipView];
2809 
2810  if (!clipView)
2811  return;
2812 
2813  [clipView scrollToPoint:[self convertPoint:aPoint toView:clipView]];
2814 }
2815 
2821 - (BOOL)scrollRectToVisible:(CGRect)aRect
2822 {
2823  // Make sure we have a rect that exists.
2824  aRect = CGRectIntersection(aRect, _bounds);
2825 
2826  // If aRect is empty no scrolling required.
2827  if (CGRectIsEmpty(aRect))
2828  return NO;
2829 
2830  var enclosingClipView = [self _enclosingClipView];
2831 
2832  // If we're not in a clip view, then there isn't much we can do.
2833  if (!enclosingClipView)
2834  return NO;
2835 
2836  var documentView = [enclosingClipView documentView];
2837 
2838  // If the clip view doesn't have a document view, then there isn't much we can do.
2839  if (!documentView)
2840  return NO;
2841 
2842  // Get the document view visible rect and convert aRect to the document view's coordinate system
2843  var documentViewVisibleRect = [documentView visibleRect],
2844  rectInDocumentView = [self convertRect:aRect toView:documentView];
2845 
2846  // If already visible then no scrolling required.
2847  if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
2848  return NO;
2849 
2850  var currentScrollPoint = documentViewVisibleRect.origin,
2851  scrollPoint = CGPointMakeCopy(currentScrollPoint),
2852  rectInDocumentViewMinX = CGRectGetMinX(rectInDocumentView),
2853  documentViewVisibleRectMinX = CGRectGetMinX(documentViewVisibleRect),
2854  doesItFitForWidth = documentViewVisibleRect.size.width >= rectInDocumentView.size.width;
2855 
2856  // One of the following has to be true since our current visible rect didn't contain aRect.
2857  if (rectInDocumentViewMinX < documentViewVisibleRectMinX && doesItFitForWidth)
2858  // Scroll to left edge of aRect as it is to the left of the visible rect and it fit inside
2859  scrollPoint.x = rectInDocumentViewMinX;
2860  else if (CGRectGetMaxX(rectInDocumentView) > CGRectGetMaxX(documentViewVisibleRect) && doesItFitForWidth)
2861  // Scroll to right edge of aRect as it is to the right of the visible rect and it fit inside
2862  scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
2863  else if (rectInDocumentViewMinX > documentViewVisibleRectMinX)
2864  // Scroll to left edge of aRect as it is to the right of the visible rect and it doesn't fit inside
2865  scrollPoint.x = rectInDocumentViewMinX;
2866  else if (CGRectGetMaxX(rectInDocumentView) < CGRectGetMaxX(documentViewVisibleRect))
2867  // Scroll to right edge of aRect as it is to the left of the visible rect and it doesn't fit inside
2868  scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
2869 
2870  var rectInDocumentViewMinY = CGRectGetMinY(rectInDocumentView),
2871  documentViewVisibleRectMinY = CGRectGetMinY(documentViewVisibleRect),
2872  doesItFitForHeight = documentViewVisibleRect.size.height >= rectInDocumentView.size.height;
2873 
2874  if (rectInDocumentViewMinY < documentViewVisibleRectMinY && doesItFitForHeight)
2875  // Scroll to top edge of aRect as it is above the visible rect and it fit inside
2876  scrollPoint.y = rectInDocumentViewMinY;
2877  else if (CGRectGetMaxY(rectInDocumentView) > CGRectGetMaxY(documentViewVisibleRect) && doesItFitForHeight)
2878  // Scroll to bottom edge of aRect as it is below the visible rect and it fit inside
2879  scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
2880  else if (rectInDocumentViewMinY > documentViewVisibleRectMinY)
2881  // Scroll to top edge of aRect as it is below the visible rect and it doesn't fit inside
2882  scrollPoint.y = rectInDocumentViewMinY;
2883  else if (CGRectGetMaxY(rectInDocumentView) < CGRectGetMaxY(documentViewVisibleRect))
2884  // Scroll to bottom edge of aRect as it is above the visible rect and it doesn't fit inside
2885  scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
2886 
2887  // Don't scroll if aRect contains the whole visible rect as it is already as visible as possible.
2888  // We check this by comparing to new scrollPoint to the current.
2889  if (CGPointEqualToPoint(scrollPoint, currentScrollPoint))
2890  return NO;
2891 
2892  [enclosingClipView scrollToPoint:scrollPoint];
2893 
2894  return YES;
2895 }
2896 
2900 - (BOOL)autoscroll:(CPEvent)anEvent
2901 {
2902  return [[self superview] autoscroll:anEvent];
2903 }
2904 
2911 - (CGRect)adjustScroll:(CGRect)proposedVisibleRect
2912 {
2913  return proposedVisibleRect;
2914 }
2915 
2919 - (void)scrollRect:(CGRect)aRect by:(float)anAmount
2920 {
2921 
2922 }
2923 
2929 {
2930  var superview = _superview,
2931  scrollViewClass = [CPScrollView class];
2932 
2933  while (superview && ![superview isKindOfClass:scrollViewClass])
2934  superview = superview._superview;
2935 
2936  return superview;
2937 }
2938 
2944 - (void)scrollClipView:(CPClipView)aClipView toPoint:(CGPoint)aPoint
2945 {
2946  [aClipView scrollToPoint:aPoint];
2947 }
2948 
2954 - (void)reflectScrolledClipView:(CPClipView)aClipView
2955 {
2956 }
2957 
2962 {
2963  return _inLiveResize;
2964 }
2965 
2976 {
2977  _inLiveResize = YES;
2978 }
2979 
2991 {
2992  _inLiveResize = NO;
2993 }
2994 
2995 @end
2996 
2997 @implementation CPView (KeyView)
2998 
3013 - (BOOL)performKeyEquivalent:(CPEvent)anEvent
3014 {
3015  var count = [_subviews count];
3016 
3017  // Is reverse iteration correct here? It matches the other (correct) code like hit testing.
3018  while (count--)
3019  if ([_subviews[count] performKeyEquivalent:anEvent])
3020  return YES;
3021 
3022  return NO;
3023 }
3024 
3026 {
3027  return [self acceptsFirstResponder] && ![self isHiddenOrHasHiddenAncestor];
3028 }
3029 
3031 {
3032  return _nextKeyView;
3033 }
3034 
3036 {
3037  var result = [self nextKeyView],
3038  resultUID = [result UID],
3039  unsuitableResults = {};
3040 
3041  while (result && ![result canBecomeKeyView])
3042  {
3043  unsuitableResults[resultUID] = 1;
3044  result = [result nextKeyView];
3045 
3046  resultUID = [result UID];
3047 
3048  // Did we get back to a key view we already ruled out due to ![result canBecomeKeyView]?
3049  if (unsuitableResults[resultUID])
3050  return nil;
3051  }
3052 
3053  return result;
3054 }
3055 
3057 {
3058  return _previousKeyView;
3059 }
3060 
3062 {
3063  var result = [self previousKeyView],
3064  firstResult = result;
3065 
3066  while (result && ![result canBecomeKeyView])
3067  {
3068  result = [result previousKeyView];
3069 
3070  // Cycled.
3071  if (result === firstResult)
3072  return nil;
3073  }
3074 
3075  return result;
3076 }
3077 
3078 - (void)_setPreviousKeyView:(CPView)previous
3079 {
3080  if (![previous isEqual:self])
3081  {
3082  var previousWindow = [previous window];
3083 
3084  if (!previousWindow || previousWindow === _window)
3085  {
3086  _previousKeyView = previous;
3087  return;
3088  }
3089  }
3090 
3091  _previousKeyView = nil;
3092 }
3093 
3094 - (void)setNextKeyView:(CPView)next
3095 {
3096  if (![next isEqual:self])
3097  {
3098  var nextWindow = [next window];
3099 
3100  if (!nextWindow || nextWindow === _window)
3101  {
3102  _nextKeyView = next;
3103  [_nextKeyView _setPreviousKeyView:self];
3104  return;
3105  }
3106  }
3107 
3108  _nextKeyView = nil;
3109 }
3110 
3111 @end
3112 
3114 
3118 - (void)setLayer:(CALayer)aLayer
3119 {
3120  if (_layer === aLayer)
3121  return;
3122 
3123  if (_layer)
3124  {
3125  _layer._owningView = nil;
3126 #if PLATFORM(DOM)
3127  _DOMElement.removeChild(_layer._DOMElement);
3128 #endif
3129  }
3130 
3131  _layer = aLayer;
3132 
3133  if (_layer)
3134  {
3135  var bounds = CGRectMakeCopy([self bounds]);
3136 
3137  [_layer _setOwningView:self];
3138 
3139 #if PLATFORM(DOM)
3140  _layer._DOMElement.style.zIndex = 100;
3141 
3142  _DOMElement.appendChild(_layer._DOMElement);
3143 #endif
3144  }
3145 }
3146 
3151 {
3152  return _layer;
3153 }
3154 
3159 - (void)setWantsLayer:(BOOL)aFlag
3160 {
3161  _wantsLayer = !!aFlag;
3162 }
3163 
3168 - (BOOL)wantsLayer
3169 {
3170  return _wantsLayer;
3171 }
3172 
3173 @end
3174 
3175 
3176 @implementation CPView (Scaling)
3177 
3183 - (void)setScaleSize:(CGSize)aSize
3184 {
3185  if (CGSizeEqualToSize(_scaleSize, aSize))
3186  return;
3187 
3188  var size = CGSizeMakeZero(),
3189  scale = CGSizeMakeCopy([self scaleSize]);
3190 
3191  size.height = aSize.height / scale.height;
3192  size.width = aSize.width / scale.width;
3193 
3194  [self scaleUnitSquareToSize:size];
3195  [self setNeedsDisplay:YES];
3196 }
3197 
3198 
3202 - (CGSize)scaleSize
3203 {
3204  return _scaleSize || CGSizeMake(1.0, 1.0);
3205 }
3206 
3207 @end
3208 
3209 
3210 @implementation CPView (Theming)
3211 
3212 #pragma mark Override
3213 
3214 - (BOOL)setThemeState:(ThemeState)aState
3215 {
3216  var shouldLayout = [super setThemeState:aState];
3217 
3218  if (!shouldLayout)
3219  return NO;
3220 
3221  [self setNeedsLayout:YES];
3222  [self setNeedsDisplay:YES];
3223 
3224  return YES;
3225 }
3226 
3227 - (BOOL)unsetThemeState:(ThemeState)aState
3228 {
3229  var shouldLayout = [super unsetThemeState:aState];
3230 
3231  if (!shouldLayout)
3232  return NO;
3233 
3234  [self setNeedsLayout:YES];
3235  [self setNeedsDisplay:YES];
3236 
3237  return YES;
3238 }
3239 
3240 - (void)setThemeClass:(CPString)theClass
3241 {
3242  [super setThemeClass:theClass];
3243 
3244  [self setNeedsLayout];
3245  [self setNeedsDisplay:YES];
3246 }
3247 
3248 
3249 #pragma mark First responder
3250 
3252 {
3253  var r = [super becomeFirstResponder];
3254 
3255  if (r)
3256  [self _notifyViewDidBecomeFirstResponder];
3257 
3258  return r;
3259 }
3260 
3261 - (void)_notifyViewDidBecomeFirstResponder
3262 {
3263  [self setThemeState:CPThemeStateFirstResponder];
3264 
3265  var count = [_subviews count];
3266 
3267  while (count--)
3268  [_subviews[count] _notifyViewDidBecomeFirstResponder];
3269 }
3270 
3272 {
3273  var r = [super resignFirstResponder];
3274 
3275  if (r)
3276  [self _notifyViewDidResignFirstResponder];
3277 
3278  return r;
3279 }
3280 
3281 - (void)_notifyViewDidResignFirstResponder
3282 {
3283  [self unsetThemeState:CPThemeStateFirstResponder];
3284 
3285  var count = [_subviews count];
3286 
3287  while (count--)
3288  [_subviews[count] _notifyViewDidResignFirstResponder];
3289 }
3290 
3291 - (void)_notifyWindowDidBecomeKey
3292 {
3293  [self setThemeState:CPThemeStateKeyWindow];
3294 
3295  var count = [_subviews count];
3296 
3297  while (count--)
3298  [_subviews[count] _notifyWindowDidBecomeKey];
3299 }
3300 
3301 - (void)_notifyWindowDidResignKey
3302 {
3303  [self unsetThemeState:CPThemeStateKeyWindow];
3304 
3305  var count = [_subviews count];
3306 
3307  while (count--)
3308  [_subviews[count] _notifyWindowDidResignKey];
3309 }
3310 
3311 #pragma mark Theme Attributes
3312 
3313 - (void)_setThemeIncludingDescendants:(CPTheme)aTheme
3314 {
3315  [self setTheme:aTheme];
3316  [[self subviews] makeObjectsPerformSelector:@selector(_setThemeIncludingDescendants:) withObject:aTheme];
3317 }
3318 
3320 {
3321  if (!_themeAttributes)
3322  return;
3323 
3324  [super objectDidChangeTheme];
3325 
3326  [self setNeedsLayout];
3327  [self setNeedsDisplay:YES];
3328 }
3329 
3330 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
3331 {
3332  var currentValue = [self currentValueForThemeAttribute:aName];
3333 
3334  [super setValue:aValue forThemeAttribute:aName inState:aState];
3335 
3336  if ([self currentValueForThemeAttribute:aName] === currentValue)
3337  return;
3338 
3339  [self setNeedsDisplay:YES];
3340  [self setNeedsLayout];
3341 }
3342 
3343 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
3344 {
3345  var currentValue = [self currentValueForThemeAttribute:aName];
3346 
3347  [super setValue:aValue forThemeAttribute:aName ];
3348 
3349  if ([self currentValueForThemeAttribute:aName] === currentValue)
3350  return;
3351 
3352  [self setNeedsDisplay:YES];
3353  [self setNeedsLayout];
3354 }
3355 
3356 - (CPView)createEphemeralSubviewNamed:(CPString)aViewName
3357 {
3358  return nil;
3359 }
3360 
3361 - (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
3362 {
3363  return CGRectMakeZero();
3364 }
3365 
3366 - (CPView)layoutEphemeralSubviewNamed:(CPString)aViewName
3367  positioned:(CPWindowOrderingMode)anOrderingMode
3368  relativeToEphemeralSubviewNamed:(CPString)relativeToViewName
3369 {
3370  if (!_ephemeralSubviewsForNames)
3371  {
3372  _ephemeralSubviewsForNames = {};
3373  _ephemeralSubviews = [CPSet set];
3374  }
3375 
3376  var frame = [self rectForEphemeralSubviewNamed:aViewName];
3377 
3378  if (frame)
3379  {
3380  if (!_ephemeralSubviewsForNames[aViewName])
3381  {
3382  _ephemeralSubviewsForNames[aViewName] = [self createEphemeralSubviewNamed:aViewName];
3383 
3384  [_ephemeralSubviews addObject:_ephemeralSubviewsForNames[aViewName]];
3385 
3386  if (_ephemeralSubviewsForNames[aViewName])
3387  [self addSubview:_ephemeralSubviewsForNames[aViewName] positioned:anOrderingMode relativeTo:_ephemeralSubviewsForNames[relativeToViewName]];
3388  }
3389 
3390  if (_ephemeralSubviewsForNames[aViewName])
3391  [_ephemeralSubviewsForNames[aViewName] setFrame:frame];
3392  }
3393  else if (_ephemeralSubviewsForNames[aViewName])
3394  {
3395  [_ephemeralSubviewsForNames[aViewName] removeFromSuperview];
3396 
3397  [_ephemeralSubviews removeObject:_ephemeralSubviewsForNames[aViewName]];
3398  delete _ephemeralSubviewsForNames[aViewName];
3399  }
3400 
3401  return _ephemeralSubviewsForNames[aViewName];
3402 }
3403 
3404 - (CPView)ephemeralSubviewNamed:(CPString)aViewName
3405 {
3406  if (!_ephemeralSubviewsForNames)
3407  return nil;
3408 
3409  return (_ephemeralSubviewsForNames[aViewName] || nil);
3410 }
3411 
3412 @end
3413 
3414 
3415 @implementation CPView (Appearance)
3416 
3420 {
3421  if (_appearance)
3422  return _appearance;
3423 
3424  return [_superview effectiveAppearance];
3425 }
3426 
3427 - (void)setAppearance:(CPAppearance)anAppearance
3428 {
3429  if ([_appearance isEqual:anAppearance])
3430  return;
3431 
3432  [self willChangeValueForKey:@"appearance"];
3433  _appearance = anAppearance;
3434  [self didChangeValueForKey:@"appearance"];
3435 
3436  [self setNeedsLayout:YES];
3437 }
3438 
3441 - (void)_recomputeAppearance
3442 {
3444 
3445  if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameAqua]])
3446  {
3447  [self setThemeState:CPThemeStateAppearanceAqua];
3448  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3449  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3450  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3451  }
3452  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameLightContent]])
3453  {
3454  [self unsetThemeState:CPThemeStateAppearanceAqua];
3455  [self setThemeState:CPThemeStateAppearanceLightContent];
3456  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3457  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3458  }
3459  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
3460  {
3461  [self unsetThemeState:CPThemeStateAppearanceAqua];
3462  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3463  [self setThemeState:CPThemeStateAppearanceVibrantLight];
3464  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3465  }
3466  else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]])
3467  {
3468  [self unsetThemeState:CPThemeStateAppearanceAqua];
3469  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3470  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3471  [self setThemeState:CPThemeStateAppearanceVibrantDark];
3472  }
3473  else
3474  {
3475  [self unsetThemeState:CPThemeStateAppearanceAqua];
3476  [self unsetThemeState:CPThemeStateAppearanceLightContent];
3477  [self unsetThemeState:CPThemeStateAppearanceVibrantLight];
3478  [self unsetThemeState:CPThemeStateAppearanceVibrantDark];
3479  }
3480 
3481 // var start = [CPDate new];
3482 
3483  for (var i = 0, size = [_subviews count]; i < size; i++)
3484  {
3485  [[_subviews objectAtIndex:i] _recomputeAppearance];
3486  }
3487 // [_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
3488 
3489 /* var now = [CPDate new];
3490  var elapsedSeconds = [now timeIntervalSinceReferenceDate] - [start timeIntervalSinceReferenceDate];
3491 
3492  CPLog.trace(@"_recomputeAppearance " + [_subviews count] + " subviews in " + elapsedSeconds + @" seconds");
3493 */}
3494 
3495 
3496 @end
3497 
3499 
3500 - (void)addTrackingArea:(CPTrackingArea)trackingArea
3501 {
3502  // Consistency check
3503  if (!trackingArea || [_trackingAreas containsObjectIdenticalTo:trackingArea])
3504  return;
3505 
3506  if ([trackingArea view])
3507  [CPException raise:CPInternalInconsistencyException reason:"Tracking area has already been added to another view."];
3508 
3509  [_trackingAreas addObject:trackingArea];
3510  [trackingArea setView:self];
3511 
3512  if (_window)
3513  [_window _addTrackingArea:trackingArea];
3514 
3515  [trackingArea _updateWindowRect];
3516 }
3517 
3518 - (void)removeTrackingArea:(CPTrackingArea)trackingArea
3519 {
3520  // Consistency check
3521  if (!trackingArea)
3522  return;
3523 
3524  if (![_trackingAreas containsObjectIdenticalTo:trackingArea])
3525  [CPException raise:CPInternalInconsistencyException reason:"Trying to remove unreferenced trackingArea"];
3526 
3527  [self _removeTrackingArea:trackingArea];
3528 }
3529 
3547 {
3548 
3549 }
3550 
3565 {
3566  while (_trackingAreas.length > 0)
3567  [self _removeTrackingArea:_trackingAreas[0]];
3568 }
3569 
3570 // Internal methods
3571 
3572 - (void)_removeTrackingArea:(CPTrackingArea)trackingArea
3573 {
3574  if (_window)
3575  [_window _removeTrackingArea:trackingArea];
3576 
3577  [trackingArea setView:nil];
3578  [_trackingAreas removeObjectIdenticalTo:trackingArea];
3579 }
3580 
3581 - (void)_updateTrackingAreasWithRecursion:(BOOL)shouldCallRecursively
3582 {
3583  _inhibitUpdateTrackingAreas = YES;
3584 
3585  [self _updateTrackingAreasForOwners:[self _calcTrackingAreaOwners]];
3586 
3587  if (shouldCallRecursively)
3588  {
3589  // Now, call _updateTrackingAreasWithRecursion on subviews
3590 
3591  for (var i = 0; i < _subviews.length; i++)
3592  [_subviews[i] _updateTrackingAreasWithRecursion:YES];
3593  }
3594 
3595  _inhibitUpdateTrackingAreas = NO;
3596 }
3597 
3598 - (CPArray)_calcTrackingAreaOwners
3599 {
3600  // First search all owners that must be notified
3601  // Remark: 99.99% of time, the only owner will be the view itself
3602  // In the same time, update the rects of InVisibleRect tracking areas
3603 
3604  var owners = [];
3605 
3606  for (var i = 0; i < _trackingAreas.length; i++)
3607  {
3608  var trackingArea = _trackingAreas[i];
3609 
3610  if ([trackingArea options] & CPTrackingInVisibleRect)
3611  [trackingArea _updateWindowRect];
3612 
3613  else
3614  {
3615  var owner = [trackingArea owner];
3616 
3617  if (![owners containsObjectIdenticalTo:owner])
3618  [owners addObject:owner];
3619  }
3620  }
3621 
3622  return owners;
3623 }
3624 
3625 - (void)_updateTrackingAreasForOwners:(CPArray)owners
3626 {
3627  for (var i = 0; i < owners.length; i++)
3628  [owners[i] updateTrackingAreas];
3629 }
3630 
3631 @end
3632 
3633 var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
3634  CPViewAutoresizesSubviewsKey = @"CPViewAutoresizesSubviews",
3635  CPViewBackgroundColorKey = @"CPViewBackgroundColor",
3636  CPViewBoundsKey = @"CPViewBoundsKey",
3637  CPViewFrameKey = @"CPViewFrameKey",
3638  CPViewHitTestsKey = @"CPViewHitTestsKey",
3639  CPViewToolTipKey = @"CPViewToolTipKey",
3640  CPViewIsHiddenKey = @"CPViewIsHiddenKey",
3641  CPViewOpacityKey = @"CPViewOpacityKey",
3642  CPViewSubviewsKey = @"CPViewSubviewsKey",
3643  CPViewSuperviewKey = @"CPViewSuperviewKey",
3644  CPViewTagKey = @"CPViewTagKey",
3645  CPViewWindowKey = @"CPViewWindowKey",
3646  CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
3647  CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey",
3648  CPReuseIdentifierKey = @"CPReuseIdentifierKey",
3649  CPViewScaleKey = @"CPViewScaleKey",
3650  CPViewSizeScaleKey = @"CPViewSizeScaleKey",
3651  CPViewIsScaledKey = @"CPViewIsScaledKey",
3652  CPViewAppearanceKey = @"CPViewAppearanceKey",
3653  CPViewTrackingAreasKey = @"CPViewTrackingAreasKey";
3654 
3655 @implementation CPView (CPCoding)
3656 
3662 - (id)initWithCoder:(CPCoder)aCoder
3663 {
3664  // We create the DOMElement "early" because there is a chance that we
3665  // will decode our superview before we are done decoding, at which point
3666  // we have to have an element to place in the tree. Perhaps there is
3667  // a more "elegant" way to do this...?
3668 #if PLATFORM(DOM)
3669  _DOMElement = DOMElementPrototype.cloneNode(false);
3670  AppKitTagDOMElement(self, _DOMElement);
3671 #endif
3672 
3673  // Also decode these "early".
3674  _frame = [aCoder decodeRectForKey:CPViewFrameKey];
3675  _bounds = [aCoder decodeRectForKey:CPViewBoundsKey];
3676 
3677  self = [super initWithCoder:aCoder];
3678 
3679  if (self)
3680  {
3681  _trackingAreas = [aCoder decodeObjectForKey:CPViewTrackingAreasKey];
3682 
3683  if (!_trackingAreas)
3684  _trackingAreas = [];
3685 
3686  // We have to manually check because it may be 0, so we can't use ||
3687  _tag = [aCoder containsValueForKey:CPViewTagKey] ? [aCoder decodeIntForKey:CPViewTagKey] : -1;
3688  _identifier = [aCoder decodeObjectForKey:CPReuseIdentifierKey];
3689 
3690  _window = [aCoder decodeObjectForKey:CPViewWindowKey];
3691  _superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
3692  // We have to manually add the subviews so that they will receive
3693  // viewWillMoveToSuperview: and viewDidMoveToSuperview:
3694  _subviews = [];
3695 
3696  var subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
3697 
3698  for (var i = 0, count = [subviews count]; i < count; ++i)
3699  {
3700  // addSubview won't do anything if the superview is already self, so clear it
3701  subviews[i]._superview = nil;
3702  [self addSubview:subviews[i]];
3703  }
3704 
3705  // FIXME: Should we encode/decode this?
3706  _registeredDraggedTypes = [CPSet set];
3707  _registeredDraggedTypesArray = [];
3708 
3709  // Other views (CPBox) might set an autoresizes mask on their subviews before it is actually decoded.
3710  // We make sure we don't override the value by checking if it was already set.
3711  if (_autoresizingMask === nil)
3712  _autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey] || CPViewNotSizable;
3713 
3714  _autoresizesSubviews = ![aCoder containsValueForKey:CPViewAutoresizesSubviewsKey] || [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
3715 
3716  _hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeBoolForKey:CPViewHitTestsKey];
3717 
3718  _toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
3719 
3720  if (_toolTip)
3721  [self _installToolTipEventHandlers];
3722 
3723  _scaleSize = [aCoder containsValueForKey:CPViewScaleKey] ? [aCoder decodeSizeForKey:CPViewScaleKey] : CGSizeMake(1.0, 1.0);
3724  _hierarchyScaleSize = [aCoder containsValueForKey:CPViewSizeScaleKey] ? [aCoder decodeSizeForKey:CPViewSizeScaleKey] : CGSizeMake(1.0, 1.0);
3725  _isScaled = [aCoder containsValueForKey:CPViewIsScaledKey] ? [aCoder decodeBoolForKey:CPViewIsScaledKey] : NO;
3726 
3727  // DOM SETUP
3728 #if PLATFORM(DOM)
3729  _DOMImageParts = [];
3730  _DOMImageSizes = [];
3731 
3732  CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, CGRectGetMinX(_frame), CGRectGetMinY(_frame));
3733  [self _setDisplayServerSetStyleSize:_frame.size];
3734 
3735  var index = 0,
3736  count = _subviews.length;
3737 
3738  for (; index < count; ++index)
3739  {
3740  CPDOMDisplayServerAppendChild(_DOMElement, _subviews[index]._DOMElement);
3741  //_subviews[index]._superview = self;
3742  }
3743 #endif
3744 
3745  [self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
3746  _isHiddenOrHasHiddenAncestor = NO;
3747 
3748  if ([aCoder containsValueForKey:CPViewOpacityKey])
3749  [self setAlphaValue:[aCoder decodeIntForKey:CPViewOpacityKey]];
3750  else
3751  _opacity = 1.0;
3752 
3753  [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
3754  [self _setupViewFlags];
3755  [self _decodeThemeObjectsWithCoder:aCoder];
3756 
3757  [self setAppearance:[aCoder decodeObjectForKey:CPViewAppearanceKey]];
3758 
3759  [self setNeedsDisplay:YES];
3760  [self setNeedsLayout];
3761  }
3762 
3763  return self;
3764 }
3765 
3770 - (void)encodeWithCoder:(CPCoder)aCoder
3771 {
3772  [super encodeWithCoder:aCoder];
3773 
3774  if (_tag !== -1)
3775  [aCoder encodeInt:_tag forKey:CPViewTagKey];
3776 
3777  [aCoder encodeRect:_frame forKey:CPViewFrameKey];
3778  [aCoder encodeRect:_bounds forKey:CPViewBoundsKey];
3779 
3780  // This will come out nil on the other side with decodeObjectForKey:
3781  if (_window !== nil)
3782  [aCoder encodeConditionalObject:_window forKey:CPViewWindowKey];
3783 
3784  var count = [_subviews count],
3785  encodedSubviews = _subviews;
3786 
3787  if (count > 0 && [_ephemeralSubviews count] > 0)
3788  {
3789  encodedSubviews = [encodedSubviews copy];
3790 
3791  while (count--)
3792  if ([_ephemeralSubviews containsObject:encodedSubviews[count]])
3793  encodedSubviews.splice(count, 1);
3794  }
3795 
3796  if (encodedSubviews.length > 0)
3797  [aCoder encodeObject:encodedSubviews forKey:CPViewSubviewsKey];
3798 
3799  // This will come out nil on the other side with decodeObjectForKey:
3800  if (_superview !== nil)
3801  [aCoder encodeConditionalObject:_superview forKey:CPViewSuperviewKey];
3802 
3803  if (_autoresizingMask !== CPViewNotSizable)
3804  [aCoder encodeInt:_autoresizingMask forKey:CPViewAutoresizingMaskKey];
3805 
3806  if (!_autoresizesSubviews)
3807  [aCoder encodeBool:_autoresizesSubviews forKey:CPViewAutoresizesSubviewsKey];
3808 
3809  if (_backgroundColor !== nil)
3810  [aCoder encodeObject:_backgroundColor forKey:CPViewBackgroundColorKey];
3811 
3812  if (_hitTests !== YES)
3813  [aCoder encodeBool:_hitTests forKey:CPViewHitTestsKey];
3814 
3815  if (_opacity !== 1.0)
3816  [aCoder encodeFloat:_opacity forKey:CPViewOpacityKey];
3817 
3818  if (_isHidden)
3819  [aCoder encodeBool:_isHidden forKey:CPViewIsHiddenKey];
3820 
3821  if (_toolTip)
3822  [aCoder encodeObject:_toolTip forKey:CPViewToolTipKey];
3823 
3824  var nextKeyView = [self nextKeyView];
3825 
3826  if (nextKeyView !== nil && ![nextKeyView isEqual:self])
3827  [aCoder encodeConditionalObject:nextKeyView forKey:CPViewNextKeyViewKey];
3828 
3829  var previousKeyView = [self previousKeyView];
3830 
3831  if (previousKeyView !== nil && ![previousKeyView isEqual:self])
3832  [aCoder encodeConditionalObject:previousKeyView forKey:CPViewPreviousKeyViewKey];
3833 
3834  [self _encodeThemeObjectsWithCoder:aCoder];
3835 
3836  if (_identifier)
3837  [aCoder encodeObject:_identifier forKey:CPReuseIdentifierKey];
3838 
3839  [aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
3840  [aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
3841  [aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
3842  [aCoder encodeObject:_appearance forKey:CPViewAppearanceKey];
3843  [aCoder encodeObject:_trackingAreas forKey:CPViewTrackingAreasKey];
3844 }
3845 
3846 @end
3847 
3848 var _CPViewFullScreenModeStateMake = function(aView)
3849 {
3850  var superview = aView._superview;
3851 
3852  return { autoresizingMask:aView._autoresizingMask, frame:CGRectMakeCopy(aView._frame), index:(superview ? [superview._subviews indexOfObjectIdenticalTo:aView] : 0), superview:superview };
3853 };
3854 
3855 var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
3856 {
3857  var transform = CGAffineTransformMakeIdentity(),
3858  sameWindow = YES,
3859  fromWindow = nil,
3860  toWindow = nil;
3861 
3862  if (fromView)
3863  {
3864  var view = fromView;
3865 
3866  // FIXME: This doesn't handle the case when the outside views are equal.
3867  // If we have a fromView, "climb up" the view tree until
3868  // we hit the root node or we hit the toLayer.
3869  while (view && view != toView)
3870  {
3871  var frame = view._frame;
3872 
3873  if (view._isScaled)
3874  {
3875  var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
3876  CGAffineTransformConcatTo(transform, affineZoom, transform);
3877  }
3878 
3879  transform.tx += CGRectGetMinX(frame);
3880  transform.ty += CGRectGetMinY(frame);
3881 
3882  if (view._boundsTransform)
3883  {
3884  var inverseBoundsTransform = CGAffineTransformMakeCopy(view._boundsTransform);
3885 
3886  if (view._isScaled)
3887  {
3888  var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
3889  CGAffineTransformConcatTo(inverseBoundsTransform, affineZoom, inverseBoundsTransform);
3890  }
3891 
3892  CGAffineTransformConcatTo(transform, inverseBoundsTransform, transform);
3893  }
3894 
3895  view = view._superview;
3896  }
3897 
3898  // If we hit toView, then we're done.
3899  if (view === toView)
3900  {
3901  return transform;
3902  }
3903  else if (fromView && toView)
3904  {
3905  fromWindow = [fromView window];
3906  toWindow = [toView window];
3907 
3908  if (fromWindow && toWindow && fromWindow !== toWindow)
3909  sameWindow = NO;
3910  }
3911  }
3912 
3913  // FIXME: For now we can do things this way, but eventually we need to do them the "hard" way.
3914  var view = toView,
3915  transform2 = CGAffineTransformMakeIdentity();
3916 
3917  while (view && view != fromView)
3918  {
3919  var frame = CGRectMakeCopy(view._frame);
3920 
3921  // FIXME : For now we don't care about rotate transform and so on
3922  if (view._isScaled)
3923  {
3924  transform2.a *= 1 / view._scaleSize.width;
3925  transform2.d *= 1 / view._scaleSize.height;
3926  }
3927 
3928  transform2.tx += CGRectGetMinX(frame) * transform2.a;
3929  transform2.ty += CGRectGetMinY(frame) * transform2.d;
3930 
3931  if (view._boundsTransform)
3932  {
3933  var inverseBoundsTransform = CGAffineTransformMakeIdentity();
3934  inverseBoundsTransform.tx -= view._inverseBoundsTransform.tx * transform2.a;
3935  inverseBoundsTransform.ty -= view._inverseBoundsTransform.ty * transform2.d;
3936 
3937  CGAffineTransformConcatTo(transform2, inverseBoundsTransform, transform2);
3938  }
3939 
3940  view = view._superview;
3941  }
3942 
3943  transform2.tx = -transform2.tx;
3944  transform2.ty = -transform2.ty;
3945 
3946  if (view === fromView)
3947  {
3948  // toView is inside of fromView
3949  return transform2;
3950  }
3951 
3952  CGAffineTransformConcatTo(transform, transform2, transform);
3953 
3954  return transform;
3955 
3956 
3957 
3958 /* var views = [],
3959  view = toView;
3960 
3961  while (view)
3962  {
3963  views.push(view);
3964  view = view._superview;
3965  }
3966 
3967  var index = views.length;
3968 
3969  while (index--)
3970  {
3971  var frame = views[index]._frame;
3972 
3973  transform.tx -= CGRectGetMinX(frame);
3974  transform.ty -= CGRectGetMinY(frame);
3975  }*/
3976 
3977  return transform;
3978 };
id initWithFrame:(CGRect aFrame)
Definition: CPView.j:334
Used to implement exception handling (creating & raising).
Definition: CPException.h:2
void viewDidMoveToSuperview()
Definition: CPView.j:858
void lockFocus()
Definition: CPView.j:2648
BOOL postsBoundsChangedNotifications()
Definition: CPView.j:2384
void viewWillLayout()
Definition: CPView.j:2752
BOOL canBecomeKeyView()
Definition: CPView.j:3025
Definition: CPMenu.h:2
void addSubview:(CPView aSubview)
Definition: CPView.j:512
void drawRect:(CGRect aRect)
Definition: CPView.j:2464
void layoutSubviews()
Definition: CPView.j:2765
CGPoint frameOrigin()
Definition: CPView.j:1027
void setAppearance:(CPAppearance anAppearance)
Definition: CPView.j:3427
void layoutIfNeeded()
Definition: CPView.j:2743
BOOL setThemeState:(ThemeState aState)
Definition: CPView.j:3214
CPCSSRGBAFeature
CPView nextValidKeyView()
Definition: CPView.j:3035
function CGAffineTransformMakeIdentity()
var isEqual
void postNotificationName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
void scrollToPoint:(CGPoint aPoint)
Definition: CPClipView.j:102
BOOL clipsToBounds()
Definition: CPView.j:1714
An object representation of nil.
Definition: CPNull.h:2
var CPReuseIdentifierKey
Definition: CPView.j:3648
BOOL needsDisplay()
Definition: CPView.j:2585
CPViewWidthSizable
Definition: CPView.j:67
void layout()
Definition: CPView.j:2730
function CGAffineTransformMakeScale(sx, sy)
CPViewMaxYMargin
Definition: CPView.j:91
var CPViewIsHiddenKey
Definition: CPView.j:3640
var CPViewSubviewsKey
Definition: CPView.j:3642
BOOL hitTests()
Definition: CPView.j:1814
CGPoint center()
Definition: CPView.j:1053
BOOL inLiveResize()
Definition: CPView.j:2961
CPView previousKeyView()
Definition: CPView.j:3056
void setView:(CPView aValue)
BOOL isFlipped()
Definition: CPView.j:984
BOOL autoscroll:(CPEvent anEvent)
Definition: CPView.j:2900
function CPBrowserBackingStorePixelRatio(context)
var CPViewHasCustomLayoutSubviews
Definition: CPView.j:115
var CPViewPreviousKeyViewKey
Definition: CPView.j:3647
CGSize boundsSize()
Definition: CPView.j:1312
void setFrame:(CGRect aFrame)
Definition: CPView.j:996
void viewDidHide()
Definition: CPView.j:1781
function CGContextRestoreGState(aContext)
Definition: CGContext.j:156
function CGAffineTransformMakeCopy(anAffineTransform)
var CPViewFrameKey
Definition: CPView.j:3637
var CPViewBoundsKey
Definition: CPView.j:3636
void setCurrentContext:(CPGraphicsContext aGraphicsContext)
void viewWillDraw()
Definition: CPView.j:2641
int width
CGRect bounds()
Definition: CPView.j:1302
void raise:reason:(CPString aName, [reason] CPString aReason)
Definition: CPException.j:66
CPArray registeredDraggedTypes()
Definition: CPView.j:2441
CPInteger tag()
Definition: CPView.j:956
void removeFromSuperview()
Definition: CPView.j:654
var CPViewOpacityKey
Definition: CPView.j:3641
void viewWillMoveToWindow:(CPWindow aWindow)
Definition: CPView.j:889
Definition: CALayer.h:2
BOOL enterFullScreenMode:withOptions:(CPScreen aScreen, [withOptions] CPDictionary options)
Definition: CPView.j:1515
BOOL postsFrameChangedNotifications()
Definition: CPView.j:2352
CPColor backgroundColor()
Definition: CPView.j:2196
void initialize()
Definition: CPView.j:240
var CPViewHasCustomDrawRect
Definition: CPView.j:114
void viewDidLayout()
Definition: CPView.j:2760
void setNeedsDisplayInRect:(CGRect aRect)
Definition: CPView.j:2569
var CPViewTagKey
Definition: CPView.j:3644
var CPViewAppearanceKey
Definition: CPView.j:3652
CPNotificationCenter defaultCenter()
CPInvalidArgumentException
Definition: CPException.j:25
A mutable key-value pair collection.
Definition: CPDictionary.h:2
CPScrollView enclosingScrollView()
Definition: CPView.j:2928
BOOL isInFullScreenMode()
Definition: CPView.j:1570
var CPViewSizeScaleKey
Definition: CPView.j:3650
BOOL enterFullScreenMode()
Definition: CPView.j:1505
function ThemeState(stateNames)
Definition: CPTheme.j:314
void setNeedsDisplay()
Definition: CALayer.j:830
void displayRectIgnoringOpacity:inContext:(CGRect aRect, [inContext] CPGraphicsContext aGraphicsContext)
Definition: CPView.j:2626
void setBoundsOrigin:(CGPoint aPoint)
Definition: CPView.j:1323
void displayRect:(CGRect aRect)
Definition: CPView.j:2617
var CPViewWindowKey
Definition: CPView.j:3645
CPHiddenBinding
CPWindow window()
Definition: CPView.j:503
CGSize frameSize()
Definition: CPView.j:1032
CGPoint boundsOrigin()
Definition: CPView.j:1307
void setNeedsLayout:(BOOL needLayout)
Definition: CPView.j:2712
CPColor blackColor()
Definition: CPColor.j:283
id initWithContentRect:styleMask:(CGRect aContentRect, [styleMask] unsigned aStyleMask)
Definition: CPWindow.j:263
void viewWillMoveToSuperview:(CPView aView)
Definition: CPView.j:875
BOOL resignFirstResponder()
Definition: CPView.j:3271
var CPViewAutoresizingMaskKey
Definition: CPView.j:3633
CPView previousValidKeyView()
Definition: CPView.j:3061
CPView createEphemeralSubviewNamed:(CPString aViewName)
Definition: CPView.j:3356
id initWithName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
var CPViewTrackingAreasKey
Definition: CPView.j:3653
An immutable string (collection of characters).
Definition: CPString.h:2
CGPoint convertPoint:fromView:(CGPoint aPoint, [fromView] CPView aView)
Definition: CPView.j:2208
var CPViewBackgroundColorKey
Definition: CPView.j:3635
var CPViewIsScaledKey
Definition: CPView.j:3651
Definition: CPImage.h:2
CPSet keyPathsForValuesAffectingFrame()
Definition: CPView.j:285
void addSubview:positioned:relativeTo:(CPView aSubview, [positioned] CPWindowOrderingMode anOrderingMode, [relativeTo] CPView anotherView)
Definition: CPView.j:523
function CPFeatureIsCompatible(aFeature)
id init()
Definition: CPView.j:325
BOOL mouseDownCanMoveWindow()
Definition: CPView.j:1891
var CachedNotificationCenter
Definition: CPView.j:101
CPSet keyPathsForValuesAffectingBounds()
Definition: CPView.j:290
CGRect convertRect:toView:(CGRect aRect, [toView] CPView aView)
Definition: CPView.j:2309
CPViewMinXMargin
Definition: CPView.j:61
CPView nextValidKeyView()
Definition: CPView.j:3035
void viewDidMoveToWindow()
Definition: CPView.j:867
void setHidden:(BOOL aFlag)
Definition: CPView.j:1579
CPView previousKeyView()
Definition: CPView.j:3056
void setAutoresizingMask:(unsigned aMask)
Definition: CPView.j:1487
void exitFullScreenMode()
Definition: CPView.j:1544
BOOL isOpaque()
Definition: CPView.j:2773
void setNeedsDisplay:(BOOL aFlag)
Definition: CPView.j:2556
CPGraphicsContext graphicsContextWithGraphicsPort:flipped:(CGContext aContext, [flipped] BOOL aFlag)
void viewDidEndLiveResize()
Definition: CPView.j:2990
CPMenu menuForEvent:(CPEvent anEvent)
Definition: CPView.j:1914
BOOL isHidden()
Definition: CPView.j:1697
CPAppearanceNameAqua
Definition: CPAppearance.j:24
CGPoint convertPoint:toView:(CGPoint aPoint, [toView] CPView aView)
Definition: CPView.j:2232
CPViewBoundsDidChangeNotification
Definition: CPView.j:98
BOOL isVisible()
Definition: CPWindow.j:1093
CPWindow window()
Definition: CPEvent.j:341
function CGAffineTransformMakeTranslation(tx, ty)
var CPViewSuperviewKey
Definition: CPView.j:3643
function CGRectApplyAffineTransform(aRect, anAffineTransform)
function CGAffineTransformInvert(aTransform)
var CPViewScaleKey
Definition: CPView.j:3649
function CGContextClearRect(aContext, aRect)
Definition: CGContextVML.j:51
var CPViewToolTipKey
Definition: CPView.j:3639
A notification that can be posted to a CPNotificationCenter.
Definition: CPNotification.h:2
var CPViewHitTestsKey
Definition: CPView.j:3638
function CGAffineTransformConcatTo(lhs, rhs, to)
CPTheme defaultTheme()
Definition: CPTheme.j:44
CPArray subviews()
Definition: CPView.j:495
void setAlphaValue:(float anAlphaValue)
Definition: CPView.j:1724
BOOL isHighDPIDrawingEnabled()
Definition: CPView.j:280
void orderOut:(id aSender)
Definition: CPWindow.j:1005
void setNeedsLayout()
Definition: CPView.j:2707
void objectDidChangeTheme()
Definition: CPView.j:3319
CGRect convertRect:fromView:(CGRect aRect, [fromView] CPView aView)
Definition: CPView.j:2285
void scaleUnitSquareToSize:(CGSize aSize)
Definition: CPView.j:2477
function CGSizeApplyAffineTransform(aSize, aTransform)
CPViewMaxXMargin
Definition: CPView.j:73
BOOL needsLayout()
Definition: CPView.j:2725
CPAppearanceNameLightContent
Definition: CPAppearance.j:25
CPMenuItem enclosingMenuItem()
Definition: CPView.j:931
CPAppearanceNameVibrantDark
Definition: CPAppearance.j:26
global appkit_tag_dom_elements typedef _CPViewFullScreenModeState CPViewNotSizable
Definition: CPView.j:55
var CPViewFlags
Definition: CPView.j:113
function CPBrowserStyleProperty(aProperty)
Defines methods for use when archiving & restoring (enc/decoding).
Definition: CPCoder.h:2
BOOL becomeFirstResponder()
Definition: CPView.j:3251
CPAppearance effectiveAppearance()
Definition: CPView.j:3419
CPNotFound
Definition: CPObjJRuntime.j:62
var CPViewHighDPIDrawingEnabled
Definition: CPView.j:118
CPThemeStateFirstResponder
Definition: CPTheme.j:560
BOOL unsetThemeState:(ThemeState aState)
Definition: CPView.j:3227
function CGContextSaveGState(aContext)
Definition: CGContext.j:146
Sends messages (CPNotification) between objects.
BOOL needsPanelToBecomeKey()
Definition: CPView.j:1882
CPViewHeightSizable
Definition: CPView.j:85
Definition: CPTheme.h:2
CGSize scaleSize()
Definition: CPView.j:3202
CGSize scaleSize()
Definition: CPView.j:3202
void didAddSubview:(CPView aSubview)
Definition: CPView.j:646
CPView nextKeyView()
Definition: CPView.j:3030
void setBounds:(CGRect bounds)
Definition: CPView.j:1276
CPString description()
Definition: CPString.j:178
CGAffineTransform affineTransform()
Definition: CALayer.j:293
var CPViewNextKeyViewKey
Definition: CPView.j:3646
void setBackgroundColor:(CPColor aColor)
Definition: CPView.j:1923
void setBoundsSize:(CGSize aSize)
Definition: CPView.j:1372
CPAppearance effectiveAppearance()
Definition: CPView.j:3419
float alphaValue()
Definition: CPView.j:1750
CPViewMinYMargin
Definition: CPView.j:79
var CPViewAutoresizesSubviewsKey
Definition: CPView.j:3634
void setFrameSize:(CGSize aSize)
Definition: CPView.j:1100
CPOpacityRequiresFilterFeature
Definition: CPEvent.h:2
void viewWillStartLiveResize()
Definition: CPView.j:2975
void unlockFocus()
Definition: CPView.j:2700
CPView superview()
Definition: CPView.j:486
CPAppearanceNameVibrantLight
Definition: CPAppearance.j:27
var CPViewHasCustomViewWillLayout
Definition: CPView.j:116
CPView nextKeyView()
Definition: CPView.j:3030
unsigned autoresizingMask()
Definition: CPView.j:1495
CPPlatformWindow platformWindow()
Definition: CPWindow.j:384
CGRect frame()
Definition: CPView.j:1022
function CGPointApplyAffineTransform(aPoint, aTransform)
function CPPlatformHasBug(aBug)
void exitFullScreenModeWithOptions:(CPDictionary options)
Definition: CPView.j:1553
void displayIfNeeded()
Definition: CPView.j:2593
function CGBitmapGraphicsContextCreate()
Definition: CGContext.j:136
BOOL autoresizesSubviews()
Definition: CPView.j:1478
CPWindowOrderingMode CPWindowAbove
CGRect visibleRect()
Definition: CPView.j:2781
void viewDidUnhide()
Definition: CPView.j:1795
void setFrameOrigin:(CGPoint aPoint)
Definition: CPView.j:1065
CPTrackingInVisibleRect
CPMenu defaultMenu()
Definition: CPView.j:295
void resizeSubviewsWithOldSize:(CGSize aSize)
Definition: CPView.j:1454
void display()
Definition: CPView.j:2602
void popUpContextMenu:withEvent:forView:(CPMenu aMenu, [withEvent] CPEvent anEvent, [forView] CPView aView)
Definition: CPMenu.j:857
void unregisterDraggedTypes()
Definition: CPView.j:2452
CPPlatformWindow primaryPlatformWindow()
CPMenu menu
id alloc()
Definition: CPObject.j:130
CPViewFrameDidChangeNotification
Definition: CPView.j:99
CGRect rectForEphemeralSubviewNamed:(CPString aViewName)
Definition: CPView.j:3361
Definition: CPView.j:136
CPThemeStateKeyWindow
Definition: CPTheme.j:562
BOOL isHiddenOrHasHiddenAncestor()
Definition: CPView.j:1759
CPCanvasParentDrawErrorsOnMovementBug