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/base/accessibility/accessible_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 string16& label)
     19     : LabelButton(NULL, label),
     20       checked_(false) {
     21   SetHorizontalAlignment(gfx::ALIGN_LEFT);
     22   LabelButtonBorder* button_border = static_cast<LabelButtonBorder*>(border());
     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   SetFocusable(true);
     28 
     29   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
     30 
     31   // Unchecked/Unfocused images.
     32   SetCustomImage(false, false, STATE_NORMAL,
     33                  *rb.GetImageSkiaNamed(IDR_CHECKBOX));
     34   SetCustomImage(false, false, STATE_HOVERED,
     35                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_HOVER));
     36   SetCustomImage(false, false, STATE_PRESSED,
     37                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_PRESSED));
     38   SetCustomImage(false, false, STATE_DISABLED,
     39                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED));
     40 
     41   // Checked/Unfocused images.
     42   SetCustomImage(true, false, STATE_NORMAL,
     43                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED));
     44   SetCustomImage(true, false, STATE_HOVERED,
     45                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_HOVER));
     46   SetCustomImage(true, false, STATE_PRESSED,
     47                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_PRESSED));
     48   SetCustomImage(true, false, STATE_DISABLED,
     49                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_DISABLED));
     50 
     51   // Unchecked/Focused images.
     52   SetCustomImage(false, true, STATE_NORMAL,
     53                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED));
     54   SetCustomImage(false, true, STATE_HOVERED,
     55                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_HOVER));
     56   SetCustomImage(false, true, STATE_PRESSED,
     57                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_PRESSED));
     58 
     59   // Checked/Focused images.
     60   SetCustomImage(true, true, STATE_NORMAL,
     61                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED));
     62   SetCustomImage(true, true, STATE_HOVERED,
     63                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_HOVER));
     64   SetCustomImage(true, true, STATE_PRESSED,
     65                  *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_PRESSED));
     66 
     67   // Limit the checkbox height to match the legacy appearance.
     68   const gfx::Size preferred_size(LabelButton::GetPreferredSize());
     69   set_min_size(gfx::Size(0, preferred_size.height() + 4));
     70 }
     71 
     72 Checkbox::~Checkbox() {
     73 }
     74 
     75 void Checkbox::SetChecked(bool checked) {
     76   checked_ = checked;
     77   UpdateImage();
     78 }
     79 
     80 void Checkbox::Layout() {
     81   LabelButton::Layout();
     82 
     83   // Construct a focus painter that only surrounds the label area.
     84   gfx::Rect rect = label()->GetMirroredBounds();
     85   rect.Inset(-2, 3);
     86   SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets(
     87                       gfx::Insets(rect.y(), rect.x(),
     88                                   height() - rect.bottom(),
     89                                   width() - rect.right())));
     90 }
     91 
     92 const char* Checkbox::GetClassName() const {
     93   return kViewClassName;
     94 }
     95 
     96 void Checkbox::GetAccessibleState(ui::AccessibleViewState* state) {
     97   LabelButton::GetAccessibleState(state);
     98   state->role = ui::AccessibilityTypes::ROLE_CHECKBUTTON;
     99   state->state = checked() ? ui::AccessibilityTypes::STATE_CHECKED : 0;
    100 }
    101 
    102 void Checkbox::OnFocus() {
    103   LabelButton::OnFocus();
    104   UpdateImage();
    105 }
    106 
    107 void Checkbox::OnBlur() {
    108   LabelButton::OnBlur();
    109   UpdateImage();
    110 }
    111 
    112 const gfx::ImageSkia& Checkbox::GetImage(ButtonState for_state) {
    113   const size_t checked_index = checked_ ? 1 : 0;
    114   const size_t focused_index = HasFocus() ? 1 : 0;
    115   if (for_state != STATE_NORMAL &&
    116       images_[checked_index][focused_index][for_state].isNull())
    117     return images_[checked_index][focused_index][STATE_NORMAL];
    118   return images_[checked_index][focused_index][for_state];
    119 }
    120 
    121 void Checkbox::SetCustomImage(bool checked,
    122                               bool focused,
    123                               ButtonState for_state,
    124                               const gfx::ImageSkia& image) {
    125   const size_t checked_index = checked ? 1 : 0;
    126   const size_t focused_index = focused ? 1 : 0;
    127   images_[checked_index][focused_index][for_state] = image;
    128   UpdateImage();
    129 }
    130 
    131 void Checkbox::NotifyClick(const ui::Event& event) {
    132   SetChecked(!checked());
    133   LabelButton::NotifyClick(event);
    134 }
    135 
    136 ui::NativeTheme::Part Checkbox::GetThemePart() const {
    137   return ui::NativeTheme::kCheckbox;
    138 }
    139 
    140 void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const {
    141   LabelButton::GetExtraParams(params);
    142   params->button.checked = checked_;
    143 }
    144 
    145 }  // namespace views
    146