hydrogen 1.2.3
PatternEditorPanel.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2024 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#include <core/Hydrogen.h>
26#include <core/Basics/Pattern.h>
28#include <core/EventQueue.h>
29using namespace H2Core;
30
31
32#include "HydrogenApp.h"
33#include "PatternEditorPanel.h"
35#include "PatternEditorRuler.h"
36#include "NotePropertiesRuler.h"
37#include "DrumPatternEditor.h"
38#include "PianoRollEditor.h"
39
40#include "../UndoActions.h"
41#include "../MainForm.h"
42#include "../Widgets/Button.h"
44#include "../Widgets/Fader.h"
46#include "../Widgets/LCDCombo.h"
48#include "../WidgetScrollArea.h"
49
50#include "../CommonStrings.h"
52
53#include <cmath>
54
55
57{
59
60 QFont font( Preferences::get_instance()->getApplicationFontFamily(), getPointSize( pPref->getFontSize() ) );
61 font.setBold( true );
62 m_pSLlabel->setFont( font );
63 m_pSLlabel->setText( Hydrogen::get_instance()->getLastLoadedDrumkitName() );
64}
65
66
68 : QWidget( pParent )
69 , m_pPattern( nullptr )
70 , m_nSelectedPatternNumber( -1 )
71 , m_bArmPatternSizeSpinBoxes( true )
72{
73 setAcceptDrops(true);
74
76
77 QFont boldFont( pPref->getApplicationFontFamily(), getPointSize( pPref->getFontSize() ) );
78 boldFont.setBold( true );
79
82
83 // Spacing between a label and the widget to its label.
84 const int nLabelSpacing = 6;
85// Editor TOP
86
87 m_pEditorTop1 = new QWidget( nullptr );
88 m_pEditorTop1->setFixedHeight(24);
89 m_pEditorTop1->setObjectName( "editor1" );
90
91 m_pEditorTop2 = new QWidget( nullptr );
92 m_pEditorTop2->setFixedHeight( 24 );
93 m_pEditorTop2->setObjectName( "editor2" );
94
95 QHBoxLayout *m_pEditorTop1_hbox = new QHBoxLayout( m_pEditorTop1 );
96 m_pEditorTop1_hbox->setSpacing( 0 );
97 m_pEditorTop1_hbox->setMargin( 0 );
98 m_pEditorTop1_hbox->setAlignment( Qt::AlignLeft );
99
100 QHBoxLayout *m_pEditorTop1_hbox_2 = new QHBoxLayout( m_pEditorTop2 );
101 m_pEditorTop1_hbox_2->setSpacing( 2 );
102 m_pEditorTop1_hbox_2->setMargin( 0 );
103 m_pEditorTop1_hbox_2->setAlignment( Qt::AlignLeft );
104
105
106 //soundlibrary name
107 m_pSLlabel = new QLabel( nullptr );
108 m_pSLlabel->setFont( boldFont );
109 m_pSLlabel->setText( Hydrogen::get_instance()->getLastLoadedDrumkitName() );
110 m_pSLlabel->setFixedSize( 170, 20 );
111 m_pSLlabel->move( 10, 3 );
112 m_pSLlabel->setToolTip( tr( "Loaded Soundlibrary" ) );
113 m_pEditorTop1_hbox->addWidget( m_pSLlabel );
114
115//wolke some background images back_size_res
116 m_pSizeResol = new QWidget( nullptr );
117 m_pSizeResol->setObjectName( "sizeResol" );
118 m_pSizeResol->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
119 m_pSizeResol->move( 0, 3 );
120 m_pEditorTop1_hbox_2->addWidget( m_pSizeResol );
121
122 QHBoxLayout* pSizeResolLayout = new QHBoxLayout( m_pSizeResol );
123 pSizeResolLayout->setContentsMargins( 2, 0, 2, 0 );
124 pSizeResolLayout->setSpacing( 2 );
125
126 // PATTERN size
127 m_pPatternSizeLbl = new ClickableLabel( m_pSizeResol, QSize( 0, 0 ), HydrogenApp::get_instance()->getCommonStrings()->getPatternSizeLabel(), ClickableLabel::Color::Dark );
128 m_pPatternSizeLbl->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
129 pSizeResolLayout->addWidget( m_pPatternSizeLbl );
130
131 m_pLCDSpinBoxNumerator = new LCDSpinBox( this, QSize( 62, 20 ), LCDSpinBox::Type::Double, 0.1, 16.0, true );
134 connect( m_pLCDSpinBoxNumerator, SIGNAL( valueChanged( double ) ), this, SLOT( patternSizeChanged( double ) ) );
135 m_pLCDSpinBoxNumerator->setKeyboardTracking( false );
136 m_pLCDSpinBoxNumerator->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
137 pSizeResolLayout->addWidget( m_pLCDSpinBoxNumerator );
138
139 QLabel* pLabel1 = new ClickableLabel( m_pSizeResol, QSize( 4, 13 ), "/", ClickableLabel::Color::Dark );
140 pLabel1->resize( QSize( 20, 17 ) );
141 pLabel1->setText( "/" );
142 pLabel1->setFont( boldFont );
143 pLabel1->setToolTip( tr( "You can use the '/' inside the pattern size spin boxes to switch back and forth." ) );
144 pLabel1->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
145 pSizeResolLayout->addWidget( pLabel1 );
146
147 m_pLCDSpinBoxDenominator = new LCDSpinBox( m_pSizeResol, QSize( 48, 20 ), LCDSpinBox::Type::Int, 1, 192, true );
150 connect( m_pLCDSpinBoxDenominator, SIGNAL( valueChanged( double ) ), this, SLOT( patternSizeChanged( double ) ) );
151 m_pLCDSpinBoxDenominator->setKeyboardTracking( false );
152 m_pLCDSpinBoxDenominator->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
153 pSizeResolLayout->addWidget( m_pLCDSpinBoxDenominator );
154 pSizeResolLayout->addSpacing( nLabelSpacing );
155
156 // GRID resolution
157 m_pResolutionLbl = new ClickableLabel( m_pSizeResol, QSize( 0, 0 ), HydrogenApp::get_instance()->getCommonStrings()->getResolutionLabel(), ClickableLabel::Color::Dark );
158 m_pResolutionLbl->setAlignment( Qt::AlignRight );
159 m_pResolutionLbl->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
160 pSizeResolLayout->addWidget( m_pResolutionLbl );
161
162 m_pResolutionCombo = new LCDCombo( m_pSizeResol, QSize( 0, 0 ), true );
163 // Large enough for "1/32T" to be fully visible at large font size.
164 // m_pResolutionCombo->setToolTip(tr( "Select grid resolution" ));
165 m_pResolutionCombo->insertItem( 0, QString( "1/4 - " )
166 .append( tr( "quarter" ) ) );
167 m_pResolutionCombo->insertItem( 1, QString( "1/8 - " )
168 .append( tr( "eighth" ) ) );
169 m_pResolutionCombo->insertItem( 2, QString( "1/16 - " )
170 .append( tr( "sixteenth" ) ) );
171 m_pResolutionCombo->insertItem( 3, QString( "1/32 - " )
172 .append( tr( "thirty-second" ) ) );
173 m_pResolutionCombo->insertItem( 4, QString( "1/64 - " )
174 .append( tr( "sixty-fourth" ) ) );
175 m_pResolutionCombo->insertSeparator( 5 );
176 m_pResolutionCombo->insertItem( 6, QString( "1/4T - " )
177 .append( tr( "quarter triplet" ) ) );
178 m_pResolutionCombo->insertItem( 7, QString( "1/8T - " )
179 .append( tr( "eighth triplet" ) ) );
180 m_pResolutionCombo->insertItem( 8, QString( "1/16T - " )
181 .append( tr( "sixteenth triplet" ) ) );
182 m_pResolutionCombo->insertItem( 9, QString( "1/32T - " )
183 .append( tr( "thirty-second triplet" ) ) );
184 m_pResolutionCombo->insertSeparator( 10 );
185 m_pResolutionCombo->insertItem( 11, tr( "off" ) );
186 m_pResolutionCombo->setMinimumSize( QSize( 24, 18 ) );
187 m_pResolutionCombo->setMaximumSize( QSize( 500, 18 ) );
188 m_pResolutionCombo->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
189 // is triggered from inside PatternEditorPanel()
190 connect( m_pResolutionCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( gridResolutionChanged( int ) ) );
191 pSizeResolLayout->addWidget( m_pResolutionCombo );
192
193 m_pRec = new QWidget( nullptr );
194 m_pRec->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
195 m_pRec->setObjectName( "pRec" );
196 m_pRec->move( 0, 3 );
197 m_pEditorTop1_hbox_2->addWidget( m_pRec );
198
199 QHBoxLayout* pRecLayout = new QHBoxLayout( m_pRec );
200 pRecLayout->setContentsMargins( 2, 0, 2, 0 );
201 pRecLayout->setSpacing( 2 );
202
203 // Hear notes btn
204 m_pHearNotesLbl = new ClickableLabel( m_pRec, QSize( 0, 0 ), HydrogenApp::get_instance()->getCommonStrings()->getHearNotesLabel(), ClickableLabel::Color::Dark );
205 m_pHearNotesLbl->setAlignment( Qt::AlignRight );
206 m_pHearNotesLbl->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
207 pRecLayout->addWidget( m_pHearNotesLbl );
208
209 m_pHearNotesBtn = new Button( m_pRec, QSize( 21, 18 ), Button::Type::Toggle,
210 "speaker.svg", "", false, QSize( 15, 13 ),
211 tr( "Hear new notes" ), false, true );
212 connect( m_pHearNotesBtn, SIGNAL( clicked() ), this, SLOT( hearNotesBtnClick() ) );
213 m_pHearNotesBtn->setChecked( pPref->getHearNewNotes() );
214 m_pHearNotesBtn->setObjectName( "HearNotesBtn" );
215 m_pHearNotesBtn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
216 pRecLayout->addWidget( m_pHearNotesBtn );
217 pRecLayout->addSpacing( nLabelSpacing );
218
219 // quantize
220 m_pQuantizeEventsLbl = new ClickableLabel( m_pRec, QSize( 0, 0 ), HydrogenApp::get_instance()->getCommonStrings()->getQuantizeEventsLabel(), ClickableLabel::Color::Dark );
221 m_pQuantizeEventsLbl->setAlignment( Qt::AlignRight );
222 m_pQuantizeEventsLbl->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
223 pRecLayout->addWidget( m_pQuantizeEventsLbl );
224
225 m_pQuantizeEventsBtn = new Button( m_pRec, QSize( 21, 18 ),
226 Button::Type::Toggle, "quantization.svg",
227 "", false, QSize( 15, 14 ),
228 tr( "Quantize keyboard/midi events to grid" ),
229 false, true );
230 m_pQuantizeEventsBtn->setChecked( pPref->getQuantizeEvents() );
231 m_pQuantizeEventsBtn->setObjectName( "QuantizeEventsBtn" );
232 connect( m_pQuantizeEventsBtn, SIGNAL( clicked() ), this, SLOT( quantizeEventsBtnClick() ) );
233 m_pQuantizeEventsBtn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
234 pRecLayout->addWidget( m_pQuantizeEventsBtn );
235 pRecLayout->addSpacing( nLabelSpacing );
236
237 // Editor mode
238 m_pShowPianoLbl = new ClickableLabel( m_pRec, QSize( 0, 0 ), HydrogenApp::get_instance()->getCommonStrings()->getShowPianoLabel(), ClickableLabel::Color::Dark );
239 m_pShowPianoLbl->setAlignment( Qt::AlignRight );
240 m_pShowPianoLbl->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
241 pRecLayout->addWidget( m_pShowPianoLbl );
242
243 __show_drum_btn = new Button( m_pRec, QSize( 25, 18 ), Button::Type::Push, "drum.svg", "", false, QSize( 17, 13 ), HydrogenApp::get_instance()->getCommonStrings()->getShowPianoRollEditorTooltip() );
244 __show_drum_btn->setObjectName( "ShowDrumBtn" );
245 connect( __show_drum_btn, SIGNAL( clicked() ), this, SLOT( showDrumEditorBtnClick() ) );
246 __show_drum_btn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
247 pRecLayout->addWidget( __show_drum_btn );
248
249 m_pEditorTop1_hbox_2->addStretch();
250
251 // Since the button to activate the piano roll is shown
252 // initially, both buttons get the same tooltip. Actually only the
253 // last one does need a tooltip since it will be shown regardless
254 // of whether it is hidden or not. But since this behavior might
255 // change in future versions of Qt the tooltip will be assigned to
256 // both of them.
257 __show_piano_btn = new Button( m_pRec, QSize( 25, 18 ), Button::Type::Push, "piano.svg", "", false, QSize( 19, 15 ), HydrogenApp::get_instance()->getCommonStrings()->getShowPianoRollEditorTooltip() );
258 __show_piano_btn->move( 178, 1 );
259 __show_piano_btn->setObjectName( "ShowPianoBtn" );
260 __show_piano_btn->hide();
261 connect( __show_piano_btn, SIGNAL( clicked() ), this, SLOT( showDrumEditorBtnClick() ) );
262 __show_piano_btn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
263 pRecLayout->addWidget( __show_piano_btn );
264
265 // zoom-in btn
266 Button *zoom_in_btn = new Button( nullptr, QSize( 19, 15 ), Button::Type::Push, "plus.svg", "", false, QSize( 9, 9 ), tr( "Zoom in" ) );
267 connect( zoom_in_btn, SIGNAL( clicked() ), this, SLOT( zoomInBtnClicked() ) );
268
269
270 // zoom-out btn
271 Button *zoom_out_btn = new Button( nullptr, QSize( 19, 15 ), Button::Type::Push, "minus.svg", "", false, QSize( 9, 9 ), tr( "Zoom out" ) );
272 connect( zoom_out_btn, SIGNAL( clicked() ), this, SLOT( zoomOutBtnClicked() ) );
273// End Editor TOP
274
275
276// RULER____________________________________
277
278 // Ruler ScrollView
279 m_pRulerScrollView = new WidgetScrollArea( nullptr );
280 m_pRulerScrollView->setFocusPolicy( Qt::NoFocus );
281 m_pRulerScrollView->setFrameShape( QFrame::NoFrame );
282 m_pRulerScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
283 m_pRulerScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
284 m_pRulerScrollView->setFixedHeight( 25 );
285 // Ruler
287 m_pPatternEditorRuler->setFocusPolicy( Qt::ClickFocus );
288
290 connect( m_pRulerScrollView->horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this,
291 SLOT( on_patternEditorHScroll( int ) ) );
294
295
296// ~ RULER
297
298
299// EDITOR _____________________________________
300 // Editor scrollview
301 m_pEditorScrollView = new WidgetScrollArea( nullptr );
302 m_pEditorScrollView->setObjectName( "EditorScrollView" );
303 m_pEditorScrollView->setFocusPolicy( Qt::NoFocus );
304 m_pEditorScrollView->setFrameShape( QFrame::NoFrame );
305 m_pEditorScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
306 m_pEditorScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
307
308
309 // Editor
311
313 m_pEditorScrollView->setFocusPolicy( Qt::ClickFocus );
315
317
318 connect( m_pEditorScrollView->verticalScrollBar(), SIGNAL( valueChanged( int ) ), this,
319 SLOT( on_patternEditorVScroll( int ) ) );
320 connect( m_pEditorScrollView->horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this,
321 SLOT( on_patternEditorHScroll( int ) ) );
324
325//PianoRollEditor
327 m_pPianoRollScrollView->setObjectName( "PianoRollScrollView" );
328 m_pPianoRollScrollView->setFocusPolicy( Qt::NoFocus );
329 m_pPianoRollScrollView->setFrameShape( QFrame::NoFrame );
330 m_pPianoRollScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
331 m_pPianoRollScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
334 connect( m_pPianoRollScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
335 this, SLOT( on_patternEditorHScroll(int) ) );
336 connect( m_pPianoRollScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
337 m_pPianoRollEditor, SLOT( scrolled( int ) ) );
338 connect( m_pPianoRollScrollView->verticalScrollBar(), SIGNAL( valueChanged( int ) ),
339 m_pPianoRollEditor, SLOT( scrolled( int ) ) );
342
345
347
348// ~ EDITOR
349
350
351
352
353
354
355// INSTRUMENT LIST
356 // Instrument list scrollview
358 m_pInstrListScrollView->setObjectName( "InstrListScrollView" );
359 m_pInstrListScrollView->setFocusPolicy( Qt::ClickFocus );
360 m_pInstrListScrollView->setFrameShape( QFrame::NoFrame );
361 m_pInstrListScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
362 m_pInstrListScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
363
364 // Instrument list
367 m_pInstrListScrollView->setFixedWidth( m_pInstrumentList->width() );
368 m_pInstrumentList->setFocusPolicy( Qt::ClickFocus );
369 m_pInstrumentList->setFocusProxy( m_pEditorScrollView );
370
371 connect( m_pInstrListScrollView->verticalScrollBar(), SIGNAL( valueChanged(int) ), this, SLOT( on_patternEditorVScroll(int) ) );
373
374// ~ INSTRUMENT LIST
375
376
377
378
379// NOTE_VELOCITY EDITOR
381 m_pNoteVelocityScrollView->setObjectName( "NoteVelocityScrollView" );
382 m_pNoteVelocityScrollView->setFocusPolicy( Qt::NoFocus );
383 m_pNoteVelocityScrollView->setFrameShape( QFrame::NoFrame );
384 m_pNoteVelocityScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
385 m_pNoteVelocityScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
389 m_pNoteVelocityScrollView->setFixedHeight( 100 );
390 connect( m_pNoteVelocityScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ), this, SLOT( on_patternEditorHScroll(int) ) );
391 connect( m_pNoteVelocityScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
392 m_pNoteVelocityEditor, SLOT( scrolled( int ) ) );
393
395
396// ~ NOTE_VELOCITY EDITOR
397
398
399// NOTE_PAN EDITOR
400 m_pNotePanScrollView = new WidgetScrollArea( nullptr );
401 m_pNotePanScrollView->setObjectName( "NotePanScrollView" );
402 m_pNotePanScrollView->setFocusPolicy( Qt::NoFocus );
403 m_pNotePanScrollView->setFrameShape( QFrame::NoFrame );
404 m_pNotePanScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
405 m_pNotePanScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
409 m_pNotePanScrollView->setFixedHeight( 100 );
410
411 connect( m_pNotePanScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
412 this, SLOT( on_patternEditorHScroll(int) ) );
413 connect( m_pNotePanScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
414 m_pNotePanEditor, SLOT( scrolled( int ) ) );
415
417
418// ~ NOTE_PAN EDITOR
419
420
421// NOTE_LEADLAG EDITOR
423 m_pNoteLeadLagScrollView->setObjectName( "NoteLeadLagScrollView" );
424 m_pNoteLeadLagScrollView->setFocusPolicy( Qt::NoFocus );
425 m_pNoteLeadLagScrollView->setFrameShape( QFrame::NoFrame );
426 m_pNoteLeadLagScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
427 m_pNoteLeadLagScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
431 m_pNoteLeadLagScrollView->setFixedHeight( 100 );
432
433 connect( m_pNoteLeadLagScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
434 this, SLOT( on_patternEditorHScroll(int) ) );
435 connect( m_pNoteLeadLagScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
436 m_pNoteLeadLagEditor, SLOT( scrolled( int ) ) );
437
439
440// ~ NOTE_LEADLAG EDITOR
441
442
443// NOTE_NOTEKEY EDITOR
444
445
447 m_pNoteNoteKeyScrollView->setObjectName( "NoteNoteKeyScrollView" );
448 m_pNoteNoteKeyScrollView->setFocusPolicy( Qt::NoFocus );
449 m_pNoteNoteKeyScrollView->setFrameShape( QFrame::NoFrame );
450 m_pNoteNoteKeyScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
451 m_pNoteNoteKeyScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
455 m_pNoteNoteKeyScrollView->setFixedHeight( 210 );
456 connect( m_pNoteNoteKeyScrollView->horizontalScrollBar(), SIGNAL( valueChanged( int ) ),
457 this, SLOT( on_patternEditorHScroll( int ) ) );
458 connect( m_pNoteNoteKeyScrollView->horizontalScrollBar(), SIGNAL( valueChanged( int ) ),
459 m_pNoteNoteKeyEditor, SLOT( scrolled( int ) ) );
462
464
465// ~ NOTE_NOTEKEY EDITOR
466
467// NOTE_PROBABILITY EDITOR
469 m_pNoteProbabilityScrollView->setObjectName( "NoteProbabilityScrollView" );
470 m_pNoteProbabilityScrollView->setFocusPolicy( Qt::NoFocus );
471 m_pNoteProbabilityScrollView->setFrameShape( QFrame::NoFrame );
472 m_pNoteProbabilityScrollView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
473 m_pNoteProbabilityScrollView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
477 m_pNoteProbabilityScrollView->setFixedHeight( 100 );
478 connect( m_pNoteProbabilityScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
479 this, SLOT( on_patternEditorHScroll(int) ) );
480 connect( m_pNoteProbabilityScrollView->horizontalScrollBar(), SIGNAL( valueChanged(int) ),
481 m_pNoteProbabilityEditor, SLOT( scrolled( int ) ) );
482
484
485// ~ NOTE_PROBABILITY EDITOR
486
487
488
489 // external horizontal scrollbar
490 m_pPatternEditorHScrollBar = new QScrollBar( Qt::Horizontal , nullptr );
491 m_pPatternEditorHScrollBar->setObjectName( "PatternEditorHScrollBar" );
492 connect( m_pPatternEditorHScrollBar, SIGNAL( valueChanged( int ) ), this,
493 SLOT( syncToExternalHorizontalScrollbar( int ) ) );
494
495 // external vertical scrollbar
496 m_pPatternEditorVScrollBar = new QScrollBar( Qt::Vertical, nullptr );
497 m_pPatternEditorVScrollBar->setObjectName( "PatternEditorVScrollBar" );
498 connect( m_pPatternEditorVScrollBar, SIGNAL(valueChanged( int)), this,
500 connect( m_pPatternEditorVScrollBar, SIGNAL( valueChanged( int ) ),
501 m_pDrumPatternEditor, SLOT( scrolled( int ) ) );
502 connect( m_pPatternEditorHScrollBar, SIGNAL( valueChanged( int ) ),
503 m_pDrumPatternEditor, SLOT( scrolled( int ) ) );
504
505 QHBoxLayout *pPatternEditorHScrollBarLayout = new QHBoxLayout();
506 pPatternEditorHScrollBarLayout->setSpacing( 0 );
507 pPatternEditorHScrollBarLayout->setMargin( 0 );
508 pPatternEditorHScrollBarLayout->addWidget( m_pPatternEditorHScrollBar );
509 pPatternEditorHScrollBarLayout->addWidget( zoom_in_btn );
510 pPatternEditorHScrollBarLayout->addWidget( zoom_out_btn );
511
512 QWidget *pPatternEditorHScrollBarContainer = new QWidget();
513 pPatternEditorHScrollBarContainer->setLayout( pPatternEditorHScrollBarLayout );
514
515
516 QPalette label_palette;
517 label_palette.setColor( QPalette::WindowText, QColor( 230, 230, 230 ) );
518
519 m_pPatternNameLbl = new QLabel( nullptr );
520 m_pPatternNameLbl->setFont( boldFont );
521 m_pPatternNameLbl->setText( "pattern name label" );
522 m_pPatternNameLbl->setPalette(label_palette);
523
524
525
526
527
528
529// NOTE_PROPERTIES BUTTONS
530 PixmapWidget *pPropertiesPanel = new PixmapWidget( nullptr );
531 pPropertiesPanel->setObjectName( "PropertiesPanel" );
532 pPropertiesPanel->setColor( QColor( 58, 62, 72 ) );
533
534 pPropertiesPanel->setFixedSize( 181, 100 );
535
536 QVBoxLayout *pPropertiesVBox = new QVBoxLayout( pPropertiesPanel );
537 pPropertiesVBox->setSpacing( 0 );
538 pPropertiesVBox->setMargin( 0 );
539
540
542 new LCDCombo( nullptr, QSize( m_pInstrumentList->width(), 18 ), false );
543 m_pPropertiesCombo->setToolTip( tr( "Select note properties" ) );
544 m_pPropertiesCombo->addItem( tr("Velocity") );
545 m_pPropertiesCombo->addItem( tr("Pan") );
546 m_pPropertiesCombo->addItem( tr("Lead and Lag") );
547 m_pPropertiesCombo->addItem( tr("NoteKey") );
548 m_pPropertiesCombo->addItem( tr("Probability") );
549 /* m_pPropertiesCombo->addItem( tr("Cutoff") ); */
550 /* m_pPropertiesCombo->addItem( tr("Resonance") ); */
551 // is triggered here below
552 m_pPropertiesCombo->setObjectName( "PropertiesCombo" );
553 connect( m_pPropertiesCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( propertiesComboChanged( int ) ) );
554
555 pPropertiesVBox->addWidget( m_pPropertiesCombo );
556
557// ~ NOTE_PROPERTIES BUTTONS
558
559
560// LAYOUT
561 QWidget *pMainPanel = new QWidget();
562
563 QGridLayout *pGrid = new QGridLayout();
564 pGrid->setSpacing( 0 );
565 pGrid->setMargin( 0 );
566
567 pGrid->addWidget( m_pEditorTop1, 0, 0 );
568 pGrid->addWidget( m_pEditorTop2, 0, 1, 1, 2 );
569 pGrid->addWidget( m_pPatternNameLbl, 1, 0 );
570 pGrid->addWidget( m_pRulerScrollView, 1, 1 );
571
572 pGrid->addWidget( m_pInstrListScrollView, 2, 0 );
573
574 pGrid->addWidget( m_pEditorScrollView, 2, 1 );
575 pGrid->addWidget( m_pPianoRollScrollView, 2, 1 );
576
577 pGrid->addWidget( m_pPatternEditorVScrollBar, 2, 2 );
578 pGrid->addWidget( pPatternEditorHScrollBarContainer, 10, 1 );
579 pGrid->addWidget( m_pNoteVelocityScrollView, 4, 1 );
580 pGrid->addWidget( m_pNotePanScrollView, 4, 1 );
581 pGrid->addWidget( m_pNoteLeadLagScrollView, 4, 1 );
582 pGrid->addWidget( m_pNoteNoteKeyScrollView, 4, 1 );
583 pGrid->addWidget( m_pNoteProbabilityScrollView, 4, 1 );
584
585 pGrid->addWidget( pPropertiesPanel, 4, 0 );
586 pGrid->setRowStretch( 2, 100 );
587 pMainPanel->setLayout( pGrid );
588
589
590 // restore grid resolution
591 int nIndex;
592 int nRes = pPref->getPatternEditorGridResolution();
593 if ( nRes == MAX_NOTES ) {
594 nIndex = 11;
595 } else if ( pPref->isPatternEditorUsingTriplets() == false ) {
596 switch ( nRes ) {
597 case 4: nIndex = 0; break;
598 case 8: nIndex = 1; break;
599 case 16: nIndex = 2; break;
600 case 32: nIndex = 3; break;
601 case 64: nIndex = 4; break;
602 default:
603 nIndex = 0;
604 ERRORLOG( QString( "Wrong grid resolution: %1" ).arg( pPref->getPatternEditorGridResolution() ) );
605 }
606 } else {
607 switch ( nRes ) {
608 case 8: nIndex = 6; break;
609 case 16: nIndex = 7; break;
610 case 32: nIndex = 8; break;
611 case 64: nIndex = 9; break;
612 default:
613 nIndex = 6;
614 ERRORLOG( QString( "Wrong grid resolution: %1" ).arg( pPref->getPatternEditorGridResolution() ) );
615 }
616 }
617 m_pResolutionCombo->setCurrentIndex( nIndex );
618
619 // LAYOUT
620 QVBoxLayout *pVBox = new QVBoxLayout();
621 pVBox->setSpacing( 0 );
622 pVBox->setMargin( 0 );
623 this->setLayout( pVBox );
624
625 pVBox->addWidget( pMainPanel );
626
628
630
631 // update
632 m_pPropertiesCombo->setCurrentIndex( 0 );
636}
637
638
639
640
644
648
650{
651 //INFOLOG( "[syncToExternalHorizontalScrollbar]" );
652
653 // drum Editor
654 m_pEditorScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
655 m_pEditorScrollView->verticalScrollBar()->setValue( m_pPatternEditorVScrollBar->value() );
656
657 // piano roll Editor
658 m_pPianoRollScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
659
660 // Ruler
661 m_pRulerScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
662
663 // Instrument list
664 m_pInstrListScrollView->verticalScrollBar()->setValue( m_pPatternEditorVScrollBar->value() );
665
666 // Velocity ruler
667 m_pNoteVelocityScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
668
669 // pan ruler
670 m_pNotePanScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
671
672 // leadlag ruler
673 m_pNoteLeadLagScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
674
675 // notekey ruler
676 m_pNoteNoteKeyScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
677
678 // Probability ruler
679 m_pNoteProbabilityScrollView->horizontalScrollBar()->setValue( m_pPatternEditorHScrollBar->value() );
680}
681
682
684{
685 //INFOLOG( "[on_patternEditorVScroll] " + QString::number(nValue) );
686 m_pPatternEditorVScrollBar->setValue( nValue );
687 resizeEvent( nullptr );
688}
689
691{
692 //INFOLOG( "[on_patternEditorHScroll] " + QString::number(nValue) );
693 m_pPatternEditorHScrollBar->setValue( nValue );
694 resizeEvent( nullptr );
695}
696
697
698
699
701{
702 int nResolution;
703 bool bUseTriplets = false;
704
705 if ( nSelected == 11 ) {
706 nResolution = MAX_NOTES;
707 }
708 else if ( nSelected > 4 ) {
709 bUseTriplets = true;
710 nResolution = 0x1 << ( nSelected - 3 );
711 }
712 else {
713 nResolution = 0x1 << ( nSelected + 2 );
714 }
715
716 // INFOLOG( QString("idx %1 -> %2 resolution").arg( nSelected ).arg( nResolution ) );
717
718 m_pDrumPatternEditor->setResolution( nResolution, bUseTriplets );
719 m_pPianoRollEditor->setResolution( nResolution, bUseTriplets );
720 m_pNoteVelocityEditor->setResolution( nResolution, bUseTriplets );
721 m_pNoteLeadLagEditor->setResolution( nResolution, bUseTriplets );
722 m_pNoteNoteKeyEditor->setResolution( nResolution, bUseTriplets );
723 m_pNoteProbabilityEditor->setResolution( nResolution, bUseTriplets );
724 m_pNotePanEditor->setResolution( nResolution, bUseTriplets );
725
726 m_nCursorIncrement = ( bUseTriplets ? 4 : 3 ) * MAX_NOTES / ( nResolution * 3 );
728
731}
732
733
734
736{
737
738 PatternList *pPatternList = Hydrogen::get_instance()->getSong()->getPatternList();
740
741 if ( ( m_nSelectedPatternNumber != -1 ) &&
742 ( m_nSelectedPatternNumber < pPatternList->size() ) ) {
743 // update pattern name text
744 m_pPattern = pPatternList->get( m_nSelectedPatternNumber );
745 QString sCurrentPatternName = m_pPattern->get_name();
746 this->setWindowTitle( ( tr( "Pattern editor - %1" ).arg( sCurrentPatternName ) ) );
747 m_pPatternNameLbl->setText( sCurrentPatternName );
748
749 // update pattern size LCD
752
753 }
754 else {
755 m_pPattern = nullptr;
756
757 this->setWindowTitle( tr( "Pattern editor - No pattern selected" ) );
758 m_pPatternNameLbl->setText( tr( "No pattern selected" ) );
759 }
760
761 resizeEvent( nullptr ); // force an update of the scrollbars
762}
763
765{
767 pref->setHearNewNotes( m_pHearNotesBtn->isChecked() );
768
769 if ( m_pHearNotesBtn->isChecked() ) {
770 ( HydrogenApp::get_instance() )->showStatusBarMessage( tr( "Hear new notes = On" ) );
771 } else {
772 ( HydrogenApp::get_instance() )->showStatusBarMessage( tr( "Hear new notes = Off" ) );
773 }
774}
775
777{
779 pref->setQuantizeEvents( m_pQuantizeEventsBtn->isChecked() );
780
781 if ( m_pQuantizeEventsBtn->isChecked() ) {
782 ( HydrogenApp::get_instance() )->showStatusBarMessage( tr( "Quantize incoming keyboard/midi events = On" ) );
783 } else {
784 ( HydrogenApp::get_instance() )->showStatusBarMessage( tr( "Quantize incoming keyboard/midi events = Off" ) );
785 }
786}
787
788static void syncScrollBarSize( QScrollBar *pDest, QScrollBar *pSrc )
789{
790 pDest->setMinimum( pSrc->minimum() );
791 pDest->setMaximum( pSrc->maximum() );
792 pDest->setSingleStep( pSrc->singleStep() );
793 pDest->setPageStep( pSrc->pageStep() );
794}
795
796void PatternEditorPanel::resizeEvent( QResizeEvent *ev )
797{
798 UNUSED( ev );
799 QScrollArea *pScrollArea = m_pEditorScrollView;
800
801 syncScrollBarSize( m_pPatternEditorHScrollBar, pScrollArea->horizontalScrollBar() );
802 syncScrollBarSize( m_pPatternEditorVScrollBar, pScrollArea->verticalScrollBar() );
803
804 syncScrollBarSize( m_pRulerScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() );
805 syncScrollBarSize( m_pNoteVelocityScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() );
806 syncScrollBarSize( m_pNotePanScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() );
807 syncScrollBarSize( m_pNoteLeadLagScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() ) ;
808 syncScrollBarSize( m_pNoteNoteKeyScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() );
809 syncScrollBarSize( m_pNoteProbabilityScrollView->horizontalScrollBar(), pScrollArea->horizontalScrollBar() );
810}
811
812void PatternEditorPanel::showEvent ( QShowEvent *ev )
813{
814 UNUSED( ev );
815}
816
817
820{
821 UNUSED( dummy );
822 //INFOLOG( "contentsMoving" );
824}
825
826
827
829{
830 resizeEvent( nullptr ); // force a scrollbar update
831}
832
834{
835 if ( __show_drum_btn->isChecked() ) {
837 } else {
839 }
840}
841
843{
844 __show_drum_btn->setToolTip( tr( "Show piano roll editor" ) );
845 __show_drum_btn->setChecked( false );
847 m_pEditorScrollView->show();
849
850 m_pEditorScrollView->setFocus();
852 m_pInstrumentList->setFocusProxy( m_pEditorScrollView );
853
855
858
859 // force a re-sync of extern scrollbars
860 resizeEvent( nullptr );
861
862}
863
865{
866 __show_drum_btn->setToolTip( tr( "Show drum editor" ) );
867 __show_drum_btn->setChecked( true );
869 m_pPianoRollScrollView->verticalScrollBar()->setValue( 250 );
870 m_pEditorScrollView->hide();
872
873 m_pPianoRollScrollView->setFocus();
876
879
881 m_pPianoRollEditor->updateEditor(); // force an update
882 // force a re-sync of extern scrollbars
883 resizeEvent( nullptr );
884}
885
887{
888 if ( __show_drum_btn->isVisible() ){
890 __show_drum_btn->hide();
891 __show_piano_btn->show();
892 __show_drum_btn->setBaseToolTip( HydrogenApp::get_instance()->getCommonStrings()->getShowDrumkitEditorTooltip() );
893 __show_piano_btn->setBaseToolTip( HydrogenApp::get_instance()->getCommonStrings()->getShowDrumkitEditorTooltip() );
894 } else {
896 __show_drum_btn->show();
897 __show_piano_btn->hide();
898 __show_drum_btn->setBaseToolTip( HydrogenApp::get_instance()->getCommonStrings()->getShowPianoRollEditorTooltip() );
899 __show_piano_btn->setBaseToolTip( HydrogenApp::get_instance()->getCommonStrings()->getShowPianoRollEditorTooltip() );
900 }
901}
902
903
924
941
943 Hydrogen *pHydrogen = Hydrogen::get_instance();
944 std::shared_ptr<Song> pSong = pHydrogen->getSong();
945
946 m_pPattern = nullptr;
948
949 if ( pSong != nullptr ) {
950 PatternList *pPatternList = pSong->getPatternList();
951 if ( ( m_nSelectedPatternNumber != -1 ) && ( m_nSelectedPatternNumber < pPatternList->size() ) ) {
952 m_pPattern = pPatternList->get( m_nSelectedPatternNumber );
953 }
954 }
955}
956
973
977
983
987
991
997
1001
1003 if ( H2Core::Hydrogen::get_instance()->isPatternEditorLocked() ) {
1004 updateEditors( true );
1005 }
1006}
1007
1009 if ( m_pPattern == nullptr ) {
1010 return;
1011 }
1012
1014
1015 double fNewDenominator = static_cast<double>( m_pPattern->get_denominator() );
1016 if ( fNewDenominator != m_pLCDSpinBoxDenominator->value() &&
1017 ! m_pLCDSpinBoxDenominator->hasFocus() ) {
1018 m_pLCDSpinBoxDenominator->setValue( fNewDenominator );
1019
1020 // Update numerator to allow only for a maximum pattern length of
1021 // four measures.
1022 m_pLCDSpinBoxNumerator->setMaximum( 4 * m_pLCDSpinBoxDenominator->value() );
1023 }
1024
1025 double fNewNumerator = static_cast<double>( m_pPattern->get_length() * m_pPattern->get_denominator() ) / static_cast<double>( MAX_NOTES );
1026 if ( fNewNumerator != m_pLCDSpinBoxNumerator->value() && ! m_pLCDSpinBoxNumerator->hasFocus() ) {
1027 m_pLCDSpinBoxNumerator->setValue( fNewNumerator );
1028 }
1029
1031}
1032
1034 if ( m_pPattern == nullptr ) {
1035 return;
1036 }
1037
1039 // Don't execute this function if the values of the spin boxes
1040 // have been set by Hydrogen instead of by the user.
1041 return;
1042 }
1043
1044 auto pHydrogen = Hydrogen::get_instance();
1045 auto pAudioEngine = pHydrogen->getAudioEngine();
1046 auto pInstrumentList = pHydrogen->getSong()->getInstrumentList();
1047
1048 // Update numerator to allow only for a maximum pattern length of
1049 // four measures.
1050 m_pLCDSpinBoxNumerator->setMaximum( 4 * m_pLCDSpinBoxDenominator->value() );
1051
1052 double fNewNumerator = m_pLCDSpinBoxNumerator->value();
1053 double fNewDenominator = m_pLCDSpinBoxDenominator->value();
1054
1055 /* Note: user can input a non integer numerator and this feature
1056 is very powerful because it allows to set really any possible
1057 pattern size (in ticks) using ANY arbitrary denominator.
1058 e.g. pattern size of 38 ticks will result from both inputs 1/5
1059 (quintuplet) and 0.79/4 of a whole note, since both are rounded
1060 and BOTH are UNSUPPORTED, but the first notation looks more
1061 meaningful */
1062
1063 int nNewLength =
1064 std::round( static_cast<double>( MAX_NOTES ) / fNewDenominator * fNewNumerator );
1065
1066 if ( nNewLength == m_pPattern->get_length() ) {
1067 return;
1068 }
1069
1070 QUndoStack* pUndoStack = HydrogenApp::get_instance()->m_pUndoStack;
1071 pUndoStack->beginMacro( QString( "Change pattern size to %1/%2" )
1072 .arg( fNewNumerator ).arg( fNewDenominator ) );
1073
1074 pUndoStack->push( new SE_patternSizeChangedAction( nNewLength,
1076 fNewDenominator,
1079 pUndoStack->endMacro();
1080}
1081
1082void PatternEditorPanel::patternSizeChangedAction( int nLength, double fDenominator,
1083 int nSelectedPatternNumber ) {
1084 auto pHydrogen = Hydrogen::get_instance();
1085 auto pAudioEngine = pHydrogen->getAudioEngine();
1086 auto pPatternList = pHydrogen->getSong()->getPatternList();
1087 H2Core::Pattern* pPattern = nullptr;
1088
1089 if ( ( nSelectedPatternNumber != -1 ) &&
1090 ( nSelectedPatternNumber < pPatternList->size() ) ) {
1091 pPattern = pPatternList->get( nSelectedPatternNumber );
1092 }
1093
1094 if ( pPattern == nullptr ) {
1095 ERRORLOG( QString( "Pattern corresponding to pattern number [%1] could not be retrieved" )
1096 .arg( nSelectedPatternNumber ) );
1097 return;
1098 }
1099
1100 pAudioEngine->lock( RIGHT_HERE );
1101 // set length and denominator
1102 pPattern->set_length( nLength );
1103 pPattern->set_denominator( static_cast<int>( fDenominator ) );
1104 pHydrogen->updateSongSize();
1105 pAudioEngine->unlock();
1106
1107 pHydrogen->setIsModified( true );
1108
1110}
1111
1112void PatternEditorPanel::dragEnterEvent( QDragEnterEvent *event )
1113{
1115}
1116
1117
1118
1119void PatternEditorPanel::dropEvent( QDropEvent *event )
1120{
1121 m_pInstrumentList->dropEvent( event );
1122}
1123
1125 // A new song got loaded
1126 if ( nValue == 0 ) {
1127 // Performs an editor update with updateEditor() (and no argument).
1131 updateEditors( true );
1133 }
1134}
1135
1137{
1138 if ( nSelected == 0 ) { // Velocity
1139 m_pNotePanScrollView->hide();
1144
1146 }
1147 else if ( nSelected == 1 ) { // Pan
1151 m_pNotePanScrollView->show();
1153
1155 }
1156 else if ( nSelected == 2 ) { // Lead and Lag
1158 m_pNotePanScrollView->hide();
1162
1164 }
1165 else if ( nSelected == 3 ) { // NoteKey
1167 m_pNotePanScrollView->hide();
1171
1173 }
1174 else if ( nSelected == 4 ) { // Probability
1175 m_pNotePanScrollView->hide();
1180
1182 }
1183 /*
1184 else if ( nSelected == 5 ) { // Cutoff
1185 }
1186 else if ( nSelected == 6 ) { // Resonance
1187 }
1188 */
1189 else {
1190 ERRORLOG( QString( "unhandled value : %1" ).arg( nSelected ) );
1191 }
1192}
1193
1198
1205
1207{
1208 if ( nCursorPosition < 0 ) {
1210 } else if ( m_pPattern != nullptr && nCursorPosition >= m_pPattern->get_length() ) {
1212 } else {
1213 m_nCursorPosition = nCursorPosition;
1214 }
1215}
1216
1218{
1220 0 );
1221
1223
1224 return m_nCursorPosition;
1225}
1226
1228{
1229 if ( m_pPattern == nullptr ) {
1230 return 0;
1231 }
1232
1235
1237
1238 return m_nCursorPosition;
1239}
1240
1242 auto pPref = H2Core::Preferences::get_instance();
1243
1244 if ( changes & H2Core::Preferences::Changes::Font ) {
1245
1246 // It's sufficient to check the properties of just one label
1247 // because they will always carry the same.
1248 QFont boldFont( pPref->getApplicationFontFamily(), getPointSize( pPref->getFontSize() ) );
1249 boldFont.setBold( true );
1250 m_pSLlabel->setFont( boldFont );
1251 m_pPatternNameLbl->setFont( boldFont );
1252
1254 }
1255
1256 if ( changes & ( H2Core::Preferences::Changes::Colors ) ) {
1258 }
1259}
1260
1262
1263 auto pPref = H2Core::Preferences::get_instance();
1264 int nFactorTop = 112;
1265
1266 QColor topColorLight = pPref->getColorTheme()->m_midColor.lighter( nFactorTop );
1267 QColor topColorDark = pPref->getColorTheme()->m_midColor.darker( nFactorTop );
1268
1269 QString sEditorTopStyleSheet = QString( "\
1270QWidget#editor1 {\
1271 background-color: qlineargradient(x1: 0.5, y1: 0.1, x2: 0.5, y2: 0.9, \
1272 stop: 0 %1, stop: 1 %2); \
1273} \
1274QWidget#editor2 {\
1275 background-color: qlineargradient(x1: 0.5, y1: 0.1, x2: 0.5, y2: 0.9, \
1276 stop: 0 %1, stop: 1 %2); \
1277}")
1278 .arg( topColorLight.name() ).arg( topColorDark.name() );
1279 QString sWidgetTopStyleSheet = QString( "\
1280QWidget#sizeResol {\
1281 background-color: %1;\
1282} \
1283QWidget#pRec {\
1284 background-color: %1;\
1285}" )
1286 .arg( pPref->getColorTheme()->m_midLightColor.name() );
1287
1288 m_pEditorTop1->setStyleSheet( sEditorTopStyleSheet );
1289 m_pEditorTop2->setStyleSheet( sEditorTopStyleSheet );
1290
1291 m_pSizeResol->setStyleSheet( sWidgetTopStyleSheet );
1292 m_pRec->setStyleSheet( sWidgetTopStyleSheet );
1293
1294}
1295
1297 if ( ! m_pLCDSpinBoxDenominator->hasFocus() ) {
1298 m_pLCDSpinBoxDenominator->setFocus();
1299 } else {
1300 m_pLCDSpinBoxNumerator->setFocus();
1301 }
1302}
1303
1305{
1307
1308 switch ( m_pPropertiesCombo->currentIndex() ) {
1309 case 0:
1311 break;
1312 case 1:
1314 break;
1315 case 2:
1317 break;
1318 case 3:
1320 break;
1321 case 4:
1323 break;
1324 default:
1325 ERRORLOG( QString( "Unsupported m_pPropertiesCombo index [%1]" )
1326 .arg( m_pPropertiesCombo->currentIndex() ) );
1327 }
1328
1329 return mode;
1330}
#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
Definition AudioEngine.h:59
#define ERRORLOG(x)
Definition Object.h:239
static void syncScrollBarSize(QScrollBar *pDest, QScrollBar *pSrc)
Generic Button with SVG icons or text.
Definition Button.h:60
@ Push
Button is not set checkable.
@ Toggle
Button is set checkable.
void setBaseToolTip(const QString &sNewTip)
Definition Button.cpp:306
Custom QLabel that emits a signal when clicked.
Drum pattern editor.
virtual void updateEditor(bool bPatternOnly=false) override
void onPreferencesChanged(H2Core::Preferences::Changes changes)
virtual void selectedInstrumentChangedEvent() override
static EventQueue * get_instance()
Returns a pointer to the current EventQueue singleton stored in __instance.
Definition EventQueue.h:224
void push_event(const EventType type, const int nValue)
Queues the next event into the EventQueue.
Hydrogen Audio Engine.
Definition Hydrogen.h:54
std::shared_ptr< Song > getSong() const
Get the current song.
Definition Hydrogen.h:122
int getSelectedInstrumentNumber() const
Definition Hydrogen.h:664
int getSelectedPatternNumber() const
Definition Hydrogen.h:660
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:83
PatternList is a collection of patterns.
Definition PatternList.h:43
Pattern * get(int idx)
get a pattern from the list
Pattern class is a Note container.
Definition Pattern.h:46
const QString & get_name() const
set the category of the pattern
Definition Pattern.h:310
void set_denominator(int denominator)
get the denominator of the pattern
Definition Pattern.h:345
int get_length() const
set the denominator of the pattern
Definition Pattern.h:340
int get_denominator() const
get the note multimap
Definition Pattern.h:350
void set_length(int length)
get the length of the pattern
Definition Pattern.h:335
Manager for User Preferences File (singleton)
Definition Preferences.h:78
void setPatternEditorGridHeight(unsigned value)
void setHearNewNotes(bool value)
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
const QString & getApplicationFontFamily() const
void setPatternEditorUsingTriplets(bool value)
int getPatternEditorGridResolution()
bool isPatternEditorUsingTriplets()
unsigned getPatternEditorGridHeight()
FontTheme::FontSize getFontSize() const
Changes
Bitwise or-able options showing which part of the Preferences were altered using the PreferencesDialo...
@ Font
Either the font size or font family have changed.
@ Colors
At least one of the colors has changed.
void setPatternEditorGridResolution(int value)
void setQuantizeEvents(bool value)
void setPatternEditorGridWidth(unsigned value)
void addEventListener(EventListener *pListener)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
QUndoStack * m_pUndoStack
void preferencesChanged(H2Core::Preferences::Changes changes)
Propagates a change in the Preferences through the GUI.
void addItem(const QString &text, const QVariant &userData=QVariant())
Definition LCDCombo.cpp:63
Custom spin box.
Definition LCDSpinBox.h:50
void setValue(double fValue)
@ PatternSizeNumerator
The minimum value - a fractional one - can only be reached by entering it using the keyboard.
@ PatternSizeDenominator
Only a limited number of values is allowed.
void setKind(Kind kind)
Definition LCDSpinBox.h:132
void slashKeyPressed()
NotePropertiesEditor is (currently) a single class instantiated in different "modes" to select which ...
virtual void updateEditor(bool bPatternOnly=false) override
void onPreferencesChanged(H2Core::Preferences::Changes changes)
virtual void dragEnterEvent(QDragEnterEvent *event) override
virtual void dropEvent(QDropEvent *event) override
void selectInstrumentNotes(int nInstrument)
ClickableLabel * m_pQuantizeEventsLbl
NotePropertiesRuler::Mode getNotePropertiesMode() const
void setCursorPosition(int nCursorPosition)
QScrollArea * m_pEditorScrollView
QScrollArea * m_pPianoRollScrollView
QScrollBar * m_pPatternEditorVScrollBar
NotePropertiesRuler * m_pNoteVelocityEditor
PianoRollEditor * m_pPianoRollEditor
QScrollArea * m_pNoteProbabilityScrollView
LCDSpinBox * m_pLCDSpinBoxNumerator
QScrollArea * m_pNoteNoteKeyScrollView
bool m_bArmPatternSizeSpinBoxes
Indicates whether the LCD spin boxes for the pattern size have been altered by Hydrogen or by the use...
NotePropertiesRuler * m_pNoteProbabilityEditor
ClickableLabel * m_pHearNotesLbl
void gridResolutionChanged(int nSelected)
virtual void resizeEvent(QResizeEvent *ev) override
virtual void patternModifiedEvent() override
void updatePatternSizeLCD()
Batch version for setting the values of the pattern size spin boxes.
void onPreferencesChanged(H2Core::Preferences::Changes changes)
void updateEditors(bool bPatternOnly=false)
virtual void updateSongEvent(int nValue) override
virtual void stackedModeActivationEvent(int) override
virtual void songModeActivationEvent() override
QScrollArea * m_pRulerScrollView
QScrollBar * m_pPatternEditorHScrollBar
QScrollArea * m_pNoteLeadLagScrollView
virtual void drumkitLoadedEvent() override
void syncToExternalHorizontalScrollbar(int)
virtual void dragEnterEvent(QDragEnterEvent *event) override
virtual void showEvent(QShowEvent *ev) override
ClickableLabel * m_pResolutionLbl
void propertiesComboChanged(int nSelected)
NotePropertiesRuler * m_pNotePanEditor
virtual void selectedInstrumentChangedEvent() override
virtual void songSizeChangedEvent() override
virtual void playingPatternsChangedEvent() override
PatternEditorPanel(QWidget *parent)
PatternEditorRuler * m_pPatternEditorRuler
PatternEditorInstrumentList * m_pInstrumentList
DrumPatternEditor * m_pDrumPatternEditor
ClickableLabel * m_pShowPianoLbl
virtual void relocationEvent() override
QScrollArea * m_pNotePanScrollView
virtual void dropEvent(QDropEvent *event) override
ClickableLabel * m_pPatternSizeLbl
NotePropertiesRuler * m_pNoteLeadLagEditor
virtual void selectedPatternChangedEvent() override
QScrollArea * m_pNoteVelocityScrollView
H2Core::Pattern * m_pPattern
QScrollArea * m_pInstrListScrollView
virtual void patternEditorLockedEvent() override
NotePropertiesRuler * m_pNoteNoteKeyEditor
void patternSizeChangedAction(int nLength, double fDenominator, int nSelectedPatternNumber)
void contentsMoving(int dummy)
richiamato dall'uso dello scroll del mouse
LCDSpinBox * m_pLCDSpinBoxDenominator
void onPreferencesChanged(H2Core::Preferences::Changes changes)
float getGridWidth() const
void updateEditor(bool bRedrawAll=false)
void updatePosition(bool bForce=false)
Queries the audio engine to update the current position of the playhead.
virtual void selectInstrumentNotes(int nInstrument)
virtual void selectNone()
static bool isUsingAdditionalPatterns(const H2Core::Pattern *pPattern)
Determines whether to pattern editor should show further patterns (determined by getPattersToShow()) ...
unsigned getGridHeight() const
void mergeSelectionGroups(PatternEditor *pPatternEditor)
Merge together the selection groups of two PatternEditor objects to share a common selection.
void zoomIn()
Zoom in / out on the time axis.
void setResolution(uint res, bool bUseTriplets)
Set the editor grid resolution, dividing a whole note into res subdivisions.
virtual void updateEditor(bool bPatternOnly=false) override
void onPreferencesChanged(H2Core::Preferences::Changes changes)
virtual void selectedPatternChangedEvent() override
void setColor(const QColor &color)
constexpr int getPointSize(H2Core::FontTheme::FontSize fontSize) const
#define MAX_NOTES
Maximum number of notes.
Definition config.dox:79
#define UNUSED(v)
Definition Globals.h:42
@ EVENT_PATTERN_MODIFIED
A pattern was added, deleted, or modified.
Definition EventQueue.h:68