blob: 0e672d1d5a663fa52b87bcba1d99952219b0f8a4 [file] [log] [blame]
// Copyright (c) 2012 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/system/chromeos/tray_display.h"
#include "ash/display/display_controller.h"
#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_views.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/aura/display_manager.h"
#include "ui/aura/env.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#if defined(USE_X11)
#include "ui/base/x/x11_util.h"
#endif
namespace ash {
namespace internal {
class DisplayView : public ash::internal::ActionableView {
public:
explicit DisplayView(user::LoginStatus login_status)
: login_status_(login_status) {
SetLayoutManager(new
views::BoxLayout(views::BoxLayout::kHorizontal,
ash::kTrayPopupPaddingHorizontal, 0,
ash::kTrayPopupPaddingBetweenItems));
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
views::ImageView* image =
new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
image->SetImage(
bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia());
AddChildView(image);
label_ = new views::Label();
AddChildView(label_);
Update();
}
virtual ~DisplayView() {}
void Update() {
switch (Shell::GetInstance()->output_configurator()->output_state()) {
case chromeos::STATE_INVALID:
case chromeos::STATE_HEADLESS:
case chromeos::STATE_SINGLE:
SetVisible(false);
return;
case chromeos::STATE_DUAL_MIRROR: {
// Simply assumes that the primary display appears first and the
// secondary display appears next in the list.
std::vector<std::string> display_names;
#if defined(USE_X11)
std::vector<XID> output_ids;
ui::GetOutputDeviceHandles(&output_ids);
display_names = ui::GetDisplayNames(output_ids);
#endif
if (display_names.size() > 1) {
label_->SetText(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
UTF8ToUTF16(display_names[1])));
SetVisible(true);
} else {
SetVisible(false);
}
return;
}
case chromeos::STATE_DUAL_PRIMARY_ONLY:
case chromeos::STATE_DUAL_SECONDARY_ONLY: {
aura::DisplayManager* display_manager =
aura::Env::GetInstance()->display_manager();
if (display_manager->GetNumDisplays() > 1) {
label_->SetText(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
UTF8ToUTF16(display_manager->GetDisplayNameFor(
ScreenAsh::GetSecondaryDisplay()))));
SetVisible(true);
} else {
SetVisible(false);
}
return;
}
default:
NOTREACHED();
}
}
private:
// Overridden from ActionableView.
virtual bool PerformAction(const ui::Event& event) OVERRIDE {
if (login_status_ == ash::user::LOGGED_IN_USER ||
login_status_ == ash::user::LOGGED_IN_OWNER ||
login_status_ == ash::user::LOGGED_IN_GUEST) {
ash::Shell::GetInstance()->tray_delegate()->ShowDisplaySettings();
}
return true;
}
user::LoginStatus login_status_;
views::Label* label_;
DISALLOW_COPY_AND_ASSIGN(DisplayView);
};
TrayDisplay::TrayDisplay()
: default_(NULL) {
aura::Env::GetInstance()->display_manager()->AddObserver(this);
ash::Shell::GetInstance()->output_configurator()->AddObserver(this);
}
TrayDisplay::~TrayDisplay() {
aura::Env::GetInstance()->display_manager()->RemoveObserver(this);
ash::Shell::GetInstance()->output_configurator()->RemoveObserver(this);
}
views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) {
default_ = new DisplayView(status);
return default_;
}
void TrayDisplay::DestroyDefaultView() {
default_ = NULL;
}
void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) {
if (default_)
default_->Update();
}
void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) {
if (default_)
default_->Update();
}
void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) {
if (default_)
default_->Update();
}
void TrayDisplay::OnDisplayModeChanged() {
if (default_)
default_->Update();
}
} // namespace internal
} // namespace ash