Home | History | Annotate | Download | only in focus
      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