1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3/* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7#include "ViewRegion.h" 8#import <Cocoa/Cocoa.h> 9 10#include "nsChildView.h" 11 12using namespace mozilla; 13 14ViewRegion::~ViewRegion() { 15 for (size_t i = 0; i < mViews.Length(); i++) { 16 [mViews[i] removeFromSuperview]; 17 } 18} 19 20bool ViewRegion::UpdateRegion(const LayoutDeviceIntRegion& aRegion, 21 const nsChildView& aCoordinateConverter, NSView* aContainerView, 22 NSView* (^aViewCreationCallback)()) { 23 if (mRegion == aRegion) { 24 return false; 25 } 26 27 // We need to construct the required region using as many EffectViews 28 // as necessary. We try to update the geometry of existing views if 29 // possible, or create new ones or remove old ones if the number of 30 // rects in the region has changed. 31 32 nsTArray<NSView*> viewsToRecycle = std::move(mViews); 33 // The mViews array is now empty. 34 35 size_t i = 0; 36 for (auto iter = aRegion.RectIter(); !iter.Done() || i < viewsToRecycle.Length(); i++) { 37 if (!iter.Done()) { 38 NSView* view = nil; 39 NSRect rect = aCoordinateConverter.DevPixelsToCocoaPoints(iter.Get()); 40 if (i < viewsToRecycle.Length()) { 41 view = viewsToRecycle[i]; 42 } else { 43 view = aViewCreationCallback(); 44 [aContainerView addSubview:view]; 45 46 // Now that the view is in the view hierarchy, it'll be kept alive by 47 // its superview, so we can drop our reference. 48 [view release]; 49 } 50 if (!NSEqualRects(rect, [view frame])) { 51 [view setFrame:rect]; 52 } 53 [view setNeedsDisplay:YES]; 54 mViews.AppendElement(view); 55 iter.Next(); 56 } else { 57 // Our new region is made of fewer rects than the old region, so we can 58 // remove this view. We only have a weak reference to it, so removing it 59 // from the view hierarchy will release it. 60 [viewsToRecycle[i] removeFromSuperview]; 61 } 62 } 63 64 mRegion = aRegion; 65 return true; 66} 67