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 #include "ui/views/controls/button/radio_button.h"
7 #include "base/logging.h"
8 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/events/event_utils.h"
11 #include "ui/resources/grit/ui_resources.h"
12 #include "ui/views/widget/widget.h"
17 const char RadioButton::kViewClassName
[] = "RadioButton";
19 RadioButton::RadioButton(const base::string16
& label
, int group_id
)
23 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
25 // Unchecked/Unfocused images.
26 SetCustomImage(false, false, STATE_NORMAL
,
27 *rb
.GetImageSkiaNamed(IDR_RADIO
));
28 SetCustomImage(false, false, STATE_HOVERED
,
29 *rb
.GetImageSkiaNamed(IDR_RADIO_HOVER
));
30 SetCustomImage(false, false, STATE_PRESSED
,
31 *rb
.GetImageSkiaNamed(IDR_RADIO_PRESSED
));
32 SetCustomImage(false, false, STATE_DISABLED
,
33 *rb
.GetImageSkiaNamed(IDR_RADIO_DISABLED
));
35 // Checked/Unfocused images.
36 SetCustomImage(true, false, STATE_NORMAL
,
37 *rb
.GetImageSkiaNamed(IDR_RADIO_CHECKED
));
38 SetCustomImage(true, false, STATE_HOVERED
,
39 *rb
.GetImageSkiaNamed(IDR_RADIO_CHECKED_HOVER
));
40 SetCustomImage(true, false, STATE_PRESSED
,
41 *rb
.GetImageSkiaNamed(IDR_RADIO_CHECKED_PRESSED
));
42 SetCustomImage(true, false, STATE_DISABLED
,
43 *rb
.GetImageSkiaNamed(IDR_RADIO_CHECKED_DISABLED
));
45 // Unchecked/Focused images.
46 SetCustomImage(false, true, STATE_NORMAL
,
47 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED
));
48 SetCustomImage(false, true, STATE_HOVERED
,
49 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED_HOVER
));
50 SetCustomImage(false, true, STATE_PRESSED
,
51 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED_PRESSED
));
53 // Checked/Focused images.
54 SetCustomImage(true, true, STATE_NORMAL
,
55 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED
));
56 SetCustomImage(true, true, STATE_HOVERED
,
57 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED_HOVER
));
58 SetCustomImage(true, true, STATE_PRESSED
,
59 *rb
.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED_PRESSED
));
62 RadioButton::~RadioButton() {
65 void RadioButton::SetChecked(bool checked
) {
66 if (checked
== RadioButton::checked())
69 // We can't just get the root view here because sometimes the radio
70 // button isn't attached to a root view (e.g., if it's part of a tab page
71 // that is currently not active).
72 View
* container
= parent();
73 while (container
&& container
->parent())
74 container
= container
->parent();
77 container
->GetViewsInGroup(GetGroup(), &other
);
78 for (Views::iterator
i(other
.begin()); i
!= other
.end(); ++i
) {
80 if (strcmp((*i
)->GetClassName(), kViewClassName
)) {
81 NOTREACHED() << "radio-button-nt has same group as other non "
82 "radio-button-nt views.";
85 RadioButton
* peer
= static_cast<RadioButton
*>(*i
);
86 peer
->SetChecked(false);
91 Checkbox::SetChecked(checked
);
94 const char* RadioButton::GetClassName() const {
95 return kViewClassName
;
98 void RadioButton::GetAccessibleState(ui::AXViewState
* state
) {
99 Checkbox::GetAccessibleState(state
);
100 state
->role
= ui::AX_ROLE_RADIO_BUTTON
;
103 View
* RadioButton::GetSelectedViewForGroup(int group
) {
105 GetWidget()->GetRootView()->GetViewsInGroup(group
, &views
);
109 for (Views::const_iterator
i(views
.begin()); i
!= views
.end(); ++i
) {
110 // REVIEW: why don't we check the runtime type like is done above?
111 RadioButton
* radio_button
= static_cast<RadioButton
*>(*i
);
112 if (radio_button
->checked())
118 bool RadioButton::IsGroupFocusTraversable() const {
119 // When focusing a radio button with tab/shift+tab, only the selected button
120 // from the group should be focused.
124 void RadioButton::OnFocus() {
127 ui::MouseEvent
event(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
128 ui::EventTimeForNow(), 0, 0);
129 LabelButton::NotifyClick(event
);
132 void RadioButton::NotifyClick(const ui::Event
& event
) {
133 // Set the checked state to true only if we are unchecked, since we can't
134 // be toggled on and off like a checkbox.
138 LabelButton::NotifyClick(event
);
141 ui::NativeTheme::Part
RadioButton::GetThemePart() const {
142 return ui::NativeTheme::kRadio
;