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

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

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

Powered by Google App Engine
This is Rietveld 408576698