summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 18:19:59 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 18:19:59 +0000
commit7e342930e757290f6bd1ba80ed9e25853d2e3e75 (patch)
tree1316834dc00d905e796d6d905122cd96cfdf92b0
parentd1d25e4d3c8fa47a78352813c061cc9f71f562ab (diff)
downloadchromium_src-7e342930e757290f6bd1ba80ed9e25853d2e3e75.zip
chromium_src-7e342930e757290f6bd1ba80ed9e25853d2e3e75.tar.gz
chromium_src-7e342930e757290f6bd1ba80ed9e25853d2e3e75.tar.bz2
GTK: Popup notification should have transparent rounded corners.
Also uses the new consistent border color in GTK theme mode. Review URL: http://codereview.chromium.org/165356 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23189 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/blocked_popup_container_view_gtk.cc118
-rw-r--r--chrome/browser/gtk/blocked_popup_container_view_gtk.h5
-rw-r--r--chrome/browser/gtk/info_bubble_gtk.cc7
-rw-r--r--chrome/browser/gtk/status_bubble_gtk.cc7
-rw-r--r--chrome/common/gtk_util.cc5
-rw-r--r--chrome/common/gtk_util.h4
6 files changed, 102 insertions, 44 deletions
diff --git a/chrome/browser/gtk/blocked_popup_container_view_gtk.cc b/chrome/browser/gtk/blocked_popup_container_view_gtk.cc
index 6fe1671..b48b93e 100644
--- a/chrome/browser/gtk/blocked_popup_container_view_gtk.cc
+++ b/chrome/browser/gtk/blocked_popup_container_view_gtk.cc
@@ -22,18 +22,57 @@ namespace {
// The minimal border around the edge of the notification.
const int kSmallPadding = 2;
-// Size of the border painted in kBorderColor
-const int kBorderPadding = 1;
-
// Color of the border.
-const double kBorderColor[] = { 190.0 / 255, 205.0 / 255, 223.0 / 255 };
+const GdkColor kBorderColor = GDK_COLOR_RGB(190, 205, 223);
// Color of the gradient in the background.
const double kBackgroundColorTop[] = { 246.0 / 255, 250.0 / 255, 1.0 };
const double kBackgroundColorBottom[] = { 219.0 / 255, 235.0 / 255, 1.0 };
// Rounded corner radius (in pixels).
-const int kBackgroundCornerRadius = 4;
+const int kCornerSize = 4;
+
+enum FrameType {
+ FRAME_MASK,
+ FRAME_STROKE,
+};
+
+std::vector<GdkPoint> MakeFramePolygonPoints(int width,
+ int height,
+ FrameType type) {
+ using gtk_util::MakeBidiGdkPoint;
+ std::vector<GdkPoint> points;
+
+ bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
+ // If we have a stroke, we have to offset some of our points by 1 pixel.
+ // We have to inset by 1 pixel when we draw horizontal lines that are on the
+ // bottom or when we draw vertical lines that are closer to the end (end is
+ // right for ltr).
+ int y_off = (type == FRAME_MASK) ? 0 : -1;
+ // We use this one for LTR.
+ int x_off_l = ltr ? y_off : 0;
+ // We use this one for RTL.
+ int x_off_r = !ltr ? -y_off : 0;
+
+ // Bottom left corner.
+ points.push_back(MakeBidiGdkPoint(0, height + y_off, width, ltr));
+
+ // Top left (rounded) corner.
+ points.push_back(MakeBidiGdkPoint(x_off_r, kCornerSize - 1, width, ltr));
+ points.push_back(MakeBidiGdkPoint(kCornerSize + x_off_r - 1, 0, width, ltr));
+
+ // Top right (rounded) corner.
+ points.push_back(MakeBidiGdkPoint(
+ width - kCornerSize + 1 + x_off_l, 0, width, ltr));
+ points.push_back(MakeBidiGdkPoint(
+ width + x_off_l, kCornerSize - 1, width, ltr));
+
+ // Bottom right corner.
+ points.push_back(MakeBidiGdkPoint(
+ width + x_off_l, height + y_off, width, ltr));
+
+ return points;
+}
} // namespace
@@ -150,7 +189,9 @@ BlockedPopupContainerViewGtk::BlockedPopupContainerViewGtk(
BlockedPopupContainer* container)
: model_(container),
theme_provider_(GtkThemeProvider::GetFrom(container->profile())),
- close_button_(CustomDrawButton::CloseButton(theme_provider_)) {
+ close_button_(CustomDrawButton::CloseButton(theme_provider_)),
+ notification_width_(-1),
+ notification_height_(-1) {
Init();
registrar_.Add(this,
@@ -223,13 +264,30 @@ gboolean BlockedPopupContainerViewGtk::OnContainerExpose(
int width = widget->allocation.width;
int height = widget->allocation.height;
- // Clip to our damage rect
- cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
- cairo_rectangle(cr, event->area.x, event->area.y,
- event->area.width, event->area.height);
- cairo_clip(cr);
+ // Update our window shape if we need to.
+ if (container->notification_width_ != widget->allocation.width ||
+ container->notification_height_ != widget->allocation.height) {
+ // We need to update the shape of the status bubble whenever our GDK
+ // window changes shape.
+ std::vector<GdkPoint> mask_points = MakeFramePolygonPoints(
+ widget->allocation.width, widget->allocation.height, FRAME_MASK);
+ GdkRegion* mask_region = gdk_region_polygon(&mask_points[0],
+ mask_points.size(),
+ GDK_EVEN_ODD_RULE);
+ gdk_window_shape_combine_region(widget->window, mask_region, 0, 0);
+ gdk_region_destroy(mask_region);
+
+ container->notification_width_ = widget->allocation.width;
+ container->notification_height_ = widget->allocation.height;
+ }
if (!container->theme_provider_->UseGtkTheme()) {
+ // Clip to our damage rect.
+ cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(event->window));
+ cairo_rectangle(cr, event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_clip(cr);
+
// TODO(erg): We draw the gradient background only when GTK themes are
// off. This isn't a perfect solution as this isn't themed! The views
// version doesn't appear to be themed either, so at least for now,
@@ -247,30 +305,24 @@ gboolean BlockedPopupContainerViewGtk::OnContainerExpose(
cairo_set_source(cr, pattern);
cairo_paint(cr);
cairo_pattern_destroy(pattern);
+
+ cairo_destroy(cr);
+ }
+
+ GdkDrawable* drawable = GDK_DRAWABLE(event->window);
+ GdkGC* gc = gdk_gc_new(drawable);
+ if (container->theme_provider_->UseGtkTheme()) {
+ GdkColor color = container->theme_provider_->GetBorderColor();
+ gdk_gc_set_rgb_fg_color(gc, &color);
+ } else {
+ gdk_gc_set_rgb_fg_color(gc, &kBorderColor);
}
- // TODO(erg): We need to figure out the border situation, too. We aren't
- // provided a color from the theme system and the Windows implementation
- // still uses constants for color. See the status bubble, too.
-
- // Sets up our stroke pen.
- cairo_set_source_rgb(cr, kBorderColor[0], kBorderColor[1], kBorderColor[2]);
- cairo_set_line_width(cr, 1.5);
-
- // Draws rounded corners around the edge of the notification, clockwise
- // starting from the bottom left. (A bezier curve with control points at 90
- // degree angles forms a circular arc.)
- cairo_move_to(cr, 0, height);
- cairo_line_to(cr, 0, kBackgroundCornerRadius);
- cairo_curve_to(cr, 0, kBackgroundCornerRadius,
- 0, 0, kBackgroundCornerRadius, 0);
- cairo_line_to(cr, width - kBackgroundCornerRadius, 0);
- cairo_curve_to(cr, width - kBackgroundCornerRadius, 0,
- width, 0, width, kBackgroundCornerRadius);
- cairo_line_to(cr, width, height);
- cairo_stroke(cr);
-
- cairo_destroy(cr);
+ // Stroke the frame border.
+ std::vector<GdkPoint> points = MakeFramePolygonPoints(
+ widget->allocation.width, widget->allocation.height, FRAME_STROKE);
+ gdk_draw_lines(drawable, gc, &points[0], points.size());
+ g_object_unref(gc);
return FALSE; // Allow subwidgets to paint.
}
diff --git a/chrome/browser/gtk/blocked_popup_container_view_gtk.h b/chrome/browser/gtk/blocked_popup_container_view_gtk.h
index f74e880..f8de623 100644
--- a/chrome/browser/gtk/blocked_popup_container_view_gtk.h
+++ b/chrome/browser/gtk/blocked_popup_container_view_gtk.h
@@ -105,6 +105,11 @@ class BlockedPopupContainerViewGtk : public BlockedPopupContainerView,
// The popup menu with options to launch blocked popups.
scoped_ptr<MenuGtk> launch_menu_;
+ // Cached allocation of |container_|. We keep this on hand so that we can
+ // reset the widget's shape when the width/height change.
+ int notification_width_;
+ int notification_height_;
+
DISALLOW_COPY_AND_ASSIGN(BlockedPopupContainerViewGtk);
};
diff --git a/chrome/browser/gtk/info_bubble_gtk.cc b/chrome/browser/gtk/info_bubble_gtk.cc
index 8c7286f..5bb5715 100644
--- a/chrome/browser/gtk/info_bubble_gtk.cc
+++ b/chrome/browser/gtk/info_bubble_gtk.cc
@@ -14,6 +14,7 @@
#include "base/gfx/rect.h"
#include "base/logging.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
+#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_service.h"
namespace {
@@ -38,11 +39,6 @@ const GdkColor kFrameColor = GDK_COLOR_RGB(0x63, 0x63, 0x63);
const gchar* kInfoBubbleToplevelKey = "__INFO_BUBBLE_TOPLEVEL__";
-GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr) {
- GdkPoint point = {ltr ? x : width - x, y};
- return point;
-}
-
enum FrameType {
FRAME_MASK,
FRAME_STROKE,
@@ -57,6 +53,7 @@ enum FrameType {
std::vector<GdkPoint> MakeFramePolygonPoints(int width,
int height,
FrameType type) {
+ using gtk_util::MakeBidiGdkPoint;
std::vector<GdkPoint> points;
bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc
index a951e52..335d780 100644
--- a/chrome/browser/gtk/status_bubble_gtk.cc
+++ b/chrome/browser/gtk/status_bubble_gtk.cc
@@ -31,12 +31,6 @@ const int kCornerSize = 4;
// Milliseconds before we hide the status bubble widget when you mouseout.
const int kHideDelay = 250;
-// Reverses a point in RTL mode.
-GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr) {
- GdkPoint point = {ltr ? x : width - x, y};
- return point;
-}
-
enum FrameType {
FRAME_MASK,
FRAME_STROKE,
@@ -48,6 +42,7 @@ enum FrameType {
std::vector<GdkPoint> MakeFramePolygonPoints(int width,
int height,
FrameType type) {
+ using gtk_util::MakeBidiGdkPoint;
std::vector<GdkPoint> points;
bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc
index c97a3a5..661517e 100644
--- a/chrome/common/gtk_util.cc
+++ b/chrome/common/gtk_util.cc
@@ -501,4 +501,9 @@ gfx::Point ClientPoint(GtkWidget* widget) {
return gfx::Point(x, y);
}
+GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr) {
+ GdkPoint point = {ltr ? x : width - x, y};
+ return point;
+}
+
} // namespace gtk_util
diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h
index 867dbc5..556e77f 100644
--- a/chrome/common/gtk_util.h
+++ b/chrome/common/gtk_util.h
@@ -156,6 +156,10 @@ gfx::Point ScreenPoint(GtkWidget* widget);
// Get the current location of the mouse cursor relative to the widget.
gfx::Point ClientPoint(GtkWidget* widget);
+// Reverses a point in RTL mode. Used in making vectors of GdkPoints for window
+// shapes.
+GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr);
+
} // namespace gtk_util
#endif // CHROME_COMMON_GTK_UTIL_H_