bubble_frame_view.cc revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 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 "app/resource_bundle.h" 8#include "gfx/canvas_skia.h" 9#include "gfx/font.h" 10#include "gfx/insets.h" 11#include "gfx/path.h" 12#include "gfx/rect.h" 13#include "chrome/browser/chromeos/frame/bubble_window.h" 14#include "chrome/browser/views/bubble_border.h" 15#include "grit/theme_resources.h" 16#include "views/controls/button/image_button.h" 17#include "views/controls/label.h" 18#include "views/window/hit_test.h" 19#include "views/window/window.h" 20#include "views/window/window_delegate.h" 21#include "third_party/skia/include/core/SkPaint.h" 22 23namespace { 24 25static const int kTitleTopPadding = 10; 26static const int kTitleContentPadding = 10; 27static const int kHorizontalPadding = 10; 28 29} // namespace 30 31namespace chromeos { 32 33BubbleFrameView::BubbleFrameView(views::Window* frame, 34 BubbleWindow::Style style) 35 : frame_(frame), 36 style_(style), 37 title_(NULL), 38 close_button_(NULL) { 39 set_border(new BubbleBorder(BubbleBorder::NONE)); 40 41 if (frame_->GetDelegate()->ShouldShowWindowTitle()) { 42 title_ = new views::Label(frame_->GetDelegate()->GetWindowTitle()); 43 title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 44 title_->SetFont(title_->font().DeriveFont(1, gfx::Font::BOLD)); 45 AddChildView(title_); 46 } 47 48 if (style_ & BubbleWindow::STYLE_XBAR) { 49 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 50 close_button_ = new views::ImageButton(this); 51 close_button_->SetImage(views::CustomButton::BS_NORMAL, 52 rb.GetBitmapNamed(IDR_CLOSE_BAR)); 53 close_button_->SetImage(views::CustomButton::BS_HOT, 54 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); 55 close_button_->SetImage(views::CustomButton::BS_PUSHED, 56 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); 57 AddChildView(close_button_); 58 } 59} 60 61BubbleFrameView::~BubbleFrameView() { 62} 63 64gfx::Rect BubbleFrameView::GetBoundsForClientView() const { 65 return client_view_bounds_; 66} 67 68gfx::Rect BubbleFrameView::GetWindowBoundsForClientBounds( 69 const gfx::Rect& client_bounds) const { 70 gfx::Insets insets = GetInsets(); 71 gfx::Size title_size; 72 if (title_) { 73 title_size = title_->GetPreferredSize(); 74 } 75 76 gfx::Size close_button_size = gfx::Size(); 77 if (close_button_) { 78 close_button_size = close_button_->GetPreferredSize(); 79 } 80 81 int top_height = insets.top(); 82 if (title_size.height() > 0 || close_button_size.height() > 0) 83 top_height += std::max(title_size.height(), close_button_size.height()) + 84 kTitleContentPadding; 85 return gfx::Rect(std::max(0, client_bounds.x() - insets.left()), 86 std::max(0, client_bounds.y() - top_height), 87 client_bounds.width() + insets.width(), 88 client_bounds.height() + top_height + insets.bottom()); 89} 90 91int BubbleFrameView::NonClientHitTest(const gfx::Point& point) { 92 return HTNOWHERE; 93} 94 95void BubbleFrameView::GetWindowMask(const gfx::Size& size, 96 gfx::Path* window_mask) { 97} 98 99void BubbleFrameView::EnableClose(bool enable) { 100} 101 102void BubbleFrameView::ResetWindowControls() { 103} 104 105gfx::Insets BubbleFrameView::GetInsets() const { 106 gfx::Insets border_insets; 107 border()->GetInsets(&border_insets); 108 109 gfx::Insets insets(kTitleTopPadding, 110 kHorizontalPadding, 111 0, 112 kHorizontalPadding); 113 insets += border_insets; 114 return insets; 115} 116 117gfx::Size BubbleFrameView::GetPreferredSize() { 118 gfx::Size pref = frame_->GetClientView()->GetPreferredSize(); 119 gfx::Rect bounds(0, 0, pref.width(), pref.height()); 120 return frame_->GetNonClientView()->GetWindowBoundsForClientBounds( 121 bounds).size(); 122} 123 124void BubbleFrameView::Layout() { 125 gfx::Insets insets = GetInsets(); 126 127 gfx::Size title_size; 128 if (title_) { 129 title_size = title_->GetPreferredSize(); 130 } 131 132 gfx::Size close_button_size = gfx::Size(); 133 if (close_button_) { 134 close_button_size = close_button_->GetPreferredSize(); 135 } 136 137 if (title_) { 138 title_->SetBounds( 139 insets.left(), insets.top(), 140 std::max(0, width() - insets.width() - close_button_size.width()), 141 title_size.height()); 142 } 143 144 if (close_button_) { 145 close_button_->SetBounds( 146 width() - insets.right() - close_button_size.width(), insets.top(), 147 close_button_size.width(), close_button_size.height()); 148 } 149 150 int top_height = insets.top(); 151 if (title_size.height() > 0 || close_button_size.height() > 0) 152 top_height += std::max(title_size.height(), close_button_size.height()) + 153 kTitleContentPadding; 154 client_view_bounds_.SetRect(insets.left(), top_height, 155 std::max(0, width() - insets.width()), 156 std::max(0, height() - top_height - insets.bottom())); 157} 158 159void BubbleFrameView::Paint(gfx::Canvas* canvas) { 160 // The border of this view creates an anti-aliased round-rect region for the 161 // contents, which we need to fill with the background color. 162 SkPaint paint; 163 paint.setAntiAlias(true); 164 paint.setStyle(SkPaint::kFill_Style); 165 paint.setColor(BubbleWindow::kBackgroundColor); 166 gfx::Path path; 167 gfx::Rect bounds(GetLocalBounds(false)); 168 SkRect rect; 169 rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), 170 SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom())); 171 SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); 172 path.addRoundRect(rect, radius, radius); 173 canvas->AsCanvasSkia()->drawPath(path, paint); 174 175 PaintBorder(canvas); 176} 177 178void BubbleFrameView::ButtonPressed(views::Button* sender, 179 const views::Event& event) { 180 if (close_button_ != NULL && sender == close_button_) { 181 frame_->Close(); 182 } 183} 184 185} // namespace chromeos 186