Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: ash/common/wm/workspace/magnetism_matcher.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "ash/common/wm/workspace/magnetism_matcher.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 #include "base/memory/ptr_util.h"
11
12 namespace ash {
13 namespace {
14
15 // Returns true if |a| is close enough to |b| that the two edges snap.
16 bool IsCloseEnough(int a, int b) {
17 return abs(a - b) <= MagnetismMatcher::kMagneticDistance;
18 }
19
20 // Returns true if the specified SecondaryMagnetismEdge can be matched with a
21 // primary edge of |primary|. |edges| is a bitmask of the allowed
22 // MagnetismEdges.
23 bool CanMatchSecondaryEdge(MagnetismEdge primary,
24 SecondaryMagnetismEdge secondary,
25 uint32_t edges) {
26 // Convert |secondary| to a MagnetismEdge so we can compare it to |edges|.
27 MagnetismEdge secondary_as_magnetism_edge = MAGNETISM_EDGE_TOP;
28 switch (primary) {
29 case MAGNETISM_EDGE_TOP:
30 case MAGNETISM_EDGE_BOTTOM:
31 if (secondary == SECONDARY_MAGNETISM_EDGE_LEADING)
32 secondary_as_magnetism_edge = MAGNETISM_EDGE_LEFT;
33 else if (secondary == SECONDARY_MAGNETISM_EDGE_TRAILING)
34 secondary_as_magnetism_edge = MAGNETISM_EDGE_RIGHT;
35 else
36 NOTREACHED();
37 break;
38 case MAGNETISM_EDGE_LEFT:
39 case MAGNETISM_EDGE_RIGHT:
40 if (secondary == SECONDARY_MAGNETISM_EDGE_LEADING)
41 secondary_as_magnetism_edge = MAGNETISM_EDGE_TOP;
42 else if (secondary == SECONDARY_MAGNETISM_EDGE_TRAILING)
43 secondary_as_magnetism_edge = MAGNETISM_EDGE_BOTTOM;
44 else
45 NOTREACHED();
46 break;
47 }
48 return (edges & secondary_as_magnetism_edge) != 0;
49 }
50
51 } // namespace
52
53 // MagnetismEdgeMatcher --------------------------------------------------------
54
55 MagnetismEdgeMatcher::MagnetismEdgeMatcher(const gfx::Rect& bounds,
56 MagnetismEdge edge)
57 : bounds_(bounds), edge_(edge) {
58 ranges_.push_back(GetSecondaryRange(bounds_));
59 }
60
61 MagnetismEdgeMatcher::~MagnetismEdgeMatcher() {}
62
63 bool MagnetismEdgeMatcher::ShouldAttach(const gfx::Rect& bounds) {
64 if (is_edge_obscured())
65 return false;
66
67 if (IsCloseEnough(GetPrimaryCoordinate(bounds_, edge_),
68 GetPrimaryCoordinate(bounds, FlipEdge(edge_)))) {
69 const Range range(GetSecondaryRange(bounds));
70 Ranges::const_iterator i =
71 std::lower_bound(ranges_.begin(), ranges_.end(), range);
72 // Close enough, but only attach if some portion of the edge is visible.
73 if ((i != ranges_.begin() && RangesIntersect(*(i - 1), range)) ||
74 (i != ranges_.end() && RangesIntersect(*i, range))) {
75 return true;
76 }
77 }
78 // NOTE: this checks against the current bounds, we may want to allow some
79 // flexibility here.
80 const Range primary_range(GetPrimaryRange(bounds));
81 if (primary_range.first <= GetPrimaryCoordinate(bounds_, edge_) &&
82 primary_range.second >= GetPrimaryCoordinate(bounds_, edge_)) {
83 UpdateRanges(GetSecondaryRange(bounds));
84 }
85 return false;
86 }
87
88 void MagnetismEdgeMatcher::UpdateRanges(const Range& range) {
89 Ranges::const_iterator it =
90 std::lower_bound(ranges_.begin(), ranges_.end(), range);
91 if (it != ranges_.begin() && RangesIntersect(*(it - 1), range))
92 --it;
93 if (it == ranges_.end())
94 return;
95
96 for (size_t i = it - ranges_.begin();
97 i < ranges_.size() && RangesIntersect(ranges_[i], range);) {
98 if (range.first <= ranges_[i].first && range.second >= ranges_[i].second) {
99 ranges_.erase(ranges_.begin() + i);
100 } else if (range.first < ranges_[i].first) {
101 DCHECK_GT(range.second, ranges_[i].first);
102 ranges_[i] = Range(range.second, ranges_[i].second);
103 ++i;
104 } else {
105 Range existing(ranges_[i]);
106 ranges_[i].second = range.first;
107 ++i;
108 if (existing.second > range.second) {
109 ranges_.insert(ranges_.begin() + i,
110 Range(range.second, existing.second));
111 ++i;
112 }
113 }
114 }
115 }
116
117 // MagnetismMatcher ------------------------------------------------------------
118
119 // static
120 const int MagnetismMatcher::kMagneticDistance = 8;
121
122 MagnetismMatcher::MagnetismMatcher(const gfx::Rect& bounds, uint32_t edges)
123 : edges_(edges) {
124 if (edges & MAGNETISM_EDGE_TOP) {
125 matchers_.push_back(
126 base::MakeUnique<MagnetismEdgeMatcher>(bounds, MAGNETISM_EDGE_TOP));
127 }
128 if (edges & MAGNETISM_EDGE_LEFT) {
129 matchers_.push_back(
130 base::MakeUnique<MagnetismEdgeMatcher>(bounds, MAGNETISM_EDGE_LEFT));
131 }
132 if (edges & MAGNETISM_EDGE_BOTTOM) {
133 matchers_.push_back(
134 base::MakeUnique<MagnetismEdgeMatcher>(bounds, MAGNETISM_EDGE_BOTTOM));
135 }
136 if (edges & MAGNETISM_EDGE_RIGHT) {
137 matchers_.push_back(
138 base::MakeUnique<MagnetismEdgeMatcher>(bounds, MAGNETISM_EDGE_RIGHT));
139 }
140 }
141
142 MagnetismMatcher::~MagnetismMatcher() {}
143
144 bool MagnetismMatcher::ShouldAttach(const gfx::Rect& bounds,
145 MatchedEdge* edge) {
146 for (const auto& matcher : matchers_) {
147 if (matcher->ShouldAttach(bounds)) {
148 edge->primary_edge = matcher->edge();
149 AttachToSecondaryEdge(bounds, edge->primary_edge,
150 &(edge->secondary_edge));
151 return true;
152 }
153 }
154 return false;
155 }
156
157 bool MagnetismMatcher::AreEdgesObscured() const {
158 for (const auto& matcher : matchers_) {
159 if (!matcher->is_edge_obscured())
160 return false;
161 }
162 return true;
163 }
164
165 void MagnetismMatcher::AttachToSecondaryEdge(
166 const gfx::Rect& bounds,
167 MagnetismEdge edge,
168 SecondaryMagnetismEdge* secondary_edge) const {
169 const gfx::Rect& src_bounds(matchers_[0]->bounds());
170 if (edge == MAGNETISM_EDGE_LEFT || edge == MAGNETISM_EDGE_RIGHT) {
171 if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_LEADING, edges_) &&
172 IsCloseEnough(bounds.y(), src_bounds.y())) {
173 *secondary_edge = SECONDARY_MAGNETISM_EDGE_LEADING;
174 } else if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_TRAILING,
175 edges_) &&
176 IsCloseEnough(bounds.bottom(), src_bounds.bottom())) {
177 *secondary_edge = SECONDARY_MAGNETISM_EDGE_TRAILING;
178 } else {
179 *secondary_edge = SECONDARY_MAGNETISM_EDGE_NONE;
180 }
181 } else {
182 if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_LEADING, edges_) &&
183 IsCloseEnough(bounds.x(), src_bounds.x())) {
184 *secondary_edge = SECONDARY_MAGNETISM_EDGE_LEADING;
185 } else if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_TRAILING,
186 edges_) &&
187 IsCloseEnough(bounds.right(), src_bounds.right())) {
188 *secondary_edge = SECONDARY_MAGNETISM_EDGE_TRAILING;
189 } else {
190 *secondary_edge = SECONDARY_MAGNETISM_EDGE_NONE;
191 }
192 }
193 }
194
195 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/workspace/magnetism_matcher.h ('k') | ash/common/wm/workspace/multi_window_resize_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698