- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / focus / view_storage.cc
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