diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 22:09:20 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 22:09:20 +0000 |
commit | 10c7a9fc09c8bc73cafb36631ad47d1d574724b1 (patch) | |
tree | f0503f9b72aa9d014b2025546be45586ed74d247 | |
parent | db17b7630cfab40322b51ca86ac22934a069e5d3 (diff) | |
download | chromium_src-10c7a9fc09c8bc73cafb36631ad47d1d574724b1.zip chromium_src-10c7a9fc09c8bc73cafb36631ad47d1d574724b1.tar.gz chromium_src-10c7a9fc09c8bc73cafb36631ad47d1d574724b1.tar.bz2 |
[Mac] Convert Omnibox border to bezier paths.
In preparation for rounding the corners. Doing this in two pieces
because the difference between NSFrameRect*() and framing a rectangle
using NSBezierPath is a little subtle.
BUG=45762
TEST=Omnibox should look identical.
Review URL: http://codereview.chromium.org/2828008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50042 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/cocoa/styled_text_field_cell.mm | 121 |
1 files changed, 87 insertions, 34 deletions
diff --git a/chrome/browser/cocoa/styled_text_field_cell.mm b/chrome/browser/cocoa/styled_text_field_cell.mm index 7093f17..d9416e9 100644 --- a/chrome/browser/cocoa/styled_text_field_cell.mm +++ b/chrome/browser/cocoa/styled_text_field_cell.mm @@ -11,6 +11,58 @@ #include "gfx/font.h" #include "grit/theme_resources.h" +namespace { + +NSBezierPath* RectPathWithInset(const NSRect frame, + const CGFloat inset) { + const NSRect insetFrame = NSInsetRect(frame, inset, inset); + return [NSBezierPath bezierPathWithRect:insetFrame]; +} + +// Similar to |NSRectFill()|, additionally sets |color| as the fill +// color. +void FillRectWithInset(const NSRect frame, + const CGFloat inset, + NSColor* color) { + NSBezierPath* path = RectPathWithInset(frame, inset); + [color setFill]; + [path fill]; +} + +// Similar to |NSFrameRectWithWidth()|, additionally sets |color| as +// the stroke color (as opposed to the fill color). +void FrameRectWithInset(const NSRect frame, + const CGFloat inset, + const CGFloat lineWidth, + NSColor* color) { + const CGFloat finalInset = inset + (lineWidth / 2.0); + NSBezierPath* path = RectPathWithInset(frame, finalInset); + [color setStroke]; + [path setLineWidth:lineWidth]; + [path stroke]; +} + +// TODO(shess): Maybe we need a |cocoa_util.h|? +class ScopedSaveGraphicsState { + public: + ScopedSaveGraphicsState() + : context_([NSGraphicsContext currentContext]) { + [context_ saveGraphicsState]; + } + explicit ScopedSaveGraphicsState(NSGraphicsContext* context) + : context_(context) { + [context_ saveGraphicsState]; + } + ~ScopedSaveGraphicsState() { + [context_ restoreGraphicsState]; + } + +private: + NSGraphicsContext* context_; +}; + +} // namespace + @implementation StyledTextFieldCell - (CGFloat)baselineAdjust { @@ -52,55 +104,56 @@ // TODO(shess): This inset is also reflected by |kFieldVisualInset| // in autocomplete_popup_view_mac.mm. - NSRect frame = NSInsetRect(cellFrame, 0, 1); - NSRect midFrame = NSInsetRect(frame, 0.5, 0.5); - NSRect innerFrame = NSInsetRect(frame, 1, 1); + const NSRect frame = NSInsetRect(cellFrame, 0, 1); // Paint button background image if there is one (otherwise the border won't // look right). ThemeProvider* themeProvider = [[controlView window] themeProvider]; - NSColor* backgroundImageColor = nil; if (themeProvider) { - backgroundImageColor = + NSColor* backgroundImageColor = themeProvider->GetNSImageColorNamed(IDR_THEME_BUTTON_BACKGROUND, false); - } - if (backgroundImageColor) { - [backgroundImageColor set]; - // Set the phase to match window. - NSRect trueRect = [controlView convertRect:cellFrame toView:nil]; - [[NSGraphicsContext currentContext] - setPatternPhase:NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect))]; - NSRectFillUsingOperation(midFrame, NSCompositeCopy); - } - - // Draw the outer stroke (over the background). - BOOL active = [[controlView window] isMainWindow]; - if (themeProvider) { + if (backgroundImageColor) { + // Set the phase to match window. + NSRect trueRect = [controlView convertRect:cellFrame toView:nil]; + NSPoint midPoint = NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect)); + [[NSGraphicsContext currentContext] setPatternPhase:midPoint]; + + // NOTE(shess): This seems like it should be using a 0.0 inset, + // but AFAICT using a 0.5 inset is important in mixing the + // toolbar background and the omnibox background. + FillRectWithInset(frame, 0.5, backgroundImageColor); + } + + // Draw the outer stroke (over the background). + BOOL active = [[controlView window] isMainWindow]; NSColor* strokeColor = themeProvider->GetNSColor( active ? BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE : BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, true); - [strokeColor set]; + FrameRectWithInset(frame, 0.0, 1.0, strokeColor); } - NSFrameRectWithWidthUsingOperation(frame, 1, NSCompositeSourceOver); - // Draw the background for the interior. - [[self backgroundColor] setFill]; - NSRectFill(innerFrame); - - // Draw the shadow. - NSRect topShadowFrame, leftShadowFrame, restFrame; - NSDivideRect(innerFrame, &topShadowFrame, &restFrame, 1, NSMinYEdge); - NSDivideRect(restFrame, &leftShadowFrame, &restFrame, 1, NSMinXEdge); - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.05] setFill]; - NSRectFillUsingOperation(topShadowFrame, NSCompositeSourceOver); - NSRectFillUsingOperation(leftShadowFrame, NSCompositeSourceOver); + // Fill interior with background color. + FillRectWithInset(frame, 1.0, [self backgroundColor]); + + // Draw the shadow. For the rounded-rect case, the shadow needs to + // slightly turn in at the corners. |shadowFrame| is at the same + // midline as the inner border line on the top and left, but at the + // outer border line on the bottom and right. The clipping change + // will clip the bottom and right edges (and corner). + { + ScopedSaveGraphicsState state; + [RectPathWithInset(frame, 1.0) addClip]; + const NSRect shadowFrame = NSOffsetRect(frame, 0.5, 0.5); + NSColor* shadowShade = [NSColor colorWithCalibratedWhite:0.0 alpha:0.05]; + FrameRectWithInset(shadowFrame, 0.5, 1.0, shadowShade); + } // Draw the focus ring if needed. if ([self showsFirstResponder]) { - [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set]; - NSFrameRectWithWidthUsingOperation(NSInsetRect(frame, 0, 0), 2, - NSCompositeSourceOver); + NSColor* color = + [[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5]; + FrameRectWithInset(frame, 0.0, 2.0, color); } [self drawInteriorWithFrame:cellFrame inView:controlView]; |