• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/browser/tabs/tab_strip_selection_model.h"
6 
7 #include <algorithm>
8 #include <valarray>
9 
10 #include "base/logging.h"
11 
12 // static
13 const int TabStripSelectionModel::kUnselectedIndex = -1;
14 
IncrementFromImpl(int index,int * value)15 static void IncrementFromImpl(int index, int* value) {
16   if (*value >= index)
17     (*value)++;
18 }
19 
DecrementFromImpl(int index,int * value)20 static bool DecrementFromImpl(int index, int* value) {
21   if (*value == index) {
22     *value = TabStripSelectionModel::kUnselectedIndex;
23     return true;
24   }
25   if (*value > index)
26     (*value)--;
27   return false;
28 }
29 
TabStripSelectionModel()30 TabStripSelectionModel::TabStripSelectionModel()
31     : active_(kUnselectedIndex),
32       anchor_(kUnselectedIndex) {
33 }
34 
~TabStripSelectionModel()35 TabStripSelectionModel::~TabStripSelectionModel() {
36 }
37 
IncrementFrom(int index)38 void TabStripSelectionModel::IncrementFrom(int index) {
39   // Shift the selection to account for the newly inserted tab.
40   for (SelectedIndices::iterator i = selected_indices_.begin();
41        i != selected_indices_.end(); ++i) {
42     IncrementFromImpl(index, &(*i));
43   }
44   IncrementFromImpl(index, &anchor_);
45   IncrementFromImpl(index, &active_);
46 }
47 
DecrementFrom(int index)48 void TabStripSelectionModel::DecrementFrom(int index) {
49   for (SelectedIndices::iterator i = selected_indices_.begin();
50        i != selected_indices_.end(); ) {
51     if (DecrementFromImpl(index, &(*i)))
52       i = selected_indices_.erase(i);
53     else
54       ++i;
55   }
56   DecrementFromImpl(index, &anchor_);
57   DecrementFromImpl(index, &active_);
58 }
59 
SetSelectedIndex(int index)60 void TabStripSelectionModel::SetSelectedIndex(int index) {
61   anchor_ = active_ = index;
62   SetSelectionFromAnchorTo(index);
63 }
64 
IsSelected(int index) const65 bool TabStripSelectionModel::IsSelected(int index) const {
66   return std::find(selected_indices_.begin(), selected_indices_.end(), index) !=
67       selected_indices_.end();
68 }
69 
AddIndexToSelection(int index)70 void TabStripSelectionModel::AddIndexToSelection(int index) {
71   if (!IsSelected(index)) {
72     selected_indices_.push_back(index);
73     std::sort(selected_indices_.begin(), selected_indices_.end());
74   }
75 }
76 
RemoveIndexFromSelection(int index)77 void TabStripSelectionModel::RemoveIndexFromSelection(int index) {
78   SelectedIndices::iterator i = std::find(selected_indices_.begin(),
79                                           selected_indices_.end(), index);
80   if (i != selected_indices_.end())
81     selected_indices_.erase(i);
82 }
83 
SetSelectionFromAnchorTo(int index)84 void TabStripSelectionModel::SetSelectionFromAnchorTo(int index) {
85   if (anchor_ == kUnselectedIndex) {
86     SetSelectedIndex(index);
87   } else {
88     int delta = std::abs(index - anchor_);
89     SelectedIndices new_selection(delta + 1, 0);
90     for (int i = 0, min = std::min(index, anchor_); i <= delta; ++i)
91       new_selection[i] = i + min;
92     selected_indices_.swap(new_selection);
93     active_ = index;
94   }
95 }
96 
AddSelectionFromAnchorTo(int index)97 void TabStripSelectionModel::AddSelectionFromAnchorTo(int index) {
98   if (anchor_ == kUnselectedIndex) {
99     SetSelectedIndex(index);
100   } else {
101     for (int i = std::min(index, anchor_), end = std::max(index, anchor_);
102          i <= end; ++i) {
103       if (!IsSelected(i))
104         selected_indices_.push_back(i);
105     }
106     std::sort(selected_indices_.begin(), selected_indices_.end());
107     active_ = index;
108   }
109 }
110 
Move(int from,int to)111 void TabStripSelectionModel::Move(int from, int to) {
112   DCHECK_NE(to, from);
113   bool was_anchor = from == anchor_;
114   bool was_active = from == active_;
115   bool was_selected = IsSelected(from);
116   if (to < from) {
117     IncrementFrom(to);
118     DecrementFrom(from + 1);
119   } else {
120     DecrementFrom(from);
121     IncrementFrom(to);
122   }
123   if (was_active)
124     active_ = to;
125   if (was_anchor)
126     anchor_ = to;
127   if (was_selected)
128     AddIndexToSelection(to);
129 }
130 
Clear()131 void TabStripSelectionModel::Clear() {
132   anchor_ = active_ = kUnselectedIndex;
133   SelectedIndices empty_selection;
134   selected_indices_.swap(empty_selection);
135 }
136 
Copy(const TabStripSelectionModel & source)137 void TabStripSelectionModel::Copy(const TabStripSelectionModel& source) {
138   selected_indices_ = source.selected_indices_;
139   active_ = source.active_;
140   anchor_ = source.anchor_;
141 }
142