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#ifndef CHROME_BROWSER_TABS_TAB_STRIP_SELECTION_MODEL_H_
6#define CHROME_BROWSER_TABS_TAB_STRIP_SELECTION_MODEL_H_
7#pragma once
8
9#include <vector>
10
11#include "base/basictypes.h"
12
13// Selection model used by the tab strip. In addition to the set of selected
14// indices TabStripSelectionModel maintains the following:
15// active: the index of the currently visible tab in the tab strip.
16// anchor: the index of the last tab the user clicked on. Extending the
17// selection extends it from this index.
18//
19// Typically there is only one selected tab in the tabstrip, in which case the
20// anchor and active index correspond to the same thing.
21class TabStripSelectionModel {
22 public:
23  typedef std::vector<int> SelectedIndices;
24
25  // Used to identify no selection.
26  static const int kUnselectedIndex;
27
28  TabStripSelectionModel();
29  ~TabStripSelectionModel();
30
31  // See class description for details of the anchor.
32  void set_anchor(int anchor) { anchor_ = anchor; }
33  int anchor() const { return anchor_; }
34
35  // See class description for details of active.
36  void set_active(int active) { active_ = active; }
37  int active() const { return active_; }
38
39  // True if nothing is selected.
40  bool empty() const { return selected_indices_.empty(); }
41
42  // Number of selected indices.
43  size_t size() const { return selected_indices_.size(); }
44
45  // Increments all indices >= |index|. For example, if the selection consists
46  // of [0, 1, 5] and this is invoked with 1, it results in [0, 2, 6]. This also
47  // updates the anchor and active indices.
48  // This is used when a new tab is inserted into the tabstrip.
49  void IncrementFrom(int index);
50
51  // Shifts all indices < |index| down by 1. If |index| is selected, it is
52  // removed. For example, if the selection consists of [0, 1, 5] and this is
53  // invoked with 1, it results in [0, 4]. This is used when a tab is removed
54  // from the tabstrip.
55  void DecrementFrom(int index);
56
57  // Sets the anchor, active and selection to |index|.
58  void SetSelectedIndex(int index);
59
60  // Returns true if |index| is selected.
61  bool IsSelected(int index) const;
62
63  // Adds |index| to the selection. This does not change the active or anchor
64  // indices.
65  void AddIndexToSelection(int index);
66
67  // Removes |index| from the selection. This does not change the active or
68  // anchor indices.
69  void RemoveIndexFromSelection(int index);
70
71  // Extends the selection from the anchor to |index|. If the anchor is empty,
72  // this sets the anchor, selection and active indices to |index|.
73  void SetSelectionFromAnchorTo(int index);
74
75  // Makes sure the indices from the anchor to |index| are selected. This only
76  // adds to the selection.
77  void AddSelectionFromAnchorTo(int index);
78
79  // Invoked when an item moves. |from| is the original index, and |to| the
80  // target index.
81  // NOTE: this matches the TabStripModel API. If moving to a greater index,
82  // |to| should be the index *after* removing |from|. For example, consider
83  // three tabs 'A B C', to move A to the end of the list, this should be
84  // invoked with '0, 2'.
85  void Move(int from, int to);
86
87  // Sets the anchor and active to kUnselectedIndex, and removes all the
88  // selected indices.
89  void Clear();
90
91  // Returns the selected indices. The selection is always ordered in acending
92  // order.
93  const SelectedIndices& selected_indices() const { return selected_indices_; }
94
95  // Copies the selection from |source| to this.
96  void Copy(const TabStripSelectionModel& source);
97
98 private:
99  SelectedIndices selected_indices_;
100
101  int active_;
102
103  int anchor_;
104
105  DISALLOW_COPY_AND_ASSIGN(TabStripSelectionModel);
106};
107
108#endif  // CHROME_BROWSER_TABS_TAB_STRIP_SELECTION_MODEL_H_
109