15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/text_button.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/throb_animation.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/painter.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/skia_utils_win.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/platform_font_win.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/native_theme_win.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default space between the icon and text. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultIconTextSpacing = 5; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Preferred padding between text and edge. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPreferredPaddingHorizontal = 6; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPreferredPaddingVertical = 5; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Preferred padding between text and edge for NativeTheme border. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPreferredNativeThemePaddingHorizontal = 12; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPreferredNativeThemePaddingVertical = 5; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// By default the focus rect is drawn at the border of the view. For a button, 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// we inset the focus rect by 3 pixels so that it doesn't draw on top of the 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// button's border. This roughly matches how the Windows native focus rect for 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// buttons looks. A subclass that draws a button with different padding may need 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// to provide a different focus painter and do something different. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFocusRectInset = 3; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How long the hover fade animation should last. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHoverAnimationDurationMs = 170; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These sizes are from http://msdn.microsoft.com/en-us/library/aa511279.aspx 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinWidthDLUs = 50; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinHeightDLUs = 14; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The default hot and pushed button image IDs; normal has none by default. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kHotImages[] = IMAGE_GRID(IDR_TEXTBUTTON_HOVER); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPushedImages[] = IMAGE_GRID(IDR_TEXTBUTTON_PRESSED); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char TextButtonBase::kViewClassName[] = "TextButtonBase"; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char TextButton::kViewClassName[] = "TextButton"; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TextButtonBorder ----------------------------------------------------------- 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TextButtonBorder::TextButtonBorder() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextButtonBorder::~TextButtonBorder() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TextButtonBorder::Paint(const View& view, gfx::Canvas* canvas) { 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Insets TextButtonBorder::GetInsets() const { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return insets_; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Size TextButtonBorder::GetMinimumSize() const { 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gfx::Size(); 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextButtonBorder::SetInsets(const gfx::Insets& insets) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insets_ = insets; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TextButtonDefaultBorder ---------------------------------------------------- 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TextButtonDefaultBorder::TextButtonDefaultBorder() 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : vertical_padding_(kPreferredPaddingVertical) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_hot_painter(Painter::CreateImageGridPainter(kHotImages)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_pushed_painter(Painter::CreateImageGridPainter(kPushedImages)); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetInsets(gfx::Insets(vertical_padding_, kPreferredPaddingHorizontal, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertical_padding_, kPreferredPaddingHorizontal)); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TextButtonDefaultBorder::~TextButtonDefaultBorder() { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextButtonDefaultBorder::Paint(const View& view, gfx::Canvas* canvas) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TextButton* button = static_cast<const TextButton*>(&view); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int state = button->state(); 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool animating = button->GetAnimation()->is_animating(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Painter* painter = normal_painter_.get(); 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Use the hot painter when we're hovered. Also use the hot painter when we're 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // STATE_NORMAL and |animating| so that we show throb animations started from 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // CustomButton::StartThrobbing which should start throbbing the button 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // regardless of whether it is hovered. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button->show_multiple_icon_states() && 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ((state == TextButton::STATE_HOVERED) || 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (state == TextButton::STATE_PRESSED) || 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ((state == TextButton::STATE_NORMAL) && animating))) { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) painter = (state == TextButton::STATE_PRESSED) ? 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pushed_painter_.get() : hot_painter_.get(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (painter) { 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (animating) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkasting): Really this should crossfade between states so it could 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // handle the case of having a non-NULL |normal_painter_|. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->SaveLayerAlpha(static_cast<uint8>( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->GetAnimation()->CurrentValueBetween(0, 255))); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) painter->Paint(canvas, view.size()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->Restore(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) painter->Paint(canvas, view.size()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Size TextButtonDefaultBorder::GetMinimumSize() const { 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size size; 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (normal_painter_) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size.SetToMax(normal_painter_->GetMinimumSize()); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hot_painter_) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size.SetToMax(hot_painter_->GetMinimumSize()); 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pushed_painter_) 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size.SetToMax(pushed_painter_->GetMinimumSize()); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return size; 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TextButtonNativeThemeBorder ------------------------------------------------ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextButtonNativeThemeBorder::TextButtonNativeThemeBorder( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NativeThemeDelegate* delegate) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetInsets(gfx::Insets(kPreferredNativeThemePaddingVertical, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPreferredNativeThemePaddingHorizontal, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPreferredNativeThemePaddingVertical, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPreferredNativeThemePaddingHorizontal)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextButtonNativeThemeBorder::~TextButtonNativeThemeBorder() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonNativeThemeBorder::Paint(const View& view, gfx::Canvas* canvas) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::NativeTheme* theme = view.GetNativeTheme(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TextButtonBase* tb = static_cast<const TextButton*>(&view); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::Part part = delegate_->GetThemePart(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect rect(delegate_->GetThemePaintRect()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tb->show_multiple_icon_states() && 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->GetThemeAnimation() != NULL && 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->GetThemeAnimation()->is_animating()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Paint background state. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams prev_extra; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::State prev_state = 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->GetBackgroundThemeState(&prev_extra); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme->Paint(canvas->sk_canvas(), part, prev_state, rect, prev_extra); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Composite foreground state above it. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams extra; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::State state = delegate_->GetForegroundThemeState(&extra); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int alpha = delegate_->GetThemeAnimation()->CurrentValueBetween(0, 255); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->SaveLayerAlpha(static_cast<uint8>(alpha)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme->Paint(canvas->sk_canvas(), part, state, rect, extra); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->Restore(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams extra; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::State state = delegate_->GetThemeState(&extra); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme->Paint(canvas->sk_canvas(), part, state, rect, extra); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TextButtonBase ------------------------------------------------------------- 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextButtonBase::TextButtonBase(ButtonListener* listener, 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& text) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : CustomButton(listener), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alignment_(ALIGN_LEFT), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_width_(0), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_height_(0), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_width_(0), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_multiple_icon_states_(true), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_default_(false), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_line_(false), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_enabled_color_from_theme_(true), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_disabled_color_from_theme_(true), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_highlight_color_from_theme_(true), 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) use_hover_color_from_theme_(true), 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) focus_painter_(Painter::CreateDashedFocusPainter()) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetText(text); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAnimationDuration(kHoverAnimationDurationMs); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextButtonBase::~TextButtonBase() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetIsDefault(bool is_default) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_default == is_default_) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_default_ = is_default; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_default_) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextButtonBase::SetText(const base::string16& text) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text == text_) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_ = text; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAccessibleName(text); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTextSize(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextButtonBase::SetFontList(const gfx::FontList& font_list) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) font_list_ = font_list; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTextSize(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetEnabledColor(SkColor color) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_enabled_ = color; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_enabled_color_from_theme_ = false; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColor(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetDisabledColor(SkColor color) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_disabled_ = color; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_disabled_color_from_theme_ = false; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColor(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetHighlightColor(SkColor color) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_highlight_ = color; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_highlight_color_from_theme_ = false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetHoverColor(SkColor color) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_hover_ = color; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_hover_color_from_theme_ = false; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::ClearMaxTextSize() { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_text_size_ = text_size_; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetShowMultipleIconStates(bool show_multiple_icon_states) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_multiple_icon_states_ = show_multiple_icon_states; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::SetMultiLine(bool multi_line) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (multi_line != multi_line_) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_line_ = multi_line; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_text_size_.SetSize(0, 0); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTextSize(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size TextButtonBase::GetPreferredSize() const { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Insets insets = GetInsets(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the max size to set the button boundaries. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In multiline mode max size can be undefined while 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // width() is 0, so max it out with current text size. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size prefsize(std::max(max_text_size_.width(), 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size_.width()) + insets.width(), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(max_text_size_.height(), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size_.height()) + insets.height()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max_width_ > 0) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(std::min(max_width_, prefsize.width())); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(std::max(prefsize.width(), min_width_)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height(std::max(prefsize.height(), min_height_)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefsize; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int TextButtonBase::GetHeightForWidth(int w) const { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!multi_line_) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return View::GetHeightForWidth(w); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max_width_ > 0) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = std::min(max_width_, w); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size text_size; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateTextSize(&text_size, w); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height = text_size.height() + GetInsets().height(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::max(height, min_height_); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::OnPaint(gfx::Canvas* canvas) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PaintButton(canvas, PB_NORMAL); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::OnBoundsChanged(const gfx::Rect& previous_bounds) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (multi_line_) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTextSize(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const gfx::Animation* TextButtonBase::GetAnimation() const { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hover_animation_.get(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::UpdateColor() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_ = enabled() ? color_enabled_ : color_disabled_; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::UpdateTextSize() { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int text_width = width(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If width is defined, use GetTextBounds.width() for maximum text width, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as it will take size of checkbox/radiobutton into account. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text_width != 0) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect text_bounds = GetTextBounds(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_width = text_bounds.width(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateTextSize(&text_size_, text_width); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before layout width() is 0, and multiline text will be treated as one line. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not store max_text_size in this case. UpdateTextSize will be called 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again once width() changes. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!multi_line_ || text_width != 0) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_text_size_.SetSize(std::max(max_text_size_.width(), text_size_.width()), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(max_text_size_.height(), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size_.height())); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TextButtonBase::CalculateTextSize(gfx::Size* text_size, 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int max_width) const { 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int h = font_list_.GetHeight(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int w = multi_line_ ? max_width : 0; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = ComputeCanvasStringFlags(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!multi_line_) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::NO_ELLIPSIS; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Canvas::SizeStringInt(text_, font_list_, &w, &h, 0, flags); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size->SetSize(w, h); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TextButtonBase::OnPaintText(gfx::Canvas* canvas, PaintButtonMode mode) { 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Rect text_bounds(GetTextBounds()); 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (text_bounds.width() > 0) { 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Because the text button can (at times) draw multiple elements on the 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // canvas, we can not mirror the button by simply flipping the canvas as 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // doing this will mirror the text itself. Flipping the canvas will also 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // make the icons look wrong because icons are almost always represented as 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // direction-insensitive images and such images should never be flipped 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // horizontally. 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Due to the above, we must perform the flipping manually for RTL UIs. 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) text_bounds.set_x(GetMirroredXForRect(text_bounds)); 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkColor text_color = (show_multiple_icon_states_ && 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (state() == STATE_HOVERED || state() == STATE_PRESSED)) ? 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) color_hover_ : color_; 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int draw_string_flags = gfx::Canvas::DefaultCanvasTextAlignment() | 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ComputeCanvasStringFlags(); 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mode == PB_FOR_DRAG) { 383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Disable sub-pixel rendering as background is transparent. 384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) draw_string_flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas->DrawStringRectWithHalo(text_, font_list_, 386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SK_ColorBLACK, SK_ColorWHITE, 387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) text_bounds, draw_string_flags); 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas->DrawStringRectWithFlags(text_, font_list_, text_color, 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) text_bounds, draw_string_flags); 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TextButtonBase::ComputeCanvasStringFlags() const { 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!multi_line_) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int flags = gfx::Canvas::MULTI_LINE; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (alignment_) { 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ALIGN_LEFT: 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_LEFT; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ALIGN_RIGHT: 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ALIGN_CENTER: 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_CENTER; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flags; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TextButtonBase::OnFocus() { 415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) View::OnFocus(); 416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (focus_painter_) 417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SchedulePaint(); 418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TextButtonBase::OnBlur() { 421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) View::OnBlur(); 422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (focus_painter_) 423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SchedulePaint(); 424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::GetExtraParams( 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams* params) const { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.checked = false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.indeterminate = false; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.is_default = false; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.is_focused = false; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.has_border = false; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.classic_state = 0; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.background_color = 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNativeTheme()->GetSystemColor( 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonBackgroundColor); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect TextButtonBase::GetContentBounds(int extra_width) const { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Insets insets = GetInsets(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int available_width = width() - insets.width(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int content_width = text_size_.width() + extra_width; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int content_x = 0; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(alignment_) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ALIGN_LEFT: 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_x = insets.left(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ALIGN_RIGHT: 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_x = width() - insets.right() - content_width; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_x < insets.left()) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_x = insets.left(); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ALIGN_CENTER: 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_x = insets.left() + std::max(0, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (available_width - content_width) / 2); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_width = std::min(content_width, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width() - insets.right() - content_x); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int available_height = height() - insets.height(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int content_y = (available_height - text_size_.height()) / 2 + insets.top(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(content_x, content_y, content_width, text_size_.height()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bounds; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect TextButtonBase::GetTextBounds() const { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetContentBounds(0); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TextButtonBase::SetFocusPainter(scoped_ptr<Painter> focus_painter) { 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) focus_painter_ = focus_painter.Pass(); 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode == PB_NORMAL) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPaintBackground(canvas); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPaintBorder(canvas); 479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnPaintText(canvas, mode); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size TextButtonBase::GetMinimumSize() const { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return max_text_size_; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::OnEnabledChanged() { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should always call UpdateColor() since the state of the button might be 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed by other functions like CustomButton::SetState(). 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColor(); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CustomButton::OnEnabledChanged(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* TextButtonBase::GetClassName() const { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButtonBase::OnNativeThemeChanged(const ui::NativeTheme* theme) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_enabled_color_from_theme_) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_enabled_ = theme->GetSystemColor( 50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonEnabledColor); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_disabled_color_from_theme_) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_disabled_ = theme->GetSystemColor( 50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonDisabledColor); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_highlight_color_from_theme_) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_highlight_ = theme->GetSystemColor( 51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonHighlightColor); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_hover_color_from_theme_) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_hover_ = theme->GetSystemColor( 51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonHoverColor); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColor(); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect TextButtonBase::GetThemePaintRect() const { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetLocalBounds(); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::NativeTheme::State TextButtonBase::GetThemeState( 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams* params) const { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExtraParams(params); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(state()) { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_DISABLED: 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kDisabled; 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_NORMAL: 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kNormal; 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_HOVERED: 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kHovered; 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_PRESSED: 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kPressed; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unknown state: " << state(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kNormal; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const gfx::Animation* TextButtonBase::GetThemeAnimation() const { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetNativeTheme() == ui::NativeThemeWin::instance()) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeThemeWin::instance()->IsThemingActive() ? 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hover_animation_.get() : NULL; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hover_animation_.get(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::NativeTheme::State TextButtonBase::GetBackgroundThemeState( 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams* params) const { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExtraParams(params); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kNormal; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::NativeTheme::State TextButtonBase::GetForegroundThemeState( 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NativeTheme::ExtraParams* params) const { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExtraParams(params); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kHovered; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TextButton ----------------------------------------------------------------- 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextButton::TextButton(ButtonListener* listener, const base::string16& text) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : TextButtonBase(listener, text), 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_placement_(ICON_ON_LEFT), 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_hover_icon_(false), 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_pushed_icon_(false), 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_text_spacing_(kDefaultIconTextSpacing), 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ignore_minimum_size_(true), 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) full_justification_(false) { 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBorder(scoped_ptr<Border>(new TextButtonDefaultBorder)); 576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( 577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Insets(kFocusRectInset, kFocusRectInset, 578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kFocusRectInset, kFocusRectInset))); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextButton::~TextButton() { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::SetIcon(const gfx::ImageSkia& icon) { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_ = icon; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::SetHoverIcon(const gfx::ImageSkia& icon) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_hover_ = icon; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_hover_icon_ = true; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::SetPushedIcon(const gfx::ImageSkia& icon) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_pushed_ = icon; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_pushed_icon_ = true; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size TextButton::GetPreferredSize() const { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size prefsize(TextButtonBase::GetPreferredSize()); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(icon_.width(), 0); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height(std::max(prefsize.height(), icon_.height())); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the max size to set the button boundaries. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_.width() > 0 && !text_.empty()) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(icon_text_spacing_, 0); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max_width_ > 0) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(std::min(max_width_, prefsize.width())); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clamp the size returned to at least the minimum size. 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ignore_minimum_size_) { 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::PlatformFontWin* platform_font = static_cast<gfx::PlatformFontWin*>( 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) font_list_.GetPrimaryFont().platform_font()); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(std::max( 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.width(), 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) platform_font->horizontal_dlus_to_pixels(kMinWidthDLUs))); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height(std::max( 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.height(), 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) platform_font->vertical_dlus_to_pixels(kMinHeightDLUs))); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(std::max(prefsize.width(), min_width_)); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height(std::max(prefsize.height(), min_height_)); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefsize; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (full_justification_ && icon_placement_ == ICON_ON_LEFT) 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_alignment(ALIGN_RIGHT); 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextButtonBase::PaintButton(canvas, mode); 638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnPaintIcon(canvas, mode); 639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TextButton::OnPaintIcon(gfx::Canvas* canvas, PaintButtonMode mode) { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon = GetImageToPaint(); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon.width() > 0) { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect text_bounds = GetTextBounds(); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int icon_x = 0; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int spacing = text_.empty() ? 0 : icon_text_spacing_; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Insets insets = GetInsets(); 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (icon_placement_) { 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case ICON_ON_LEFT: 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) icon_x = full_justification_ ? insets.left() 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : text_bounds.x() - icon.width() - spacing; 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case ICON_ON_RIGHT: 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) icon_x = full_justification_ ? width() - insets.right() - icon.width() 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : text_bounds.right() + spacing; 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case ICON_CENTERED: 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(text_.empty()); 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) icon_x = (width() - insets.width() - icon.width()) / 2 + insets.left(); 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int available_height = height() - insets.height(); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_y = (available_height - icon.height()) / 2 + insets.top(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mirroring the icon position if necessary. 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect icon_bounds(icon_x, icon_y, icon.width(), icon.height()); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_bounds.set_x(GetMirroredXForRect(icon_bounds)); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->DrawImageInt(icon, icon_bounds.x(), icon_bounds.y()); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::set_ignore_minimum_size(bool ignore_minimum_size) { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_minimum_size_ = ignore_minimum_size; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextButton::set_full_justification(bool full_justification) { 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) full_justification_ = full_justification; 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* TextButton::GetClassName() const { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::NativeTheme::Part TextButton::GetThemePart() const { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kPushButton; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextButtonBase::GetExtraParams(params); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.is_default = is_default_; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect TextButton::GetTextBounds() const { 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_width = 0; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon = GetImageToPaint(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon.width() > 0) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_width = icon.width() + (text_.empty() ? 0 : icon_text_spacing_); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(GetContentBounds(extra_width)); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_width > 0) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the icon is always fully visible. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_placement_ == ICON_ON_LEFT) { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.Inset(extra_width, 0, 0, 0); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (icon_placement_ == ICON_ON_RIGHT) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.Inset(0, 0, extra_width, 0); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bounds; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::ImageSkia& TextButton::GetImageToPaint() const { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show_multiple_icon_states_) { 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (has_hover_icon_ && (state() == STATE_HOVERED)) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return icon_hover_; 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (has_pushed_icon_ && (state() == STATE_PRESSED)) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return icon_pushed_; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return icon_; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 730