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
{
14 : style_(BUTTON_CLICKABLE
), state_(BUTTON_NORMAL
), is_pressed_(false) {
20 bool Button::CreateButton(uint32 id
,
21 const pp::Point
& origin
,
23 Control::Owner
* owner
,
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
))
38 normal_
= face_normal
;
39 highlighted_
= face_highlighted
;
40 pressed_
= face_pressed
;
46 void Button::Paint(pp::ImageData
* image_data
, const pp::Rect
& rc
) {
50 pp::Rect draw_rc
= rc
.Intersect(rect());
51 if (draw_rc
.IsEmpty())
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
) {
64 // Button handles mouse events only.
65 pp::MouseInputEvent
mouse_event(event
);
66 if (mouse_event
.is_null())
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);
77 owner()->SetCursor(id(), PP_CURSORTYPE_POINTER
);
78 owner()->SetEventCapture(id(), true);
81 switch (event
.GetType()) {
82 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
83 if (state_
== BUTTON_NORMAL
)
84 ChangeState(BUTTON_HIGHLIGHTED
, false);
86 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
87 if (mouse_event
.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT
) {
88 ChangeState(BUTTON_PRESSED
, false);
92 case PP_INPUTEVENT_TYPE_MOUSEUP
:
93 if (mouse_event
.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT
&&
98 // Since button has not been pressed, return false to allow other
99 // controls (scrollbar) to process mouse button up.
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.
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
)
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() {
138 case BUTTON_NORMAL
: return normal_
;
139 case BUTTON_HIGHLIGHTED
: return highlighted_
;
141 case BUTTON_PRESSED_STICKY
: return pressed_
;
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
))
157 if (state_
!= new_state
) {
159 owner()->Invalidate(id(), rect());
163 void Button::OnButtonClicked() {
165 case BUTTON_CLICKABLE
:
166 ChangeState(BUTTON_HIGHLIGHTED
, true);
167 owner()->OnEvent(id(), EVENT_ID_BUTTON_CLICKED
, NULL
);
170 SetPressedState(!IsPressed());
171 owner()->OnEvent(id(), EVENT_ID_BUTTON_STATE_CHANGED
, NULL
);
178 } // namespace chrome_pdf