// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/cocoa/table_row_nsimage_cache.h" #include "base/logging.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_util_mac.h" TableRowNSImageCache::TableRowNSImageCache(Table* model) : model_(model), icon_images_([[NSPointerArray alloc] initWithOptions: NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality]) { int count = model_->RowCount(); [icon_images_ setCount:count]; } TableRowNSImageCache::~TableRowNSImageCache() {} void TableRowNSImageCache::OnModelChanged() { int count = model_->RowCount(); [icon_images_ setCount:0]; [icon_images_ setCount:count]; } void TableRowNSImageCache::OnItemsChanged(int start, int length) { DCHECK_LE(start + length, static_cast([icon_images_ count])); for (int i = start; i < (start + length); ++i) { [icon_images_ replacePointerAtIndex:i withPointer:NULL]; } DCHECK_EQ(model_->RowCount(), static_cast([icon_images_ count])); } void TableRowNSImageCache::OnItemsAdded(int start, int length) { DCHECK_LE(start, static_cast([icon_images_ count])); // -[NSPointerArray insertPointer:atIndex:] throws if index == count. // Instead expand the array with NULLs. if (start == static_cast([icon_images_ count])) { [icon_images_ setCount:start + length]; } else { for (int i = 0; i < length; ++i) { [icon_images_ insertPointer:NULL atIndex:start]; // Values slide up. } } DCHECK_EQ(model_->RowCount(), static_cast([icon_images_ count])); } void TableRowNSImageCache::OnItemsRemoved(int start, int length) { DCHECK_LE(start + length, static_cast([icon_images_ count])); for (int i = 0; i < length; ++i) { [icon_images_ removePointerAtIndex:start]; // Values slide down. } DCHECK_EQ(model_->RowCount(), static_cast([icon_images_ count])); } NSImage* TableRowNSImageCache::GetImageForRow(int row) { DCHECK_EQ(model_->RowCount(), static_cast([icon_images_ count])); DCHECK_GE(row, 0); DCHECK_LT(row, static_cast([icon_images_ count])); NSImage* image = static_cast([icon_images_ pointerAtIndex:row]); if (!image) { const gfx::ImageSkia image_skia_icon = model_->GetIcon(row); // This means GetIcon() will get called until it returns a non-empty image. // Empty images are intentionally not cached. if (!image_skia_icon.isNull()) { image = gfx::NSImageFromImageSkia(image_skia_icon); DCHECK(image); [icon_images_ replacePointerAtIndex:row withPointer:image]; } } return image; }