1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/views/focus/view_storage.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/memory/singleton.h" 11 #include "base/stl_util.h" 12 13 namespace views { 14 15 // static 16 ViewStorage* ViewStorage::GetInstance() { 17 return Singleton<ViewStorage>::get(); 18 } 19 20 ViewStorage::ViewStorage() : view_storage_next_id_(0) { 21 } 22 23 ViewStorage::~ViewStorage() { 24 STLDeleteContainerPairSecondPointers(view_to_ids_.begin(), 25 view_to_ids_.end()); 26 } 27 28 int ViewStorage::CreateStorageID() { 29 return view_storage_next_id_++; 30 } 31 32 void ViewStorage::StoreView(int storage_id, View* view) { 33 DCHECK(view); 34 std::map<int, View*>::iterator iter = id_to_view_.find(storage_id); 35 36 if (iter != id_to_view_.end()) { 37 NOTREACHED(); 38 RemoveView(storage_id); 39 } 40 41 id_to_view_[storage_id] = view; 42 43 std::vector<int>* ids = NULL; 44 std::map<View*, std::vector<int>*>::iterator id_iter = 45 view_to_ids_.find(view); 46 if (id_iter == view_to_ids_.end()) { 47 ids = new std::vector<int>(); 48 view_to_ids_[view] = ids; 49 } else { 50 ids = id_iter->second; 51 } 52 ids->push_back(storage_id); 53 } 54 55 View* ViewStorage::RetrieveView(int storage_id) { 56 std::map<int, View*>::iterator iter = id_to_view_.find(storage_id); 57 if (iter == id_to_view_.end()) 58 return NULL; 59 return iter->second; 60 } 61 62 void ViewStorage::RemoveView(int storage_id) { 63 EraseView(storage_id, false); 64 } 65 66 void ViewStorage::ViewRemoved(View* removed) { 67 // Let's first retrieve the ids for that view. 68 std::map<View*, std::vector<int>*>::iterator ids_iter = 69 view_to_ids_.find(removed); 70 71 if (ids_iter == view_to_ids_.end()) { 72 // That view is not in the view storage. 73 return; 74 } 75 76 std::vector<int>* ids = ids_iter->second; 77 DCHECK(!ids->empty()); 78 EraseView((*ids)[0], true); 79 } 80 81 void ViewStorage::EraseView(int storage_id, bool remove_all_ids) { 82 // Remove the view from id_to_view_location_. 83 std::map<int, View*>::iterator view_iter = id_to_view_.find(storage_id); 84 if (view_iter == id_to_view_.end()) 85 return; 86 87 View* view = view_iter->second; 88 id_to_view_.erase(view_iter); 89 90 // Also update view_to_ids_. 91 std::map<View*, std::vector<int>*>::iterator ids_iter = 92 view_to_ids_.find(view); 93 DCHECK(ids_iter != view_to_ids_.end()); 94 std::vector<int>* ids = ids_iter->second; 95 96 if (remove_all_ids) { 97 for (size_t i = 0; i < ids->size(); ++i) { 98 view_iter = id_to_view_.find((*ids)[i]); 99 if (view_iter != id_to_view_.end()) 100 id_to_view_.erase(view_iter); 101 } 102 ids->clear(); 103 } else { 104 std::vector<int>::iterator id_iter = 105 std::find(ids->begin(), ids->end(), storage_id); 106 DCHECK(id_iter != ids->end()); 107 ids->erase(id_iter); 108 } 109 110 if (ids->empty()) { 111 delete ids; 112 view_to_ids_.erase(ids_iter); 113 } 114 } 115 116 } // namespace views 117