1 /** 2 * File name: MidiKeyWidget.h 3 * Project: Geonkick (A kick synthesizer) 4 * 5 * Copyright (C) 2020 Iurie Nistor (http://iuriepage.wordpress.com) 6 * 7 * This file is part of Geonkick. 8 * 9 * GeonKick is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 3 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #ifndef GEONKICK_MIDIKEY_WIDGET_H 25 #define GEONKICK_MIDIKEY_WIDGET_H 26 27 #include "geonkick_widget.h" 28 #include "percussion_model.h" 29 30 #include <RkPainter.h> 31 32 class KeyCell { 33 public: KeyCell()34 constexpr KeyCell() : midiKey{0}, cellColumn{-1}, cellRow{-1} {} 35 friend constexpr bool operator==(const KeyCell &c1, const KeyCell &c2) 36 { 37 return c1.rect() == c2.rect() && c1.key() == c2.key() 38 && c1.column() == c2.column() && c1.row() == c2.row(); 39 } 40 41 friend constexpr bool operator!=(const KeyCell &c1, const KeyCell &c2) 42 { 43 return c1.rect() != c2.rect() || c1.key() != c2.key() 44 || c1.column() != c2.column() || c1.row() != c2.row(); 45 } setColumn(int col)46 constexpr void setColumn(int col) { cellColumn = col; } column()47 constexpr int column() const { return cellColumn; } setRow(int row)48 constexpr void setRow(int row) { cellRow = row; } row()49 constexpr int row() const { return cellRow; } setRect(const RkRect & r)50 constexpr void setRect(const RkRect &r) { cellRect = r; } rect()51 constexpr const RkRect& rect() const {return cellRect; } setKey(GeonkickTypes::MidiKey k)52 constexpr void setKey(GeonkickTypes::MidiKey k) { midiKey = k; } key()53 constexpr GeonkickTypes::MidiKey key() const { return midiKey; } isValid()54 constexpr bool isValid() const 55 { 56 return (cellColumn >= 0 && cellRow >= 0 57 && cellColumn <= 12 && cellRow <= 7) 58 && ((midiKey >= 21 && midiKey <= 109) 59 || (midiKey == GeonkickTypes::geonkickAnyKey)); 60 } 61 62 private: 63 RkRect cellRect; 64 GeonkickTypes::MidiKey midiKey; 65 int cellColumn; 66 int cellRow; 67 }; 68 69 class MidiKeyWidget: public GeonkickWidget 70 { 71 public: 72 MidiKeyWidget(GeonkickWidget *parent, 73 PercussionModel *model, 74 Rk::WindowFlags flag = Rk::WindowFlags::Popup); 75 RK_DECL_ACT(keySelected, 76 keySelected(GeonkickTypes::MidiKey key), 77 RK_ARG_TYPE(GeonkickTypes::MidiKey), 78 RK_ARG_VAL(key)); 79 RK_DECL_ACT(isAboutToClose, 80 isAboutToClose(), 81 RK_ARG_TYPE(), 82 RK_ARG_VAL()); 83 static RkString midiKeyToNote(GeonkickTypes::MidiKey key); 84 85 protected: 86 void drawCell(RkPainter &painter, GeonkickTypes::MidiKey key, int row, int col); 87 KeyCell getCell(int x, int y) const; 88 KeyCell getCell(GeonkickTypes::MidiKey key) const; 89 void paintWidget(RkPaintEvent *event) override; 90 void mouseButtonPressEvent(RkMouseEvent *event) override; 91 void mouseButtonReleaseEvent(RkMouseEvent *event) override; 92 void mouseMoveEvent(RkMouseEvent *event) override; 93 void onUpdateKey(PercussionModel::KeyIndex key); 94 void closeEvent(RkCloseEvent *event) override; 95 void hoverEvent(RkHoverEvent *event) override; 96 97 private: 98 PercussionModel *percussionModel; 99 RkSize cellSize; 100 int widgetPadding; 101 int midiRows; 102 int midiColumns; 103 KeyCell selectedCell; 104 KeyCell hoverCell; 105 }; 106 107 #endif // GEONKICK_MIDIKEY_WIDGET_H 108