| Index: ui/gfx/display_layout.cc
|
| diff --git a/ui/gfx/display_layout.cc b/ui/gfx/display_layout.cc
|
| index d42bf6e435b9c51be5e31b5a58b3aadd9e0fa170..9445452a70c83acdff729507b0655d8523741265 100644
|
| --- a/ui/gfx/display_layout.cc
|
| +++ b/ui/gfx/display_layout.cc
|
| @@ -12,6 +12,7 @@
|
| #include "base/strings/stringprintf.h"
|
| #include "base/values.h"
|
| #include "ui/gfx/display.h"
|
| +#include "ui/gfx/geometry/insets.h"
|
|
|
| namespace gfx {
|
| namespace {
|
| @@ -34,28 +35,51 @@ bool IsIdInList(int64_t id, const DisplayIdList& list) {
|
| return iter != list.end();
|
| }
|
|
|
| +gfx::Display* FindDisplayById(DisplayList* display_list, int64_t id) {
|
| + auto iter = std::find_if(
|
| + display_list->begin(), display_list->end(),
|
| + [id](const gfx::Display& display) { return display.id() == id; });
|
| + return &(*iter);
|
| +}
|
| +
|
| } // namespace
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // DisplayPlacement
|
|
|
| DisplayPlacement::DisplayPlacement()
|
| - : display_id(gfx::Display::kInvalidDisplayID),
|
| - parent_display_id(gfx::Display::kInvalidDisplayID),
|
| - position(DisplayPlacement::RIGHT),
|
| - offset(0) {}
|
| -
|
| -DisplayPlacement::DisplayPlacement(const DisplayPlacement& placement)
|
| - : display_id(placement.display_id),
|
| - parent_display_id(placement.parent_display_id),
|
| - position(placement.position),
|
| - offset(placement.offset) {}
|
| + : DisplayPlacement(gfx::Display::kInvalidDisplayID,
|
| + gfx::Display::kInvalidDisplayID,
|
| + DisplayPlacement::RIGHT,
|
| + 0,
|
| + DisplayPlacement::TOP_LEFT) {}
|
|
|
| DisplayPlacement::DisplayPlacement(Position pos, int offset)
|
| - : display_id(gfx::Display::kInvalidDisplayID),
|
| - parent_display_id(gfx::Display::kInvalidDisplayID),
|
| - position(pos),
|
| - offset(offset) {
|
| + : DisplayPlacement(gfx::Display::kInvalidDisplayID,
|
| + gfx::Display::kInvalidDisplayID,
|
| + position,
|
| + offset,
|
| + DisplayPlacement::TOP_LEFT) {}
|
| +
|
| +DisplayPlacement::DisplayPlacement(Position position,
|
| + int offset,
|
| + OffsetReference offset_reference)
|
| + : DisplayPlacement(gfx::Display::kInvalidDisplayID,
|
| + gfx::Display::kInvalidDisplayID,
|
| + position,
|
| + offset,
|
| + offset_reference) {}
|
| +
|
| +DisplayPlacement::DisplayPlacement(int64_t display_id,
|
| + int64_t parent_display_id,
|
| + Position position,
|
| + int offset,
|
| + OffsetReference offset_reference)
|
| + : display_id(display_id),
|
| + parent_display_id(parent_display_id),
|
| + position(position),
|
| + offset(offset),
|
| + offset_reference(offset_reference) {
|
| DCHECK_LE(TOP, position);
|
| DCHECK_GE(LEFT, position);
|
| // Set the default value to |position| in case position is invalid. DCHECKs
|
| @@ -66,6 +90,13 @@ DisplayPlacement::DisplayPlacement(Position pos, int offset)
|
| DCHECK_GE(kMaxValidOffset, abs(offset));
|
| }
|
|
|
| +DisplayPlacement::DisplayPlacement(const DisplayPlacement& placement)
|
| + : display_id(placement.display_id),
|
| + parent_display_id(placement.parent_display_id),
|
| + position(placement.position),
|
| + offset(placement.offset),
|
| + offset_reference(placement.offset_reference) {}
|
| +
|
| DisplayPlacement& DisplayPlacement::Swap() {
|
| switch (position) {
|
| case TOP:
|
| @@ -150,6 +181,91 @@ DisplayLayout::DisplayLayout()
|
|
|
| DisplayLayout::~DisplayLayout() {}
|
|
|
| +void DisplayLayout::ApplyToDisplayList(
|
| + DisplayList* display_list,
|
| + std::vector<int64_t>* updated_ids,
|
| + int minimum_offset_overlap) const {
|
| + // Layout from primary, then dependent displays.
|
| + std::set<int64_t> parents;
|
| + parents.insert(primary_id);
|
| + while (parents.size()) {
|
| + int64_t parent_id = *parents.begin();
|
| + parents.erase(parent_id);
|
| + for (const DisplayPlacement* placement : placement_list) {
|
| + if (placement->parent_display_id == parent_id) {
|
| + if (ApplyDisplayPlacement(*placement,
|
| + display_list,
|
| + minimum_offset_overlap) &&
|
| + updated_ids)
|
| + updated_ids->push_back(placement->display_id);
|
| + parents.insert(placement->display_id);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool DisplayLayout::ApplyDisplayPlacement(
|
| + const DisplayPlacement& placement,
|
| + DisplayList* display_list,
|
| + int minimum_offset_overlap) const {
|
| + const gfx::Display& parent_display =
|
| + *FindDisplayById(display_list, placement.parent_display_id);
|
| + DCHECK(parent_display.is_valid());
|
| + gfx::Display* target_display =
|
| + FindDisplayById(display_list, placement.display_id);
|
| + gfx::Rect old_bounds(target_display->bounds());
|
| + DCHECK(target_display);
|
| +
|
| + const gfx::Rect& parent_bounds = parent_display.bounds();
|
| + const gfx::Rect& target_bounds = target_display->bounds();
|
| + gfx::Point new_target_origin = parent_bounds.origin();
|
| +
|
| + DisplayPlacement::Position position = placement.position;
|
| +
|
| + // Ignore the offset in case the target display doesn't share edges with
|
| + // the parent display.
|
| + int offset = placement.offset;
|
| + if (position == DisplayPlacement::TOP ||
|
| + position == DisplayPlacement::BOTTOM) {
|
| + if (placement.offset_reference == DisplayPlacement::BOTTOM_RIGHT)
|
| + offset += parent_bounds.width() - target_bounds.width();
|
| +
|
| + offset = std::min(
|
| + offset, parent_bounds.width() - minimum_offset_overlap);
|
| + offset = std::max(
|
| + offset, -target_bounds.width() + minimum_offset_overlap);
|
| + } else {
|
| + if (placement.offset_reference == DisplayPlacement::BOTTOM_RIGHT)
|
| + offset += parent_bounds.height() - target_bounds.height();
|
| +
|
| + offset = std::min(
|
| + offset, parent_bounds.height() - minimum_offset_overlap);
|
| + offset = std::max(
|
| + offset, -target_bounds.height() + minimum_offset_overlap);
|
| + }
|
| + switch (position) {
|
| + case DisplayPlacement::TOP:
|
| + new_target_origin.Offset(offset, -target_bounds.height());
|
| + break;
|
| + case DisplayPlacement::RIGHT:
|
| + new_target_origin.Offset(parent_bounds.width(), offset);
|
| + break;
|
| + case DisplayPlacement::BOTTOM:
|
| + new_target_origin.Offset(offset, parent_bounds.height());
|
| + break;
|
| + case DisplayPlacement::LEFT:
|
| + new_target_origin.Offset(-target_bounds.width(), offset);
|
| + break;
|
| + }
|
| +
|
| + gfx::Insets insets = target_display->GetWorkAreaInsets();
|
| + target_display->set_bounds(
|
| + gfx::Rect(new_target_origin, target_bounds.size()));
|
| + target_display->UpdateWorkAreaFromInsets(insets);
|
| +
|
| + return old_bounds != target_display->bounds();
|
| +}
|
| +
|
| // static
|
| bool DisplayLayout::Validate(const DisplayIdList& list,
|
| const DisplayLayout& layout) {
|
|
|