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