Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: ash/wm/dialog_frame_view.cc

Issue 9187061: Preliminary implementation of Google-style dialogs in ash::internal::DialogFrameView (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/dialog_frame_view.h" 5 #include "ash/wm/dialog_frame_view.h"
6 6
7 #include "grit/ui_resources_standard.h"
7 #include "ui/base/hit_test.h" 8 #include "ui/base/hit_test.h"
9 #include "ui/base/resource/resource_bundle.h"
8 #include "ui/gfx/canvas.h" 10 #include "ui/gfx/canvas.h"
9 #include "ui/gfx/font.h" 11 #include "ui/gfx/font.h"
12 #include "ui/gfx/insets.h"
10 #include "ui/views/background.h" 13 #include "ui/views/background.h"
11 #include "ui/views/border.h" 14 #include "ui/views/border.h"
15 #include "ui/views/controls/button/image_button.h"
12 #include "ui/views/widget/widget.h" 16 #include "ui/views/widget/widget.h"
13 #include "ui/views/widget/widget_delegate.h" 17 #include "ui/views/widget/widget_delegate.h"
14 18
19 namespace {
20
21 // TODO(benrg): Make frame shadow and stroke agree with the spec.
22
23 // TODO(benrg): Title bar text should be #222, not black. Text in the client
24 // area should also be #222, but is currently usually black. Punting on this
25 // until the overhaul of color handling that will be happening Real Soon Now.
26 const SkColor kDialogTitleColor = SK_ColorBLACK;
27 const SkColor kDialogBackgroundColor = SK_ColorWHITE;
28
29 // Dialog-size-dependent padding values from the spec, in pixels.
30 const int kGoogleSmallDialogVPadding = 16;
31 const int kGoogleSmallDialogHPadding = 20;
32 const int kGoogleMediumDialogVPadding = 28;
33 const int kGoogleMediumDialogHPadding = 32;
34 const int kGoogleLargeDialogVPadding = 30;
35 const int kGoogleLargeDialogHPadding = 42;
36
37 // Dialog layouts themselves contain some padding, which should be ignored in
38 // favor of the padding values above. Currently we hack it by nudging the
39 // client area outward.
40 const int kDialogHPaddingNudge = 13;
41 const int kDialogTopPaddingNudge = 5;
42 const int kDialogBottomPaddingNudge = 10;
43
44 // TODO(benrg): There are no examples in the spec of close boxes on medium- or
45 // small-size dialogs, and the close button size is not factored into other
46 // sizing decisions. This value could cause problems with smaller dialogs.
47 const int kCloseButtonSize = 44;
48
49 } // namespace
50
15 namespace ash { 51 namespace ash {
16 namespace internal { 52 namespace internal {
17 53
18 // static 54 // static
19 const char DialogFrameView::kViewClassName[] = "ash/wm/DialogFrameView"; 55 const char DialogFrameView::kViewClassName[] = "ash/wm/DialogFrameView";
20 56
21 // static 57 // static
22 gfx::Font* DialogFrameView::title_font_ = NULL; 58 gfx::Font* DialogFrameView::title_font_ = NULL;
23 59
24 // TODO(benrg): tweak these values until they match Google-style.
25 // TODO(benrg): this may also mean tweaking the frame shadow opacity.
26 const SkColor kDialogBackgroundColor = SK_ColorWHITE;
27 // const SkColor kDialogBorderColor = SkColorSetRGB(0xCC, 0xCC, 0xCC);
28 const SkColor kDialogTitleColor = SK_ColorBLACK;
29
30 // TODO(benrg): Replace with width-based padding heuristic.
31 // |kDialogPadding| is the standardized padding amount, the specific per-side
32 // padding values are offset from this to achieve a uniform look with our
33 // existing code.
34 static int kDialogPadding = 30;
35 static int kDialogHPadding = kDialogPadding - 13;
36 static int kDialogTopPadding = kDialogPadding;
37 static int kDialogBottomPadding = kDialogPadding - 10;
38 static int kDialogContentVSpacing = 5;
39
40 const int kCloseButtonSize = 16;
41
42 //////////////////////////////////////////////////////////////////////////////// 60 ////////////////////////////////////////////////////////////////////////////////
43 // DialogFrameView, public: 61 // DialogFrameView, public:
44 62
45 DialogFrameView::DialogFrameView() { 63 DialogFrameView::DialogFrameView() {
46 set_background(views::Background::CreateSolidBackground( 64 set_background(views::Background::CreateSolidBackground(
47 kDialogBackgroundColor)); 65 kDialogBackgroundColor));
48 if (!title_font_) 66 if (!title_font_)
49 title_font_ = new gfx::Font(gfx::Font().DeriveFont(4, gfx::Font::NORMAL)); 67 title_font_ = new gfx::Font(gfx::Font().DeriveFont(4, gfx::Font::NORMAL));
68
69 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
70 close_button_ = new views::ImageButton(this);
71 close_button_->SetImage(views::CustomButton::BS_NORMAL,
72 rb.GetBitmapNamed(IDR_CLOSE_BAR));
73 close_button_->SetImage(views::CustomButton::BS_HOT,
74 rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
75 close_button_->SetImage(views::CustomButton::BS_PUSHED,
76 rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
77 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
78 views::ImageButton::ALIGN_MIDDLE);
79 AddChildView(close_button_);
50 } 80 }
51 81
52 DialogFrameView::~DialogFrameView() { 82 DialogFrameView::~DialogFrameView() {
53 } 83 }
54 84
55 //////////////////////////////////////////////////////////////////////////////// 85 ////////////////////////////////////////////////////////////////////////////////
56 // DialogFrameView, views::NonClientFrameView: 86 // DialogFrameView, views::NonClientFrameView:
57 87
58 gfx::Rect DialogFrameView::GetBoundsForClientView() const { 88 gfx::Rect DialogFrameView::GetBoundsForClientView() const {
59 gfx::Rect client_bounds = GetLocalBounds(); 89 gfx::Rect client_bounds = GetLocalBounds();
60 client_bounds.Inset(kDialogHPadding, GetNonClientTopHeight(), 90 client_bounds.Inset(GetClientInsets());
61 kDialogHPadding, kDialogBottomPadding);
62 return client_bounds; 91 return client_bounds;
63 } 92 }
64 93
65 gfx::Rect DialogFrameView::GetWindowBoundsForClientBounds( 94 gfx::Rect DialogFrameView::GetWindowBoundsForClientBounds(
66 const gfx::Rect& client_bounds) const { 95 const gfx::Rect& client_bounds) const {
67 gfx::Rect window_bounds = client_bounds; 96 gfx::Rect window_bounds = client_bounds;
68 window_bounds.Inset(-kDialogHPadding, -GetNonClientTopHeight(), 97 window_bounds.Inset(-GetClientInsets());
69 -kDialogHPadding, -kDialogBottomPadding);
70 return window_bounds; 98 return window_bounds;
71 } 99 }
72 100
73 int DialogFrameView::NonClientHitTest(const gfx::Point& point) { 101 int DialogFrameView::NonClientHitTest(const gfx::Point& point) {
74 if (close_button_rect_.Contains(point)) 102 if (close_button_->GetMirroredBounds().Contains(point))
75 return HTCLOSE; 103 return HTCLOSE;
76 return point.y() < GetNonClientTopHeight() ? HTCAPTION : HTCLIENT; 104 return point.y() < GetClientInsets().top() ? HTCAPTION : HTCLIENT;
77 } 105 }
78 106
79 void DialogFrameView::GetWindowMask(const gfx::Size& size, 107 void DialogFrameView::GetWindowMask(const gfx::Size& size,
80 gfx::Path* window_mask) { 108 gfx::Path* window_mask) {
81 // Nothing to do. 109 // Nothing to do.
82 } 110 }
83 111
84 void DialogFrameView::ResetWindowControls() { 112 void DialogFrameView::ResetWindowControls() {
85 // Nothing to do. 113 // Nothing to do.
86 } 114 }
87 115
88 void DialogFrameView::UpdateWindowIcon() { 116 void DialogFrameView::UpdateWindowIcon() {
89 // Nothing to do. 117 // Nothing to do.
90 } 118 }
91 119
92 //////////////////////////////////////////////////////////////////////////////// 120 ////////////////////////////////////////////////////////////////////////////////
93 // DialogFrameView, views::View overrides: 121 // DialogFrameView, views::View overrides:
94 122
95 std::string DialogFrameView::GetClassName() const { 123 std::string DialogFrameView::GetClassName() const {
96 return kViewClassName; 124 return kViewClassName;
97 } 125 }
98 126
99 void DialogFrameView::Layout() { 127 void DialogFrameView::Layout() {
100 title_display_rect_ = GetLocalBounds(); 128 title_display_rect_ = GetLocalBounds();
101 // TODO(benrg): size based on font height rather than bottom padding. 129 title_display_rect_.Inset(GetPaddingInsets());
102 close_button_rect_.SetRect(width() - kDialogPadding - kCloseButtonSize,
103 kDialogTopPadding, kCloseButtonSize,
104 kCloseButtonSize);
105 title_display_rect_.Inset(kDialogPadding, kDialogTopPadding,
106 kDialogPadding + kCloseButtonSize,
107 kDialogBottomPadding);
108 title_display_rect_.set_height(title_font_->GetHeight()); 130 title_display_rect_.set_height(title_font_->GetHeight());
131
132 // The hot rectangle for the close button is flush with the upper right of the
133 // dialog. The close button image is smaller, and is centered in the hot rect.
134 close_button_->SetBounds(
135 width() - kCloseButtonSize,
136 0, kCloseButtonSize, kCloseButtonSize);
109 } 137 }
110 138
111 void DialogFrameView::OnPaint(gfx::Canvas* canvas) { 139 void DialogFrameView::OnPaint(gfx::Canvas* canvas) {
112 views::View::OnPaint(canvas); 140 views::View::OnPaint(canvas);
113 canvas->FillRect(SK_ColorRED, close_button_rect_);
114 views::WidgetDelegate* delegate = GetWidget()->widget_delegate(); 141 views::WidgetDelegate* delegate = GetWidget()->widget_delegate();
115 if (!delegate) 142 if (!delegate)
116 return; 143 return;
117 canvas->DrawStringInt(delegate->GetWindowTitle(), *title_font_, 144 canvas->DrawStringInt(delegate->GetWindowTitle(), *title_font_,
118 kDialogTitleColor, title_display_rect_); 145 kDialogTitleColor, title_display_rect_);
119 } 146 }
120 147
121 // TODO(benrg): You may want to use a views::Button for the close box instead. 148 ////////////////////////////////////////////////////////////////////////////////
122 bool DialogFrameView::OnMousePressed(const views::MouseEvent& event) { 149 // DialogFrameView, views::ButtonListener overrides:
123 if (close_button_rect_.Contains(event.location())) 150
124 return true; 151 void DialogFrameView::ButtonPressed(views::Button* sender,
125 return View::OnMousePressed(event); 152 const views::Event& event) {
126 } 153 if (sender == close_button_)
127 void DialogFrameView::OnMouseReleased(const views::MouseEvent& event) {
128 if (close_button_rect_.Contains(event.location()))
129 GetWidget()->Close(); 154 GetWidget()->Close();
130 } 155 }
131 156
132 //////////////////////////////////////////////////////////////////////////////// 157 ////////////////////////////////////////////////////////////////////////////////
133 // DialogFrameView, private: 158 // DialogFrameView, private:
134 159
135 int DialogFrameView::GetNonClientTopHeight() const { 160 gfx::Insets DialogFrameView::GetPaddingInsets() const {
136 return kDialogTopPadding + title_font_->GetHeight() + kDialogContentVSpacing; 161 // These three discrete padding sizes come from the spec. If we ever wanted
162 // our Google-style dialogs to be resizable, we would probably need to
163 // smoothly interpolate the padding size instead.
164 int v_padding, h_padding;
165 if (width() <= 280) {
166 v_padding = kGoogleSmallDialogVPadding;
167 h_padding = kGoogleSmallDialogHPadding;
168 } else if (width() <= 480) {
169 v_padding = kGoogleMediumDialogVPadding;
170 h_padding = kGoogleMediumDialogHPadding;
171 } else {
172 v_padding = kGoogleLargeDialogVPadding;
173 h_padding = kGoogleLargeDialogHPadding;
174 }
175 return gfx::Insets(v_padding, h_padding, v_padding, h_padding);
176 }
177
178 gfx::Insets DialogFrameView::GetClientInsets() const {
179 gfx::Insets insets = GetPaddingInsets();
180 // The title should be separated from the client area by 1 em (dialog spec),
181 // and one em is equal to the font size (CSS spec).
182 insets += gfx::Insets(
183 title_font_->GetHeight() + title_font_->GetFontSize() -
184 kDialogTopPaddingNudge,
185 -kDialogHPaddingNudge,
186 -kDialogBottomPaddingNudge,
187 -kDialogHPaddingNudge);
188 return insets;
137 } 189 }
138 190
139 } // namespace internal 191 } // namespace internal
140 } // namespace views 192 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698