diff options
Diffstat (limited to 'xfa_test/pdf/button.cc')
-rw-r--r-- | xfa_test/pdf/button.cc | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/xfa_test/pdf/button.cc b/xfa_test/pdf/button.cc new file mode 100644 index 0000000000..3a30164c14 --- /dev/null +++ b/xfa_test/pdf/button.cc @@ -0,0 +1,179 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pdf/button.h" + +#include "base/logging.h" +#include "pdf/draw_utils.h" +#include "ppapi/cpp/input_event.h" + +namespace chrome_pdf { + +Button::Button() + : style_(BUTTON_CLICKABLE), state_(BUTTON_NORMAL), is_pressed_(false) { +} + +Button::~Button() { +} + +bool Button::CreateButton(uint32 id, + const pp::Point& origin, + bool visible, + Control::Owner* owner, + ButtonStyle style, + const pp::ImageData& face_normal, + const pp::ImageData& face_highlighted, + const pp::ImageData& face_pressed) { + DCHECK(face_normal.size().GetArea()); + DCHECK(face_normal.size() == face_highlighted.size()); + DCHECK(face_normal.size() == face_pressed.size()); + + pp::Rect rc(origin, face_normal.size()); + if (!Control::Create(id, rc, visible, owner)) + return false; + + style_ = style; + + normal_ = face_normal; + highlighted_ = face_highlighted; + pressed_ = face_pressed; + + return true; +} + + +void Button::Paint(pp::ImageData* image_data, const pp::Rect& rc) { + if (!visible()) + return; + + pp::Rect draw_rc = rc.Intersect(rect()); + if (draw_rc.IsEmpty()) + return; + + pp::Point origin = draw_rc.point(); + draw_rc.Offset(-rect().x(), -rect().y()); + + AlphaBlend(GetCurrentImage(), draw_rc, image_data, origin, transparency()); +} + +bool Button::HandleEvent(const pp::InputEvent& event) { + if (!visible()) + return false; + + // Button handles mouse events only. + pp::MouseInputEvent mouse_event(event); + if (mouse_event.is_null()) + return false; + + pp::Point pt = mouse_event.GetPosition(); + if (!rect().Contains(pt) || + event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) { + ChangeState(BUTTON_NORMAL, false); + owner()->SetEventCapture(id(), false); + return false; + } + + owner()->SetCursor(id(), PP_CURSORTYPE_POINTER); + owner()->SetEventCapture(id(), true); + + bool handled = true; + switch (event.GetType()) { + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + if (state_ == BUTTON_NORMAL) + ChangeState(BUTTON_HIGHLIGHTED, false); + break; + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) { + ChangeState(BUTTON_PRESSED, false); + is_pressed_ = true; + } + break; + case PP_INPUTEVENT_TYPE_MOUSEUP: + if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT && + is_pressed_) { + OnButtonClicked(); + is_pressed_ = false; + } else { + // Since button has not been pressed, return false to allow other + // controls (scrollbar) to process mouse button up. + return false; + } + break; + default: + handled = false; + break; + } + + return handled; +} + +void Button::OnEventCaptureReleased() { + ChangeState(BUTTON_NORMAL, false); +} + +void Button::Show(bool visible, bool invalidate) { + // If button become invisible, remove pressed flag. + if (!visible) + is_pressed_ = false; + Control::Show(visible, invalidate); +} + +void Button::AdjustTransparency(uint8 transparency, bool invalidate) { + // If button become invisible, remove pressed flag. + if (transparency == kTransparentAlpha) + is_pressed_ = false; + Control::AdjustTransparency(transparency, invalidate); +} + +void Button::SetPressedState(bool pressed) { + if (style_ == BUTTON_STATE) { + if (IsPressed() != pressed) + ChangeState(pressed ? BUTTON_PRESSED_STICKY : BUTTON_NORMAL, true); + } +} + +const pp::ImageData& Button::GetCurrentImage() { + switch (state_) { + case BUTTON_NORMAL: return normal_; + case BUTTON_HIGHLIGHTED: return highlighted_; + case BUTTON_PRESSED: + case BUTTON_PRESSED_STICKY: return pressed_; + } + NOTREACHED(); + return normal_; +} + +void Button::ChangeState(ButtonState new_state, bool force) { + if (style_ == BUTTON_STATE && !force) { + // If button is a state button and pressed state is sticky, + // user have to click on this button again to unpress it. + if ((state_ == BUTTON_PRESSED_STICKY && new_state != BUTTON_PRESSED_STICKY) + || + (state_ != BUTTON_PRESSED_STICKY && new_state == BUTTON_PRESSED_STICKY)) + return; + } + + if (state_ != new_state) { + state_ = new_state; + owner()->Invalidate(id(), rect()); + } +} + +void Button::OnButtonClicked() { + switch (style_) { + case BUTTON_CLICKABLE: + ChangeState(BUTTON_HIGHLIGHTED, true); + owner()->OnEvent(id(), EVENT_ID_BUTTON_CLICKED, NULL); + break; + case BUTTON_STATE: + SetPressedState(!IsPressed()); + owner()->OnEvent(id(), EVENT_ID_BUTTON_STATE_CHANGED, NULL); + break; + default: + NOTREACHED(); + } +} + +} // namespace chrome_pdf + |