| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/display/display_layout.h" |
| |
| #include "ash/display/display_pref_util.h" |
| #include "base/json/json_value_converter.h" |
| #include "base/logging.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_piece.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/values.h" |
| #include "ui/gfx/display.h" |
| |
| namespace ash { |
| 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; |
| |
| // Persistent key names |
| const char kPositionKey[] = "position"; |
| const char kOffsetKey[] = "offset"; |
| const char kMirroredKey[] = "mirrored"; |
| const char kPrimaryIdKey[] = "primary-id"; |
| |
| typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap; |
| |
| const PositionToStringMap* GetPositionToStringMap() { |
| static const PositionToStringMap* map = CreateToStringMap( |
| DisplayLayout::TOP, "top", |
| DisplayLayout::BOTTOM, "bottom", |
| DisplayLayout::RIGHT, "right", |
| DisplayLayout::LEFT, "left"); |
| return map; |
| } |
| |
| bool GetPositionFromString(const base::StringPiece& position, |
| DisplayLayout::Position* field) { |
| if (ReverseFind(GetPositionToStringMap(), position, field)) |
| return true; |
| LOG(ERROR) << "Invalid position value:" << position; |
| return false; |
| } |
| |
| std::string GetStringFromPosition(DisplayLayout::Position position) { |
| const PositionToStringMap* map = GetPositionToStringMap(); |
| PositionToStringMap::const_iterator iter = map->find(position); |
| return iter != map->end() ? iter->second : std::string("unknown"); |
| } |
| |
| bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) { |
| return base::StringToInt64(position, field); |
| } |
| |
| } // namespace |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // DisplayLayout |
| |
| // static |
| DisplayLayout DisplayLayout::FromInts(int position, int offsets) { |
| return DisplayLayout(static_cast<Position>(position), offsets); |
| } |
| |
| DisplayLayout::DisplayLayout() |
| : position(RIGHT), |
| offset(0), |
| mirrored(false), |
| primary_id(gfx::Display::kInvalidDisplayID) { |
| } |
| |
| DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) |
| : position(position), |
| offset(offset), |
| mirrored(false), |
| primary_id(gfx::Display::kInvalidDisplayID) { |
| DCHECK_LE(TOP, position); |
| DCHECK_GE(LEFT, position); |
| |
| // Set the default value to |position| in case position is invalid. DCHECKs |
| // above doesn't stop in Release builds. |
| if (TOP > position || LEFT < position) |
| this->position = RIGHT; |
| |
| DCHECK_GE(kMaxValidOffset, abs(offset)); |
| } |
| |
| DisplayLayout DisplayLayout::Invert() const { |
| Position inverted_position = RIGHT; |
| switch (position) { |
| case TOP: |
| inverted_position = BOTTOM; |
| break; |
| case BOTTOM: |
| inverted_position = TOP; |
| break; |
| case RIGHT: |
| inverted_position = LEFT; |
| break; |
| case LEFT: |
| inverted_position = RIGHT; |
| break; |
| } |
| DisplayLayout ret = DisplayLayout(inverted_position, -offset); |
| ret.primary_id = primary_id; |
| return ret; |
| } |
| |
| // static |
| bool DisplayLayout::ConvertFromValue(const base::Value& value, |
| DisplayLayout* layout) { |
| base::JSONValueConverter<DisplayLayout> converter; |
| return converter.Convert(value, layout); |
| } |
| |
| // static |
| bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, |
| base::Value* value) { |
| base::DictionaryValue* dict_value = NULL; |
| if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) |
| return false; |
| |
| const std::string position_str = GetStringFromPosition(layout.position); |
| dict_value->SetString(kPositionKey, position_str); |
| dict_value->SetInteger(kOffsetKey, layout.offset); |
| dict_value->SetBoolean(kMirroredKey, layout.mirrored); |
| dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); |
| return true; |
| } |
| |
| std::string DisplayLayout::ToString() const { |
| const std::string position_str = GetStringFromPosition(position); |
| return base::StringPrintf( |
| "%s, %d%s", |
| position_str.c_str(), offset, mirrored ? ", mirrored" : ""); |
| } |
| |
| // static |
| void DisplayLayout::RegisterJSONConverter( |
| base::JSONValueConverter<DisplayLayout>* converter) { |
| converter->RegisterCustomField<Position>( |
| kPositionKey, &DisplayLayout::position, &GetPositionFromString); |
| converter->RegisterIntField(kOffsetKey, &DisplayLayout::offset); |
| converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored); |
| converter->RegisterCustomField<int64>( |
| kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString); |
| } |
| |
| } // namespace ash |