Home | History | Annotate | Download | only in button
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/views/controls/button/checkbox.h"
      6 
      7 #include "grit/ui_resources.h"
      8 #include "ui/accessibility/ax_view_state.h"
      9 #include "ui/base/resource/resource_bundle.h"
     10 #include "ui/views/controls/button/label_button_border.h"
     11 #include "ui/views/painter.h"
     12 
     13 namespace views {
     14 
     15 // static
     16 const char Checkbox::kViewClassName[] = "Checkbox";
     17 
     18 Checkbox::Checkbox(const base::string16& label)
     19     : LabelButton(NULL, label),
     20       checked_(false) {
     21   SetHorizontalAlignment(gfx::ALIGN_LEFT);
     22   scoped_ptr<LabelButtonBorder> button_border(new LabelButtonBorder(style()));
     23   button_border->SetPainter(false, STATE_HOVERED, NULL);
     24   button_border->SetPainter(false, STATE_PRESSED, NULL);
     25   // Inset the trailing side by a couple pixels for the focus border.
     26   button_border->set_insets(gfx::Insets(0, 0, 0, 2));
     27   SetBorder(button_border.PassAs<Border>());
     28   SetFocusable(true);
     29 
     30   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
     31 
     32   // Unchecked/Unfocused images.
     33   SetCustomImage(false, false, STATE_NORMAL,
     34                  *rb.GetImageSkiaNamed(IDR_CHECKBOX));
     35   SetCustomImage(false, false, STATE_HOVERED,
     36                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_HOVER));
     37   SetCustomImage(false, false, STATE_PRESSED,
     38                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_PRESSED));
     39   SetCustomImage(false, false, STATE_DISABLED,
     40                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED));
     41 
     42   // Checked/Unfocused images.
     43   SetCustomImage(true, false, STATE_NORMAL,
     44                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED));
     45   SetCustomImage(true, false, STATE_HOVERED,
     46                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_HOVER));
     47   SetCustomImage(true, false, STATE_PRESSED,
     48                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_PRESSED));
     49   SetCustomImage(true, false, STATE_DISABLED,
     50                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_DISABLED));
     51 
     52   // Unchecked/Focused images.
     53   SetCustomImage(false, true, STATE_NORMAL,
     54                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED));
     55   SetCustomImage(false, true, STATE_HOVERED,
     56                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_HOVER));
     57   SetCustomImage(false, true, STATE_PRESSED,
     58                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_PRESSED));
     59 
     60   // Checked/Focused images.
     61   SetCustomImage(true, true, STATE_NORMAL,
     62                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED));
     63   SetCustomImage(true, true, STATE_HOVERED,
     64                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_HOVER));
     65   SetCustomImage(true, true, STATE_PRESSED,
     66                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_PRESSED));
     67 
     68   // Limit the checkbox height to match the legacy appearance.
     69   const gfx::Size preferred_size(LabelButton::GetPreferredSize());
     70   set_min_size(gfx::Size(0, preferred_size.height() + 4));
     71 }
     72 
     73 Checkbox::~Checkbox() {
     74 }
     75 
     76 void Checkbox::SetChecked(bool checked) {
     77   checked_ = checked;
     78   UpdateImage();
     79 }
     80 
     81 void Checkbox::Layout() {
     82   LabelButton::Layout();
     83 
     84   // Construct a focus painter that only surrounds the label area.
     85   gfx::Rect rect = label()->GetMirroredBounds();
     86   rect.Inset(-2, 3);
     87   SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets(
     88                       gfx::Insets(rect.y(), rect.x(),
     89                                   height() - rect.bottom(),
     90                                   width() - rect.right())));
     91 }
     92 
     93 const char* Checkbox::GetClassName() const {
     94   return kViewClassName;
     95 }
     96 
     97 void Checkbox::GetAccessibleState(ui::AXViewState* state) {
     98   LabelButton::GetAccessibleState(state);
     99   state->role = ui::AX_ROLE_CHECK_BOX;
    100   if (checked())
    101     state->AddStateFlag(ui::AX_STATE_CHECKED);
    102 }
    103 
    104 void Checkbox::OnFocus() {
    105   LabelButton::OnFocus();
    106   UpdateImage();
    107 }
    108 
    109 void Checkbox::OnBlur() {
    110   LabelButton::OnBlur();
    111   UpdateImage();
    112 }
    113 
    114 const gfx::ImageSkia& Checkbox::GetImage(ButtonState for_state) {
    115   const size_t checked_index = checked_ ? 1 : 0;
    116   const size_t focused_index = HasFocus() ? 1 : 0;
    117   if (for_state != STATE_NORMAL &&
    118       images_[checked_index][focused_index][for_state].isNull())
    119     return images_[checked_index][focused_index][STATE_NORMAL];
    120   return images_[checked_index][focused_index][for_state];
    121 }
    122 
    123 void Checkbox::SetCustomImage(bool checked,
    124                               bool focused,
    125                               ButtonState for_state,
    126                               const gfx::ImageSkia& image) {
    127   const size_t checked_index = checked ? 1 : 0;
    128   const size_t focused_index = focused ? 1 : 0;
    129   images_[checked_index][focused_index][for_state] = image;
    130   UpdateImage();
    131 }
    132 
    133 void Checkbox::NotifyClick(const ui::Event& event) {
    134   SetChecked(!checked());
    135   LabelButton::NotifyClick(event);
    136 }
    137 
    138 ui::NativeTheme::Part Checkbox::GetThemePart() const {
    139   return ui::NativeTheme::kCheckbox;
    140 }
    141 
    142 void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const {
    143   LabelButton::GetExtraParams(params);
    144   params->button.checked = checked_;
    145 }
    146 
    147 }  // namespace views
    148