// ---------------------------------------------------------------------- // // Copyright (C) 2010-2012 Fons Adriaensen // Modified by falkTX on Jan 2015 for inclusion in Carla // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // ---------------------------------------------------------------------- #include #include #include #include "rotary.h" namespace AT1 { int RotaryCtl::_wb_up = 4; int RotaryCtl::_wb_dn = 5; int RotaryCtl::_keymod = 0; int RotaryCtl::_button = 0; int RotaryCtl::_rcount = 0; int RotaryCtl::_rx = 0; int RotaryCtl::_ry = 0; RotaryCtl::RotaryCtl (X_window *parent, X_callback *cbobj, int cbind, RotaryGeom *rgeom, int xp, int yp) : X_window (parent, rgeom->_x0 + xp, rgeom->_y0 + yp, rgeom->_dx, rgeom->_dy, rgeom->_backg->pixel), _cbobj (cbobj), _cbind (cbind), _rgeom (rgeom), _state (0), _count (0), _value (0), _angle (0) { x_add_events ( ExposureMask | Button1MotionMask | ButtonPressMask | ButtonReleaseMask); _cairo->initIfNeeded(parent->disp()); _cairotype = _cairo->type; _cairosurf = _cairo->surf; } RotaryCtl::~RotaryCtl (void) { } void RotaryCtl::handle_event (XEvent *E) { switch (E->type) { case Expose: render (); break; case ButtonPress: bpress ((XButtonEvent *) E); break; case ButtonRelease: brelse ((XButtonEvent *) E); break; case MotionNotify: motion ((XMotionEvent *) E); break; default: fprintf (stderr, "RotaryCtl: event %d\n", E->type ); } } void RotaryCtl::bpress (XButtonEvent *E) { int r = 0; double d; d = hypot (E->x - _rgeom->_xref, E->y - _rgeom->_yref); if (d > _rgeom->_rad + 3) return; _keymod = E->state; if (E->button < 4) { _rx = E->x; _ry = E->y; _button = E->button; r = handle_button (); _rcount = _count; } else if (_button) return; else if ((int)E->button == _wb_up) { r = handle_mwheel (1); } else if ((int)E->button == _wb_dn) { r = handle_mwheel (-1); } if (r) { callback (r); render (); } } void RotaryCtl::brelse (XButtonEvent *E) { if (_button == (int)E->button) { _button = 0; callback (RELSE); } } void RotaryCtl::motion (XMotionEvent *E) { int dx, dy, r; if (_button) { _keymod = E->state; dx = E->x - _rx; dy = E->y - _ry; r = handle_motion (dx, dy); if (r) { callback (r); render (); } } } void RotaryCtl::set_state (int s) { if (_state != s) { _state = s; render (); } } void RotaryCtl::render (void) { XImage *I; double a, c, r, x, y; I = _rgeom->_image [_state]; XPutImage (dpy (), win (), dgc (), I, _rgeom->_x0, _rgeom->_y0, 0, 0, _rgeom->_dx, _rgeom->_dy); cairo_xlib_surface_set_drawable (_cairosurf, win(), _rgeom->_dx, _rgeom->_dy); c = _rgeom->_lncol [_state] ? 1.0 : 0.0; a = _angle * M_PI / 180; r = _rgeom->_rad; x = _rgeom->_xref; y = _rgeom->_yref; cairo_new_path (_cairotype); cairo_move_to (_cairotype, x, y); x += r * sin (a); y -= r * cos (a); cairo_line_to (_cairotype, x, y); cairo_set_source_rgb (_cairotype, c, c, c); cairo_set_line_width (_cairotype, 2.2); cairo_stroke (_cairotype); } }