1 // Copyright (c) 2013 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 "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h" 6 7 #include <string> 8 9 #include "ash/display/display_controller.h" 10 #include "ash/screen_util.h" 11 #include "ash/shell.h" 12 #include "base/bind.h" 13 #include "base/logging.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/values.h" 16 #include "chrome/browser/chromeos/display/overscan_calibrator.h" 17 #include "chrome/grit/generated_resources.h" 18 #include "content/public/browser/web_ui.h" 19 #include "ui/base/l10n/l10n_util.h" 20 #include "ui/gfx/display.h" 21 #include "ui/gfx/screen.h" 22 23 namespace chromeos { 24 namespace options { 25 namespace { 26 27 // The value for the orientation of overscan operations. 28 const char kOrientationHorizontal[] = "horizontal"; 29 const char kOrientationVertical[] = "vertical"; 30 31 } 32 33 DisplayOverscanHandler::DisplayOverscanHandler() { 34 ash::Shell::GetScreen()->AddObserver(this); 35 } 36 37 DisplayOverscanHandler::~DisplayOverscanHandler() { 38 ash::Shell::GetScreen()->RemoveObserver(this); 39 } 40 41 void DisplayOverscanHandler::GetLocalizedValues( 42 base::DictionaryValue* localized_strings) { 43 RegisterTitle(localized_strings, "displayOverscanPage", 44 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_TAB_TITLE); 45 localized_strings->SetString("shrinkAndExpand", l10n_util::GetStringUTF16( 46 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_SHRINK_EXPAND)); 47 localized_strings->SetString("move", l10n_util::GetStringUTF16( 48 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_MOVE)); 49 localized_strings->SetString("overscanReset", l10n_util::GetStringUTF16( 50 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_RESET_BUTTON_LABEL)); 51 localized_strings->SetString("overscanOK", l10n_util::GetStringUTF16( 52 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_OK_BUTTON_LABEL)); 53 localized_strings->SetString("overscanCancel", l10n_util::GetStringUTF16( 54 IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_CANCEL_BUTTON_LABEL)); 55 } 56 57 void DisplayOverscanHandler::RegisterMessages() { 58 web_ui()->RegisterMessageCallback( 59 "start", 60 base::Bind(&DisplayOverscanHandler::HandleStart, 61 base::Unretained(this))); 62 web_ui()->RegisterMessageCallback( 63 "commit", 64 base::Bind(&DisplayOverscanHandler::HandleCommit, 65 base::Unretained(this))); 66 web_ui()->RegisterMessageCallback( 67 "reset", 68 base::Bind(&DisplayOverscanHandler::HandleReset, 69 base::Unretained(this))); 70 web_ui()->RegisterMessageCallback( 71 "cancel", 72 base::Bind(&DisplayOverscanHandler::HandleCancel, 73 base::Unretained(this))); 74 web_ui()->RegisterMessageCallback( 75 "move", 76 base::Bind(&DisplayOverscanHandler::HandleMove, 77 base::Unretained(this))); 78 web_ui()->RegisterMessageCallback( 79 "resize", 80 base::Bind(&DisplayOverscanHandler::HandleResize, 81 base::Unretained(this))); 82 } 83 84 void DisplayOverscanHandler::OnDisplayAdded(const gfx::Display& new_display) { 85 if (!overscan_calibrator_) 86 return; 87 88 web_ui()->CallJavascriptFunction( 89 "options.DisplayOverscan.onOverscanCanceled"); 90 } 91 92 void DisplayOverscanHandler::OnDisplayRemoved(const gfx::Display& old_display) { 93 if (!overscan_calibrator_) 94 return; 95 96 web_ui()->CallJavascriptFunction( 97 "options.DisplayOverscan.onOverscanCanceled"); 98 } 99 100 void DisplayOverscanHandler::OnDisplayMetricsChanged(const gfx::Display&, 101 uint32_t) { 102 } 103 104 void DisplayOverscanHandler::HandleStart(const base::ListValue* args) { 105 int64 display_id = gfx::Display::kInvalidDisplayID; 106 std::string id_value; 107 if (!args->GetString(0, &id_value)) { 108 LOG(ERROR) << "Can't find ID"; 109 return; 110 } 111 112 if (!base::StringToInt64(id_value, &display_id) || 113 display_id == gfx::Display::kInvalidDisplayID) { 114 LOG(ERROR) << "Invalid parameter: " << id_value; 115 return; 116 } 117 118 const gfx::Display& display = ash::ScreenUtil::GetDisplayForId(display_id); 119 DCHECK(display.is_valid()); 120 if (!display.is_valid()) 121 return; 122 123 ash::DisplayController* display_controller = 124 ash::Shell::GetInstance()->display_controller(); 125 overscan_calibrator_.reset(new OverscanCalibrator( 126 display, 127 display_controller->GetOverscanInsets(display_id))); 128 } 129 130 void DisplayOverscanHandler::HandleCommit(const base::ListValue* unused_args) { 131 if (overscan_calibrator_.get()) { 132 overscan_calibrator_->Commit(); 133 overscan_calibrator_.reset(); 134 } 135 } 136 137 void DisplayOverscanHandler::HandleReset(const base::ListValue* unused_args) { 138 if (overscan_calibrator_.get()) 139 overscan_calibrator_->Reset(); 140 } 141 142 void DisplayOverscanHandler::HandleCancel(const base::ListValue* unused_args) { 143 overscan_calibrator_.reset(); 144 } 145 146 void DisplayOverscanHandler::HandleMove(const base::ListValue* args) { 147 std::string orientation; 148 double length; 149 if (!args->GetString(0, &orientation)) { 150 LOG(ERROR) << "The first argument must be orientation"; 151 return; 152 } 153 if (!args->GetDouble(1, &length)) { 154 LOG(ERROR) << "The second argument must be a numeric"; 155 return; 156 } 157 158 if (!overscan_calibrator_.get()) 159 return; 160 161 gfx::Insets insets = overscan_calibrator_->insets(); 162 if (orientation == kOrientationHorizontal) { 163 insets.Set(insets.top(), insets.left() + length, 164 insets.bottom(), insets.right() - length); 165 } else if (orientation == kOrientationVertical) { 166 insets.Set(insets.top() + length, insets.left(), 167 insets.bottom() - length, insets.right()); 168 } else { 169 LOG(ERROR) << "The orientation must be '" << kOrientationHorizontal 170 << "' or '" << kOrientationVertical << "': " 171 << orientation; 172 return; 173 } 174 overscan_calibrator_->UpdateInsets(insets); 175 } 176 177 void DisplayOverscanHandler::HandleResize(const base::ListValue* args) { 178 std::string orientation; 179 double length; 180 if (!args->GetString(0, &orientation)) { 181 LOG(ERROR) << "The first argument must be orientation"; 182 return; 183 } 184 if (!args->GetDouble(1, &length)) { 185 LOG(ERROR) << "The second argument must be a numeric"; 186 return; 187 } 188 189 if (!overscan_calibrator_.get()) 190 return; 191 192 gfx::Insets insets = overscan_calibrator_->insets(); 193 if (orientation == kOrientationHorizontal) { 194 insets.Set(insets.top(), insets.left() + length, 195 insets.bottom(), insets.right() + length); 196 } else if (orientation == kOrientationVertical) { 197 insets.Set(insets.top() + length, insets.left(), 198 insets.bottom() + length, insets.right()); 199 } else { 200 LOG(ERROR) << "The orientation must be '" << kOrientationHorizontal 201 << "' or '" << kOrientationVertical << "': " 202 << orientation; 203 return; 204 } 205 overscan_calibrator_->UpdateInsets(insets); 206 } 207 208 } // namespace options 209 } // namespace chromeos 210