123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /*
- This file is part of QTau
- Copyright (C) 2013-2018 Tobias "Tomoko" Platen <tplaten@posteo.de>
- Copyright (C) 2013 digited <https://github.com/digited>
- Copyright (C) 2010-2013 HAL@ShurabaP <https://github.com/haruneko>
- QTau 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.
- 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, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: GPL-3.0+
- */
- #include "ui/piano.h"
- #include <qevent.h>
- #include <qpainter.h>
- #include <QDebug>
- #include "ui/Config.h"
- const int CONST_PIANO_LABELHEIGHT = 14;
- const int CONST_PIANO_LABELWIDTH = 50;
- qtauPiano::qtauPiano(QWidget *parent)
- : QWidget(parent),
- _offset(0, 0),
- _labelCache(nullptr),
- _pressedKey(-1),
- _hoveredKey(-1) {
- // setup widget
- setFocusPolicy(Qt::NoFocus);
- setMouseTracking(true);
- installEventFilter(this);
- }
- #if 0
- bool qtauPiano::eventFilter(QObject *object, QEvent *event)
- {
- //if(object==this && (event->type()==QEvent::Enter || event->type()==QEvent::Leave))
- // onHover(event->type()==QEvent::Enter);
- return false;
- }
- #endif
- //----------------------------------------------------------------
- inline void cacheLbl(QPainter &p, QRect &r, const QString &txt, int &vOff,
- const QColor &offClr, const QColor &onClr) {
- r.moveTopLeft(QPoint(0, vOff));
- p.setPen(offClr);
- p.drawText(r, txt);
- r.moveLeft(CONST_PIANO_LABELWIDTH);
- p.setPen(onClr);
- p.drawText(r, txt);
- vOff += CONST_PIANO_LABELHEIGHT;
- }
- inline void whiteLbl(QPainter &p, QRect &r, const QString &txt, int &vOff) {
- cacheLbl(p, r, txt, vOff, QColor(cdef_color_piano_lbl_wh),
- QColor(cdef_color_piano_lbl_wh_on));
- }
- inline void blackLbl(QPainter &p, QRect &r, const QString &txt, int &vOff) {
- cacheLbl(p, r, txt, vOff, QColor(cdef_color_piano_lbl_bl),
- QColor(cdef_color_piano_lbl_bl_on));
- }
- //----------------------------------------------------------------
- qtauPiano::~qtauPiano() {}
- void qtauPiano::setOffset(int voff) {
- if (_offset.y() != voff) {
- _offset.setY(voff);
- update();
- }
- }
- void qtauPiano::configure(const SNoteSetup &newSetup) {
- _ns = newSetup;
- update();
- }
- // move to midi_support.c
- bool isBlack(int num) {
- num = num % 12;
- if (num == 1 || num == 3 || num == 6 || num == 8 || num == 10) return true;
- return false;
- }
- //--------------------------------------------
- void qtauPiano::paintEvent(QPaintEvent *event) {
- (void)event;
- QVector<QRect> whites;
- QVector<QRect> blacks;
- double pixels_per_semitone = _ns.octHeight / 12.0;
- int basenote = (_ns.baseOctave + _ns.numOctaves) * 12 -
- 1; // basenote is a B in a flipped geometry
- for (int i = _ns.baseOctave * 12; i <= basenote; i++) {
- int w = this->width();
- QRect r(0, (basenote - i) * pixels_per_semitone, w, pixels_per_semitone);
- if (isBlack(i))
- blacks.append(r);
- else
- whites.append(r);
- }
- QPainter p(this);
- p.translate(-_offset);
- p.setBrush(Qt::white);
- p.drawRects(whites);
- p.setBrush(QColor(cdef_color_black_key_bg));
- p.drawRects(blacks);
- int w = this->width();
- for (int i = 12; i < 96; i++) {
- QRect r(0, (95 - i) * pixels_per_semitone, w, pixels_per_semitone);
- if (i % 12 == 0) // draw hover notename (transposed)
- {
- int oct = i / 12 - 2;
- p.drawText(r, "C" + QVariant(oct).toString());
- }
- }
- if (_pressedKey >= 0) {
- QRect r(0, (basenote - _pressedKey) * pixels_per_semitone, w,
- pixels_per_semitone);
- p.setBrush(Qt::blue);
- p.drawRect(r);
- }
- }
- void qtauPiano::resizeEvent(QResizeEvent *event) {
- emit heightChanged(event->size().height());
- }
- //------------ input handling ---------------
- void qtauPiano::mouseDoubleClickEvent(QMouseEvent *event) { (void)event; }
- void qtauPiano::mouseMoveEvent(QMouseEvent *event) { (void)event; }
- void qtauPiano::mousePressEvent(QMouseEvent *event) {
- double y = event->y() + _offset.y();
- double pixels_per_semitone = _ns.octHeight / 12.0;
- int basenote = (_ns.baseOctave + _ns.numOctaves) * 12 -
- 1; // basenote is a B in a flipped geometry
- int ngeom = y / pixels_per_semitone;
- int nn = basenote - ngeom;
- _pressedKey = nn;
- this->repaint();
- emit keyPressed(nn - 12);
- }
- void qtauPiano::mouseReleaseEvent(QMouseEvent *event) {
- (void)event;
- emit keyReleased(_pressedKey - 12);
- _pressedKey = -1; // invalid
- this->repaint();
- }
- void qtauPiano::wheelEvent(QWheelEvent *event) {
- emit scrolled(event->delta());
- }
|