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

Side by Side Diff: ui/gfx/display_layout.cc

Issue 1813493002: COMPLETED PREVIEW Migrate to Display Placement (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gfxmove
Patch Set: Created 4 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
« no previous file with comments | « ui/gfx/display_layout.h ('k') | ui/gfx/display_layout_builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/display_layout.h" 5 #include "ui/gfx/display_layout.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "ui/gfx/display.h" 14 #include "ui/gfx/display.h"
15 #include "ui/gfx/geometry/insets.h"
15 16
16 namespace gfx { 17 namespace gfx {
17 namespace { 18 namespace {
18 19
19 // DisplayPlacement Positions 20 // DisplayPlacement Positions
20 const char kTop[] = "top"; 21 const char kTop[] = "top";
21 const char kRight[] = "right"; 22 const char kRight[] = "right";
22 const char kBottom[] = "bottom"; 23 const char kBottom[] = "bottom";
23 const char kLeft[] = "left"; 24 const char kLeft[] = "left";
24 const char kUnknown[] = "unknown"; 25 const char kUnknown[] = "unknown";
25 26
26 // The maximum value for 'offset' in DisplayLayout in case of outliers. Need 27 // The maximum value for 'offset' in DisplayLayout in case of outliers. Need
27 // to change this value in case to support even larger displays. 28 // to change this value in case to support even larger displays.
28 const int kMaxValidOffset = 10000; 29 const int kMaxValidOffset = 10000;
29 30
30 bool IsIdInList(int64_t id, const DisplayIdList& list) { 31 bool IsIdInList(int64_t id, const DisplayIdList& list) {
31 const auto iter = 32 const auto iter =
32 std::find_if(list.begin(), list.end(), 33 std::find_if(list.begin(), list.end(),
33 [id](int64_t display_id) { return display_id == id; }); 34 [id](int64_t display_id) { return display_id == id; });
34 return iter != list.end(); 35 return iter != list.end();
35 } 36 }
36 37
38 gfx::Display* FindDisplayById(DisplayList* display_list, int64_t id) {
39 auto iter = std::find_if(
40 display_list->begin(), display_list->end(),
41 [id](const gfx::Display& display) { return display.id() == id; });
42 return &(*iter);
43 }
44
37 } // namespace 45 } // namespace
38 46
39 //////////////////////////////////////////////////////////////////////////////// 47 ////////////////////////////////////////////////////////////////////////////////
40 // DisplayPlacement 48 // DisplayPlacement
41 49
42 DisplayPlacement::DisplayPlacement() 50 DisplayPlacement::DisplayPlacement()
43 : display_id(gfx::Display::kInvalidDisplayID), 51 : DisplayPlacement(gfx::Display::kInvalidDisplayID,
44 parent_display_id(gfx::Display::kInvalidDisplayID), 52 gfx::Display::kInvalidDisplayID,
45 position(DisplayPlacement::RIGHT), 53 DisplayPlacement::RIGHT,
46 offset(0) {} 54 0,
47 55 DisplayPlacement::TOP_LEFT) {}
48 DisplayPlacement::DisplayPlacement(const DisplayPlacement& placement)
49 : display_id(placement.display_id),
50 parent_display_id(placement.parent_display_id),
51 position(placement.position),
52 offset(placement.offset) {}
53 56
54 DisplayPlacement::DisplayPlacement(Position pos, int offset) 57 DisplayPlacement::DisplayPlacement(Position pos, int offset)
55 : display_id(gfx::Display::kInvalidDisplayID), 58 : DisplayPlacement(gfx::Display::kInvalidDisplayID,
56 parent_display_id(gfx::Display::kInvalidDisplayID), 59 gfx::Display::kInvalidDisplayID,
57 position(pos), 60 position,
58 offset(offset) { 61 offset,
62 DisplayPlacement::TOP_LEFT) {}
63
64 DisplayPlacement::DisplayPlacement(Position position,
65 int offset,
66 OffsetReference offset_reference)
67 : DisplayPlacement(gfx::Display::kInvalidDisplayID,
68 gfx::Display::kInvalidDisplayID,
69 position,
70 offset,
71 offset_reference) {}
72
73 DisplayPlacement::DisplayPlacement(int64_t display_id,
74 int64_t parent_display_id,
75 Position position,
76 int offset,
77 OffsetReference offset_reference)
78 : display_id(display_id),
79 parent_display_id(parent_display_id),
80 position(position),
81 offset(offset),
82 offset_reference(offset_reference) {
59 DCHECK_LE(TOP, position); 83 DCHECK_LE(TOP, position);
60 DCHECK_GE(LEFT, position); 84 DCHECK_GE(LEFT, position);
61 // Set the default value to |position| in case position is invalid. DCHECKs 85 // Set the default value to |position| in case position is invalid. DCHECKs
62 // above doesn't stop in Release builds. 86 // above doesn't stop in Release builds.
63 if (TOP > position || LEFT < position) 87 if (TOP > position || LEFT < position)
64 this->position = RIGHT; 88 this->position = RIGHT;
65 89
66 DCHECK_GE(kMaxValidOffset, abs(offset)); 90 DCHECK_GE(kMaxValidOffset, abs(offset));
67 } 91 }
68 92
93 DisplayPlacement::DisplayPlacement(const DisplayPlacement& placement)
94 : display_id(placement.display_id),
95 parent_display_id(placement.parent_display_id),
96 position(placement.position),
97 offset(placement.offset),
98 offset_reference(placement.offset_reference) {}
99
69 DisplayPlacement& DisplayPlacement::Swap() { 100 DisplayPlacement& DisplayPlacement::Swap() {
70 switch (position) { 101 switch (position) {
71 case TOP: 102 case TOP:
72 position = BOTTOM; 103 position = BOTTOM;
73 break; 104 break;
74 case BOTTOM: 105 case BOTTOM:
75 position = TOP; 106 position = TOP;
76 break; 107 break;
77 case RIGHT: 108 case RIGHT:
78 position = LEFT; 109 position = LEFT;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 //////////////////////////////////////////////////////////////////////////////// 174 ////////////////////////////////////////////////////////////////////////////////
144 // DisplayLayout 175 // DisplayLayout
145 176
146 DisplayLayout::DisplayLayout() 177 DisplayLayout::DisplayLayout()
147 : mirrored(false), 178 : mirrored(false),
148 default_unified(true), 179 default_unified(true),
149 primary_id(gfx::Display::kInvalidDisplayID) {} 180 primary_id(gfx::Display::kInvalidDisplayID) {}
150 181
151 DisplayLayout::~DisplayLayout() {} 182 DisplayLayout::~DisplayLayout() {}
152 183
184 void DisplayLayout::ApplyToDisplayList(
185 DisplayList* display_list,
186 std::vector<int64_t>* updated_ids,
187 int minimum_offset_overlap) const {
188 // Layout from primary, then dependent displays.
189 std::set<int64_t> parents;
190 parents.insert(primary_id);
191 while (parents.size()) {
192 int64_t parent_id = *parents.begin();
193 parents.erase(parent_id);
194 for (const DisplayPlacement* placement : placement_list) {
195 if (placement->parent_display_id == parent_id) {
196 if (ApplyDisplayPlacement(*placement,
197 display_list,
198 minimum_offset_overlap) &&
199 updated_ids)
200 updated_ids->push_back(placement->display_id);
201 parents.insert(placement->display_id);
202 }
203 }
204 }
205 }
206
207 bool DisplayLayout::ApplyDisplayPlacement(
208 const DisplayPlacement& placement,
209 DisplayList* display_list,
210 int minimum_offset_overlap) const {
211 const gfx::Display& parent_display =
212 *FindDisplayById(display_list, placement.parent_display_id);
213 DCHECK(parent_display.is_valid());
214 gfx::Display* target_display =
215 FindDisplayById(display_list, placement.display_id);
216 gfx::Rect old_bounds(target_display->bounds());
217 DCHECK(target_display);
218
219 const gfx::Rect& parent_bounds = parent_display.bounds();
220 const gfx::Rect& target_bounds = target_display->bounds();
221 gfx::Point new_target_origin = parent_bounds.origin();
222
223 DisplayPlacement::Position position = placement.position;
224
225 // Ignore the offset in case the target display doesn't share edges with
226 // the parent display.
227 int offset = placement.offset;
228 if (position == DisplayPlacement::TOP ||
229 position == DisplayPlacement::BOTTOM) {
230 if (placement.offset_reference == DisplayPlacement::BOTTOM_RIGHT)
231 offset += parent_bounds.width() - target_bounds.width();
232
233 offset = std::min(
234 offset, parent_bounds.width() - minimum_offset_overlap);
235 offset = std::max(
236 offset, -target_bounds.width() + minimum_offset_overlap);
237 } else {
238 if (placement.offset_reference == DisplayPlacement::BOTTOM_RIGHT)
239 offset += parent_bounds.height() - target_bounds.height();
240
241 offset = std::min(
242 offset, parent_bounds.height() - minimum_offset_overlap);
243 offset = std::max(
244 offset, -target_bounds.height() + minimum_offset_overlap);
245 }
246 switch (position) {
247 case DisplayPlacement::TOP:
248 new_target_origin.Offset(offset, -target_bounds.height());
249 break;
250 case DisplayPlacement::RIGHT:
251 new_target_origin.Offset(parent_bounds.width(), offset);
252 break;
253 case DisplayPlacement::BOTTOM:
254 new_target_origin.Offset(offset, parent_bounds.height());
255 break;
256 case DisplayPlacement::LEFT:
257 new_target_origin.Offset(-target_bounds.width(), offset);
258 break;
259 }
260
261 gfx::Insets insets = target_display->GetWorkAreaInsets();
262 target_display->set_bounds(
263 gfx::Rect(new_target_origin, target_bounds.size()));
264 target_display->UpdateWorkAreaFromInsets(insets);
265
266 return old_bounds != target_display->bounds();
267 }
268
153 // static 269 // static
154 bool DisplayLayout::Validate(const DisplayIdList& list, 270 bool DisplayLayout::Validate(const DisplayIdList& list,
155 const DisplayLayout& layout) { 271 const DisplayLayout& layout) {
156 // The primary display should be in the list. 272 // The primary display should be in the list.
157 DCHECK(IsIdInList(layout.primary_id, list)); 273 DCHECK(IsIdInList(layout.primary_id, list));
158 274
159 // Unified mode, or mirror mode switched from unified mode, 275 // Unified mode, or mirror mode switched from unified mode,
160 // may not have the placement yet. 276 // may not have the placement yet.
161 if (layout.placement_list.size() == 0u) 277 if (layout.placement_list.size() == 0u)
162 return true; 278 return true;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 int64_t display_id) const { 364 int64_t display_id) const {
249 const auto iter = 365 const auto iter =
250 std::find_if(placement_list.begin(), placement_list.end(), 366 std::find_if(placement_list.begin(), placement_list.end(),
251 [display_id](const DisplayPlacement* placement) { 367 [display_id](const DisplayPlacement* placement) {
252 return placement->display_id == display_id; 368 return placement->display_id == display_id;
253 }); 369 });
254 return (iter == placement_list.end()) ? nullptr : *iter; 370 return (iter == placement_list.end()) ? nullptr : *iter;
255 } 371 }
256 372
257 } // namespace gfx 373 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/display_layout.h ('k') | ui/gfx/display_layout_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698