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.
5 #ifndef UI_VIEWS_BUBBLE_BUBBLE_BORDER_H_
6 #define UI_VIEWS_BUBBLE_BUBBLE_BORDER_H_
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "ui/views/background.h"
11 #include "ui/views/border.h"
19 // Renders a border, with optional arrow, and a custom dropshadow.
20 // This can be used to produce floating "bubble" objects with rounded corners.
21 class VIEWS_EXPORT BubbleBorder
: public Border
{
23 // Possible locations for the (optional) arrow.
24 // 0 bit specifies left or right.
25 // 1 bit specifies top or bottom.
26 // 2 bit specifies horizontal or vertical.
27 // 3 bit specifies whether the arrow at the center of its residing edge.
28 enum ArrowLocationMask
{
39 BOTTOM_RIGHT
= BOTTOM
| RIGHT
,
41 RIGHT_TOP
= VERTICAL
| RIGHT
,
42 LEFT_BOTTOM
= VERTICAL
| BOTTOM
,
43 RIGHT_BOTTOM
= VERTICAL
| BOTTOM
| RIGHT
,
45 BOTTOM_CENTER
= CENTER
| BOTTOM
,
46 LEFT_CENTER
= CENTER
| VERTICAL
,
47 RIGHT_CENTER
= CENTER
| VERTICAL
| RIGHT
,
48 NONE
= 16, // No arrow. Positioned under the supplied rect.
49 FLOAT
= 17, // No arrow. Centered over the supplied rect.
60 // The position of the bubble in relation to the anchor.
61 enum BubbleAlignment
{
62 // The tip of the arrow points to the middle of the anchor.
63 ALIGN_ARROW_TO_MID_ANCHOR
,
64 // The edge nearest to the arrow is lined up with the edge of the anchor.
65 ALIGN_EDGE_TO_ANCHOR_EDGE
68 BubbleBorder(ArrowLocation arrow_location
, Shadow shadow
);
70 // Returns the radius of the corner of the border.
71 // TODO(xiyuan): Get rid of this since it's part of BorderImages now?
72 static int GetCornerRadius() {
73 // We can't safely calculate a border radius by comparing the sizes of the
74 // side and corner images, because either may have been extended in various
75 // directions in order to do more subtle dropshadow fading or other effects.
76 // So we hardcode the most accurate value.
80 // Sets the location for the arrow.
81 void set_arrow_location(ArrowLocation loc
) { arrow_location_
= loc
; }
82 ArrowLocation
arrow_location() const { return arrow_location_
; }
84 // Sets the alignment.
85 void set_alignment(BubbleAlignment alignment
) { alignment_
= alignment
; }
86 BubbleAlignment
alignment() const { return alignment_
; }
88 static ArrowLocation
horizontal_mirror(ArrowLocation loc
) {
89 return (loc
== TOP_CENTER
|| loc
== BOTTOM_CENTER
|| loc
>= NONE
) ?
90 loc
: static_cast<ArrowLocation
>(loc
^ RIGHT
);
93 static ArrowLocation
vertical_mirror(ArrowLocation loc
) {
94 return (loc
== LEFT_CENTER
|| loc
== RIGHT_CENTER
|| loc
>= NONE
) ?
95 loc
: static_cast<ArrowLocation
>(loc
^ BOTTOM
);
98 static bool has_arrow(ArrowLocation loc
) {
99 return loc
>= NONE
? false : true;
102 static bool is_arrow_on_left(ArrowLocation loc
) {
103 return (loc
== TOP_CENTER
|| loc
== BOTTOM_CENTER
|| loc
>= NONE
) ?
104 false : !(loc
& RIGHT
);
107 static bool is_arrow_on_top(ArrowLocation loc
) {
108 return (loc
== LEFT_CENTER
|| loc
== RIGHT_CENTER
|| loc
>= NONE
) ?
109 false : !(loc
& BOTTOM
);
112 static bool is_arrow_on_horizontal(ArrowLocation loc
) {
113 return loc
>= NONE
? false : !(loc
& VERTICAL
);
116 static bool is_arrow_at_center(ArrowLocation loc
) {
117 return has_arrow(loc
) && !!(loc
& CENTER
);
120 // Sets the background color for the arrow body. This is irrelevant if you do
121 // not also set the arrow location to something other than NONE.
122 void set_background_color(SkColor color
) { background_color_
= color
; }
123 SkColor
background_color() const { return background_color_
; }
125 void set_client_bounds(const gfx::Rect
& bounds
) { client_bounds_
= bounds
; }
126 const gfx::Rect
& client_bounds() const { return client_bounds_
; }
128 // Sets a fixed offset for the arrow from the beginning of corresponding edge.
129 // The arrow will still point to the same location but the bubble will shift
130 // location to make that happen.
131 void set_arrow_offset(int offset
) { override_arrow_offset_
= offset
; }
133 // For borders with an arrow, gives the desired bounds (in screen coordinates)
134 // given the rect to point to and the size of the contained contents. This
135 // depends on the arrow location, so if you change that, you should call this
136 // again to find out the new coordinates.
137 virtual gfx::Rect
GetBounds(const gfx::Rect
& position_relative_to
,
138 const gfx::Size
& contents_size
) const;
140 // Returns the corner radius of the current image set.
141 int GetBorderCornerRadius() const;
143 // Gets the arrow offset to use.
144 int GetArrowOffset(const gfx::Size
& border_size
) const;
146 // Overridden from Border:
147 virtual void GetInsets(gfx::Insets
* insets
) const OVERRIDE
;
149 // How many pixels the bubble border is from the edge of the images.
150 virtual int GetBorderThickness() const;
153 virtual ~BubbleBorder();
155 // Calculates the insets for a specific arrow location. Normally called from
156 // GetInsets(arrow_location()), but may be called by specialized BubbleBorder
158 virtual void GetInsetsForArrowLocation(gfx::Insets
* insets
,
159 ArrowLocation arrow_loc
) const;
164 // Loads images if necessary.
165 static BorderImages
* GetBorderImages(Shadow shadow
);
167 // Overridden from Border:
168 virtual void Paint(const View
& view
,
169 gfx::Canvas
* canvas
) const OVERRIDE
;
171 void DrawEdgeWithArrow(gfx::Canvas
* canvas
,
173 const gfx::ImageSkia
& edge
,
174 const gfx::ImageSkia
& arrow
,
181 void DrawArrowInterior(gfx::Canvas
* canvas
, float tip_x
, float tip_y
) const;
184 struct BorderImages
* images_
;
187 static struct BorderImages
* border_images_
[SHADOW_COUNT
];
189 // Minimal offset of the arrow from the closet edge of bounding rect.
192 // If specified, overrides the pre-calculated |arrow_offset_| of the arrow.
193 int override_arrow_offset_
;
195 ArrowLocation arrow_location_
;
196 BubbleAlignment alignment_
;
197 SkColor background_color_
;
199 // The client/content bounds; must be clipped from the background on Windows.
200 // TODO(msw): Clean this up when Windows native controls are no longer needed.
201 gfx::Rect client_bounds_
;
203 DISALLOW_COPY_AND_ASSIGN(BubbleBorder
);
206 // A Background that clips itself to the specified BubbleBorder and uses
207 // the background color of the BubbleBorder.
208 class VIEWS_EXPORT BubbleBackground
: public Background
{
210 explicit BubbleBackground(BubbleBorder
* border
) : border_(border
) {}
212 // Overridden from Background:
213 virtual void Paint(gfx::Canvas
* canvas
, View
* view
) const OVERRIDE
;
216 BubbleBorder
* border_
;
218 DISALLOW_COPY_AND_ASSIGN(BubbleBackground
);
223 #endif // UI_VIEWS_BUBBLE_BUBBLE_BORDER_H_