Home | History | Annotate | Download | only in bubble
      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
      3 // found in the LICENSE file.
      4 
      5 #include <gtk/gtk.h>
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "chrome/browser/ui/browser.h"
      9 #include "chrome/browser/ui/browser_window.h"
     10 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
     11 #include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
     12 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
     13 #include "chrome/browser/ui/gtk/gtk_util.h"
     14 #include "chrome/test/base/in_process_browser_test.h"
     15 #include "ui/base/gtk/gtk_hig_constants.h"
     16 
     17 class BubbleGtkTest : public InProcessBrowserTest,
     18                       public BubbleDelegateGtk {
     19  public:
     20   BubbleGtkTest() : browser_window_(NULL) {
     21   }
     22 
     23   virtual ~BubbleGtkTest() {
     24   }
     25 
     26   // BubbleDelegateGtk implementation.
     27   virtual void BubbleClosing(BubbleGtk* bubble,
     28                              bool closed_by_escape) OVERRIDE {
     29   }
     30 
     31   Profile* GetProfile() {
     32     return browser()->profile();
     33   }
     34 
     35   GtkWidget* GetNativeBrowserWindow() {
     36     if (!browser_window_)
     37       browser_window_ = GTK_WIDGET(browser()->window()->GetNativeWindow());
     38     return browser_window_;
     39   }
     40 
     41  private:
     42   GtkWidget* browser_window_;
     43 };
     44 
     45 // Tests that we can adjust a bubble arrow so we can show a bubble without being
     46 // clipped. This test verifies the following four issues:
     47 // 1. Shows a bubble to the top-left corner and see its frame style always
     48 // becomes ANCHOR_TOP_LEFT.
     49 // 2. Shows a bubble to the top-right corner and see its frame style always
     50 // becomes ANCHOR_TOP_RIGHT.
     51 // 3. Shows a bubble to the bottom-left corner and see its frame style always
     52 // becomes ANCHOR_BOTTOM_LEFT.
     53 // 4. Shows a bubble to the top-left corner and see its frame style always
     54 // becomes ANCHOR_BOTTOM_RIGHT.
     55 IN_PROC_BROWSER_TEST_F(BubbleGtkTest, ArrowLocation) {
     56   int width = gdk_screen_get_width(gdk_screen_get_default());
     57   int height = gdk_screen_get_height(gdk_screen_get_default());
     58   struct {
     59     int x, y;
     60     BubbleGtk::FrameStyle expected;
     61   } points[] = {
     62     {0, 0, BubbleGtk::ANCHOR_TOP_LEFT},
     63     {width - 1, 0, BubbleGtk::ANCHOR_TOP_RIGHT},
     64     {0, height - 1, BubbleGtk::ANCHOR_BOTTOM_LEFT},
     65     {width - 1, height - 1, BubbleGtk::ANCHOR_BOTTOM_RIGHT},
     66   };
     67   static const BubbleGtk::FrameStyle kPreferredLocations[] = {
     68     BubbleGtk::ANCHOR_TOP_LEFT,
     69     BubbleGtk::ANCHOR_TOP_RIGHT,
     70     BubbleGtk::ANCHOR_BOTTOM_LEFT,
     71     BubbleGtk::ANCHOR_BOTTOM_RIGHT,
     72   };
     73 
     74   GtkWidget* anchor = GetNativeBrowserWindow();
     75   GtkThemeService* theme_service = GtkThemeService::GetFrom(GetProfile());
     76   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(points); ++i) {
     77     for (size_t j = 0; j < arraysize(kPreferredLocations); ++j) {
     78       static const char kText[] =
     79           "Google's mission is to organize the world's information and make it"
     80           " universally accessible and useful.";
     81       GtkWidget* label = theme_service->BuildLabel(kText, ui::kGdkBlack);
     82       gfx::Rect rect(points[i].x, points[i].y, 0, 0);
     83       BubbleGtk* bubble = BubbleGtk::Show(anchor,
     84                                           &rect,
     85                                           label,
     86                                           kPreferredLocations[j],
     87                                           BubbleGtk::MATCH_SYSTEM_THEME |
     88                                               BubbleGtk::POPUP_WINDOW |
     89                                               BubbleGtk::GRAB_INPUT,
     90                                           theme_service,
     91                                           this);
     92       EXPECT_EQ(points[i].expected, bubble->actual_frame_style_);
     93       bubble->Close();
     94     }
     95   }
     96 }
     97 
     98 IN_PROC_BROWSER_TEST_F(BubbleGtkTest, NoArrow) {
     99   int width = gdk_screen_get_width(gdk_screen_get_default());
    100   int height = gdk_screen_get_height(gdk_screen_get_default());
    101   struct {
    102     int x, y;
    103     BubbleGtk::FrameStyle expected;
    104   } points[] = {
    105     {0, 0, BubbleGtk::FLOAT_BELOW_RECT},
    106     {width - 1, 0, BubbleGtk::FLOAT_BELOW_RECT},
    107     {0, height - 1, BubbleGtk::CENTER_OVER_RECT},
    108     {width - 1, height - 1, BubbleGtk::CENTER_OVER_RECT},
    109   };
    110   static const BubbleGtk::FrameStyle kPreferredLocations[] = {
    111     BubbleGtk::FLOAT_BELOW_RECT,
    112     BubbleGtk::CENTER_OVER_RECT,
    113   };
    114 
    115   GtkWidget* anchor = GetNativeBrowserWindow();
    116   GtkThemeService* theme_service = GtkThemeService::GetFrom(GetProfile());
    117   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(points); ++i) {
    118     for (size_t j = 0; j < arraysize(kPreferredLocations); ++j) {
    119       static const char kText[] =
    120           "Google's mission is to organize the world's information and make it"
    121           " universally accessible and useful.";
    122       GtkWidget* label = theme_service->BuildLabel(kText, ui::kGdkBlack);
    123       gfx::Rect rect(points[i].x, points[i].y, 0, 0);
    124       BubbleGtk* bubble = BubbleGtk::Show(anchor,
    125                                           &rect,
    126                                           label,
    127                                           kPreferredLocations[j],
    128                                           BubbleGtk::MATCH_SYSTEM_THEME |
    129                                               BubbleGtk::POPUP_WINDOW |
    130                                               BubbleGtk::GRAB_INPUT,
    131                                           theme_service,
    132                                           this);
    133       EXPECT_EQ(points[i].expected, bubble->actual_frame_style_);
    134       bubble->Close();
    135     }
    136   }
    137 }
    138