1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any purpose with 6 * or without fee is hereby granted, provided that the above copyright notice and this 7 * permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN 11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef DGL_COMMON_HPP_INCLUDED 18 #define DGL_COMMON_HPP_INCLUDED 19 20 #include "../ImageWidgets.hpp" 21 22 START_NAMESPACE_DGL 23 24 // ----------------------------------------------------------------------- 25 26 struct ButtonImpl { 27 enum State { 28 kStateNormal = 0, 29 kStateHover, 30 kStateDown 31 }; 32 33 int button; 34 int state; 35 Widget* self; 36 37 ImageButton::Callback* callback_img; 38 ButtonImplButtonImpl39 ButtonImpl(Widget* const s) noexcept 40 : button(-1), 41 state(kStateNormal), 42 self(s), 43 callback_img(nullptr) {} 44 onMouseButtonImpl45 bool onMouse(const Widget::MouseEvent& ev) 46 { 47 // button was released, handle it now 48 if (button != -1 && ! ev.press) 49 { 50 DISTRHO_SAFE_ASSERT(state == kStateDown); 51 52 // release button 53 const int button2 = button; 54 button = -1; 55 56 // cursor was moved outside the button bounds, ignore click 57 if (! self->contains(ev.pos)) 58 { 59 state = kStateNormal; 60 self->repaint(); 61 return true; 62 } 63 64 // still on bounds, register click 65 state = kStateHover; 66 self->repaint(); 67 68 if (callback_img != nullptr) 69 callback_img->imageButtonClicked((ImageButton*)self, button2); 70 71 return true; 72 } 73 74 // button was pressed, wait for release 75 if (ev.press && self->contains(ev.pos)) 76 { 77 button = ev.button; 78 state = kStateDown; 79 self->repaint(); 80 return true; 81 } 82 83 return false; 84 } 85 onMotionButtonImpl86 bool onMotion(const Widget::MotionEvent& ev) 87 { 88 // keep pressed 89 if (button != -1) 90 return true; 91 92 if (self->contains(ev.pos)) 93 { 94 // check if entering hover 95 if (state == kStateNormal) 96 { 97 state = kStateHover; 98 self->repaint(); 99 return true; 100 } 101 } 102 else 103 { 104 // check if exiting hover 105 if (state == kStateHover) 106 { 107 state = kStateNormal; 108 self->repaint(); 109 return true; 110 } 111 } 112 113 return false; 114 } 115 116 DISTRHO_PREVENT_HEAP_ALLOCATION 117 DISTRHO_DECLARE_NON_COPY_STRUCT(ButtonImpl) 118 }; 119 120 // ----------------------------------------------------------------------- 121 122 END_NAMESPACE_DGL 123 124 #endif // DGL_APP_PRIVATE_DATA_HPP_INCLUDED 125