Index: ash/display/display_controller.cc |
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc |
index 7954d44ac9e84e8d0762880499c8ca11290bd3fb..10d63455219f923fd1da87aa55a3aefe577eadd2 100644 |
--- a/ash/display/display_controller.cc |
+++ b/ash/display/display_controller.cc |
@@ -15,6 +15,9 @@ |
#include "ash/wm/property_util.h" |
#include "ash/wm/window_util.h" |
#include "base/command_line.h" |
+#include "base/json/json_value_converter.h" |
+#include "base/string_piece.h" |
+#include "base/values.h" |
#include "ui/aura/client/screen_position_client.h" |
#include "ui/aura/env.h" |
#include "ui/aura/root_window.h" |
@@ -27,16 +30,83 @@ namespace ash { |
namespace internal { |
namespace { |
+// The maximum value for 'offset' in DisplayLayout in case of outliers. Need |
+// to change this value in case to support even larger displays. |
+const int kMaxValidOffset = 10000; |
+ |
// The number of pixels to overlap between the primary and secondary displays, |
// in case that the offset value is too large. |
const int kMinimumOverlapForInvalidOffset = 50; |
+bool GetPositionFromString(const base::StringPiece& position, |
+ DisplayLayout::Position* field) { |
+ if (position == "top") { |
+ *field = DisplayLayout::TOP; |
+ return true; |
+ } else if (position == "bottom") { |
+ *field = DisplayLayout::BOTTOM; |
+ return true; |
+ } else if (position == "right") { |
+ *field = DisplayLayout::RIGHT; |
+ return true; |
+ } else if (position == "left") { |
+ *field = DisplayLayout::LEFT; |
+ return true; |
+ } |
+ LOG(ERROR) << "Invalid position value: " << position; |
+ |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+DisplayLayout::DisplayLayout() |
+ : position(RIGHT), offset(0) {} |
+ |
+DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) |
+ : position(position), offset(offset) { |
+ DCHECK_LE(TOP, position); |
+ DCHECK_GE(LEFT, position); |
+ |
+ if (TOP > position || LEFT < position) |
oshima
2012/08/29 00:10:44
Add comment why we're doing this.
Jun Mukai
2012/08/29 02:15:03
Done.
|
+ this->position = RIGHT; |
+ |
+ DCHECK_GE(kMaxValidOffset, offset); |
oshima
2012/08/29 00:10:44
DCHECK_GE(kMaxValidOffsetAbs, abs(offset))
Jun Mukai
2012/08/29 02:15:03
Done.
|
+} |
+ |
+void DisplayLayout::RegisterJSONConverter( |
+ base::JSONValueConverter<DisplayLayout>* converter) { |
+ converter->RegisterCustomField<Position>( |
+ "position", &DisplayLayout::position, &GetPositionFromString); |
+ converter->RegisterIntField("offset", &DisplayLayout::offset); |
+} |
+ |
+bool DisplayLayout::ConvertToValue(base::DictionaryValue* value) { |
+ std::string position_value; |
+ switch (position) { |
+ case TOP: |
+ position_value = "top"; |
+ break; |
+ case BOTTOM: |
+ position_value = "bottom"; |
+ break; |
+ case RIGHT: |
+ position_value = "right"; |
+ break; |
+ case LEFT: |
+ position_value = "left"; |
+ break; |
+ default: |
+ return false; |
+ } |
+ |
+ value->SetString("position", position_value); |
+ value->SetInteger("offset", offset); |
+ return true; |
} |
DisplayController::DisplayController() |
- : secondary_display_layout_(RIGHT), |
- secondary_display_offset_(0), |
- dont_warp_mouse_(false) { |
+ : dont_warp_mouse_(false) { |
aura::Env::GetInstance()->display_manager()->AddObserver(this); |
} |
@@ -128,17 +198,28 @@ DisplayController::GetAllRootWindowControllers() { |
return controllers; |
} |
-void DisplayController::SetSecondaryDisplayLayout( |
- SecondaryDisplayLayout layout) { |
- secondary_display_layout_ = layout; |
+void DisplayController::SetDefaultDisplayLayout(const DisplayLayout& layout) { |
+ default_display_layout_ = layout; |
UpdateDisplayBoundsForLayout(); |
} |
-void DisplayController::SetSecondaryDisplayOffset(int offset) { |
- secondary_display_offset_ = offset; |
+void DisplayController::SetLayoutForDisplayName(const std::string& name, |
+ const DisplayLayout& layout) { |
+ secondary_layouts_[name] = layout; |
UpdateDisplayBoundsForLayout(); |
} |
+const DisplayLayout& DisplayController::GetLayoutForDisplayName( |
+ const std::string& name) { |
+ std::map<std::string, DisplayLayout>::const_iterator it = |
+ secondary_layouts_.find(name); |
+ |
+ if (it != secondary_layouts_.end()) |
+ return it->second; |
+ else |
+ return default_display_layout_; |
oshima
2012/08/29 00:10:44
just return (no else)
Jun Mukai
2012/08/29 02:15:03
Done.
|
+} |
+ |
bool DisplayController::WarpMouseCursorIfNecessary( |
aura::RootWindow* current_root, |
const gfx::Point& point_in_root) { |
@@ -255,15 +336,22 @@ void DisplayController::UpdateDisplayBoundsForLayout() { |
aura::Env::GetInstance()->display_manager(); |
const gfx::Rect& primary_bounds = display_manager->GetDisplayAt(0)->bounds(); |
gfx::Display* secondary_display = display_manager->GetDisplayAt(1); |
+ const std::string& secondary_name = display_manager->GetDisplayNameAt(1); |
const gfx::Rect& secondary_bounds = secondary_display->bounds(); |
gfx::Point new_secondary_origin = primary_bounds.origin(); |
- // TODO(oshima|mukai): Implement more flexible layout. |
+ const DisplayLayout* layout = &default_display_layout_; |
+ std::map<std::string, DisplayLayout>::const_iterator iter = |
+ secondary_layouts_.find(secondary_name); |
+ if (iter != secondary_layouts_.end()) |
+ layout = &iter->second; |
+ |
+ DisplayLayout::Position position = layout->position; |
// Ignore the offset in case the secondary display doesn't share edges with |
// the primary display. |
- int offset = secondary_display_offset_; |
- if (secondary_display_layout_ == TOP || secondary_display_layout_ == BOTTOM) { |
+ int offset = layout->offset; |
+ if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { |
offset = std::min( |
offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); |
offset = std::max( |
@@ -274,17 +362,17 @@ void DisplayController::UpdateDisplayBoundsForLayout() { |
offset = std::max( |
offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); |
} |
- switch (secondary_display_layout_) { |
- case TOP: |
+ switch (position) { |
+ case DisplayLayout::TOP: |
new_secondary_origin.Offset(offset, -secondary_bounds.height()); |
break; |
- case RIGHT: |
+ case DisplayLayout::RIGHT: |
new_secondary_origin.Offset(primary_bounds.width(), offset); |
break; |
- case BOTTOM: |
+ case DisplayLayout::BOTTOM: |
new_secondary_origin.Offset(offset, primary_bounds.height()); |
break; |
- case LEFT: |
+ case DisplayLayout::LEFT: |
new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
break; |
} |