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

Side by Side Diff: chrome/browser/views/constrained_window_win.cc

Issue 132047: GTK: HTTP Auth dialogs under linux. (Closed)
Patch Set: Fix for evanm Created 11 years, 6 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
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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/views/constrained_window_win.h"
6
7 #include "app/gfx/canvas.h"
8 #include "app/gfx/font.h"
9 #include "app/gfx/path.h"
10 #include "app/gfx/text_elider.h"
11 #include "app/l10n_util.h"
12 #include "app/resource_bundle.h"
13 #include "app/win_util.h"
14 #include "base/gfx/rect.h"
15 #include "chrome/app/chrome_dll_resource.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/profile.h"
18 #include "chrome/browser/tab_contents/tab_contents.h"
19 #include "chrome/browser/tab_contents/tab_contents_view.h"
20 #include "chrome/browser/toolbar_model.h"
21 #include "chrome/browser/views/frame/browser_view.h"
22 #include "chrome/browser/window_sizer.h"
23 #include "chrome/common/chrome_constants.h"
24 #include "chrome/common/notification_service.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/pref_service.h"
27 #include "grit/app_resources.h"
28 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h"
30 #include "grit/theme_resources.h"
31 #include "net/base/net_util.h"
32 #include "views/controls/button/image_button.h"
33 #include "views/focus/focus_manager.h"
34 #include "views/window/client_view.h"
35 #include "views/window/non_client_view.h"
36 #include "views/window/window_resources.h"
37
38 using base::TimeDelta;
39
40 namespace views {
41 class ClientView;
42 }
43
44 // An enumeration of bitmap resources used by this window.
45 enum {
46 FRAME_PART_BITMAP_FIRST = 0, // Must be first.
47
48 // Window Controls.
49 FRAME_CLOSE_BUTTON_ICON,
50 FRAME_CLOSE_BUTTON_ICON_H,
51 FRAME_CLOSE_BUTTON_ICON_P,
52
53 // Window Frame Border.
54 FRAME_BOTTOM_EDGE,
55 FRAME_BOTTOM_LEFT_CORNER,
56 FRAME_BOTTOM_RIGHT_CORNER,
57 FRAME_LEFT_EDGE,
58 FRAME_RIGHT_EDGE,
59 FRAME_TOP_EDGE,
60 FRAME_TOP_LEFT_CORNER,
61 FRAME_TOP_RIGHT_CORNER,
62
63 FRAME_WINDOW,
64 FRAME_WINDOW_INACTIVE,
65 FRAME_WINDOW_INCOGNITO,
66 FRAME_WINDOW_INCOGNITO_INACTIVE,
67
68 FRAME_PART_BITMAP_COUNT // Must be last.
69 };
70
71 static const int kXPFramePartIDs[] = {
72 0,
73 IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
74 IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER,
75 IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE,
76 IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER,
77 IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER,
78 IDR_THEME_FRAME, IDR_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INCOGNITO,
79 IDR_THEME_FRAME_INCOGNITO_INACTIVE,
80 0 };
81 static const int kVistaFramePartIDs[] = {
82 0,
83 IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
84 IDR_CONSTRAINED_BOTTOM_CENTER_V, IDR_CONSTRAINED_BOTTOM_LEFT_CORNER_V,
85 IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER_V, IDR_CONSTRAINED_LEFT_SIDE_V,
86 IDR_CONSTRAINED_RIGHT_SIDE_V, IDR_CONSTRAINED_TOP_CENTER_V,
87 IDR_CONSTRAINED_TOP_LEFT_CORNER_V, IDR_CONSTRAINED_TOP_RIGHT_CORNER_V,
88 IDR_THEME_FRAME, IDR_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INCOGNITO,
89 IDR_THEME_FRAME_INCOGNITO_INACTIVE,
90 0 };
91
92 class XPWindowResources : public views::WindowResources {
93 public:
94 XPWindowResources() {
95 InitClass();
96 }
97 virtual ~XPWindowResources() {}
98
99 virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const {
100 return bitmaps_[part_id];
101 }
102
103 private:
104 static void InitClass() {
105 static bool initialized = false;
106 if (!initialized) {
107 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
108 for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
109 int id = kXPFramePartIDs[i];
110 if (id != 0)
111 bitmaps_[i] = rb.GetBitmapNamed(id);
112 }
113 initialized = true;
114 }
115 }
116
117 static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT];
118
119 DISALLOW_EVIL_CONSTRUCTORS(XPWindowResources);
120 };
121
122 class VistaWindowResources : public views::WindowResources {
123 public:
124 VistaWindowResources() {
125 InitClass();
126 }
127 virtual ~VistaWindowResources() {}
128
129 virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const {
130 return bitmaps_[part_id];
131 }
132
133 private:
134 static void InitClass() {
135 static bool initialized = false;
136 if (!initialized) {
137 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
138 for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
139 int id = kVistaFramePartIDs[i];
140 if (id != 0)
141 bitmaps_[i] = rb.GetBitmapNamed(id);
142 }
143 initialized = true;
144 }
145 }
146
147 static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT];
148
149 DISALLOW_EVIL_CONSTRUCTORS(VistaWindowResources);
150 };
151
152 SkBitmap* XPWindowResources::bitmaps_[];
153 SkBitmap* VistaWindowResources::bitmaps_[];
154
155 ////////////////////////////////////////////////////////////////////////////////
156 // ConstrainedWindowFrameView
157
158 class ConstrainedWindowFrameView
159 : public views::NonClientFrameView,
160 public views::ButtonListener {
161 public:
162 explicit ConstrainedWindowFrameView(ConstrainedWindowWin* container);
163 virtual ~ConstrainedWindowFrameView();
164
165 void UpdateWindowTitle();
166
167 // Overridden from views::NonClientFrameView:
168 virtual gfx::Rect GetBoundsForClientView() const;
169 virtual bool AlwaysUseCustomFrame() const;
170 virtual gfx::Rect GetWindowBoundsForClientBounds(
171 const gfx::Rect& client_bounds) const;
172 virtual gfx::Point GetSystemMenuPoint() const;
173 virtual int NonClientHitTest(const gfx::Point& point);
174 virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
175 virtual void EnableClose(bool enable);
176 virtual void ResetWindowControls() { }
177
178 // Overridden from views::View:
179 virtual void Paint(gfx::Canvas* canvas);
180 virtual void Layout();
181 virtual void ThemeChanged();
182
183 // Overridden from views::ButtonListener:
184 virtual void ButtonPressed(views::Button* sender);
185
186 private:
187 // Returns the thickness of the border that makes up the window frame edges.
188 // This does not include any client edge.
189 int FrameBorderThickness() const;
190
191 // Returns the thickness of the entire nonclient left, right, and bottom
192 // borders, including both the window frame and any client edge.
193 int NonClientBorderThickness() const;
194
195 // Returns the height of the entire nonclient top border, including the window
196 // frame, any title area, and any connected client edge.
197 int NonClientTopBorderHeight() const;
198
199 // Calculates multiple values related to title layout. Returns the height of
200 // the entire titlebar including any connected client edge.
201 int TitleCoordinates(int* title_top_spacing,
202 int* title_thickness) const;
203
204 // Paints different parts of the window to the incoming canvas.
205 void PaintFrameBorder(gfx::Canvas* canvas);
206 void PaintTitleBar(gfx::Canvas* canvas);
207 void PaintClientEdge(gfx::Canvas* canvas);
208
209 // Layout various sub-components of this view.
210 void LayoutWindowControls();
211 void LayoutTitleBar();
212 void LayoutClientView();
213
214 // Returns the bounds of the client area for the specified view size.
215 gfx::Rect CalculateClientAreaBounds(int width, int height) const;
216
217 SkColor GetTitleColor() const {
218 return (container_->owner()->profile()->IsOffTheRecord() ||
219 !win_util::ShouldUseVistaFrame()) ? SK_ColorWHITE : SK_ColorBLACK;
220 }
221
222 // Loads the appropriate set of WindowResources for the frame view.
223 void InitWindowResources();
224
225 ConstrainedWindowWin* container_;
226
227 scoped_ptr<views::WindowResources> resources_;
228
229 gfx::Rect title_bounds_;
230
231 views::ImageButton* close_button_;
232
233 // The bounds of the ClientView.
234 gfx::Rect client_view_bounds_;
235
236 static void InitClass();
237
238 // The font to be used to render the titlebar text.
239 static gfx::Font* title_font_;
240
241 DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowFrameView);
242 };
243
244 gfx::Font* ConstrainedWindowFrameView::title_font_ = NULL;
245
246 namespace {
247 // The frame border is only visible in restored mode and is hardcoded to 4 px on
248 // each side regardless of the system window border size.
249 const int kFrameBorderThickness = 4;
250 // Various edges of the frame border have a 1 px shadow along their edges; in a
251 // few cases we shift elements based on this amount for visual appeal.
252 const int kFrameShadowThickness = 1;
253 // In the window corners, the resize areas don't actually expand bigger, but the
254 // 16 px at the end of each edge triggers diagonal resizing.
255 const int kResizeAreaCornerSize = 16;
256 // The titlebar never shrinks to less than 20 px tall, including the height of
257 // the frame border and client edge.
258 const int kTitlebarMinimumHeight = 20;
259 // The icon is inset 2 px from the left frame border.
260 const int kIconLeftSpacing = 2;
261 // The title text starts 2 px below the bottom of the top frame border.
262 const int kTitleTopSpacing = 2;
263 // There is a 5 px gap between the title text and the caption buttons.
264 const int kTitleCaptionSpacing = 5;
265 // The caption buttons are always drawn 1 px down from the visible top of the
266 // window (the true top in restored mode, or the top of the screen in maximized
267 // mode).
268 const int kCaptionTopSpacing = 1;
269
270 const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
271 }
272
273 ////////////////////////////////////////////////////////////////////////////////
274 // ConstrainedWindowFrameView, public:
275
276 ConstrainedWindowFrameView::ConstrainedWindowFrameView(
277 ConstrainedWindowWin* container)
278 : NonClientFrameView(),
279 container_(container),
280 close_button_(new views::ImageButton(this)) {
281 InitClass();
282 InitWindowResources();
283
284 close_button_->SetImage(views::CustomButton::BS_NORMAL,
285 resources_->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON));
286 close_button_->SetImage(views::CustomButton::BS_HOT,
287 resources_->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_H));
288 close_button_->SetImage(views::CustomButton::BS_PUSHED,
289 resources_->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_P));
290 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
291 views::ImageButton::ALIGN_MIDDLE);
292 AddChildView(close_button_);
293 }
294
295 ConstrainedWindowFrameView::~ConstrainedWindowFrameView() {
296 }
297
298 void ConstrainedWindowFrameView::UpdateWindowTitle() {
299 SchedulePaint(title_bounds_, false);
300 }
301
302 ////////////////////////////////////////////////////////////////////////////////
303 // ConstrainedWindowFrameView, views::NonClientFrameView implementation:
304
305 gfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const {
306 return client_view_bounds_;
307 }
308
309 bool ConstrainedWindowFrameView::AlwaysUseCustomFrame() const {
310 // Constrained windows always use the custom frame - they just have a
311 // different set of bitmaps.
312 return true;
313 }
314
315 gfx::Rect ConstrainedWindowFrameView::GetWindowBoundsForClientBounds(
316 const gfx::Rect& client_bounds) const {
317 int top_height = NonClientTopBorderHeight();
318 int border_thickness = NonClientBorderThickness();
319 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
320 std::max(0, client_bounds.y() - top_height),
321 client_bounds.width() + (2 * border_thickness),
322 client_bounds.height() + top_height + border_thickness);
323 }
324
325 gfx::Point ConstrainedWindowFrameView::GetSystemMenuPoint() const {
326 // Doesn't really matter, since we never show system menus on constrained
327 // windows...
328 gfx::Point system_menu_point(FrameBorderThickness(),
329 NonClientTopBorderHeight());
330 ConvertPointToScreen(this, &system_menu_point);
331 return system_menu_point;
332 }
333
334 int ConstrainedWindowFrameView::NonClientHitTest(const gfx::Point& point) {
335 if (!bounds().Contains(point))
336 return HTNOWHERE;
337
338 int frame_component = container_->GetClientView()->NonClientHitTest(point);
339 if (frame_component != HTNOWHERE)
340 return frame_component;
341
342 // Then see if the point is within any of the window controls.
343 if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point))
344 return HTCLOSE;
345
346 int window_component = GetHTComponentForFrame(point, FrameBorderThickness(),
347 NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize,
348 container_->GetDelegate()->CanResize());
349 // Fall back to the caption if no other component matches.
350 return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
351 }
352
353 void ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size,
354 gfx::Path* window_mask) {
355 DCHECK(window_mask);
356
357 // Redefine the window visible region for the new size.
358 window_mask->moveTo(0, 3);
359 window_mask->lineTo(1, 2);
360 window_mask->lineTo(1, 1);
361 window_mask->lineTo(2, 1);
362 window_mask->lineTo(3, 0);
363
364 window_mask->lineTo(SkIntToScalar(size.width() - 3), 0);
365 window_mask->lineTo(SkIntToScalar(size.width() - 2), 1);
366 window_mask->lineTo(SkIntToScalar(size.width() - 1), 1);
367 window_mask->lineTo(SkIntToScalar(size.width() - 1), 2);
368 window_mask->lineTo(SkIntToScalar(size.width()), 3);
369
370 window_mask->lineTo(SkIntToScalar(size.width()),
371 SkIntToScalar(size.height()));
372 window_mask->lineTo(0, SkIntToScalar(size.height()));
373 window_mask->close();
374 }
375
376 void ConstrainedWindowFrameView::EnableClose(bool enable) {
377 close_button_->SetEnabled(enable);
378 }
379
380 ////////////////////////////////////////////////////////////////////////////////
381 // ConstrainedWindowFrameView, views::View implementation:
382
383 void ConstrainedWindowFrameView::Paint(gfx::Canvas* canvas) {
384 PaintFrameBorder(canvas);
385 PaintTitleBar(canvas);
386 PaintClientEdge(canvas);
387 }
388
389 void ConstrainedWindowFrameView::Layout() {
390 LayoutWindowControls();
391 LayoutTitleBar();
392 LayoutClientView();
393 }
394
395 void ConstrainedWindowFrameView::ThemeChanged() {
396 InitWindowResources();
397 }
398
399 ////////////////////////////////////////////////////////////////////////////////
400 // ConstrainedWindowFrameView, views::ButtonListener implementation:
401
402 void ConstrainedWindowFrameView::ButtonPressed(views::Button* sender) {
403 if (sender == close_button_)
404 container_->ExecuteSystemMenuCommand(SC_CLOSE);
405 }
406
407 ////////////////////////////////////////////////////////////////////////////////
408 // ConstrainedWindowFrameView, private:
409
410 int ConstrainedWindowFrameView::FrameBorderThickness() const {
411 return kFrameBorderThickness;
412 }
413
414 int ConstrainedWindowFrameView::NonClientBorderThickness() const {
415 return FrameBorderThickness() + kClientEdgeThickness;
416 }
417
418 int ConstrainedWindowFrameView::NonClientTopBorderHeight() const {
419 int title_top_spacing, title_thickness;
420 return TitleCoordinates(&title_top_spacing, &title_thickness);
421 }
422
423 int ConstrainedWindowFrameView::TitleCoordinates(
424 int* title_top_spacing,
425 int* title_thickness) const {
426 int frame_thickness = FrameBorderThickness();
427 int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness;
428 *title_top_spacing = frame_thickness + kTitleTopSpacing;
429 // The bottom spacing should be the same apparent height as the top spacing,
430 // plus have the client edge tacked on.
431 int title_bottom_spacing = *title_top_spacing + kClientEdgeThickness;
432 *title_thickness = std::max(title_font_->height(),
433 min_titlebar_height - *title_top_spacing - title_bottom_spacing);
434 return *title_top_spacing + *title_thickness + title_bottom_spacing;
435 }
436
437 void ConstrainedWindowFrameView::PaintFrameBorder(gfx::Canvas* canvas) {
438 SkBitmap* top_left_corner = resources_->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
439 SkBitmap* top_right_corner =
440 resources_->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
441 SkBitmap* top_edge = resources_->GetPartBitmap(FRAME_TOP_EDGE);
442 SkBitmap* right_edge = resources_->GetPartBitmap(FRAME_RIGHT_EDGE);
443 SkBitmap* left_edge = resources_->GetPartBitmap(FRAME_LEFT_EDGE);
444 SkBitmap* bottom_left_corner =
445 resources_->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER);
446 SkBitmap* bottom_right_corner =
447 resources_->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
448 SkBitmap* bottom_edge = resources_->GetPartBitmap(FRAME_BOTTOM_EDGE);
449
450 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
451 SkBitmap* theme_frame = rb.GetBitmapNamed(IDR_THEME_FRAME);
452 SkColor frame_color = ResourceBundle::frame_color;
453
454 // Fill with the frame color first so we have a constant background for
455 // areas not covered by the theme image.
456 canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height());
457 // Now fill down the sides
458 canvas->FillRectInt(frame_color,
459 0, theme_frame->height(),
460 left_edge->width(), height() - theme_frame->height());
461 canvas->FillRectInt(frame_color,
462 width() - right_edge->width(), theme_frame->height(),
463 right_edge->width(), height() - theme_frame->height());
464 // Now fill the bottom area.
465 canvas->FillRectInt(frame_color,
466 left_edge->width(), height() - bottom_edge->height(),
467 width() - left_edge->width() - right_edge->width(),
468 bottom_edge->height());
469
470 // Draw the theme frame.
471 canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
472
473 // Top.
474 canvas->DrawBitmapInt(*top_left_corner, 0, 0);
475 canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
476 width() - top_right_corner->width(), top_edge->height());
477 canvas->DrawBitmapInt(*top_right_corner,
478 width() - top_right_corner->width(), 0);
479
480 // Right.
481 canvas->TileImageInt(*right_edge, width() - right_edge->width(),
482 top_right_corner->height(), right_edge->width(),
483 height() - top_right_corner->height() -
484 bottom_right_corner->height());
485
486 // Bottom.
487 canvas->DrawBitmapInt(*bottom_right_corner,
488 width() - bottom_right_corner->width(),
489 height() - bottom_right_corner->height());
490 canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(),
491 height() - bottom_edge->height(),
492 width() - bottom_left_corner->width() -
493 bottom_right_corner->width(),
494 bottom_edge->height());
495 canvas->DrawBitmapInt(*bottom_left_corner, 0,
496 height() - bottom_left_corner->height());
497
498 // Left.
499 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
500 left_edge->width(),
501 height() - top_left_corner->height() - bottom_left_corner->height());
502 }
503
504 void ConstrainedWindowFrameView::PaintTitleBar(gfx::Canvas* canvas) {
505 canvas->DrawStringInt(container_->GetWindowTitle(), *title_font_,
506 GetTitleColor(), MirroredLeftPointForRect(title_bounds_),
507 title_bounds_.y(), title_bounds_.width(), title_bounds_.height());
508 }
509
510 void ConstrainedWindowFrameView::PaintClientEdge(gfx::Canvas* canvas) {
511 gfx::Rect client_edge_bounds(CalculateClientAreaBounds(width(), height()));
512 client_edge_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness);
513 gfx::Rect frame_shadow_bounds(client_edge_bounds);
514 frame_shadow_bounds.Inset(-kFrameShadowThickness, -kFrameShadowThickness);
515
516 canvas->FillRectInt(kContentsBorderShadow, frame_shadow_bounds.x(),
517 frame_shadow_bounds.y(), frame_shadow_bounds.width(),
518 frame_shadow_bounds.height());
519
520 canvas->FillRectInt(ResourceBundle::toolbar_color, client_edge_bounds.x(),
521 client_edge_bounds.y(), client_edge_bounds.width(),
522 client_edge_bounds.height());
523 }
524
525 void ConstrainedWindowFrameView::LayoutWindowControls() {
526 gfx::Size close_button_size = close_button_->GetPreferredSize();
527 close_button_->SetBounds(
528 width() - close_button_size.width() - FrameBorderThickness(),
529 kCaptionTopSpacing, close_button_size.width(),
530 close_button_size.height());
531 }
532
533 void ConstrainedWindowFrameView::LayoutTitleBar() {
534 // Size the title.
535 int title_x = FrameBorderThickness() + kIconLeftSpacing;
536 int title_top_spacing, title_thickness;
537 TitleCoordinates(&title_top_spacing, &title_thickness);
538 title_bounds_.SetRect(title_x,
539 title_top_spacing + ((title_thickness - title_font_->height()) / 2),
540 std::max(0, close_button_->x() - kTitleCaptionSpacing - title_x),
541 title_font_->height());
542 }
543
544 void ConstrainedWindowFrameView::LayoutClientView() {
545 client_view_bounds_ = CalculateClientAreaBounds(width(), height());
546 }
547
548 gfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds(
549 int width,
550 int height) const {
551 int top_height = NonClientTopBorderHeight();
552 int border_thickness = NonClientBorderThickness();
553 return gfx::Rect(border_thickness, top_height,
554 std::max(0, width - (2 * border_thickness)),
555 std::max(0, height - top_height - border_thickness));
556 }
557
558 void ConstrainedWindowFrameView::InitWindowResources() {
559 if (win_util::ShouldUseVistaFrame()) {
560 resources_.reset(new VistaWindowResources);
561 } else {
562 resources_.reset(new XPWindowResources);
563 }
564 }
565
566 // static
567 void ConstrainedWindowFrameView::InitClass() {
568 static bool initialized = false;
569 if (!initialized) {
570 title_font_ = new gfx::Font(win_util::GetWindowTitleFont());
571
572 initialized = true;
573 }
574 }
575
576 ////////////////////////////////////////////////////////////////////////////////
577 // ConstrainedWindowWin, public:
578
579 // The space (in pixels) between minimized pop-ups stacked horizontally and
580 // vertically.
581 static const int kPopupRepositionOffset = 5;
582 static const int kConstrainedWindowEdgePadding = 10;
583
584 ConstrainedWindowWin::~ConstrainedWindowWin() {
585 }
586
587 ////////////////////////////////////////////////////////////////////////////////
588 // ConstrainedWindowWin, ConstrainedWindow implementation:
589
590 views::NonClientFrameView* ConstrainedWindowWin::CreateFrameViewForWindow() {
591 return new ConstrainedWindowFrameView(this);
592 }
593
594 void ConstrainedWindowWin::CloseConstrainedWindow() {
595 // Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
596 // One example of such an observer is AutomationCWindowTracker in the
597 // automation component.
598 NotificationService::current()->Notify(NotificationType::CWINDOW_CLOSED,
599 Source<ConstrainedWindow>(this),
600 NotificationService::NoDetails());
601
602 Close();
603 }
604
605 std::wstring ConstrainedWindowWin::GetWindowTitle() const {
606 std::wstring display_title;
607 if (GetDelegate())
608 display_title = GetDelegate()->GetWindowTitle();
609 else
610 display_title = L"Untitled";
611
612 return display_title;
613 }
614
615 const gfx::Rect& ConstrainedWindowWin::GetCurrentBounds() const {
616 return current_bounds_;
617 }
618
619 ////////////////////////////////////////////////////////////////////////////////
620 // ConstrainedWindowWin, private:
621
622 ConstrainedWindowWin::ConstrainedWindowWin(
623 TabContents* owner,
624 views::WindowDelegate* window_delegate)
625 : WindowWin(window_delegate),
626 owner_(owner) {
627 GetNonClientView()->SetFrameView(CreateFrameViewForWindow());
628
629 focus_restoration_disabled_ = false;
630 set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION |
631 WS_THICKFRAME | WS_SYSMENU);
632 set_focus_on_creation(false);
633
634 WindowWin::Init(owner_->GetNativeView(), gfx::Rect());
635 ActivateConstrainedWindow();
636 }
637
638 void ConstrainedWindowWin::ActivateConstrainedWindow() {
639 // Other pop-ups are simply moved to the front of the z-order.
640 SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
641
642 // Store the focus of our parent focus manager so we can restore it when we
643 // close.
644 views::FocusManager* focus_manager =
645 views::FocusManager::GetFocusManager(GetNativeView());
646 DCHECK(focus_manager);
647 focus_manager = focus_manager->GetParentFocusManager();
648 if (focus_manager) {
649 // We could not have a parent focus manager if the ConstrainedWindow is
650 // displayed in a tab that is not currently selected.
651 // TODO(jcampan): we should store the ConstrainedWindow active events in
652 // that case and replay them when the TabContents becomes selected.
653 focus_manager->StoreFocusedView();
654
655 // Give our window the focus so we get keyboard messages.
656 ::SetFocus(GetNativeView());
657 }
658 }
659
660 ////////////////////////////////////////////////////////////////////////////////
661 // ConstrainedWindowWin, views::WidgetWin overrides:
662
663 void ConstrainedWindowWin::OnDestroy() {
664 // We do this here, rather than |Close|, since the window may be destroyed in
665 // a way other than by some other component calling Close, e.g. by the native
666 // window hierarchy closing. We are guaranteed to receive a WM_DESTROY
667 // message regardless of how the window is closed.
668 // Note that when we get this message, the focus manager of the
669 // ConstrainedWindow has already been destroyed (by the processing of
670 // WM_DESTROY in FocusManager). So the FocusManager we retrieve here is the
671 // parent one (the one from the top window).
672 views::FocusManager* focus_manager =
673 views::FocusManager::GetFocusManager(GetNativeView());
674 if (focus_manager) {
675 // We may not have a focus manager if:
676 // - we are hidden when closed (the TabContent would be detached).
677 // - the tab has been closed and we are closed as a result.
678 // TODO(jcampan): when hidden, we should modify the stored focus of the tab
679 // so when it becomes visible again we retrieve the focus appropriately.
680 if (!focus_restoration_disabled_)
681 focus_manager->RestoreFocusedView();
682 }
683
684 // Make sure we call super so that it can do its cleanup.
685 WindowWin::OnDestroy();
686 }
687
688 void ConstrainedWindowWin::OnFinalMessage(HWND window) {
689 // Tell our constraining TabContents that we've gone so it can update its
690 // list.
691 owner_->WillClose(this);
692
693 WindowWin::OnFinalMessage(window);
694 }
695
696 LRESULT ConstrainedWindowWin::OnMouseActivate(HWND window,
697 UINT hittest_code,
698 UINT message) {
699 // We only detach the window if the user clicked on the title bar. That
700 // way, users can click inside the contents of legitimate popups obtained
701 // with a mouse gesture.
702 if (hittest_code != HTCLIENT && hittest_code != HTNOWHERE &&
703 hittest_code != HTCLOSE) {
704 ActivateConstrainedWindow();
705 }
706
707 return MA_ACTIVATE;
708 }
709
710 void ConstrainedWindowWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
711 // If the window was moved or sized, tell the owner.
712 if (!(window_pos->flags & SWP_NOMOVE) || !(window_pos->flags & SWP_NOSIZE))
713 owner_->DidMoveOrResize(this);
714 SetMsgHandled(FALSE);
715 }
716
717
718 // static
719 ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
720 TabContents* parent,
721 views::WindowDelegate* window_delegate) {
722 ConstrainedWindowWin* window = new ConstrainedWindowWin(parent,
723 window_delegate);
724 return window;
725 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698