/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * knob.cc * * Thu Feb 28 07:37:27 CET 2013 * Copyright 2013 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo 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 3 of the License, or * (at your option) any later version. * * DrumGizmo 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 DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "knob.h" #include "painter.h" #include #include // M_PI is not defined in math.h if __STRICT_ANSI__ is defined. #ifdef __STRICT_ANSI__ #undef __STRICT_ANSI__ #endif #include namespace GUI { Knob::Knob(Widget *parent) : Widget(parent) , img_knob(":knob.png") { state = up; maximum = 1.0; minimum = 0.0; currentValue = minimum; mouse_offset_x = 0; } void Knob::setValue(float value) { internalSetValue(value); } float Knob::value() { return currentValue; } void Knob::scrollEvent(ScrollEvent* scrollEvent) { float value = currentValue - (scrollEvent->delta / 200.0); internalSetValue(value); } void Knob::mouseMoveEvent(MouseMoveEvent* mouseMoveEvent) { if(state == down) { if(mouse_offset_x == (mouseMoveEvent->x + (-1 * mouseMoveEvent->y))) { return; } float dval = mouse_offset_x - (mouseMoveEvent->x + (-1 * mouseMoveEvent->y)); float value = currentValue - (dval / 300.0); internalSetValue(value); mouse_offset_x = mouseMoveEvent->x + (-1 * mouseMoveEvent->y); } } void Knob::keyEvent(KeyEvent* keyEvent) { if(keyEvent->direction != Direction::up) { return; } float value = currentValue; switch(keyEvent->keycode) { case Key::up: value += 0.01; break; case Key::down: value -= 0.01; break; case Key::right: value += 0.01; break; case Key::left: value -= 0.01; break; case Key::home: value = 0; break; case Key::end: value = 1; break; default: break; } internalSetValue(value); } void Knob::buttonEvent(ButtonEvent* buttonEvent) { if(buttonEvent->direction == Direction::down) { state = down; mouse_offset_x = buttonEvent->x + (-1 * buttonEvent->y); } if(buttonEvent->direction == Direction::up) { state = up; mouse_offset_x = buttonEvent->x + (-1 * buttonEvent->y); clicked(); } } void Knob::repaintEvent(RepaintEvent* repaintEvent) { int diameter = (width()>height()?height():width()); int radius = diameter / 2; int center_x = width() / 2; int center_y = height() / 2; Painter p(*this); p.clear(); p.drawImageStretched(0, 0, img_knob, diameter, diameter); char buf[64]; sprintf(buf, "%.2f", currentValue * maximum); p.drawText(center_x - font.textWidth(buf) / 2 + 1, center_y + font.textHeight(buf) / 2 + 1, font, buf); // Make it start from 20% and stop at 80% double padval = currentValue * 0.8 + 0.1; double from_x = sin((-1 * padval + 1) * 2 * M_PI) * radius * 0.6; double from_y = cos((-1 * padval + 1) * 2 * M_PI) * radius * 0.6; double to_x = sin((-1 * padval + 1) * 2 * M_PI) * radius * 0.8; double to_y = cos((-1 * padval + 1) * 2 * M_PI) * radius * 0.8; // Draw "fat" line by drawing 9 lines with moved start/ending points. p.setColour(Colour(1, 0, 0, 1)); for(int _x = -1; _x < 2; _x++) { for(int _y = -1; _y < 2; _y++) { p.drawLine(from_x + center_x + _x, from_y + center_y + _y, to_x + center_x + _x, to_y + center_y + _y); } } } void Knob::internalSetValue(float value) { if(value < minimum) { value = minimum; } if(value > maximum) { value = maximum; } if(value == currentValue) { return; } currentValue = value; valueChangedNotifier(currentValue); repaintEvent(nullptr); } } // GUI::