Home | History | Annotate | Download | only in frame
      1 // Copyright (c) 2011 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/chromeos/frame/bubble_frame_view.h"
      6 
      7 #include "chrome/browser/chromeos/frame/bubble_window.h"
      8 #include "chrome/browser/chromeos/login/helper.h"
      9 #include "chrome/browser/ui/views/bubble/bubble_border.h"
     10 #include "grit/theme_resources.h"
     11 #include "ui/base/resource/resource_bundle.h"
     12 #include "ui/gfx/canvas_skia.h"
     13 #include "ui/gfx/font.h"
     14 #include "ui/gfx/insets.h"
     15 #include "ui/gfx/path.h"
     16 #include "ui/gfx/rect.h"
     17 #include "views/controls/button/image_button.h"
     18 #include "views/controls/label.h"
     19 #include "views/controls/throbber.h"
     20 #include "views/window/hit_test.h"
     21 #include "views/window/window.h"
     22 #include "views/window/window_delegate.h"
     23 #include "third_party/skia/include/core/SkPaint.h"
     24 
     25 namespace {
     26 
     27 static const int kTitleTopPadding = 10;
     28 static const int kTitleContentPadding = 10;
     29 static const int kHorizontalPadding = 10;
     30 
     31 // Title font size correction.
     32 #if defined(CROS_FONTS_USING_BCI)
     33 static const int kTitleFontSizeDelta = 0;
     34 #else
     35 static const int kTitleFontSizeDelta = 1;
     36 #endif
     37 
     38 }  // namespace
     39 
     40 namespace chromeos {
     41 
     42 BubbleFrameView::BubbleFrameView(views::Window* frame,
     43                                  BubbleWindow::Style style)
     44     : frame_(frame),
     45       style_(style),
     46       title_(NULL),
     47       close_button_(NULL),
     48       throbber_(NULL) {
     49   set_border(new BubbleBorder(BubbleBorder::NONE));
     50 
     51   if (frame_->window_delegate()->ShouldShowWindowTitle()) {
     52     title_ = new views::Label(frame_->window_delegate()->GetWindowTitle());
     53     title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     54     title_->SetFont(title_->font().DeriveFont(kFontSizeCorrectionDelta,
     55                                               gfx::Font::BOLD));
     56     AddChildView(title_);
     57   }
     58 
     59   if (style_ & BubbleWindow::STYLE_XBAR) {
     60     ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     61     close_button_ = new views::ImageButton(this);
     62     close_button_->SetImage(views::CustomButton::BS_NORMAL,
     63         rb.GetBitmapNamed(IDR_CLOSE_BAR));
     64     close_button_->SetImage(views::CustomButton::BS_HOT,
     65         rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
     66     close_button_->SetImage(views::CustomButton::BS_PUSHED,
     67         rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
     68     AddChildView(close_button_);
     69   }
     70 
     71   if (style_ & BubbleWindow::STYLE_THROBBER) {
     72     throbber_ = CreateDefaultSmoothedThrobber();
     73     AddChildView(throbber_);
     74   }
     75 }
     76 
     77 BubbleFrameView::~BubbleFrameView() {
     78 }
     79 
     80 void BubbleFrameView::StartThrobber() {
     81   DCHECK(throbber_ != NULL);
     82   if (title_)
     83     title_->SetText(std::wstring());
     84   throbber_->Start();
     85 }
     86 
     87 void BubbleFrameView::StopThrobber() {
     88   DCHECK(throbber_ != NULL);
     89   throbber_->Stop();
     90   if (title_)
     91     title_->SetText(frame_->window_delegate()->GetWindowTitle());
     92 }
     93 
     94 gfx::Rect BubbleFrameView::GetBoundsForClientView() const {
     95   return client_view_bounds_;
     96 }
     97 
     98 gfx::Rect BubbleFrameView::GetWindowBoundsForClientBounds(
     99     const gfx::Rect& client_bounds) const {
    100   gfx::Insets insets = GetInsets();
    101 
    102   gfx::Size title_size;
    103   if (title_)
    104     title_size = title_->GetPreferredSize();
    105   gfx::Size close_button_size;
    106   if (close_button_)
    107     close_button_size = close_button_->GetPreferredSize();
    108   gfx::Size throbber_size;
    109   if (throbber_)
    110     throbber_size = throbber_->GetPreferredSize();
    111 
    112   int top_height = insets.top();
    113   if (title_size.height() > 0 ||
    114       close_button_size.height() > 0 ||
    115       throbber_size.height() > 0) {
    116     top_height += kTitleContentPadding + std::max(
    117         std::max(title_size.height(), close_button_size.height()),
    118         throbber_size.height());
    119   }
    120   return gfx::Rect(std::max(0, client_bounds.x() - insets.left()),
    121                    std::max(0, client_bounds.y() - top_height),
    122                    client_bounds.width() + insets.width(),
    123                    client_bounds.height() + top_height + insets.bottom());
    124 }
    125 
    126 int BubbleFrameView::NonClientHitTest(const gfx::Point& point) {
    127   return HTNOWHERE;
    128 }
    129 
    130 void BubbleFrameView::GetWindowMask(const gfx::Size& size,
    131                                     gfx::Path* window_mask) {
    132 }
    133 
    134 void BubbleFrameView::EnableClose(bool enable) {
    135 }
    136 
    137 void BubbleFrameView::ResetWindowControls() {
    138 }
    139 
    140 void BubbleFrameView::UpdateWindowIcon() {
    141 }
    142 
    143 gfx::Insets BubbleFrameView::GetInsets() const {
    144   gfx::Insets border_insets;
    145   border()->GetInsets(&border_insets);
    146 
    147   gfx::Insets insets(kTitleTopPadding,
    148                      kHorizontalPadding,
    149                      0,
    150                      kHorizontalPadding);
    151   insets += border_insets;
    152   return insets;
    153 }
    154 
    155 gfx::Size BubbleFrameView::GetPreferredSize() {
    156   gfx::Size pref = frame_->client_view()->GetPreferredSize();
    157   gfx::Rect bounds(0, 0, pref.width(), pref.height());
    158   return frame_->non_client_view()->GetWindowBoundsForClientBounds(
    159       bounds).size();
    160 }
    161 
    162 void BubbleFrameView::Layout() {
    163   gfx::Insets insets = GetInsets();
    164 
    165   gfx::Size title_size;
    166   if (title_)
    167     title_size = title_->GetPreferredSize();
    168   gfx::Size close_button_size;
    169   if (close_button_)
    170     close_button_size = close_button_->GetPreferredSize();
    171   gfx::Size throbber_size;
    172   if (throbber_)
    173     throbber_size = throbber_->GetPreferredSize();
    174 
    175   if (title_) {
    176     title_->SetBounds(
    177         insets.left(), insets.top(),
    178         std::max(0, width() - insets.width() - close_button_size.width()),
    179         title_size.height());
    180   }
    181 
    182   if (close_button_) {
    183     close_button_->SetBounds(
    184         width() - insets.right() - close_button_size.width(), insets.top(),
    185         close_button_size.width(), close_button_size.height());
    186   }
    187 
    188   if (throbber_) {
    189     throbber_->SetBounds(
    190         insets.left(), insets.top(),
    191         std::min(throbber_size.width(), width()),
    192         throbber_size.height());
    193   }
    194 
    195   int top_height = insets.top();
    196   if (title_size.height() > 0 ||
    197       close_button_size.height() > 0 ||
    198       throbber_size.height() > 0) {
    199     top_height += kTitleContentPadding + std::max(
    200         std::max(title_size.height(), close_button_size.height()),
    201         throbber_size.height());
    202   }
    203   client_view_bounds_.SetRect(insets.left(), top_height,
    204       std::max(0, width() - insets.width()),
    205       std::max(0, height() - top_height - insets.bottom()));
    206 }
    207 
    208 void BubbleFrameView::OnPaint(gfx::Canvas* canvas) {
    209   // The border of this view creates an anti-aliased round-rect region for the
    210   // contents, which we need to fill with the background color.
    211   SkPaint paint;
    212   paint.setAntiAlias(true);
    213   paint.setStyle(SkPaint::kFill_Style);
    214   paint.setColor(BubbleWindow::kBackgroundColor);
    215   gfx::Path path;
    216   gfx::Rect bounds(GetContentsBounds());
    217   SkRect rect;
    218   rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()),
    219            SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom()));
    220   SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius());
    221   path.addRoundRect(rect, radius, radius);
    222   canvas->AsCanvasSkia()->drawPath(path, paint);
    223 
    224   OnPaintBorder(canvas);
    225 }
    226 
    227 void BubbleFrameView::ButtonPressed(views::Button* sender,
    228                                     const views::Event& event) {
    229   if (close_button_ != NULL && sender == close_button_)
    230     frame_->CloseWindow();
    231 }
    232 
    233 }  // namespace chromeos
    234