[Mac] A more robust way to ensure panels avoid key status on window close
[chromium-blink-merge.git] / pdf / button.cc
blob3a30164c14792e4d9c285ee3da89ed8d06c1a19b
1 // Copyright (c) 2010 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 "pdf/button.h"
7 #include "base/logging.h"
8 #include "pdf/draw_utils.h"
9 #include "ppapi/cpp/input_event.h"
11 namespace chrome_pdf {
13 Button::Button()
14 : style_(BUTTON_CLICKABLE), state_(BUTTON_NORMAL), is_pressed_(false) {
17 Button::~Button() {
20 bool Button::CreateButton(uint32 id,
21 const pp::Point& origin,
22 bool visible,
23 Control::Owner* owner,
24 ButtonStyle style,
25 const pp::ImageData& face_normal,
26 const pp::ImageData& face_highlighted,
27 const pp::ImageData& face_pressed) {
28 DCHECK(face_normal.size().GetArea());
29 DCHECK(face_normal.size() == face_highlighted.size());
30 DCHECK(face_normal.size() == face_pressed.size());
32 pp::Rect rc(origin, face_normal.size());
33 if (!Control::Create(id, rc, visible, owner))
34 return false;
36 style_ = style;
38 normal_ = face_normal;
39 highlighted_ = face_highlighted;
40 pressed_ = face_pressed;
42 return true;
46 void Button::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
47 if (!visible())
48 return;
50 pp::Rect draw_rc = rc.Intersect(rect());
51 if (draw_rc.IsEmpty())
52 return;
54 pp::Point origin = draw_rc.point();
55 draw_rc.Offset(-rect().x(), -rect().y());
57 AlphaBlend(GetCurrentImage(), draw_rc, image_data, origin, transparency());
60 bool Button::HandleEvent(const pp::InputEvent& event) {
61 if (!visible())
62 return false;
64 // Button handles mouse events only.
65 pp::MouseInputEvent mouse_event(event);
66 if (mouse_event.is_null())
67 return false;
69 pp::Point pt = mouse_event.GetPosition();
70 if (!rect().Contains(pt) ||
71 event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) {
72 ChangeState(BUTTON_NORMAL, false);
73 owner()->SetEventCapture(id(), false);
74 return false;
77 owner()->SetCursor(id(), PP_CURSORTYPE_POINTER);
78 owner()->SetEventCapture(id(), true);
80 bool handled = true;
81 switch (event.GetType()) {
82 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
83 if (state_ == BUTTON_NORMAL)
84 ChangeState(BUTTON_HIGHLIGHTED, false);
85 break;
86 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
87 if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
88 ChangeState(BUTTON_PRESSED, false);
89 is_pressed_ = true;
91 break;
92 case PP_INPUTEVENT_TYPE_MOUSEUP:
93 if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT &&
94 is_pressed_) {
95 OnButtonClicked();
96 is_pressed_ = false;
97 } else {
98 // Since button has not been pressed, return false to allow other
99 // controls (scrollbar) to process mouse button up.
100 return false;
102 break;
103 default:
104 handled = false;
105 break;
108 return handled;
111 void Button::OnEventCaptureReleased() {
112 ChangeState(BUTTON_NORMAL, false);
115 void Button::Show(bool visible, bool invalidate) {
116 // If button become invisible, remove pressed flag.
117 if (!visible)
118 is_pressed_ = false;
119 Control::Show(visible, invalidate);
122 void Button::AdjustTransparency(uint8 transparency, bool invalidate) {
123 // If button become invisible, remove pressed flag.
124 if (transparency == kTransparentAlpha)
125 is_pressed_ = false;
126 Control::AdjustTransparency(transparency, invalidate);
129 void Button::SetPressedState(bool pressed) {
130 if (style_ == BUTTON_STATE) {
131 if (IsPressed() != pressed)
132 ChangeState(pressed ? BUTTON_PRESSED_STICKY : BUTTON_NORMAL, true);
136 const pp::ImageData& Button::GetCurrentImage() {
137 switch (state_) {
138 case BUTTON_NORMAL: return normal_;
139 case BUTTON_HIGHLIGHTED: return highlighted_;
140 case BUTTON_PRESSED:
141 case BUTTON_PRESSED_STICKY: return pressed_;
143 NOTREACHED();
144 return normal_;
147 void Button::ChangeState(ButtonState new_state, bool force) {
148 if (style_ == BUTTON_STATE && !force) {
149 // If button is a state button and pressed state is sticky,
150 // user have to click on this button again to unpress it.
151 if ((state_ == BUTTON_PRESSED_STICKY && new_state != BUTTON_PRESSED_STICKY)
153 (state_ != BUTTON_PRESSED_STICKY && new_state == BUTTON_PRESSED_STICKY))
154 return;
157 if (state_ != new_state) {
158 state_ = new_state;
159 owner()->Invalidate(id(), rect());
163 void Button::OnButtonClicked() {
164 switch (style_) {
165 case BUTTON_CLICKABLE:
166 ChangeState(BUTTON_HIGHLIGHTED, true);
167 owner()->OnEvent(id(), EVENT_ID_BUTTON_CLICKED, NULL);
168 break;
169 case BUTTON_STATE:
170 SetPressedState(!IsPressed());
171 owner()->OnEvent(id(), EVENT_ID_BUTTON_STATE_CHANGED, NULL);
172 break;
173 default:
174 NOTREACHED();
178 } // namespace chrome_pdf