From b762ad706f0f51e309fa16e12c1f3c44e72dcec1 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Mon, 23 Jan 2006 09:25:49 +0000 Subject: [PATCH] lot of bugfixes, UI-improvements and more git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@56 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 114 ++++++++++ Makefile.am | 6 + TODO | 9 +- configure.in | 5 +- include/arp_and_chords_tab_widget.h | 8 +- include/bb_editor.h | 18 +- include/bb_track.h | 10 +- include/combobox.h | 117 ++++++++++ include/config_mgr.h | 6 + include/envelope_tab_widget.h | 15 +- include/export_project_dialog.h | 17 +- include/lcd_spinbox.h | 4 +- include/name_label.h | 27 ++- include/pattern.h | 20 +- include/piano_roll.h | 13 +- include/pixmap_button.h | 10 +- include/qt3support.h | 7 +- include/qxembed.h | 1 - include/rubberband.h | 121 ++++++++++ include/song_editor.h | 35 +-- include/tab_button.h | 16 +- include/timeline.h | 9 +- include/tool_button.h | 14 +- include/track.h | 29 ++- include/track_container.h | 32 ++- resources/arp_free.png | Bin 0 -> 273 bytes resources/arp_sort.png | Bin 0 -> 267 bytes resources/arp_sync.png | Bin 0 -> 326 bytes resources/autoscroll_off.png | Bin 737 -> 1092 bytes resources/autoscroll_on.png | Bin 894 -> 1192 bytes resources/back_to_start.png | Bin 1001 -> 1211 bytes resources/back_to_zero.png | Bin 1164 -> 1356 bytes resources/cancel.png | Bin 882 -> 1092 bytes resources/colorize.png | Bin 1857 -> 1599 bytes resources/combobox_arrow.png | Bin 0 -> 477 bytes resources/combobox_bg.png | Bin 0 -> 138 bytes resources/drum.png | Bin 3113 -> 3345 bytes resources/edit_arrow.png | Bin 0 -> 606 bytes resources/edit_copy.png | Bin 589 -> 688 bytes resources/edit_cut.png | Bin 1195 -> 1333 bytes resources/edit_draw.png | Bin 0 -> 1380 bytes resources/edit_erase.png | Bin 1265 -> 1471 bytes resources/edit_move.png | Bin 0 -> 1323 bytes resources/edit_paste.png | Bin 880 -> 938 bytes resources/edit_redo.png | Bin 738 -> 830 bytes resources/edit_select.png | Bin 0 -> 1070 bytes resources/edit_undo.png | Bin 682 -> 919 bytes resources/error.png | Bin 1370 -> 1518 bytes resources/filter_2lp.png | Bin 0 -> 594 bytes resources/filter_ap.png | Bin 0 -> 322 bytes resources/filter_bp.png | Bin 0 -> 609 bytes resources/filter_hp.png | Bin 0 -> 469 bytes resources/filter_lp.png | Bin 0 -> 486 bytes resources/filter_notch.png | Bin 0 -> 595 bytes resources/freeze.png | Bin 2238 -> 3032 bytes resources/hq_mode.png | Bin 1635 -> 1671 bytes resources/keep_stop_position.png | Bin 833 -> 1014 bytes resources/loop_points_off.png | Bin 927 -> 1063 bytes resources/loop_points_on.png | Bin 909 -> 1091 bytes resources/master_pitch.png | Bin 951 -> 1188 bytes resources/master_volume.png | Bin 667 -> 753 bytes resources/mute_off.png | Bin 1022 -> 1370 bytes resources/mute_on.png | Bin 1062 -> 1395 bytes resources/note_double_whole.png | Bin 4106 -> 1272 bytes resources/note_eighth.png | Bin 4136 -> 984 bytes resources/note_half.png | Bin 4310 -> 859 bytes resources/note_none.png | Bin 5379 -> 1846 bytes resources/note_quarter.png | Bin 4154 -> 851 bytes resources/note_sixteenth.png | Bin 4090 -> 893 bytes resources/note_thirtysecond.png | Bin 4244 -> 1089 bytes resources/pause.png | Bin 380 -> 538 bytes resources/piano.png | Bin 838 -> 944 bytes resources/play.png | Bin 576 -> 731 bytes resources/record.png | Bin 389 -> 749 bytes resources/reload.png | Bin 1156 -> 1350 bytes resources/rename.png | Bin 1075 -> 1027 bytes resources/step_btn_add.png | Bin 725 -> 979 bytes resources/step_btn_remove.png | Bin 544 -> 733 bytes resources/stop.png | Bin 297 -> 485 bytes resources/track_op_menu.png | Bin 1834 -> 2049 bytes resources/unfreeze.png | Bin 1511 -> 1306 bytes resources/xclock.png | Bin 5087 -> 1752 bytes resources/zoom.png | Bin 1237 -> 1412 bytes src/core/arp_and_chords_tab_widget.cpp | 58 ++--- src/core/bb_editor.cpp | 54 ++++- src/core/envelope_tab_widget.cpp | 59 ++--- src/core/export_project_dialog.cpp | 34 ++- src/core/name_label.cpp | 211 ++++++++++++++---- src/core/piano_roll.cpp | 47 ++-- src/core/song_editor.cpp | 108 ++++----- src/core/timeline.cpp | 18 +- src/core/track.cpp | 239 ++++++++++++++------ src/core/track_container.cpp | 95 ++++++-- src/lib/sample_buffer.cpp | 2 +- src/tracks/bb_track.cpp | 96 ++++---- src/tracks/pattern.cpp | 152 ++++++++----- src/tracks/sample_track.cpp | 32 ++- src/widgets/combobox.cpp | 294 +++++++++++++++++++++++++ src/widgets/pixmap_button.cpp | 4 - src/widgets/rubberband.cpp | 153 +++++++++++++ src/widgets/tab_bar.cpp | 6 +- 101 files changed, 1789 insertions(+), 536 deletions(-) create mode 100644 include/combobox.h create mode 100644 include/rubberband.h create mode 100644 resources/arp_free.png create mode 100644 resources/arp_sort.png create mode 100644 resources/arp_sync.png create mode 100644 resources/combobox_arrow.png create mode 100644 resources/combobox_bg.png create mode 100644 resources/edit_arrow.png create mode 100644 resources/edit_draw.png create mode 100644 resources/edit_move.png create mode 100644 resources/edit_select.png create mode 100644 resources/filter_2lp.png create mode 100644 resources/filter_ap.png create mode 100644 resources/filter_bp.png create mode 100644 resources/filter_hp.png create mode 100644 resources/filter_lp.png create mode 100644 resources/filter_notch.png create mode 100644 src/widgets/combobox.cpp create mode 100644 src/widgets/rubberband.cpp diff --git a/ChangeLog b/ChangeLog index 9911ca20f0..43ed849e3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,117 @@ +2006-01-22 Tobias Doerffel + + * include/timeline.h: + * src/core/song_editor.cpp: + * src/core/timeline.cpp: + updates are now completely done by timeline/QTimer without being + called from song-editor out of non-GUI-thread which caused segfaults + etc. sometimes + + * include/name_label.h: + * src/core/name_label.cpp: + * src/tracks/bb_track.cpp: + * src/tracks/sample_track.cpp: + added support for user-defined track-icons + + * artwork/track_icons/*png: + added several icons to be used as track-icons + + * include/track.h: + * src/core/track.cpp: + * src/core/track_container.cpp: + do not hide track for completely repainting it, use special method for + it + + * include/pattern.h: + * src/tracks/pattern.cpp: + only repaint if neccessary, otherwise just paint the pixmap we painted + before + + * include/bb_editor.h: + * src/core/bb_editor.cpp: + added combobox for selecting bb-track inside bb-editor + + * include/combobox.h: + * src/widgets/combobox.cpp: + - added clear()-method + - do not crash when having no items + - scale pixmap to fit into combobox + - place menu below combobox if possible + +2006-01-21 Tobias Doerffel + + * include/track.h: + * src/core/track.cpp: + * src/tracks/pattern.cpp: + * src/tracks/sample_track.cpp: + added support for used-defined track-height by pressing and + move mouse (with pressed button) + + * include/song_editor.h: + * include/track.h: + * include/track_container.h: + * src/core/song_editor.cpp: + * src/core/track.cpp: + * src/core/track_container.cpp: + take advantage of new rubberband: + - selecting track-content-objects of any type either via rubberband or + by clicking while pressing + - move selected track-content-objects + - delete selected track-content-objects + + * include/rubberband.h: + * src/widgets/rubberband.cpp: + added rubberband which either acts as wrapper for Qt4's QRubberBand or + as a widget imitating a rubberband + + * include/track.h: + * src/core/track.cpp: + draw vertical lines for each bar + + * include/bb_editor.h: + * include/song_editor.h: + * include/track_container.h: + * src/core/bb_editor.cpp: + * src/core/song_editor.cpp: + * src/core/track.cpp: + * src/core/track_container.cpp: + fixed all that stuff with annoying scrollbars which partly hid important + widgets + +2006-01-20 Tobias Doerffel + + * src/tracks/pattern.cpp: + also update after clearing all notes + + * include/piano_roll.h: + * include/song_editor.h: + * src/core/piano_roll.cpp: + * src/core/song_editor.cpp: + use new combobox for zooming-comboboxes + + * include/export_project_dialog.h: + * src/core/export_project_dialog.cpp: + - reject() dialog when pressing cancel + - use new combobox + + * include/arp_and_chords_tab_widget.h: + * src/core/arp_and_chords_tab_widget.cpp: + use new combobox with according arpeggio-mode-icons + + * include/envelope_tab_widget.h: + * src/core/envelope_tab_widget.cpp: + * resources/filter_2lp.png: + * resources/filter_ap.png: + * resources/filter_bp.png: + * resources/filter_hp.png: + * resources/filter_lp.png: + use new combobox with according filter-icons + + * include/combobox.h: + * src/widgets/combobox.cpp: + added own cool-looking combobox with menu-extension which basically + has the same API as QComboBox + 2006-01-19 Andreas M. Brandmaier * plugins/bit_invader/bit_invader.h: diff --git a/Makefile.am b/Makefile.am index 69461aa2bd..cec44258d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,7 @@ lmms_MOC = \ ./bb_editor.moc \ ./bb_track.moc \ ./channel_track.moc \ + ./combobox.moc \ ./config_mgr.moc \ ./cpuload_widget.moc \ ./envelope_and_lfo_widget.moc \ @@ -72,6 +73,7 @@ lmms_MOC = \ ./pixmap_button.moc \ ./plugin_browser.moc \ ./project_notes.moc \ + ./rubberband.moc \ ./qxembed.moc \ ./rename_dialog.moc \ ./sample_buffer.moc \ @@ -160,6 +162,7 @@ lmms_SOURCES = \ $(srcdir)/src/tracks/channel_track.cpp \ $(srcdir)/src/tracks/pattern.cpp \ $(srcdir)/src/tracks/sample_track.cpp \ + $(srcdir)/src/widgets/combobox.cpp \ $(srcdir)/src/widgets/cpuload_widget.cpp \ $(srcdir)/src/widgets/fade_button.cpp \ $(srcdir)/src/widgets/group_box.cpp \ @@ -170,6 +173,7 @@ lmms_SOURCES = \ $(srcdir)/src/widgets/nstate_button.cpp \ $(srcdir)/src/widgets/pixmap_button.cpp \ $(srcdir)/src/widgets/project_notes.cpp \ + $(srcdir)/src/widgets/rubberband.cpp \ $(srcdir)/src/widgets/qxembed.cpp \ $(srcdir)/src/widgets/rename_dialog.cpp \ $(srcdir)/src/widgets/side_bar_widget.cpp \ @@ -283,6 +287,8 @@ lmms_SOURCES = \ $(srcdir)/include/midi_alsa_seq.h \ $(srcdir)/include/micro_timer.h \ $(srcdir)/include/fade_button.h \ + $(srcdir)/include/combobox.h \ + $(srcdir)/include/rubberband.h \ $(srcdir)/include/qxembed.h diff --git a/TODO b/TODO index 302d3681c9..6005007a1f 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,9 @@ to be done as soon as possible: -- performance-settings -- arp-sync-mode +- disable auto-cleanup of bufferAllocator during memory-expensive operations (pattern-freezing etc.) +- autosave every 30s (configurable!) and offer recovery at startup after crash +- make piano-roll use rubberband instead of implementing a simple one on it's own +- level-meters in output-graph and channel-track - do not skip samples because of rounding-errors when resampling in src/lib/sample_buffer.cpp - MIDI-program/MIDI-mapping/process program-/channel-change-events from MIDI-files - add note-len- and note-alignment-selectbox to piano-roll @@ -10,20 +12,17 @@ to be done as soon as possible: - use drawLineF() for drawing notes in pattern::paintEvent() in qt4-version - only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc. - pre-listen when opening sample with QFileDialog -- level-meters in output-graph and channel-track - panning-editing in piano-roll - speed up painting of sampleTCO - save window-positions, -states and -sizes in files - solve problems with different keyboard-layouts when playing channel-track with pc-keyboard -> use tr() - balance env+lfo -- autosave every 1 minute - plucked-string-synth: knob for metallic -> use noise as wave-shape - finish qt4-port and make LMMS usable when compiling with Qt4 - rewrite export-project-dialog using layout-mechanism - dynamic pitch-change - make piano-roll use the global clipboard?? - add more localizations: - - Italian - Swedish - Norwegian - Greece diff --git a/configure.in b/configure.in index 8c80d0a201..6a9bf417fe 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.1.2-cvs20060119, tobydox/at/users.sourceforge.net) -AM_INIT_AUTOMAKE(lmms, 0.1.2-cvs20060119) +AC_INIT(lmms, 0.1.2-cvs20060122, tobydox/at/users.sourceforge.net) +AM_INIT_AUTOMAKE(lmms, 0.1.2-cvs20060122) AM_CONFIG_HEADER(config.h) @@ -405,6 +405,7 @@ fi AC_CONFIG_FILES([Makefile artwork/Makefile + artwork/track_icons/Makefile buildtools/Makefile locale/Makefile midi-maps/Makefile diff --git a/include/arp_and_chords_tab_widget.h b/include/arp_and_chords_tab_widget.h index 248f86ddd8..8764c18b37 100644 --- a/include/arp_and_chords_tab_widget.h +++ b/include/arp_and_chords_tab_widget.h @@ -47,10 +47,10 @@ #include "types.h" -class QComboBox; class QPixmap; class channelTrack; +class comboBox; class groupBox; class knob; class ledCheckBox; @@ -124,12 +124,12 @@ private: // chord-stuff groupBox * m_chordsGroupBox; - QComboBox * m_chordsComboBox; + comboBox * m_chordsComboBox; knob * m_chordRangeKnob; // arpeggio-stuff groupBox * m_arpGroupBox; - QComboBox * m_arpComboBox; + comboBox * m_arpComboBox; knob * m_arpRangeKnob; tempoSyncKnob * m_arpTimeKnob; knob * m_arpGateKnob; @@ -140,7 +140,7 @@ private: pixmapButton * m_arpUpAndDownBtn; pixmapButton * m_arpRandomBtn; - QComboBox * m_arpModeComboBox; + comboBox * m_arpModeComboBox; } ; diff --git a/include/bb_editor.h b/include/bb_editor.h index ca71886131..9ee11db650 100644 --- a/include/bb_editor.h +++ b/include/bb_editor.h @@ -1,7 +1,7 @@ /* * bb_editor.h - declaration of class bbEditor, a basic-component of LMMS * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -33,10 +33,12 @@ #include "lmms_main_win.h" -class toolButton; -class songEditor; class QPixmap; +class comboBox; +class songEditor; +class toolButton; + class bbEditor : public trackContainer { @@ -71,7 +73,6 @@ public: } csize currentBB( void ) const; - void FASTCALL setCurrentBB( csize _bb ); tact FASTCALL lengthOfBB( csize _bb ); inline tact lengthOfCurrentBB( void ) { @@ -85,11 +86,18 @@ public: void updateBBTrack( trackContentObject * _tco ); +public slots: + void updateComboBox( void ); + void setCurrentBB( int _bb ); + + protected: virtual void closeEvent( QCloseEvent * _ce ); virtual void keyPressEvent( QKeyEvent * _ke ); virtual void resizeEvent( QResizeEvent * _re ); + virtual QRect scrollAreaRect( void ) const; + protected slots: void play( void ); @@ -111,6 +119,8 @@ private: toolButton * m_playButton; toolButton * m_stopButton; + comboBox * m_bbComboBox; + friend class songEditor; friend lmmsMainWin::~lmmsMainWin(); diff --git a/include/bb_track.h b/include/bb_track.h index 31bb4eb35d..c8f5c8c985 100644 --- a/include/bb_track.h +++ b/include/bb_track.h @@ -2,7 +2,7 @@ * bb_track.h - class bbTrack, a wrapper for using bbEditor * (which is a singleton-class) as track * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -135,12 +135,8 @@ protected: private: nameLabel * m_trackLabel; - struct bbInfoStruct - { - csize num; - QString name; - } ; - static QMap s_bbNums; + typedef QMap infoMap; + static infoMap s_infoMap; } ; diff --git a/include/combobox.h b/include/combobox.h new file mode 100644 index 0000000000..2366411dec --- /dev/null +++ b/include/combobox.h @@ -0,0 +1,117 @@ +/* + * combobox.h - class comboBox, a very cool combo-box + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _COMBOBOX_H +#define _COMBOBOX_H + +#include "qt3support.h" + +#ifdef QT4 + +#include +#include +#include +#include +#include + +#else + +#include +#include +#include +#include +#include + +#endif + +class QAction; + + +class comboBox : public QWidget +{ + Q_OBJECT +public: + comboBox( QWidget * _parent ); + virtual ~comboBox(); + + void addItem( const QString & _item, const QPixmap & _pixmap = + QPixmap() ); + + inline void clear( void ) + { + m_currentIndex = 0; + m_items.clear(); + update(); + } + + int findText( const QString & _txt ) const; + + int currentIndex( void ) const + { + return( m_currentIndex ); + } + + QString currentText( void ) const + { + return( m_items[m_currentIndex].first ); + } + + +public slots: + void setCurrentIndex( int _idx ); + + +protected: + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void paintEvent( QPaintEvent * _pe ); + virtual void wheelEvent( QWheelEvent * _we ); + + +private: + static QPixmap * s_background; + static QPixmap * s_arrow; + + QMenu m_menu; + + typedef QPair item; + + vvector m_items; + int m_currentIndex; + + bool m_pressed; + + +private slots: + void setItem( QAction * _item ); + void setItem( int _item ); + + +signals: + void activated( const QString & ); + void currentIndexChanged( int ); + +} ; + +#endif diff --git a/include/config_mgr.h b/include/config_mgr.h index 86f71c7887..01e0900e77 100644 --- a/include/config_mgr.h +++ b/include/config_mgr.h @@ -66,6 +66,7 @@ const QString PROJECTS_PATH = "projects/"; const QString PRESETS_PATH = "presets/"; const QString SAMPLES_PATH = "samples/"; const QString ARTWORK_PATH = "artwork/"; +const QString TRACK_ICON_PATH = "artwork/track_icons/"; const QString LOCALE_PATH = "locale/"; @@ -107,6 +108,11 @@ public: return( m_dataDir + ARTWORK_PATH ); } + QString trackIconsDir( void ) const + { + return( m_dataDir + TRACK_ICON_PATH ); + } + QString localeDir( void ) const { return( m_dataDir + LOCALE_PATH ); diff --git a/include/envelope_tab_widget.h b/include/envelope_tab_widget.h index a03dde991e..7e2eb48c6c 100644 --- a/include/envelope_tab_widget.h +++ b/include/envelope_tab_widget.h @@ -3,7 +3,7 @@ * provides UI- and DSP-code for using envelopes, LFOs * and a filter * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -46,14 +46,15 @@ #include "envelope_and_lfo_widget.h" -class QComboBox; -class groupBox; -class tabWidget; class QLabel; -class knob; -class pixmapButton; + class channelTrack; +class comboBox; +class groupBox; +class knob; class notePlayHandle; +class pixmapButton; +class tabWidget; class envelopeTabWidget : public QWidget, public settings @@ -97,7 +98,7 @@ private: // filter-stuff groupBox * m_filterGroupBox; - QComboBox * m_filterComboBox; + comboBox * m_filterComboBox; knob * m_filterCutKnob; knob * m_filterResKnob; diff --git a/include/export_project_dialog.h b/include/export_project_dialog.h index bb86180a87..3d4584fae9 100644 --- a/include/export_project_dialog.h +++ b/include/export_project_dialog.h @@ -2,7 +2,7 @@ * export_project_dialog.h - declaration of class exportProjectDialog which is * responsible for exporting project * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -31,7 +31,6 @@ #include #endif - #include "qt3support.h" #ifdef QT4 @@ -44,15 +43,15 @@ #endif - #include "export.h" class QLabel; class QPushButton; -class QComboBox; class QProgressBar; -class QCheckBox; + +class comboBox; +class ledCheckBox; class pixmapButton; @@ -88,11 +87,11 @@ private: QString m_fileName; QLabel * m_typeLbl; - QComboBox * m_typeCombo; + comboBox * m_typeCombo; QLabel * m_kbpsLbl; - QComboBox * m_kbpsCombo; - QCheckBox * m_vbrCb; - QCheckBox * m_hqmCb; + comboBox * m_kbpsCombo; + ledCheckBox * m_vbrCb; + ledCheckBox * m_hqmCb; QLabel * m_hourglassLbl; QPushButton * m_exportBtn; QPushButton * m_cancelBtn; diff --git a/include/lcd_spinbox.h b/include/lcd_spinbox.h index e8dd0feb36..09838803b1 100644 --- a/include/lcd_spinbox.h +++ b/include/lcd_spinbox.h @@ -1,7 +1,7 @@ /* * lcd_spinbox.h - class lcdSpinBox, an improved QLCDNumber * - * Copyright (c) 2005 Tobias Doerffel + * Copyright (c) 2005-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -58,7 +58,6 @@ public: return( m_number->intValue() ); } - void setValue( int _value ); void setLabel( const QString & _txt ); inline void addTextForValue( int _val, const QString & _text ) @@ -68,6 +67,7 @@ public: public slots: + void setValue( int _value ); virtual void setEnabled( bool _on ); diff --git a/include/name_label.h b/include/name_label.h index d7c6517922..e940500bfd 100644 --- a/include/name_label.h +++ b/include/name_label.h @@ -2,7 +2,7 @@ * name_label.h - class nameLabel, a label which is renamable by * double-clicking it * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -46,20 +46,32 @@ class nameLabel : public QLabel { Q_OBJECT public: - nameLabel( const QString & _initial_name, QWidget * _parent, - const QPixmap & _pm = QPixmap() ); + nameLabel( const QString & _initial_name, QWidget * _parent ); ~nameLabel(); - const QPixmap * pixmap( void ) const; + + const QPixmap & pixmap( void ) const + { + return( m_pixmap ); + } + + const QString & pixmapFile( void ) const + { + return( m_pixmapFile ); + } public slots: - void setPixmap( const QPixmap & _pm ); + void setPixmap( const QPixmap & _pixmap ); + void setPixmapFile( const QString & _file ); void rename( void ); + void selectPixmap( void ); signals: - void nameChanged( const QString & _new_name ); void clicked( void ); + void nameChanged( void ); + void nameChanged( const QString & _new_name ); + void pixmapChanged( void ); protected: @@ -69,7 +81,8 @@ protected: private: - QPixmap m_pm; + QPixmap m_pixmap; + QString m_pixmapFile; } ; diff --git a/include/pattern.h b/include/pattern.h index ca190cd411..d3987e2b64 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -36,6 +36,7 @@ #include #include #include +#include #else @@ -44,6 +45,7 @@ #include #include #include +#include #endif @@ -54,7 +56,6 @@ class QAction; -class QPixmap; class QProgressBar; class QPushButton; @@ -84,9 +85,6 @@ public: void init( void ); - virtual void FASTCALL movePosition( const midiTime & _pos ); - - virtual midiTime length( void ) const; note * FASTCALL addNote( const note & _new_note ); @@ -159,6 +157,10 @@ public: } +public slots: + virtual void update( void ); + + protected slots: void openInPianoRoll( bool _c ); void openInPianoRoll( void ); @@ -180,21 +182,27 @@ protected: virtual void constructContextMenu( QMenu * ); virtual void mouseDoubleClickEvent( QMouseEvent * _me ); virtual void mousePressEvent( QMouseEvent * _me ); - virtual void wheelEvent( QWheelEvent * _we ); virtual void paintEvent( QPaintEvent * _pe ); + virtual void resizeEvent( QResizeEvent * _re ) + { + m_needsUpdate = TRUE; + trackContentObject::resizeEvent( _re ); + } + virtual void wheelEvent( QWheelEvent * _we ); void ensureBeatNotes( void ); void updateBBTrack( void ); private: - static QPixmap * s_patternBg; static QPixmap * s_stepBtnOn; static QPixmap * s_stepBtnOverlay; static QPixmap * s_stepBtnOff; static QPixmap * s_stepBtnOffLight; static QPixmap * s_frozen; + QPixmap m_paintPixmap; + bool m_needsUpdate; // general stuff channelTrack * m_channelTrack; diff --git a/include/piano_roll.h b/include/piano_roll.h index a9d253cc37..94e9b46d0c 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -47,17 +47,16 @@ #include "note.h" -class QComboBox; class QPainter; class QPixmap; class QScrollBar; -class toolButton; -class pattern; -class notePlayHandle; -class timeLine; +class comboBox; class lmmsMainWin; - +class notePlayHandle; +class pattern; +class timeLine; +class toolButton; class pianoRoll : public QWidget @@ -205,7 +204,7 @@ private: toolButton * m_copyButton; toolButton * m_pasteButton; - QComboBox * m_zoomingComboBox; + comboBox * m_zoomingComboBox; QPixmap m_paintPixmap; bool m_cursorInside; diff --git a/include/pixmap_button.h b/include/pixmap_button.h index ee4b0a1096..e1bfc5edc1 100644 --- a/include/pixmap_button.h +++ b/include/pixmap_button.h @@ -1,7 +1,7 @@ /* * pixmap_button.h - declaration of class pixmapButton * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -56,11 +56,17 @@ public: void FASTCALL setInactiveGraphic( const QPixmap & _pm, bool _update = TRUE ); void FASTCALL setBgGraphic( const QPixmap & _pm ); -#ifndef QT4 + +#ifdef QT3 inline void setChecked( bool _on ) { setOn( _on ); } + + inline bool isChecked( void ) const + { + return( isOn() ); + } #endif diff --git a/include/qt3support.h b/include/qt3support.h index b7b3be02ee..8761b2b62d 100644 --- a/include/qt3support.h +++ b/include/qt3support.h @@ -69,7 +69,7 @@ inline QString baseName( const QString & _file ) } -#else +#else /* QT3 */ #define vvector QValueVector @@ -117,6 +117,7 @@ inline QString baseName( const QString & _file ) // QScrollView/QScrollArea #define setHorizontalScrollBarPolicy setHScrollBarMode +#define setVerticalScrollBarPolicy setVScrollBarMode // QScrollBar @@ -189,6 +190,10 @@ inline QString baseName( const QString & _file ) #define setColumnMinimumWidth setColSpacing +// QRect +#define normalized normalize + + // Qt-namespace #define ShiftModifier ShiftButton #define ControlModifier ControlButton diff --git a/include/qxembed.h b/include/qxembed.h index e71792f844..f1c2b90b47 100644 --- a/include/qxembed.h +++ b/include/qxembed.h @@ -27,7 +27,6 @@ #ifndef QT4 #include -/*#include */ #ifdef Q_WS_X11 diff --git a/include/rubberband.h b/include/rubberband.h new file mode 100644 index 0000000000..286b92d3a1 --- /dev/null +++ b/include/rubberband.h @@ -0,0 +1,121 @@ +/* + * rubberband.h - rubberband - either own implementation for Qt3 or wrapper for + * Qt4 + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _RUBBERBAND_H +#define _RUBBERBAND_H + +#include "qt3support.h" + +#ifndef QT3 + +#include +#include + +#else + +#include +#include + +#endif + + +class selectableObject : public QWidget +{ + Q_OBJECT +public: + selectableObject( QWidget * _parent +#ifdef QT3 + , WFlags _f +#endif + ) : + QWidget( _parent, NULL, _f ), + m_selected( FALSE ) + { + } + + virtual ~selectableObject() + { + } + + inline void setSelected( bool _selected ) + { + m_selected = _selected; + update(); + } + + inline bool isSelected( void ) const + { + return( m_selected ); + } + + +public slots: + virtual void update( void ) + { + QWidget::update(); + } + + +private: + bool m_selected; + +} ; + + + +typedef +#ifndef QT3 + QRubberBand +#else + QWidget +#endif + rubberBandBase; + + +class rubberBand : public rubberBandBase +{ +public: + rubberBand( QWidget * _parent ); + virtual ~rubberBand(); + + vvector selectedObjects( void ) const; + + +protected: + virtual void resizeEvent( QResizeEvent * _re ); +#ifdef QT3 + virtual bool event( QEvent * _e ); + void updateMask( void ); +#endif + +private: + vvector selectableObjects( void ) const; + +}; + + +#endif + diff --git a/include/song_editor.h b/include/song_editor.h index ae14685a7d..062ae3df4a 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -2,7 +2,7 @@ * song_editor.h - declaration of class songEditor, a window where you can * setup your songs * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -29,20 +29,20 @@ #include "track_container.h" #include "types.h" +#include "tool_button.h" -class QComboBox; class QLabel; class QScrollBar; class QSlider; +class comboBox; class lcdSpinBox; class lmmsMainWin; class pattern; class projectNotes; class textFloat; class timeLine; -class toolButton; const int MIN_BPM = 10; @@ -51,7 +51,6 @@ const int MAX_BPM = 999; const Uint16 MAX_SONG_LENGTH = 9999; - class songEditor : public trackContainer { Q_OBJECT @@ -204,11 +203,18 @@ public slots: protected: - void closeEvent( QCloseEvent * _ce ); - void resizeEvent( QResizeEvent * _re ); - void keyPressEvent( QKeyEvent * _ke ); - void wheelEvent( QWheelEvent * _we ); - void paintEvent( QPaintEvent * _pe ); + virtual void closeEvent( QCloseEvent * _ce ); + virtual void resizeEvent( QResizeEvent * _re ); + virtual void keyPressEvent( QKeyEvent * _ke ); + virtual void wheelEvent( QWheelEvent * _we ); + virtual void paintEvent( QPaintEvent * _pe ); + + virtual QRect scrollAreaRect( void ) const; + + virtual bool allowRubberband( void ) const + { + return( m_editModeButton->isChecked() ); + } protected slots: @@ -232,6 +238,8 @@ protected slots: void zoomingChanged( const QString & _zfac ); + void doActions( void ); + private: songEditor(); @@ -273,10 +281,11 @@ private: toolButton * m_addBBTrackButton; toolButton * m_addSampleTrackButton; - toolButton * m_insertBarButton; - toolButton * m_removeBarButton; - QComboBox * m_zoomingComboBox; + toolButton * m_drawModeButton; + toolButton * m_editModeButton; + + comboBox * m_zoomingComboBox; QString m_fileName; @@ -310,8 +319,6 @@ private: } ; vvector m_actions; - void doActions( void ); - friend class lmmsMainWin; diff --git a/include/tab_button.h b/include/tab_button.h index e8213aa8e2..c117da330c 100644 --- a/include/tab_button.h +++ b/include/tab_button.h @@ -1,7 +1,7 @@ /* * tab_button.h - declaration of class tabButton * - * Copyright (c) 2005 Tobias Doerffel + * Copyright (c) 2005-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -52,10 +52,22 @@ public: connect( this, SIGNAL( clicked() ), this, SLOT( slotClicked() ) ); } - virtual ~tabButton() + + ~tabButton() { } +#ifdef QT3 + inline void setChecked( bool _on ) + { + setOn( _on ); + } + + inline bool isChecked( void ) const + { + return( isOn() ); + } +#endif signals: void clicked( int ); diff --git a/include/timeline.h b/include/timeline.h index 16db6770f7..1a2c68fc1e 100644 --- a/include/timeline.h +++ b/include/timeline.h @@ -69,7 +69,7 @@ public: timeLine( int _xoff, int _yoff, float _ppt, songEditor::playPos & _pos, const midiTime & _begin, QWidget * _parent ); - ~timeLine(); + virtual ~timeLine(); inline songEditor::playPos & pos( void ) { @@ -117,11 +117,14 @@ public: public slots: - void updatePosition( const midiTime & = 0 ); + void updatePosition( const midiTime & ); + void updatePosition( void ) + { + updatePosition( midiTime() ); + } void toggleAutoScroll( int _n ); void toggleLoopPoints( int _n ); void toggleBehaviourAtStop( int _n ); - void checkForUpdatedPosition( void ); protected: diff --git a/include/tool_button.h b/include/tool_button.h index 6a80153e83..410736d167 100644 --- a/include/tool_button.h +++ b/include/tool_button.h @@ -1,7 +1,7 @@ /* * tool_button.h - declaration of class toolButton * - * Copyright (c) 2005 Tobias Doerffel + * Copyright (c) 2005-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -70,11 +70,21 @@ public: m_colorHighlighted = _color; } -#ifndef QT4 +#ifdef QT3 inline void setIcon( const QPixmap & _icon ) { setIconSet( _icon ); } + + inline void setChecked( bool _on ) + { + setOn( _on ); + } + + inline bool isChecked( void ) const + { + return( isOn() ); + } #endif diff --git a/include/track.h b/include/track.h index 1976dd2ae3..6da5d61fdd 100644 --- a/include/track.h +++ b/include/track.h @@ -55,6 +55,7 @@ #include "types.h" #include "midi_time.h" #include "settings.h" +#include "rubberband.h" class QMenu; @@ -76,7 +77,7 @@ const Uint16 TRACK_OP_WIDTH = 70; const Uint16 TCO_BORDER_WIDTH = 1; -class trackContentObject : public QWidget, public settings +class trackContentObject : public selectableObject, public settings { Q_OBJECT public: @@ -99,7 +100,9 @@ public: { return( m_length ); } + bool fixedTCOs( void ); + virtual void FASTCALL movePosition( const midiTime & _pos ); virtual void FASTCALL changeLength( const midiTime & _length ); @@ -132,13 +135,17 @@ protected slots: private: + enum actions + { + NONE, MOVE, MOVE_SELECTION, RESIZE + } ; + static textFloat * s_textFloat; track * m_track; midiTime m_startPosition; midiTime m_length; - bool m_moving; - bool m_resizing; + actions m_action; bool m_autoResize; Sint16 m_initialMouseX; @@ -167,10 +174,12 @@ public: { return( m_pixelsPerTact ); } + inline void setPixelsPerTact( Uint16 _ppt ) { m_pixelsPerTact = _ppt; } + tact length( void ) const; @@ -184,8 +193,7 @@ protected: virtual void dragEnterEvent( QDragEnterEvent * _dee ); virtual void dropEvent( QDropEvent * _de ); virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ); @@ -296,9 +304,11 @@ public: bool isMovingTrack( void ) const { - return( m_movingTrack ); + return( m_action == MOVE_TRACK ); } + virtual void repaint( void ); + public slots: void changePosition( const midiTime & _new_pos = -1 ); @@ -317,14 +327,17 @@ protected: private: + enum actions + { + NONE, MOVE_TRACK, RESIZE_TRACK + } ; track * m_track; trackOperationsWidget m_trackOperationsWidget; trackSettingsWidget m_trackSettingsWidget; trackContentWidget m_trackContentWidget; - bool m_movingTrack; - Sint16 m_initialMouseX; + actions m_action; } ; diff --git a/include/track_container.h b/include/track_container.h index 0486308b02..fe58b667b6 100644 --- a/include/track_container.h +++ b/include/track_container.h @@ -2,7 +2,7 @@ * track_container.h - base-class for all track-containers like Song-Editor, * BB-Editor... * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -46,10 +46,13 @@ #include "track.h" #include "settings.h" +#include "rubberband.h" const Uint16 DEFAULT_PIXELS_PER_TACT = 16; +const Uint16 DEFAULT_SCROLLBAR_SIZE = 16; + class trackContainer : public QMainWindow, public settings { @@ -102,14 +105,38 @@ public: const trackWidget * trackWidgetAt( const int _y ) const; + virtual bool allowRubberband( void ) const; + + inline bool rubberBandActive( void ) const + { + return( m_rubberBand->isVisible() ); + } + + inline vvector selectedObjects( void ) + { + if( allowRubberband() == TRUE ) + { + return( m_rubberBand->selectedObjects() ); + } + return( vvector() ); + } + + protected: virtual void dragEnterEvent( QDragEnterEvent * _dee ); virtual void dropEvent( QDropEvent * _de ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void mouseMoveEvent( QMouseEvent * _me ); + virtual void mouseReleaseEvent( QMouseEvent * _me ); virtual void resizeEvent( QResizeEvent * ); constTrackVector tracks( void ) const; trackVector tracks( void ); + virtual QRect scrollAreaRect( void ) const + { + return( rect() ); + } midiTime m_currentPosition; @@ -141,6 +168,9 @@ private: trackWidgetVector m_trackWidgets; float m_ppt; + rubberBand * m_rubberBand; + QPoint m_origin; + friend class scrollArea; diff --git a/resources/arp_free.png b/resources/arp_free.png new file mode 100644 index 0000000000000000000000000000000000000000..86bef17c1fca723020817cdfe5920041f57cf945 GIT binary patch literal 273 zcmeAS@N?&q;$mQ6;PUiv2?EjrAk4uAB;`N|Zx3-u}@7g@) z-n_=S^XoT7u!U^&Sk3k~!lW^R)mXfMBTdWXhw=>h{TdoVJeQ{F1MOz;boFyt=akR{ E0C)CTF8}}l literal 0 HcmV?d00001 diff --git a/resources/arp_sync.png b/resources/arp_sync.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c52bd56f9a87748cbe6f7cdba6759caba45e52 GIT binary patch literal 326 zcmeAS@N?&q;$mQ6;PUiv2?EjrAk4uAB;`NpthGisV3vm?cXby}hBMkmQldRtvN4>n&7XujF9Y?9-vwe7lPA1B@1opXr$jZ9^~ zy{_lOdmu46-)@aTX5vzWXGyyZukH22^j?VXNI`k Q1Uj3+)78&qol`;+0K`3kAOHXW literal 0 HcmV?d00001 diff --git a/resources/autoscroll_off.png b/resources/autoscroll_off.png index 517886512423f3b12cce309d71fc2fd077be578b..715d68fd4d94636daaa624563402b0e42fa3ba13 100644 GIT binary patch delta 1045 zcmV+w1nT?Y1;hxDBM$~*OGiWi{{a60|De66laU}Ef7SsN6*31q?R&-m00YuVL_t(Y z$EB6ejucfC#((GD>gt+?o(6|jW-tyya13k=8#OV;QT!958;ve;<$}aF@Ev>r*KT|V z7rHPpY!rxOFbp7qh%(bN)74#7_g0_d!W!&MFf>@nNvdw{{k~h@`OZ0>$9N7OKAiM= zy>q=@fA6bqxBEq>)9ISo%^2etm`v|=k3%3L^JaDiI3Xgf5W=$|gcYC%`2S5%6h&0k zO*0D$;W6L{knP1x9tC)LdD+Jp`)2kk@I2sDwF)5&RW&~7%*+H!OG{ad@sx<16Oj)^ z9*swyI>h~T}?k|gOTNphgq>%A!=p{lBH%Cg)6qMwBzP1Ck>?zD66 zbc}Js%y7F2zB9F@ zf91VjsO$P_p6B0HRW$$xz}U~4LP8o+lBXjOGFS6-$*kajYezZ@%RTby8v7TZa3f~KxejTx7$4-B5#OD ze|If}uu)ajWivYuTmtR@Lm=$B$j#V$fA)#U+amJHv_-x5b6J+Py!RWxAHde$TA0m+({v{p;e(>Nymn6xmbMCB&^!5;obFS;XKbEHH z3UEEfxCz8vl8635mSx98bjYikYvbB z7h6Er%${`4y$`Gc&xptoU|)>!*F4YH%Cfwmsy_kOfo(vXb7z1RRaG-uUCKIRrP&YmN)9U9;s?Hvr1KmO*{UriNTZ|6JX2CMvd-uv;I$#j~+cLRaHG@W>4pN z{&k+`cUAQkaJMO%adR+lzRNwgG+?voPacq|uw*b8NT<_j#TdUF4u@CFdu#`|)<{q^ zLwq-M??3@CvkDRM^YioXsOsgas@5C1g0HH|LI^vf(P&*&hrrFISqd8&;uN?&$Z>OX zb8QiM!8!L_r_*^0SPLQC1}d2v{#m1EnC>OB6gsdUI1Zd_-fsav19$!g-^TXLr5l3w P00000NkvXXu0mjf{5f2K277BtO-bIw2 z#G8jIc<`bico6(KE3~Ch>B-+iS|M%n7OkZ!HUulldvCn7kbj14a5wI4=kMG3=9^hU z%qNq{I9lrm08WcYClQ?pg5XtSoD&zoTH7NcW1H{Hyc!nAaRE}P)G~n2b%44529V3; zs9Y|O07%rC7s6sAQ{;JGf2C4+C?dz|=sCsAZ^Pm#O7V0$ecW366hOz8B1G?kAUN0( zKsud1WUZYAuzxd@3diX!7K_Wi?`K8iN2yd=i!=if(VLtT(LDg`3jTeb=XGkWr;IVP zk%t@v!3QF`zX31`U{}507<0)OGe<;uA{vV|1K;;|Ypp*L(GC%D8{7qE9&c}Nf0EDV z;|du7T-UuWBDd>IWoAB^NF?S8g@SEKrk>|@8Dp+CD1YdVQtHiiIUMmk+y&6Pr2zAb zW;s!0y4PAeACj}e%;%L-Q!RBMBImaGpdM@OYu9zh2L=Y5SRG`uS*Kd9E&#|jrGw~w zB9S<}xVTu0)IqIQyHQu%643-RA8{OK5WpZ2jR5#9B16{N?tfCz=;$bBW@b8#F=HY! zzG42u%zqb@QqLN~KlSzX6#(ofqV-S!-}fCN+9M)KW6Z_L$;rzKlze68vrQyv0aTO8 z1Jrepp^mjMiCGDDfv($Z38i;AqZ9Yl1ch2jA43P4J0 w{mApYRP1BdWYdpYYbOBo6OkpN14^mjFJ7ewi2lh+X#fBK07*qoM6N<$f>!%Q0ssI2 diff --git a/resources/autoscroll_on.png b/resources/autoscroll_on.png index 4da52a470ac1e8388b921a9c2157d59ab08c3e74..e5853f74f6da9fc8b3540dc276acb3e9ee6d625d 100644 GIT binary patch delta 1167 zcmV;A1aSNQ2B-;;DS!U}{{a7>y{D4^000SaNLh0L01DRt01DRuLMWSf00007bV*G` z2i5@<6)`I!7)0g(00cHkL_t(Y$DNkTZ&Xzr$3N%Zd3C14Oqo6?tVv2;F}Na-kZ5coU}ECJl{;Oie}fBL;L60fFwuw_6KNpYVt-2urO#=H>9q6g+{fIx z=eXdu4ybYDuI|0(obUJie!uVe{*KN=Jo>5gK6PPel+pG}Tu6Mz-p8Zd3NMjaGXS@K zuJ2(8RLsAF{+ScR+yMlF+u2^0SB8Kh-~hF)x!S`JusrUt63JoussIRI62I03gdW8F zUlHgZe5A{^tAA}0?HPiF#}H@~mCZ`AOvQBmX-&ff;@yiOxAWS5TC1b%D!fkAjsx(u zc89U-9V(S|zy@Ufx`t9D-aa2t1FJ{q+4z{=?AdK_fTx39>yOYyA}Mo5wLV8>LAiGJpnjSs`|X+h}QttG9Ya2!Cl+%+Bw)o-P4SLj)?FcF3tB zaou22&*7KN9F{GB0H8hI&8yK7_NXVRs0u3f0&oi`>Iy|L^+%0FpQ2gq1J%q9CrB&d z?QtjUCl*OCU!CQ0=0~Q}d8Et(hTgD*7Apn%60P+5o}$}L;8PloP)yd!%o zH?Od`I)8_htH3&7HL4;hx|61gHWdgP5OVKrY}RM+d2X7ktG{AfEr;(^m8PtZQDPuTN~UgOkrDNzzQG=l!5A&TpN?=xr-6HvoDaaj^VG{)PQK>K&zj4 zd;_=(6dpVajj5>9*h8>(lxQ`6-@qYXf>?Bzy??En{G459;Hcg0~M}WIf`Z( zO*w>u8Y9{s4l>NQ`WXJe8cuZ%umJUM1VVr9v|sjz`&7^Bn{<{=qDhSjk>ShrdB$@y z7=O+JLKF!G1VaO7IqdAGYVStMHX!BI;x7W<>G%9-R#e8EcG+Kg#qD1lCSpE{rgfo- z2xIypU#v|to*Bn9e+TA0{}<>7PT6>m|k-T-Dit=oW(FMm*=<^zO8zd0E*3Ej-HJmv5=0?1WF3e2$imcs}bzm&4Old>3^pQ zEPENHrhqwM%Tw|mxLx0Gw|mObCk`^0eU^B42Pt=&d?kgHCgAEU%_~wXC9dAQgJG6| zB@cKD(D7~xvOc%OJR*N;DD%PDHLkV1k>lGtB@1 delta 866 zcmV-o1D*V+3H}CB!Apw%%^w=ae@PLacW7$&wE7Dy z?)}34Ti!LU;eVB^K@1X4LJ{W<9>}0eE3ZQB2@eoyjcsIW%jS+KMVzJ3Kr`-@{Vfgv zEVeaCFcnV#07bri3ZGjX9x{M2_`y>J0FY4Bm7&LR?(=KuUf1ICMaf zQ~V>f}+oPYK=?We(^%rVMESr@l#9oj%WdBwGxr$i6s7e!n>7 zD5*D;5@+mX9)eqxBoLK%B1^Bl#`MlaD)@8&T*Cq=%*7FY-KR{ppt=A6APOGt{_;(9 zf6;XYpwE*Gc!9*#@1S?hCLr#hHWji;1#Yx^41Z%#`J-H$S^UfGqVCG?lyrtWxrb@% zX`!Vyc##N&DEQP`f0r*9K#F^t>rbsI`W4LZdHieAJm(U=YaQ^YTDi{1TatZW=b*nU zDtgd6y1mP6X2Bb6@`rWk)qEv&^Y`=Z(Kq~ub3XqWDgCR%-I_M0`JoFwWA>FqqAuCb zSzE13r?_l$z5X-wVOWv1X=OfWG)!i({N z7>R~NA;!drJQ#wIpwR~?BzOt+2Bs;XR?4M7w}suZz3ndBJ#)r~9h==!=z~vAGC6ZH z^UZ(0fA9Z&-yi<(!y5H3sKmy?#>U1)0Q$cGh~o98lN?k7EXxlgJ6pMaVIQxMCJtl( zZ;90`VnH2W)cbnn1jn=pk}nEQ&t^m*tNg?{DK#cZWraXQ6Ol} zhz9~lf#vgqnlIl{{D$y=WIE+OIE~UV*%O4 zA+jXG@quT9B@t+Xb2sl@zwYVHr==~GwuBIt$om6MdD01>9cWk(n=-3z+O9*h7rxro zdiJyQnLVGX+vnpzmcms;#qC6C~Cq}9*;XulR%NZEx z9rRKsj}P=8Kh&9R`}SN>hLvzI*6_OCe_Fl=2m#Z9^2Yt&tiAZyhS}+~(y8x$%=8{R z67N5C=#tK)I)R(O72q!*bq@z)0RXpvRv-ZQ@5JL3z3+XLNPO{OuiMj+1mZv^a2@CY zdQEt;fG5W(Lv4!eCh!MvzI*RG?}jd9&%U|y@S>Sb+Z50O`~aK<{x%?KK#do?V)J=J|OyRz1DOZ=mrK&dUgN<_mJ$m zkQarot48uDYjQk}_S(}eN6(~Njz(|1UD;Tk6RJKp#QyjP?s7YEp!00000NkvXXu0mjfD{4Iw delta 980 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 KMNUMnLSTZOSS)b> diff --git a/resources/cancel.png b/resources/cancel.png index 49dd0e6abc1537334cb649f3a8817720bec73779..36cbdeb294f3c55d2a0e70fce94668202785c398 100644 GIT binary patch delta 1072 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 diff --git a/resources/combobox_arrow.png b/resources/combobox_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..c918b0e19d01061a1be5e9d2480a4b2d2aeb5296 GIT binary patch literal 477 zcmV<30V4j1P)VhQE8g=8n?| zhDg+wuDd8!mjH>YY+tAfO}x8a^UG? zGFfjno6p6Pj;*mTk;37vRfgKP7d+|hoWPYLqOx_3aKdJi*jHHz# T`E%YF00000NkvXXu0mjf-{REH literal 0 HcmV?d00001 diff --git a/resources/combobox_bg.png b/resources/combobox_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..1faeca0070184587d622fdf08c31c584921314f8 GIT binary patch literal 138 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 literal 3113 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 delta 1235 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 M07*qoM6N<$g1cF{RsaA1 literal 880 zcmV-$1CRWPP)KPds3=Y1r6ZptuZBSAY&G7Bp4-^Z3{P@W*Z{8*bzR$-lIEWtp z0P=x)?v+AZ4g?4wmTy1)@0YQ4G~khyWB9n_KZB*E4#Sftudph%wA5obcIc^rbbunm zm&Z39&UR@#7?)i&#HJP?fLIv#gbc*Y6u_Kcf4_n0hYz3Q460v$e==}Max-v=sWUt| zcf$aeI)DIT`SqWL;r}m)x1H_(G3-6C5pNv0IQ)mG|M{EY*B>UF>Hq?Wad)rne}`my zyoOzUkc?OU%$e&9$;qCK$YKBi#PaRiKZbw5e-KP9`uYlp;P~~Q;m@Cc3}3!{V_;%} zxO(o~?f;Pq2M8dhZ{Pody@n5?17>DMAZ7w%7%(^21{)6J0|XGzV4#bEn(<+*VaUh; zHy9KYCr@65yBtIV1Q5%QpTq?Px}jiKfrH^6gO`^T!^e+b89sgb%5eGe9k3ig0I~f4 z_YcLp|G)ocVE6{afBpjXKz$~P&9#g`nh{LDfB&7~`}ZGUHVgm+5X=AnprH5(Hst@i zuM7;o{}JtC5dHV>e}><`|1z+!Ff;u7hX`|k0Ad0182-jzAZr-@z5PUVq=8)f>(?)cX0Z1mt_1mji3wpaKmf7)2YTh-uir!&3^L>Q?>}Id z!7wOgfLsfTxIcdoWivnk0SgLfCWh}{e=)GL5>5)g zks=qC)R0|?3;+U%rDfYK#u_ix|DwEqa2n`f4-1OF&Ga0R{jid9ATQaT`ql0000P)68-ILtKKlh&VJ@=g7 z|6K0aHdeIFUNIt@?B%h7)!P9Smwn)PEbg^Psm4f&L}TTXM(2i&%nHjb_*?VTiRNrzD zk0y>KN~)i$zUiD@%Ia?Jw%ok@p$;EmAoL_(I1_c3q^!7JEzTLhEJl&RtZ{syT$_i} zucTj}$W7c6eIdH$9m7#{I-$eYxE6Y`8X)98Q zOl8e`-kkS6g~3P&G=p(m55fO!)DLdB--4JEp2acj3xz1Gnsq7mT6V$brcL8oBuHy6 z1kPixir%zVn-mg{&bdC1Nt_9YD#t;6LL_ zIjt_a>JmEf3nn8woLM={8`Gy$%wOv550E~z;d?zYI&cxa1w}<}VKA;i()z^2+)!@` zUFgwo&_%SP2UoF-eB>6VZvoQpfTLzS;EF4L)gH=nIs89Mg_0ND=7`^o2ZN?6!;jgE zbP!8^C-1>lRvaLAqYQszDrCO8(+6iKHz^KlWg8{lvH!P!04&P{c`m2+-T(jq07*qo IM6N<$f_YebF#rGn literal 738 zcmV<80v-K{P)H?fKUpa#~{GK$S|LegEzom#h)QuIh;XHP#;CfvU^Jz z7F=7vaP#fW3;+Ky1TrKsJiul!KmZ{Op3Y#vz{IfMRo7J@$~cOFhm8lXS7#lc#jyMG z?hg!q859|^7(SrO0|XGn;0X{z)s)l(SpKsxJb&|?;r-|LU@1;EP6kaSO$IGZEe1&$ zNfgbS_iSdkaqY$dhI|G`bb|o`h>@Wk=zV5}`#`n;5I+D~FcBCW8yJeAUhHL1VEE6F z!0?YDUq)L-K-o(fuKD-R-wbCKo?-a);g=&rIl}>Dg8>4FfuV_EJwr24Yb!$mUca{i zEpA~r&#{r?KMxXQJIVGRsDD1Xa)1D0WT;_y4|Jg;Q1Sv!Ln|2^psEFcKAO)E0;JWT zaxZ~+4p8quhC*a500G2EFhQ0A!~Z|Sc?NzUn;$Bs3&k+77Knc$S@e_P13&;V6Eyf3 z!wUvehKCHl83GtQfqWw%76b(_5>^3X3LyRq#8-hSr{pd00G2IbRInmG+Ya4_!XexQb0Z{lA)J?cpJo}409oI z1rR{YBozP`fKU@?_)VbU5>Ugh0`VRo{tpbO#SAB4N&y0hndH*tGSuaFfQEx23}RFw z!%|?{M*;u=L_UfJCc9{$JEMV_2MYiQAVyl%AOHbGv+@`qfM{kgKmgIqV1NJv02Q;T UDbiTG{{R3007*qoM6N<$f-EE!-2eap diff --git a/resources/edit_select.png b/resources/edit_select.png new file mode 100644 index 0000000000000000000000000000000000000000..b09759a89ddf3e87e3c57675504ddb4a69ae9217 GIT binary patch literal 1070 zcmV+}1kwA6P)TC_DF6Tiyh%hs zR7l6Ql}}F_M;M2nnb}<}Uej#sbp$v?NNq?fr9uXAjHOf{A#vm@5F|cLk6icw{Q@Ww zIixbTr1de06nuz+6=`<^F7jy2;N9t==3k>WfYMi*)4cCI@62!JH)3aJ$9B72j4>#s z2*Z#t4C(cH^m;w=Jje4q>h(GR*UepBUHuXG=ybbXwzjrNl7w=(Otaaf*=*8kwbMVBd2XxKqTlaRtJT=t+ywX;c;OghNRouXV8G1G zj0%Fl7DZu$AfQ&OVT|GK-MgGcwOU0=iRXC)K|oOyjB;g~rXooaj4=S;1HU^;Daz$C zGcz-GX=!O-j5*%l-#4!7=5up%6h(pKIDGi<0f5=rS%$+QQc7IcrPJw9E|=BP(o)4* zTS}5dD5U@#KssR<(rh*fg1{PMj-Ney_Q%oDQAa8Drw}6N8ZkLJd1qy1WqEON@uAk* z3BwRT0GtD?wf5b+cjoZ$aR2@L_rC!Lz{zz0^?H4>TCF~so}PXngkS^!!0GjRv|25K zAi#CqTq$)tTD$`ct^;T^8pc}NZ@1fMt$Fg~34lEZ?CtGQtJRpBn?ndO9Cbbz3i~C% z#Kgpj*1Bl7+cu748jZ%q4)Q!F%QB2H6h(2l&R!b-8LsQvJkJ>n24q=Ao?l4kc%DbC zRwE2U9LM3d;kquBN`;~*@I3DVP_Nh7*w_Hz;NSougt+PALI@E>5o>E}!dlDJ)YSQ$ z{AaSY*4`9wsphj2_SQ#~rYX;#KPOF7*4NiB0LB>NI7Ujza5%g* z;PmvAPoF*!$MKm}{Cz}9DSY3@^E{-Kx7I*PiSPTu_kBiI!IhU>DwXg&@75ZOkB>7y zKX0|xS6}iatDw{ATxskkkRS+HSXcn~cdICu%W7(BD!hOH{$!)kFcT9KC$8&$aYst2 zZ?h~by?OIS_WS)atGEh?qDU?;FIQGpR+g*P>LY7yUu#|Dd5-J4L{W5pTTV|;ky0`~ zK28t>WLZ`^Iy(C4<;#~UNs=?G5a(9W@Apa5Q~;&L#l?ry)6);y?KbUp+YSZ;DwPUr zYij`P?(TAUc!=-&%+JrWu&}`E*RSQPSFhCDw{NBI`=47y6h)+IN|Gc(YwZXj&{`A6 zFsMnv#U5ZHip(30IfA?n&SIDQ50RV3h_UF`o93b3gCy)2mKx3@^xYe>;o?Z oa0i$Kz8MK4z5<{Cj)9MV0Z6~>2Owx-9smFU07*qoM6N<$f+j}$B>(^b literal 0 HcmV?d00001 diff --git a/resources/edit_undo.png b/resources/edit_undo.png index f81746373b1f1a0b3e94ff21f06b589a8b716e2a..56c4688f93fd0b9797bf8cb17ec93136259f7feb 100644 GIT binary patch literal 919 zcmV;I18Dq-P)IsBLDycB}qg< zR7l6|l}l_BR}_XnXU3U{?b;@BNNCdVND55=DHx2(LtV6jMFWVJSilO2Qi)9~K%k1Q zx?;l?i5*m`1QHJ^LRBRaiMBzhXiJ1?AOR(gz&42;CzIImIGz`anSd#QD8P~<{nF^( zbMJr8x&QnZKExa$yk^`5lsWUR_f6^w9#ali{bX5z??i z^cOMi$GpuG;&Pw)q`e==0R~{bErF|S@5mO)t1g|{ouGAP1Cb>fUBfHGS$CsEyuBBg znlH%$}e5p*L{r-GOY=Rww5#&(E!Ot^( zPq2$kiQdn`FP&7hr6PSCG?WJ`NfTXyGt& ztxWRQULX(Xb1H^C83jQKxFs(Dq5zv$yhs>I+W^os3iKS@IeL=8^A~}qfHup%Gm5iB zQhyvK-L+aPJZ;37_G>LCHl}LVFYs5`8KwoAGGGw>u@8M}48fD;@g>EPuHaN*JwNc* z(RE1GH@LQ_1(+21b5|!Y2vh?yjfX1ZV{B-uwO52bf}ud8V0?Py6T0?wQW(Aq3;;^W zJ-7gYw*QXd4xT0-zXhxY`esfr>6DwKGOViQ%eDvoK1>sI0~Y#WM5~vmYilL6!G-93 zfD(-ZI-9RF(Q@(-pB?`NLE4R>=J~ztXSB&YkZ_e)!%Xk0*mA3r$~CK+8!BFE>}VF! z<0`1bU>5B`(F1P3y)+jq@b7n*N!`2$bOZNh^BI}YrZADS9RyZXEUl5=sFI=%iOe)8 z4~qPA`d}ca;S-3yo)y}s_2{0{fL5n;ks!<$-~IFN;dNtlE0k{Qtu;_uoFF^V##w5`2jH$1|K!Id$$&Z}tEH002ovPDHLkV1g1xoLK+> literal 682 zcmV;b0#*HqP)Lq9mBDx{jlnX zJ$vfQ_eea{S}$-tsFgk&2x0<613<1QO`%%gc^pXZ^0DTBrgk3hQTn>Kv^O8XF;_Cc zh-}|7nnL|g?}9i5BzJ>-PloXwNe}cz@NYBY!jc1}WdoQ7W@Pua4xovTqrfO|2Z#a& zf*9NL7nWjrfX2Jl5F!fA!DTkg1vjSFaEAvIj zu9eBHya!WH0x_A1%)U!#$5?o%Y|bx^7^t^iH2`$r6)?RW*Z}|kK@J`K6C&o|@lzol QF8}}l07*qoM6N<$f(p$gTmS$7 diff --git a/resources/error.png b/resources/error.png index 220fc17833b58b5bd68797c90c42e6d74d76118c..6dc97df2f42828a1c3cad7b712eeddb04b05833e 100644 GIT binary patch delta 1495 zcmV;|1t|L33hoP#DSrR}0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2i5@<7aI-*^N8mF00n$WL_t(Y$9St~`3kRwNq3c(`f z7|N!Uq!MGNDx9cX0!KK&ffL0we?X2LbHWuW6>w2h?BbGg0)JLeVmU^Ruwz*tmRD^?g>`UCU+`-d}M zeDUswYil2T3=7!Z=)E`va22HM`$rBRIr59XvuA%*xNxCg4h}*bL$e7{^vxN^;JT=C zS@e`jg`OZ7ZQI()Cp$aKRb#e7i1&7)-Uc=3``;cM9)JGz;dAGH*8b8<1u;Af{r%uL zP^&=@JONG;$Y!BjhC%_6PE+ja%9miIu(46nJ3FiQwO)@bU0VG%m;27qW5?bujgP;P zec^?SDVGt$!_d(I`Mlld#s)MR7Tot?Xb5_HA(z9rE+PzRD-^uGOlGKOZS7l?dVT($ z)~i4$U4NxsEsc)8nm&HqB}vfrI!U7e#(?X>zyLh+jD7cg7#V?538cg%3CZ?0x?TsR z=o}mKUM!bi?3MCIKpF5HZOnj^&kKS802u_tVTd_-64l#_a2!jA>w@P&p#VZ)qKJ5I z4srW7Vq?S7H$6>ueqO3L9s&A*hmJNTgVvS;A%74;-~<72qd{`&6so@;p_HYhr6?1I z#CPu^ZrwuF>xgDSPAZC0%*;R-La}I-Qz*dL7(D+xq|+98XU8V@ zJR5iZJXEW2S&58`|3J%;zDOgGK|rus||9i@J3SCrPMpZE=5g zmWfKGaYgGdD=-Pnss&hgjPcxNb1)ajzE>=YbUu$*TeJEv6zsLp-foj*vxrOv(P$u6 zSCOtuty*P%YRX)zRO;^~$(_&PZ+{x5fCs7u%_UfB8k1ypcl+8JjgC~IAW~01jqK^M z35vxhiG2U-Bt}YVGczn+yQcs8@ZsjAB)NS9K8|1l_!sb4w3?AAz~E`Pa8ao@zh5jq z+kNz?;~qMMNT;ndQz@e-BfOa6N&~fjd}t3jqC} zb|rw63*941eeb)T_eQ7V97`N0YowIM7(pC=?F%}J%tK>p6EL#^H;m={9`G1w?itR0 zKNNr~pd%;cpc3MUhAxC~jZiTH)B4BQ5kt^~6<{8C0Mz#T^1+5{y*dNrTTivGh&_O$ xMMWLhZGD^l75}fXCjj|>;!Mln^?u;J@oz*aVG4?Wx~%{J002ovPDHLkV1gkXz0Cjs delta 1346 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 literal 0 HcmV?d00001 diff --git a/resources/filter_ap.png b/resources/filter_ap.png new file mode 100644 index 0000000000000000000000000000000000000000..ddfcb184241cb1365190d5df3c6a93ce6b22fb69 GIT binary patch literal 322 zcmeAS@N?&q;$mQ6;PUiv2?Ek$KrFz)1|)^v_NxIYwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwOQAAuvKT$FM1yD$~#5JPCIX^cyHLrxhxhOTUBsE2$ zJhLQ2AtWPJ!QIn0;C+f}9#G+OPZ!4!i_>o>8}c<92(TQVmTJ#r>aUmi)fw)jZz%1cdOjmC@2wod)w9}(ibF>yN*oSvT+jI zgIBxOaa%rT+aYr?LTFOc>Q$#Avd`|?vc<64?0FCKjkMN#qO}|ERliXb|FCev->W-GDVC@vN8z5l&#*0QR|X$fopM$HN8GCcN?^Xd(!9R|jgdx1`7 N@O1TaS?83{1OP6idtCqk literal 0 HcmV?d00001 diff --git a/resources/filter_bp.png b/resources/filter_bp.png new file mode 100644 index 0000000000000000000000000000000000000000..36f4dddf2e1e90bd66b02d739cedc2cb70e9ac1b GIT binary patch literal 609 zcmV-n0-pVeP)R$tn4+h^9g8ZZFmVEfmlgmL82QrO9w6k zjD`Ci{Ut2{eH+umX1f0xW|d=qjb&m&@fBwrzi1tybUv z1TQ=Q-0(c_&2Tt;4lo*xM4G0rfY~)*>HB`Hl!~J$Dgr2_;w;PJEX(FV{z-xZdY;!&O2w5*#dRD9$8iY5&{aysp67Ld z7;rEB__%QeRDjU;{in5B?QI;#FZ=!e<7Ts2ux(oiAt)A$qE@TjEEbEdl(GwaTd&tH z5FXwmU?tk^_N_7I0}u-#1VFV~mAziC5r$zg3`3-p073|XF$S%*Su7SLNs><{lX;RP zr>u=JGvKutkH=5;`~63t0|)@eaR`Fo1UyhV8wOyr*_bp<(ORGPJ{x2Dg(!-IWm&=) zBgFaiL3fl+H7TX2*XzIa_xt^?b2}REg50M|ektX}tGHSP*L8nvx7#m(Ip%qdj4?B< vbuOmUsa!6XjoohNT9$P+SZkfU26pQG_vu?RHx^DCeL_k_>|&cmi0hR3WI(P)_GxdZTh|3OvXmdjC=6x7loVvn+GgS^>1*@4M-A+B+N$=Qf}Kp69vW!0kAWXXEj>on@Jb z2&yX9T3W5v*}bYNA|hp3ieF`$rm1T*8b22n`SY6{d%a7x*M@h=whnM@wx{4)ZBN0q z+5-3|*W8C;IJef`!c$=GoclO}7pgi_RcDO3np&2n8e{fR6fM31hiF`O=Z%2|00000 LNkvXXu0mjf-Il_( literal 0 HcmV?d00001 diff --git a/resources/filter_lp.png b/resources/filter_lp.png new file mode 100644 index 0000000000000000000000000000000000000000..f25e8580e732e4060c23de8705fa0051b22ceb82 GIT binary patch literal 486 zcmV@P)Dl?PM3 z;hS%G?}z_ZqNr)DB@9CVrqd~a0+N0E9avukJ}G6by${210I*uEp0g}_&4ULA7P{ym zV@%R&wFaF|rwT9{jc&%{@lzf=Xfzs$_x=S)g%G*mTCJvfz20rJ+0+2u`}TZ3f6TJ% z0hs&(4~Ij&+wD@|uE@AlDq*cfDFq;+DAI8pr_Q<5IX64C4(j!~kWvcoy(lt18jKJ` zQ6#$EZn9V``p&t@skQvNc+UCyLA6@daU7?{m~=m*WAH_LdSGpg=^w1&b>P3OuL2iY z%WI>XXMHs|&pOare{43JH^846@t>?KMY&u?2=TqkL8VfeEtkvwcDvP5N^z;V_a5*4 c8khlm0t7c?*yIYO8vpmvj6}9 literal 0 HcmV?d00001 diff --git a/resources/filter_notch.png b/resources/filter_notch.png new file mode 100644 index 0000000000000000000000000000000000000000..4a77543e511725b54d8a68aed32d42ecf5819a97 GIT binary patch literal 595 zcmV-Z0<8UsP)?$d29;5+ylIe^Q!iV7D3tulfvF-5F} zgX}tsU8Klw1{`AEd|-wI{x=bT2!H{=&u0Lr0TkzWP0!YblgY$*?;ikIA|e22+xB}^ zRbQNQ`)3+N0E`gA#&Ns~g242(-upd(Rk&WSdDnFoz-`~vIcK-q?fb*wu&=7>b6J*O zFW^y)TtJj}9;f*>I8J@sA3<1rtNMz$ylv)OD=mgOe^ z`!m?YaeTj6EIwvgc9W(l7-Q&b0if$TgaFXz`WQtKX|3VC=SnH-oU_ik0sw>%Rw-q( zEW6QKKLRhfh@uF=lM^KZ5kX2xd7c{~#OgdGBZOGp-QB&DQi6WzH)yZ$+Q=DWNYj)n zrEFQ2w*a7&vQkRU7`wVISHZpO`Fw5wJOIFKHZxMn^EJH=+`FDmr+m3wS^!9r1b=h; zA}|qwF-BVJKk{z^zXbA>f`9c_gq-sqr_<>h0Dtk`UoG$bzG<48cDr44JRVKkwmb-e hH-np|sq4BfegdZJgxfn;k6Hi#002ovPDHLkV1f(C{o?=t literal 0 HcmV?d00001 diff --git a/resources/freeze.png b/resources/freeze.png index 26b817416390cfc631266c55ae7e4ba88f65ee88..130c9e8096af84e45587627f1838a559b3ccb9e4 100644 GIT binary patch delta 3021 zcmV;;3o`V+5!e@yDSrR}0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2i5@<77H+slIp&KERqAjebK$h-y=UMlPh2UkGHq>e*3MBzJ{h_-#v5o#nS)`0OSCOFS42J zcU^dYDbiRf7JusAKKE8KpD!pmK_VitDjAEZ?UtsN(=UGgmC~WH6CsuS$T1;?^-lA;>cHmZNmF!BTTp|AX+SYo>Y5RwFlpeU`OYxv0V=MT|JH76l- z`K7;j?Yu@?7ZC-a@Xn9URexI{)aTB5IjRZ<#b@FP?tg?{uR3-0M)s@kf0)>3w6s4* zt8`s+^BFRkWYOBLBh~dC<{!VaYw|3Y8X7IKW}B_SRHyInt=CzVw4BZQHoe^E74cae zAOJv;h+%(_`&J@J^fOG%sneChb@g)d2N#2?shJegNd~+i!R5}vvy_FwL`$uWrLrU> zxGKNrcz-;lZ`IdlXItBB-v=-XAX^)Y^qC;MIlHNwUroL6(WHAEfVNO5_J_huk8`o0 z-`w1__*UOv@9x-HdFF(XqadPKcm#MQO<-t1Aq@6zr_|&fUp(UQC(?x0;VNmfdGxa^ zdkBE_%B17izyAB%W&re)d8tPL+tox9LBo_~CEE67hg|0iE**J|nR3ZFEXNbpLN zK2dz=y6nlP*5-P9>Z>h#bh>CyQGo+?c5dab3c!?AxLIjWpuz%au+8n3IbZwS|B$vy}00P4Y$C3(#sWG2t z>yjxJ59TT~MM|{6sDQnj=2B62dc$*1mCt4CYn<_@fOr1$T(y7b{@mUJXa4ud!Es|( zPjmmgGmTV&LA{njduxlasrBHV-EF@%8QN>1o7y$kR(ZT*oVyj_|`{%H@l#=IOamuR91jS zD?_=&qFNR3)YAiXjyp46l}hGU(0{bQ%yX$4ZA;WAgkxYi?l_f71+D9 z7#-#-_HL$BDa&Q+o6tDjj42dGPjhEeo6D7@LU`v94>+AU!tDkf-L0U@CgX

FXzK`_^NfujIGZ!kfvQp+ZecOO4~ zRF6X9df=BAzB9A2GJh`-3V+VX$ef!gdIK-NeB5r`)2N=Ai6Na~A&Njg$3m$j@X9M4 zVrS!8;?mFm<^Hns_Do=F`ED|@>R>CIfzzk@8jep`=zEjjbKbi4-cqrU3j)XhU?~8Y zo0$?xQYxfk8&SvfrO1+Vaw`!FI|V^-h@!AkDrC3fu~1N3ujji527d>$MY&=pT!bhB zO0^8nJl_VZAyGR2&Ogt`!dniW=k9YXyI3gXHhTMpa>YU{wm5&)=X@}^mdhp|0`LLI z0T2iPxO~&CDU`LZde`yoa+RkEA+pAl)^0??E7y!BWBB0V(;bYUKH_xajcYfO)oK(pcwA!9kB|Gj-E0Y)cKVy(X!>^Z0?1uLaC&1 zc&rJF3n}dGl(BEfh&nX|zduj@`VL_k960h~w~aX5(yWTd5`TpD)}3s3B$BQ(>E#$d zGI(bE*y-(Xz#GVb6%Zte zUOO#}4CPW?Eo-CMXI7jr`Nny?XL+||E|8aip)UtRpc)X-CJe52WF z9!+OB2)u~9w1Ncu4d7hMlTg{CXm(N4yV3WSCb0)^i8EG@9s z25%NJk{|^+O=s$L`pCpNSRs)Aa}$cB|NiLhwYbgH<%>XsJ^c_RP?fHDODA78#8kVGlc(@nFL+> zy(-7>ogJyPBsZJVx!8_t>D1ZRsTSJ{-fMx)y z?|lE=FRg6#z3yGF>h^YT1PIZ0zk-vU{s27^2r+at&Oi_VnkLZNqQ)L8n6}pF-GLr) zDH8Aa^30sjJv>-U2faVOdF{&kR{+Fna(^sW(*nuIOjrv6Kp8+9K*>-V7V`v{b5e*jQe!wcDcGLw|h? z69~vP$rMj~>4Zso>Cg3?$pj&vB^C9WA|KlPm21g)#p!X~@C1C`B|+fVYl({hs-I|q z&r`)B04z9X^9#<|X#l>EZ>asxUTVthY1a0C^uZ7OBZIH?$|$P^03jzBVR`OCz~|kJ z9-a7dlV@RS2xYl$Y#>p00OoDE48i)U&xp|(Fz_wH6DxPQptE+ z5cr7M(inK*?9pR?{70SjLfO6h(S;vQr&EdhnRLp*FqJI;I{;DuO8=il`$i&0lBnr< z3V;Sc4}gOJi~vFaT(vJ#JFWO>6Y_@^@afUj18ArbO0jn0;_qTepN#(lqhIKOH$QzW P00000NkvXXu0mjf7-s7Q delta 2221 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 delta 1613 zcmV-T2D15w4dV=uDS!U}{{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2h|J&7Z*2R;>iX800r?$L_t(Y$DNgbY*lv^z(4o*{ z_wU*LhY79qwSNIV)6t8ERaGXq(BHkHe1JnwomK! zj*jCKrP41Re{9=xA5Ki@{|ngst#8l%d~fg1ipAnr4jy<(R)Z>1NHR4UJl91z4pK@i zAWjk@9ig>m$+B*g>6gD3J+Nm6BCP8ujyT;(wY4y-^%;{1?X6`NN(M_ z_3ed z_4W1r)qj}8Tn22}`u%QO%3to^w>Kq(Kq&{UH9;5>gdt%N5(FV(7^0(yIEhITgE0on zvQSDPq-1<-%xYR*2>_9;uUBr$Sus33Oxp8s z-4wR65kdgqC`EH~Gp_5Rl)`mga*a8nNK>g)&{`8k5g3D%lF{>{xQ_bllAaz9!1hwE zBcVx$0W}H=2qCb;5Gf@>2;6jnG92Yi8fC&8oL;{Y!9o|TwNxe z27fBT7(+Vk2}=kp%R&f&kP;~bQV5i7qih@7wvkdIrNmYWr4-$BFY@DcW$JAIa=#l4 zUfL7>wLhCTjX6yW#np%=1nQkp9k+zML_H?0xfFKB_3m*hjgMeza%G%r7n6vI# zmd*>XgunnwDeCI#gVFQnr)y9um2|mWK7ZNW(?b}BB*tJ%iK7%LH$@nP_`Z+t`;>hj z->*>dE7V$LZom6(M12drH_t<0NRouEB}+LwH1w}x@jVJy0x$yu1Ake!e!Y(3m`Fzm zA#fZA*LA7Q)}oX{5Qa=$oFYjQ8gmMK`EwqbwxtlAqx0rvG|6#{G2FU*h3V_-dw(em z!)RtySc?}gZr-))w=cX`EUtRy_fO-w9+t3(qKGgISvB`v7S2_qY8pwWU9vSPIy*l_ zcG0@Mq?9N5L^WSW$h2_`;xwQsgOR~Q-Af10U{d(S;A<+t-36ub4FE?$KZEJoCu*KJy!SMJRDT zpC8X3%jf5}wA9~z$DIpq?CO$UIzyZoMk;j-p3rnQ4p5&VJ>fF@whop;@}a`Qvq{N94rmU+2`9IopE;GcSq&gP#Yly@mE z3Z@FC%DGd?zc+n{FCKV@ftmcttM)?#1VHe9v3RafC=5#5mSGq)4xK$~pE-RBRsAyy z+D}+0A5;bGDR4A621{bX3xDj~+t2WfL;EU#0jj__a4~=E%~Jl@nvXMOl6#?;X0I1;3>Se4weFg*SfFmOKGbE8t?6)YigXSq>6d}5Mw|2 z8jsy~3#?y^V*5 z{>ho*Q3@%6^GP6Ve~5+KzRrVfIU26Ec@paf_i@vXt^CloJ_7s)VaKZnSeS+%00000 LNkvXXu0mjf^dk<{ diff --git a/resources/keep_stop_position.png b/resources/keep_stop_position.png index 71d68aef838b03467159c44e7b518baa5a014e96..ef7589b8c409b54685debec0768568176d2b5eb2 100644 GIT binary patch delta 967 zcmV;&133J_2KEP#BM$~*OGiWi{{a60|De66laU}Ef7SsN6*Lk6YB;L^00V?cL_t(Y z$JLcfXk1ks#((E==jBW?O=1~MgSA9jd@YPt-KfywVBN87VRne83t^`*uN_FAF zoeM#w6hUbeL1Hc1f`z7|L>eV+npiVwQm2{8%w#&b_nhP6o|ZA4NK#iGINble9KP?I z@BHugf5HEK2tcqMO^pD65+Ps!yJ57gNCE;HC?XsSMB3a-Tf&<6xwf5P<=NChfLfb&>H+^UsA=m10jN`bH> zJ-FQH6)1@a0pDSdpsz=6 z%b^nS3bYKA0_f85EQesSFda%3=T_{}iEqo{{6xXDNOmMxb-!Znn-5Ob>$BE2mwH{a zl1UYA$v(b!xWAT$aRZfF$l}psjZ23QmFhnpoOI2~8DK_geebmdZU3n+U9&hkf6*+C z9szoRuHNB&4~z%y#oDRU%jGXVzgYhA<0*6T+!Qbi`~jQ?=7Jk|;u->L!8(u*oCO#2 zG=Q_-k96($=;ZjG)90IGBf`7v1rJ&R%0Lweg(h?^#&h0_wJ~5VxGT^2dk8E6ivTNA zV+$}g3T*Zcd&z?~{8|HOW5F1(e+JA|f(T3$FEi#J&Su+k!FV|qeBCKCoG}nZV52sI zFoG}w5ynJbqSX#+fy;ibIid)n5NsIN4xFx?HA_0>R!kjPtsqQD!^^PYM5~=K6;o#= zs-x;vEQVzP^r5&1#}JMl93|lRbp(z?Qb4d1$K5!xIHm=V^zGQ^>xS35ExMM!{7b&4 pJWh|#lt#N_sX6<0a}A2ycmy$IF1V|ObW0tNm#RBkD=OMFicl*U+*;Oug-9B>TUcRT$yP^Dc z-ADaZ+G+tiza84vluaguQOJY}bNNbJ_M`05*0f^Hx_?C{I!BfqyxBQ?bYQq}a_}~vC5I@iS(Iw{({uUEz9KE zEGhxW2!Ht0K#PugE&$sMBY|XU+|QODKfX3|`_~sW1>W4>@rPGWPvu*!kWnzvylC~N zjqTlqGz?mpE?HOn`^jMOuLox)e?ED(^5@w{fCclmfcO78Rr8thXL3S2%?~E;8zibAVYBBYXU(4 zIs_35g^daX;DX3@fG#|=({lx1b|om5aDk;*uR!6xom6ScwglxFX1rrg&;`i&JVaNf pr6dnum%`@w%B-?nLkanxw3lC0D_MSZxTpXC002ovPDHLkV1oT8fp7o- diff --git a/resources/loop_points_off.png b/resources/loop_points_off.png index 941989df2f8ac200140ecd13116e09553fe0c1f8..3bc544c855e4a06b59ac05626b9da106841de58d 100644 GIT binary patch delta 1016 zcmV}9m@#U8w1^R=3N0d7QK(=k*z=yeC?0z0rQMt09(wUF zke+%H&#jaeJQP|iO%=?#5=JLPSx--J+BdzuzBFRaNtPy&u-=^;1cbe^igh<2D+NCg=PWMlV;SX&MPgz(P&%|LhR12;q&=C6B83di;IhW@pzn0Pfur5RYf9^ ze~4UPUw>{0@)rOT022XVd3pJfs;b|NkB=|4S}o-Bc``OOCUeg1LZR^I+}xbl z-`{WU?d|3&1GQRB)OG!tZQEA>9C2l3g~sFY zuSP~jzV~{)gq^59{+9%Ae?rJ-jIm(=egK40DkPK1$o%|#a$sN}000LE2hH8x z-Ri{))a&(nLl6X45CnEt#+-9-&Y5LdCywL%Myu88-vBNF^aAhz5CGup?96*|axy$S zJNt#EX`_us!#X}b&g#1U2Y?cQI)K)#eD52++M{0bm{$4u;j7;*u$$OFMg?qt;?06iUs9Do7f3_$Y=A;;gCruQIp*myf^ mo1J3sBHD$w{M38AJ^lszcAfJT&Oq$|00001pjaxwuS^N(TRcsB`Nmn-Gl=PccVB4ha)B zmjr}8#mylE6Udm8mv~su5<(1nQ5c+qikB$q6|#o)Uk^B$Hh=157@g_v>KsH5iz_6D z9D*Md6!pF0_v%&E1Mc*{m+&$polb{*-xnyQ@H`KKAb?T|*LC5#u0KCNfAOyYsZ^?A zZf@>RP1ER2zVG|q+1c5qWm#WNPEP)4+xANV8ANeao^)Q&ZE8S;?}D?(S~rx{h+W zT$`Sr{&swP{Ndu_;^S;K`@!DcUT_sFUQLFFhtbi|@!iPC$eV^?;Pmv=UtV7RxLU1R zF9JfLka2W$^u_4tXo3(Tjg5^x?CtG^qA2gHs`@mO$$xxv6?1s^ZCaM3k$znmi22Qk$BqK**S4>ae3FdTn@=(63xxc z_mj!wFWGGN*)<@O$-LFo)iocDM#7zR4Qm~ZHc+;# zv#F^mb$?)B;1Of2qf{zkXJ-d>b#*8fi)d?WBjIrPot~bapO==F{tz;m%xm#@d`;6d zb$@>!K@flt0@rmBi^UL)M&bKDs?{od-}eAO6h%TQC7$P@P$QWmP%nC>D#@ z-Q7hz9tUF#K@hPB-Cm(c%BE& zIZCAxL{S9i9Qk}6hlhvIbseQr36#=nfa|(&90$k8$1x$1NEr3?^{>jZ48|A);qv8b znt!Gb3JQIyY1-?uETdd5V|8`)iRXDgd7f8UTU#qCit?ADC?JGf@8g_N890yN#$xdM600000NkvXXt^-0~f{eYoEC2ui diff --git a/resources/loop_points_on.png b/resources/loop_points_on.png index a1a0f7f13c0bf6882ed444f6ad2022a299ea3fb1..fda03729f96506eb5abb67f02b5f29c45c673a7e 100644 GIT binary patch delta 1044 zcmV+v1nc{a2g3-EBM$~*OGiWi{{a60|De66laU}Ef7SsN6)+&I(X1~300YrUL_t(Y z$L*9$Oq^91hM)6a=E5)o4ln}+3d4Qca!a7LN6@Iz`A%}a z^L{z+e*^dRznA#8;@MU-Mc|x^qeT-a(gM>$SQZ#5%)tc`gYzT-6Oe$lT?1`v;jsYP zJ|?M z%&Nf7{EyqJZa0+PJR@o{Zr)*8(H*!d_T#K>!<3eM{ru#BxAv*RzJaA%eZB9Up1AQ@ zKM(;@n?}^wY|ASs-f`}Uw!%iYQ&=C)ys~uV{EHzgG9D3vHL*TxvK$fn(+b@cPaaDZ zf96-#X@}Z(HfWW(6znd`o41ahT8<8%i%#}m1C{})0@S{I$>pmod#Pn_(eX*uLC>rv z_Scu##%+PMSm=jeUTCwa!6JRRYhbNsWQo4{xD{$?$}TJPguO9g=j>!7PM@EWV0BPkl->3MFivHMW1S+B+x zt)VevPzr9n-I-lmSHAX;Qx0czEtd1Gr=8!-2dFF1g)dki9GjY2jE)SBTB&4IbCp*& z1}pO3wLGfQy#jhJXwtwL{+W*C=W4NUAp>ibeFtRYR|iCcstGhbA`~+$64Nm3f2tvw z=Rr82+kmz_r{2cp2L{Uedzzl$n*W8z*kaU389^o0Ii#Np=6l=F(Z3fJF zG*?_W3oOOvmx_`tMJi^|JKN0loK~dQgO&kt8+;!Juixh`Jb3(Bpi~PFFZzF4brQ?8 zp*kT!0^8y^nm!8Z3YZgE%#n&De~~lmA0jrV^7YI<-YxP>z%=<(+&~RPQN^yQL!O8^HMJM;6AGSqz2s=%1_J zSW?e0g(BppAXdrG9!YzJ%`E(g#7k3%DHI7mmnn_zE<>wnB}2?%WnliUVFCXf)@ zfKO~-l?(8t9a_L7Fbf!Wft+<$nr@{-+KnUa)<`e;U!YyN$4A}Qz3VT$fqb*#5+N@D O0000?2#p7jBYz2SNLh0L01FcU01FcV0GgZ_00007bV*G`2h|J&6D=^@CMo~` z00S*aL_t(Y$L*AVXw-EW$6ufCPj`3hF7GyXna0kRtEO-?moZZ`*f5w(WRvU%7+Oft z4;axO1^R~s1~b?i<;Xc|NhZ2>GKpNpYD@{t$i`y3Gh5E>+JAQ2ZhF7I-~05(lAvuu z{ox<6_rLGw;q`vtc^+8Q|6XDtBUFRK$|7_HQZ^_8bOn+YBrNP_LL~n);Mo##n~pV4 z7c3rLl{r5AJyLbo&pZ3j?${MDvK}XA#@1>$=cQbN(*F&x|Ms(`hWY1suYE=O)zpF$7^P?Q%Al{aYD@kW-}$}Dqq*PDpUUCJQ&x-S zUrT0sBwc&RQD41l+Z!Ks47Gm!UF+^_q*=}ZICpfiZgrq(Z$;j|l0pZcbPCy5IuGny zGv0Rjp8!t|flWomfi<-+uR@rFB83DtJw7Kt@>j-c|6L!QJ`pPc5XJ4u;&Q*yyTT(pXQm*f zfKXxC^cCvkAMlVX3jBt&`^ktA3n5W8p=hd9NM}hz1lyN>%kau_gaEgI%3SE5up>Q# zLuJ~%rr2*9!gF>C(k5soY#uwuTlSZ@9n+8+1%EMu&|;WATSNbAb_>!!K})on(X#dE z1|T7B!MQlB%~1mdF7J!l%)oel&!m?bmw}oCiUG#;VRStVx(e1Xa21=IWF|n-LE11r zsM9>PljG|eQN~n+HVepFFq49`l_hoUMu9LMs0pZUmtS$3D29SiW&`fFPv+Ha%)WNF zcW`o}a9bo}(9uI@Lei14xcT0X%l`=bD&mSO2SxpRA7yqnKsJ#f9l02}?U@I>s6DUn zWUP^26AH)^PqXLW{v!2uW-Ng`dV$Mi_|Pw~!cz={`uJt>g)i#P>Q88rGl4m`mZ<;$ N002ovPDHLkV1j&Fv>gBd diff --git a/resources/master_pitch.png b/resources/master_pitch.png index 9aa039a108ddd9376d01ae012e8cdfa2fbcb3a86..6143a84c93c48c2306131e5f5db91f76dc2e59a3 100644 GIT binary patch delta 1175 zcmV;I1ZexW2c!uyiBL{Q3K|Lk000U}NJLTq000;O000;W1^@s6;CDUv00006VoOIv z00000008+zyMK`&9)H#W6&Eij{A=TU000CsNkliFOcakAtrsBk{Rr&0fj>t{G(box>2x{-K|mBmD5Wq> z6W5(U2#qA(0YcJf2e)YL0|!uxwgvsKfKxyP(D!Cw&CSg{URYR|a9x)$42k2IIF5+I zkX+89T$(_s7}qPX^`mxZ<+DuQ1nvR>kQxAw9zEjRxqovQhC#7dq*|>~tyY+v^a-9l z<-_wIP%67T-+YE!Ns%&U`*v;*@Ky>!f&Du$2mF&2eV3ru>xo;pZedv#^?IFVvq`hr zWOlaC>gp=5Z@qyT8Yq?W(gV0R`^)Ir6*%{SUx8;pG?1+UaPs6yoNpa8O+%sRsxC_` zaZlYt2!Aki1En}Fc7Xf9gN!5{5@?#1=(>)kjlW-|(!=^_U%O<$2Q%pR`&?hUPClO} zNsOCe5Cr541yE|J zqV5QonQSIqYuaF&1{veVxI*0Z7Y zB7=Ip&b4dTa2$s)42hzMIEe}See!mWlINk)1IkIk`2+YK_$_O)wX7e~!6pOX;lqba zPfw%kI^}YidcBVC`#)>hZh3=7cFOcR8LZWy3Yz*Aru_;(!mkf7OY#y4-?#Bm(rI35~KlEj#% zfn^v3n@^DOHk#UDv-21PDT;pPX8m#CLxPo+l`l@8KK;HB!cv?P8VIr%7&JnG2;@IP#W!6;ul9~1xp002ovPDHLkV1k&+BH;i4 literal 951 zcmV;o14#UdP)E*Kun%o;JMZcD1dq*+{?0zWjr@Gce1^` zUG+SVIF3ovlr&99;+Rs&q8dz~REp=@yxh`m|FCPB8vsW~N35)@U>F9j>r$`Rsn=^X zn<0bKKl$jxI|Nma7bmB9wHzr^&L5Y?fB@p|xD_Wth^l2-L{UV$-KO1c)9dxv-{0rA zFMq`}3Y5wb0(N>o7l6fGVD0ai0WdQ&gZ+bzrfDb?XX=cnJY`4iAOsk?fl_bhu>qiI zTBhqdnpRvtrSc-Z{~0_S4taF&h)ShGmStBkMV?Dc)8M^#7tl3@k}-ZQ0Mer8?}J#o zQDfj4&;;;(pKiBHr_-U=>v4R1%)DTSY zz2`WTVhYz{XrGg3J9&S3-t(Sw1cxO=PtWMht5>cCygsCo0)G&;l+w1PY}g3QEJPC< z6O+BbHc$j4M@XalTyNjlbETA0QrSu>TiMD|ma6XCR+dsqsoVGO<$ycDdBAnJn3I-c z?;nPqO#jHNQKCea9C`8-4y-aJWvi$I-9XT(o)bU<#l+&`;G^NE(xQTiNr9rHEm0MK z573?4;jA+2sej4g(XpwScod0^iAl*}S(v(s;0k562>e(F}&=^&P6@7EFnTta8Fve`62Gk^s0rPbuXgV5lO3wKX;C`+N# z-x<|(L9CcNR*UMgSj*0tUrHnPPmL4)4uXca!ETpm34b7gJh9!!@u}UES99ZY8w%Dm zS^@x6NtRa9vzZr}Zzci1fme6ob=9o9S_de=WVH}lnn)&GmWI!$75B9XP&uz5H0Gqr_?#!o$mOpP1@Oj$WqI!xF zbCr?Vw|^`1m0T6S$3W9m+W@t(HC3vxknLXxZ^%xc2VLKXw*^p35w^#}<4fVfP6@-K zt9AnFmv1*0%?f;)T2zKlr`a#2b392l*h&O5mz5#U?tUnK1eSm#VE^x9cT|e387cRz zsqKrv&cVX1Ca6K;{N@Y+z7qj{0hxpC60{}*=q3U>ffSH#H$VXHJy-YKFj0R1m$XLe T=iIQw00000NkvXXu0mjf1dCb} literal 667 zcmV;M0%ZM(P)F5HM+RTBGJjo$<;ys0sjOSb%6Lg4mz2tfjAICEDlBzqoyW6OgbcVw7|h%_nEq)3q@N%d_MNg^V;crI5ezXl%5?Krr^W%D4{P7ki2UAZpHyy_|S_?DXNwhmOP{ zrE0tdfH6QYj-}0|FyclE4s4W5cLov577!k{UL(+jf}dj zat01WBZym03#MQpd)!1QK*BWhbPIPGJ2JF!WX z^Xu1V)61&IwITR^hqn`(Qt4DS=@qK5Z2q4Ta|PJIdcHXL{&hxMwjsiQLVqh4)00zk zPkVdg=Q|fO`nQ+^p63sGo`14)ai_)b1;D+aqu;ASXo}Zf>39GD002ovPDHLkV1k0} BC+h$J diff --git a/resources/mute_off.png b/resources/mute_off.png index 58d9e9a048986739af87578b50fc968fb8d79459..9f4bd9c8391f66afe80729b28720c808296fdcb8 100644 GIT binary patch delta 1339 zcmV-B1;qOP2igjd777>$1^@s6;CDUvksuy_)&Uh2COD%dfvx}m1o}xtK~zY`)s;(Z z8&w#Ezj=6UC!VoAo;u^1iIX-`UJ8gRNP&tLR0$CfrLGDgg{V1d88mH6)Lp2l&Ee3r7fPC^LZJ|eM1oi>hVT2#&CPM@)G3w|B8npa1o_gYTrLxh zM%l4r2Zcg`LZLuDpGOo$;_*1!w{J&L6!z}ji>7H9hOuJwcMvj}j6XX&OFErq)22;K zOiWNH6p$ndK@b4&JP&}u!9g}|+{o^K-MeWt8d#P^C=^;{;&~pvfALZTK|pM^S_FeZ zwrttL#KZ)RMuSu;g|6$w<8k8gIEG=+)zw9@SmfZrgY4S1i&Ck?{QNx4W^+Zf=oNWA z^(s&I@1atu&}=r5dU|>?J9qA6dU~4WpfB$~s@i>a2kQK5_4jktC>(_Fwut3M*2%%62Sy2?i;V`c2Vi*R3ATTg6 zz{to5fk1#pqk(Cf>9gj&h+#&_varVAsF1Z=58WF2cG9) z7zTkr04X5x^5mObxbhZckk99TDVNI_hJmi@ zM59rP#Ui?(apkoNPki?rCx4itR;ytc234WPquD)V)em^`uAAA=mEz%v6MXS>k?tQ8 zSeAulS!kMuBuR*_>ypi8X*Qb}hJoWajE;_Cm)2pDU2&uI730%SY)Q zT_AJgO>{*fJpSo%4m?+Xp!>9nWm(v^O*9%smSsdyL>eC-&m28^6jfERZ5zw7NTpH? zIQ{JY_zLbHAEy?s@X(vD@b&T`?zw%0Th@(I_ZE2Z@G;(bDo<)k#_qD{?(Rm{^;H8X zZQi^&Q>|8+nwny9aS=(9P*s(*>2TuvJm zo+m!p#x_!<(`gck1i@f%)!@mpEYsWD%gK``*|%>WXU?2K*L6(Oq_ZyZ;mV=xr5a!H|Njs?u!cqzpT)u={SyqVHkfZz7lq_EYs1^!QkK^M~)o9 zwrxg6Mp(aoJy%>P^WImlVs3T$ab}VCUux6-`~t~N6~}Q{vt|n6a2QFF{yOXceBYnmCN+lwZ2%aEPTckVSr)3Qt_sG#jB7yr zTGVPa=I7_B#Uxa<2h%kFvGPAP_-!YmD6V9Vs;X$3Myu80QaE1XT=tLld;IpWD2fCE x0es&_5QLQ`bvckPhxBg*|4=CZG5-GszW@cS+3fVPiy{C3002ovPDHLkV1lu~llA}r delta 988 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 lfdDW8dPk8_U002ovPDHLkV1hh!ilG1i literal 4310 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 Ef(%PW1^@s6 diff --git a/resources/note_none.png b/resources/note_none.png index f57882b7d5b7b54339f5d89a9da0c69ae487d8bd..bca2ee331f1f2e096d27b74dfd2ae18782a0fae2 100644 GIT binary patch literal 1846 zcmV-62g&$}P)Ge)5-W-cqGX%)-Y`%Bw?oij*VE0jXxb1WI_K_|s zg#zFK0U)XffI$4ObEoBngp-=NW9hQ_+rPJAPTjoeHC8O7$!x(B05!H^B%(x^T&?TR_Eak89?xV>0LNO^kRn-Qa(BWP z(Xg(yCXM*FPaJr%P#nwsG@JSB$x3AcxDQOI2W6SMaQW|F_|d9X!!(>FGir&NlDqdt zF$xJnaPG`0O0G-3P@pyzXMDmX5z)!_46*Xf-O8QbEVtEd@~;e>zaCTyoxlK)*NpU9 z8Eu@k{poKlU!`=-ZfS~q)o4Sfzq^Cnc!F3wf$PD&`{N`hO(t6?bNT#f?)N(^`OR+Z zv`z1`KbK4UE2+WZ?sb_<@BSP706??q7BsdjYI(jsW;;zuTPWemaa8%OCFaloaNH_GdSTelc!B5WeSAnKKy{AmpfRo|9z%EwVI<_cQRJrKx5n@ zP=<8s(}vTqbOVqEESXHF*GD3DXiCz=P=aLC#IY?>lhP#Oag>1Qr6bg|A4dsr+dGKt z`5Ck4rOEGpmGNR3+qUq0!R!Wyc)V7NG|g=W8i0@%OC@G{#XRZQBy2;XDaqm`tzVms z;@p))557mrWPkZQXzkBAOi$s z@+EX#;azLPd+k;9ty?ko?L&)3P==0*#88=GlmsaP4u1X_BV##)fa^mpZZ2E7*L`uY zN)-j=tD4-@=6PH47|x8kka8?V3l-GMFLQg^RQz4L2*>09t%)7N?Yhd4Cx}F9XlZF7 zkUF>Sl{kE3%eh^Po|Lbu72@xuRDJ0CU6_b$-v7OJ5K!l zPnS=ey`f(|?dHD!1A=MODD8QjNMaJHR0@Eut}X@!1^`e^Ge{CpDESmiK1Z%)=pG#} zw|#j!({u8JQxH4|P*gxr$=@j~?d{{oXAf*FHBI5*PhOMBh9nWkL`gw_U{bn~SfUP1 zQv}k$Rxn)DIojpYac{JI?ZWl^!9VXiUKs5?0i3I{=~w&UOf))ei#NWny;SOXYwa_n z7BpM!0~0cvuSh8bhOSUb;iD*faA&kcTgK+XP{AK9X3IwpoydIh&feqMJ6DeZXMheM z1Nh=lO^v-ksdvtM-p$R~>uhwHzy<-5z8A8Rm8Go%j>XNgB6N(jM3zUas6 zBV=+D-p#I&$|oOv)OY3Zd#B2|kqf|i;5u**COtxBsxFVqTM>2@l?EMd+qQ|PjqG4jAM77Yr;PM) zUhh5S&-b2;+WFiXU={FMqGeg%{|WH;5)!tUo3XR zMKKU)Tv`gOa8!(~9x-)>Jyl2Ryx!#eBs_R=|Mkjx8w0Uu$%he*(k&mqX> zZ3eRz@nnY7aGFeNn4r^UY>AuM^~Ja}g=2ks`ibUv@5=3i{_L?`>0H~P7;s&pW!b5Z zG0+JV0~ug}FBaQ$K?VYiOD{z#tAYyivR}WpHuB9mVYgEiu8#gRt9SNdC@$)1${1Us zGBN-m7s!Hu>4;^>=q6*!eds16as`NIVRu`GlWjc&G=m$OD)D4*^ zO6^<|#59&9T9$20MIsY`_kakX10#L0SlDV1Cj1)rlZUe8+$q;w3^D%htGWOS2U-lT41kp4uDlAsd+!-Au6*w<@u z=+H@uy|8Fn1yTy@;otQidv#09o!b6((Icl;zI@Yg>t6v5U>I2Hi^U%KkVf@S5Pzc< zj65^ps%!K2-&pRf45`IikHp0GP7}IEGP+kFieZS z!5oGKqbmZKHl%YVx&`}=4>GYT$Vk6UO-SO(hZz=b9{b%f7B`m3f0!2;8}_OP4|he1 z=C_{s8w+d+ZNTS!vDnrNI&q+J=~Tt#SwDI4O~#KtUv9cI5q)o84@t|(wT)#|hu}zO z5>*kHmd%(lKd1fjOv~kR3aPw4`l>~PcP%Q;0?}1l+Q1WH$;>iF z1fX*uOHG-dBb_NmmH093f=PS`iBy`q?)WDL`nqX9ag=py*YeC$Po6c#=XMbCJK23= zklGO;`V%^hUQYsz1rV=}`IV$jh(J ze&ec2>2)Y&Yxi~%EiGliq#!=cCaqiK44b?KRZ)$VtKKAUL2v&6>({R*Z-M6WaQT&2 zleb{Z_=$|2a0!aTN#5ct=e`wGmyM2$E76Mgog5Ih=4JNy04@avQ+eX4Jkg*V!vvpG zW#5kXF-*uC78}<$pMJLK>FK4bvzwDAPVv(6XPG^BK8DE|*uQT-Ke_*V6bC(6mf*>U zevi@9N9C>4NDq8F=(JY-{bqwr%a^ z=|yI+w%#XH_4|=o4+PE^g>EaWpOT+5At;g=vvNmkCrhrLM2Q#L`-Z8jDmdXEyL@~g z#;%sFY*_a$)njVe)v}eAZST`Cy@{sTSDqOcEh#-`ZhCl_czl32UfxFcsx`dO|7);q zP*tqrQjXvA6KZ_WFr|jwN7|^XDXAG>?mm#Ko$O2=-hCJF-7`@r(6}_9XxgcHw|qt1 zJUx&(*^?^OR6%vrO--o}!?G#*FxdZpYW;n^tY5Q@w^wxW^8W85^&EClnB>EclfLXq za=M8Wf|e5rPIeAaSsEl~ik?T;#{AvQtA(v+NB3>Gv-?96`b^n`x`Am`?$}VqE^m7}#@GM|cw$Aqzgh*zOBk&)_D&MH39*2B!YQWOD+VIAAH33wfp7P$*MAK=g&82LP!rkz7y zxcOy9EWZbL&!JD`;WxKF!jcoK8GU>^b|A>m>uV9fH48tBrfHN#L%5s{dJ+~Laf7@C zlgAXJnpqqg^)8R6QgylJmR_{=mS5_kh zST;QW>{Aq1)?jHqbPIw$jZ98QQ($C?k7~bxDn-!cko$ZUqq>EZ^A%_LoWH5Nys74r z(b4SCuwGgdbx=1lh$00}O+l3c0l3{B8m7&ps(Lgomy5dk$#}iKbEKP(R^Z#U4sD>9 z{HT$b{?apjJMMj)D^~v!7Y5eYTGIda1p0(Y;pa?kHF@#H#=Sc8EfH%PK(Q{3_-=`!5J7!Q*B4fuE9@+=yX=l%OdvrJ;e#uDFuo;s}~jzzJb-swaV_KuM7s zMc8O6E~m%s6jD~IKt(9v^M6Kqhaw zUDC$qRIqKE!|j7-q}t!x!%M$(T$~pCA>vE^k*Bn|99Z^m1m0SKz{Z+PFMjzetoZGVD3S|8+wp$xdDo`?jbAhU+4}%UDjxFpJ%rNO zh*}aoVXlS&Msd`!i$zF{^tA7lT%4mvu97>sAh4CnagwwI_+ z9K=R2;0~jH;bxSE#)~pRr>c_8q|tK*hdMqgQdERJU|1*;R0%>zRNJyUZOhgy>{vXh zhl+y^ii2U2nLK`XA#)ubw8`gnzWC*@AWv_7ul{Bit5)tMmCQ0cq!SFfm{3>Byt(7J z>Fxz!8dyT2yS%tZmf*gB*+mf_kH`7LnzxuRVFE#~#>{bHGC32sQ=w-_N4EqXDf=|V zj#{SKr2-vBK3`upi)HGR3Nk}ECO1?taZ))h zcOfsdK3gE(cDWG#Ag;y++>2(A%O$`SxF7??;UaFiIkO;MG_ZS zst}?>1v>RiW{l$WrwXCcKa{1a#EZ)zQRF8tG_k&fiS;FC;mkX~1KYQO5QySp)NkK` zy!lI5dp6-Xun}|G!aqBrOl$!dNq0nvuC~Rp$C4*GfzFqp@V0K z)7Jf=k$FDJ9f12=r4b97OuA3hZN8i&vA0lKvfu$ zlKQ^3o-!fiJ2KI-EU)MEx8l76C;cwr!61&?Zo~7=J1E7`^GjEeh`MRWedpH#w#Di<-(bXuN(KjqkOF$*83vL$ zq<|gAl0?cQC{pY*vU-P+GuF1Q_)_w;n~GICx9r!VAuU)prIuHlKLB8Ib%=N>&)Yk? z=#FRj#y7r!*Xw2O+__|Lzn%P#e_S}1E?I)(jyo>wkyD!B$YIExzW_ad{(Lf-3_bA_ zZ|~?rNo>M)Rkn*)NXJR3EW9#}ok6!=zE5gBmXXl2t#HDNZ z^x$^=9OnI?*&T;Ld{!1zmH-zI3Be|DFY zG&MER)YJsPc-v;zu|bY@r5MU6q!f*?v=5pVlTIFL6GDiUXHH~8+y7r8o6Z05_it_) zs4jK6XU=P|pMSfRX|-Wyj0>~(#9)Eg{(drF_yW1xZwEk`JC_O%J;a@N-bp+jzqq(K zbru|MyFs6vfHDT87>Z5FA1Vxd#Q-?dd@;URT2ma&p z-Dj0m1pI8xo7*%^nnj_IXY*hlo`3gP!IWx3q_PJ36Hj8USyPbM#EH0Hd4+`w7czeQ zc%sqhIfU4@O@Dv?xmp-E74^_oLZJ|Wz}cIdZdj;_WK5Y4fR$TfI7$LYX>SwQqYmsi z9uh)4curj?zV)80X_(*p?elBRG3CzDO>-v4URb@C_YU+Sg&_Hh$H@PrVDqw}0r$$4 z031Ackox-i^9uXkd+(*Wxf#oMIcz?@@lx^Dg?tSTViSt+Hgm__N^Zw%}j&`JKM|j$=UVK^p;TLz(_R4Df4=%$7 z>|hAzgAXF2Q4Gt*;|p@lHP@V1`kOaz=7SGDAf5i$U7n({Usvhw z-$9Yj!T$CvD>rvgH@VVsXdD_ENExmB+T%is$3C&NII#J<7J?go{J?*@Y&}yndZhpT zr=Pinz^z}wwr!NUI-LJ}C#|L93({{-Q(RJpl;`FgLI`Hem_bEF1p@;E=k(Wq`R|w& zEh3qBU|2SXJBOK6RWPU4E}iFp-@(L&N>o+8XXed{HLLapg^<_nTD~}c!SZ_X<^MW0 z5(=zu9(vX7*|S5ng~SqqlRtWbDPO(5pz5s2iQX*rqr9K!uWfDZ3wUp&GH}XPBL*?1rAMl&&Hne!n51d#875_%QFi%T(GZT^p8VbFh7wx)ENEc4x5*H<0JvGej#XtFAi-pV2Lb z(gwYwXHb&pqP26FoME$KYm!$sw=-k*NGssenl+Uvt5)o@lS%!y^AZ1v8c0PVw*f!3 zL7eauTdAKv)|;PoMOWuQuKKl=+lq=jE^fZ2me~`-AEmr;ooGNKma+)AB{qdBb>1wT z@S=W|4|;TJ%N%sZbt;MqrAo`tdH=Y@JKOqD1CqK4(S)Li!^4?;`LCYaSu`}5{l8nE zxcb?PzGh8DB0m7Wce)ait)24ySuUr#>fY~PpPg7&?&?We?LECiO|P%oMO}3X^Jk7= z=C~kE^&@2(r#1i~L*MKcJfQ=K|u3NXMy?gaL$AX5zGT`yekIpgvteg5&BytPz55P)aEO!4V zO{iM%xLZi^Ex*ro*Nuzn`>&ll)~qV?R~xoy&6xB94k_?T2ueY;um*jm&5&V})@^c@ zP1vyQy1s$zsVzIZ?X~Zpt*Hvj(4ZvU2@J<)W=TqA^7C8T_9 z%fHY2-}%_%e69BSyN89YV@ZDMW{ma+45p h&Gx6~|HYr%{1<_|2)Ue`*rxyh002ovPDHLkV1itnfTREb diff --git a/resources/note_quarter.png b/resources/note_quarter.png index 43ede0cc315d6d8e73d6a85856a638be900b1400..9e10c23134564a00086e079b2fa46944e645814c 100644 GIT binary patch literal 851 zcmV-Z1FZasP)-1n5%AbRj!bjlBhV{Pv_(Vrme$iXYRVb|EFkX$z*!~9^l-hmE_a}* zAq2Dl6;5L{M*t}+pFid~=l1BG@@p<`EnCyT3Q*Xe4j?xh{}$8RbiV8P2v7@@If-`) zP$({BUS)h66s?Us&;WS%ZwH`+o_m{|OlAZ{H<-rv*!Z{{De-hb&NPGWQ}|lM()KLpxAq@1bO@4v<+-7q>X6 zzr4E38!69Uz$1e!6*cuus^;F7&XI|QCSY>w9!g%!%a?C#KhHj2UwEK>wSVTex}LnL z0#l8OHvv_9C!|cX>=tms7M_E%3_>aO8>Gi<;(m3iHyKgAi5_)yzD>EO0*YzB;z6bA z?mP1m=(hDB9zTw`w;j>e(Fh?FKv!2peysX%DbbwqJ^MTYvIqqVl=-U^GsoBTLIqG` zvnhS{Y}bZk7R6#u=?HWz%LxIqRq&-6W-DRN4>NvhM!cA-?u1>WR%+2Z2~Bu1W%Gr^ zN=muJ>AWRi6_{J6Wztuuj(Nx8gCnnjF<=JBY)25W%TA17Fcb{8hI))<<4R(2(ezn9 zYv}pV`!#EA3Wx)vz#Nb*m1H*|nn0al7~yO-+XT4y)ys_imP%ERLvaZ^sn33zoiJtp dg;L1@egetL{Rd<^EOP(=002ovPDHLkV1l3tb#wp# literal 4154 zcmV-A5XJ9_P)#XRGv8t+ZN%IDjp$IJA|bpo}WdggFEVfe;`A$<3Y5u-_jy0}+rw``%jawf0)~ z-21!de7|S^zQ19gBczmkm50Jte0=2zXgwc<5Pjb!CPHCB?6Z_0NX1rK35H?+ZV&=g z1vC{*D>h5VgRRhObBQB0HG`z2)ZXKcj#gS*Pn~1;MVHskdp6wxngGiJ0hpqVq9B~K z;gAQ6V4v-{E1<3kEHsJ&iJY?IIOI8w5wr#ZJUu;|(WA>qPEJSD`rw$RNqhTgYHN3J z`gGI9SD@eU`@uFq5wR6OkvJ@z4+V&v&VjmPU`GHIoH~pd23;}{&8TO1R}!w|F5b7t zV1|!;8TctvW-)khK8hkRO%vPh^LlF+}y$MZeGgRr-s9b1Q?WZmc0|gVuRVH zGdyJ&dWj>G5eX*g8Rwi@RW(XVN->ORFIdAch(-zw!ypogU>HU(sc1BUra3N=Kt~q{ z8$|b=(KL2`wvTpvRNwL}H$GPm6*>fLkOC|~(>~n!**@-^J%F=x&kX3e^h;^HD~+r~7l%M7Fb5LiZR6#$%I z)P;Hf%tll+o+^8oMK8|7JIjDb5Rl-c)~E{~^9t@H!Qr7iP+HZ`rfdW^-E=3as>m34 zo5aLqCQqJDX=xdj1&xhO*tWv;*I&=Vg$qbYNyaeFb+O*)+4DocFxoT54uwG;FaaB| zf?W5^RV*(54gv)aZg#PUU;lX}J71`WW;ZC&H?MoH4=`%faDMfx7pSiO3ZYQf zIYiXQAAcNxB}&HlD}%!4MoPVMKrb00uaOn&_1f2F2o8{u#e%Q6Xt z0yH)rq^72pl9F*$R!-uRPj+(hWFtLz2bPIDLox88TgVPU^X_(hRu}I*wS^xnewrm) zpJPLKGnEkyMpR$MV)~+rGIYYunYknsaVQ=eirN=DvA1^J>z2 z)GxK=rmgGy7ToQLMe$Hiq7#*Jp^(EQ6N<~l;LWY&`p zP-yh}NoXpc=9Lgc?4dL!`79d}r~dxpb{kFfTs zEu_!#qE>jpqm!RsjKkr?;czl-+8m}#`5IYSLlHs{3PrFii?p=N%OKDe0^5oakbqO- z+a1L6ny5ui@aTQEktjF>B8gTRup)*MJ*pNt6Y=O}U(5Iwl^NyyB>Wg0IYVGw*m^CfZW)NzNDHiHJGGGW3@?!NmWoK82Ysv@OCO8YVh1dJFkRf59?O=6$4 z@U;c-jB!9>9|2u=f-bQ?k6%Hmpz*|s6wesPQzYsYROrkf_j4YZSk02qzfn5+M{aGScbj=;X+egO}ORbVfk2Vp9rGB!QX; z6OYT~!R_*b8bElo{|LTiStv*mubLEjhdle_j~KsnC}jFLJ(~DQ+qQdaB$vz06;}*n`}S>|K7ITWqfn{_L!6MKgBp&}l>%&uQEwAb!-ygk z`JsYo8mOv9XJ-dEB{F2Ia<7aNg0M(eRH3^E<&eb_H~fGSJ6otaVd`#11_3Bq+<;s9di3wiF)j^46U}X3Ig@lL>wm^Nt zK<-tsAL(R5#$?8nR-measZ%SM`__UK8L}Ib9(IK>gy#FLA+A|CB4NU~F^qMM;22Fj zzv@kn|GEll+n7CNF7CK^($lkui%Y`k)XB=qVDR89o`3$Ay#4lTBDN@U04`MNg*-i0 z{}{4AaVbEvz_PIRfn6BJb7cm31;u1%WpMZ1w=sQsIr4<7O=v;@s?<$nz*2TB-#h4; zZ>{9v>R(dV-oSnHZl+*yHjEs^pZ@w9UayCelF{Vn52LQGM$vT#%a%RO+i$ad&8U zcb}}7)$LoFHU|0qnr6P3(0=#3r^(71LO2}4@9z?iKKfmnnhp=Fsqd+ExY`Agv%p7f zz<@X#TnY#U!aBkfa8M#6DspHDkz^9*@o=i8jYz}*T_W3Q2 zIH4<6$1_n1TVCf z)6!@0`tjwl9#^$VzBz+$RsA!Q;;#Wy(qgtS)Jnxn@bPi(78vJ(unM-u?h5-k+1gA_ zPA&#!x7&s5B@S0&a-6IEWam2BWzMA4boE?w!9Fd@rDi+-BQWjCIs z6B*M}h63?@%1rJ!IWp-_PK_7*~+z`zJdWK6b-3dK6o zFsTc)Ahak_vAbJJ2iWdDfiI23bW*HSQaSqkI(b_A)Tp=HBWgHV6sd0cp;Bhs^0TzG zWP(9IqsEm|a78|6B{X#1Ng&X5QSe`kLIRMBoN48rdw$3(uly(L)@`P$ zs^ZdINJ_?dobKJDQ%lSbk8OtJbTBRu$$lT(vmCHaENg?ckL!sgy*YVl#qWIZ!R9v) zAKu5NP48ga7D5Od4#(wh?%K9}%;8ewmM&P_F?0Eigpw>s@Wi^Zb1Kv?*GbFwtaxk^ zzzK@%LbKPiN3p0t3Z(`UhZX0{*|u@pn_IU01;dEoaK!Y~*m&sj38<>lcB-{i4;;-G zFW&i_oWJ5;C>RV$soiyu?DM4a>Etn0AtG-FV?J^AXk1DHLJ@>@pD@L74oX`_RJA+l z&3fyNRU#`lO$wp(YU(e4S$+8gVhV{P`oYJaWG!59OY_?g{DB8oJj9`+wU87Cu9!PK z7F@zI*OUEq@=LQ2(|n0yead;n92abgX0uI)W(BT{uzBaU#JieXdkaX*GWsQ`f%^Y> zYavxtnqOP%Na&LjI`FEfatgWBq__9j-j$I^Xy%2$_c%qY{~G`SO>=Z_Wq{M^puWC| zci-K@O*c(&MWq>b#yN3#bWXLl5;&UAi+4W9{9imUm*L)P2AuQ+u|zjG%+^C&XIR!n z>$Qs#=6kJGJ= zPA$piSP;5A-C&((fp(rdgKjt^P#P`DhfL_yUHaesl(gRonwlDT=be@Po`yIa8cj_t ztXZ=GUDt?@_wdLg_eh6JJ-l?m;tcmu8;)Aw_dtj1!qe}CMhTl5sY<a zrU5O@s7E`QlRBI4R6baC-3k+TTn^wbHZ)~`6)(MZII zlH^DtFFuc}a<2K~)dkls%FfO?lAD+QcfFi(K?47P5f7wckmmFG^-w6>CQvL*(_4k6 zv=2)4{GYs4BL2Z|tB7dSRHc-*)9JAJe;DGc{<_Wo0&#-2n?Ns^xc~qF07*qoM6N<$ Ef*Mr+6aWAK diff --git a/resources/note_sixteenth.png b/resources/note_sixteenth.png index 6337e074f28e679f55f40ab696a6e3a8bcb769af..693679bbf55b7adbf6b28d8b47d8a41348085c97 100644 GIT binary patch literal 893 zcmV-@1A_dCP)_!(%O)DvcqD(4_E`(W_FFh6XAO+pA=t{5A zLr@PsM@&)?Jp@T$WD;6hX^`lM)r>iVS~}ten6Sq!JmasHMrjb+$t=O0dK5?p;->1&ST#=1%>vodyi*=ZtyFd&7FK371IvNL znP{1nP3i4>URDSmyFa}qTh7Z_A6)&fb>RT9gFIakYlmBJ3Uj#6GSot;a41%g?- z1!M#9W4xQB58!sZa1T5ldL%gyi-b&9J!_Ib*^0AtP1E)OY2&pjT3I^K7xISntyPDm zs3@O{?MGIbbeqfWv?^WKJwWnwy|A#uHQ;zU?+2RpoYL9h{c=!nJAFVkkPBF*ssKP# zqB%^w2pN_>?)O})SyKDjbk5;YN|^zPE-EGiutl7@#BP?c9=g@82W3-B26 z5j$>+u2k2UqYl9K!Mn06#PVeYd4LKS0J;D_Ff=ZKKNQd=7!r+Q$3ga4JE=_Q!LAjP zXriQI%XT0GNC3jdC;u$*(4ndk6{k+!QX_}&P3SoB{fyN9^vcEH1)<+0_#BeDe}Mp} zffbR~c)fMn_(OyiH9cmz`%kaIfCqHNPlryB@OAyu6&9UJFp*xpuKLA>QCgTQ$|MxVGhZrEG ztgLLaNtxHRwzk?{zN+sPk$&Ja&|nbsj!_adL4+h3m}i)v10kd89w7Ly>H&TM=JE@h T$Jz=a00000NkvXXu0mjfC$)+( literal 4090 zcmVn zb>H`U?*8t*&pua3DfuA}g&+9%!4uFt+F9?WJ3td)Ss(yY zG&3*=$80#{0V8?2hPv;60$qmR54Hh{h&=%miNnGcYz;0x}3g!^HCImX`0x!)p<=-ReJZ%CNndeJ$tsZXV3N?Xdo1Z za0t{Gc2o%mY^DzR5v30gg8nJsi3iJ$5ws;FMw>Zc?>u3XNB@-d#3c+k7x>FA`w@A0 z1F!-kDOQPdua*zb=4SM1pLu%KpZE6+_|#6^z`f(sI$SITMj zP6&$+PO}-r1qmBT&lvyhTdS%@ad8QT5$yzP7zWX(fngX#A`uM3=p+@5M$j}z4+*q( zfUrTFSQ$;@vt3`~qn#C3FJ|%+WiUdAfC^H81!&rb-?Hh$2>mTCDtdqsgLMFx%frn# z&lAyT1OVH%P*sJ(!a~N48_Tq5(WOi|H5Y}>{(t@8|{{t#G3>?r^^!KeuHUdtv_ zG#)9vj|EF-;4L>G5(FeT*<)0MYrkcqddrR95(#di^n%N;y6Q$$Rgp39Hi?PJj2bnL zl9Ey^3ur%UNC`N`e9-6&*STPZo)=zT6g5$mb&y@Hm@vskI)ABA%=bHvU{Ga)^%98 za6Z-52hRBW{QSW@_~4`Di-6UyjO}l+KltE@keF>AaZqR!-$2 zd)?+wHjDzQ0o-m+EQ*ItCQ3m{N(S4v?_&7yGBPr&Qw>g6xY`QOM3Yu}`_ zd=P1Kle5W5`X4|YIdTH!57hyfbkA8V+JXg5ZF(~g!va{y0zNPH&!m4-I z{^4WN%e|;0yp! z8gE*yQM?0_r%xDn?eEjl`dW&jkeS&J%c2vo*XzZ$C5?>==Rv@d;0wp(?mVG`FtmK- z$2nAi^q9ZqWe;S^l$)7TcpW%FgoSBqD6d3b%iPwmQ)bbd2PgfU+m@E=?uq7ah(zAa zw6k7kwFE$VpQ5h)G%V83LXX1 zG*DHIwzgJqN@U1Z?XP5<5MVS!tZjGh*!TDyFLB?Bzf$3=X6}sX36nJnmVUf*3!3E&AW1Zsg;)2 zm*V2f5JC_a=b@k=kF2armM&dFW#wMc{bFv67xMI2{bR_k#H9eu0?Wes8tlR_o&g!; z6%^5@cLpdfpuL&>53IkCa+rccWwXvukiaj#QpdG zjJMxj-Mvly$y$d?T@aDPHp4*F1`LR^!KHvuAgm)y0S6^Aq9Subh$NFZkB8%p%|s$G zoycZJOH*#dWh)q#0&4oY)$d~%CfD3FUeX%6$9z}IXFTO`1CytZExP=uJ1+j-KmYlc zoLH(Jv{iZo<8+A1Q!8$mP^40P*Cot+a5i^5G?y_CjKcF<3VE-E9Hv6O0|rR89@xgQ z`leVDLkPb3!xp50pB8(!@T+#xZ@eLC$mLU4-jD{cYWZ7G)k1-*@R`#?>FcjAv&W8| z+Vi$b`uG8iO)qEVH_yiQxT;O^^bGEp@?)-uzYI)CquEG~m5Q0r&X(+t;bIqrRj@Vo zez2coP4#4DWn*BTScGt;#NkRzj&u2rwXKsK<^-Bd*UA4JUp8IjrVP~lZ2@o?jJl$v za_6{famU5?oWPyAzrc-$l_!cQF~!BmX&2#=k_xTw%0ADeUjqM~zZ}DNRB$M7!;$%?J~<6yQV&aUT$| z0Tbe)XXr#K@`J$c$S)Iz>Cn${3VW5m0K074CMhYA7oUH|`h3@J-@3N9eP{+N?_Nql z!C*q606t$Mp-`ZE1SB#hTg8SV9ch?U1R4=q6sg!JqL2e@_bGudip08dMLNY}hH`P? zVB8)j74|_s3hX3U7lp^PokpeYi>TpbF;I2O50z5emb=o@k_iU=47s?3g8upZWaLbm zeaA7Q8oKTz5a{?`@ZXL?0+7kBOnjOFZ8{hrai4zql=b2^Q04dQy3$G zsESNdOCNvq;T7{1ENI=bWjoc?l|29aW9SZCeN- za5x<2-`urryVl`S;}*?Y*gE0a$%K+DNbtmVWoJ~V->s9zd#reD62J+H>_D?OuuriV zff`B*Cgv7pP209<+p8ac{0@c@!QqJMsix-8`4do8rTKVMlO8ydFP7f;guG?>?NHDc zl2T)ybFv#C&Y_dvsR|K!0~oguXAi}tBp?()SZ^1m_=bbhmJwAwk@U*{vFc^fJ3CDZ zp>%5Mop)BBKY`eW#1Y-NWk>Hhv#zdx!N+wrbE2~10rnwY+K^Z^-Z0v9LqAgv`f0{|7Yz=sH#%`%9^*- z1^3=!efIlNtlG4a3i~#2q_u|e>g~egbjzWs#dPXqY5f3H`Cjt$jD9^#dTBs|ZQEVC z(x;Dg>$WOWri`$AN&vqh%J;>hSqtTaXD1Wd zaa0Fh6jNONdYbgUs{QJvNF+4jT;NYSMQs1q3Idwuz%-3m8`SBbva*i#>p$kItA@Lx z(hNJ}oH#r>$D5i69LZ6Z&}}4uYE6p&SI{r z>T6W>)B|z3bT)7Pf<1dG!@90vnii&M@~dCXk{h?|(8`j=gJPG*#0(WpjqLVSv$w5= zL#>T8wwOfQ-4Jj=K#xto4iO4c9aJ}0b;rg1-L6L0ta+No#`;cS2@!LrwQDzV>{v5y zx3e=4Em&}~`O=E@!;)Q@W6+3+x!sNQB|=j#@FhcA9CSFLLq9eBI<&jMXOZZPXZOy7 z;=90opZ|9u;PLWk!B zSm$Y=ooCLV8x9GS8jG@i!`pP1{x6@BcDX@aT{UmM`BInD5QjsfuC9?aYd%2NHR9tv z{QB3krNgBjUNmcAhWm&LM=bDrpw)Hm>Gwj7gv~WfNxh0uL&g*p73Wz0DuJ`M*C$N4 zo{=N3>O2Ah2#2GL9zBfw{62j2(H^R*>KHSkB&{LkYv(P?Z?8RP(h~wq0~+g5kF+r@ zbt-p{nOAz{q>-PV58!T{4+tT+;fA{zJh-F_3Cpt4G@a_|{e1Gt+gx+aPn>gRU7dWu z*x591`TXdiXib--hhabu>JG`&e^imz9y=RfjRiTF3a sts|6zz9`s+6T2eRw8S9+C7eEGO{{R33&q+i< zR7l6IR&8ioRTzHG&DTwOlcq`6cD3n}*e+XBnaet)2BDq8`hl*X7TuW8QIz2a;s^ea z{ty%t{39a5{!Bpx@y`_eoQQ3yc3@U!SGOislcq_VwCR%G+}zwGH^(2nV3({}8hqh! z;NF+_d7t-v-g6F6YCRrJ*|#G{`(d-+3xEZ{U=LRA{QK2>nU6ypCB5`>fOG(;2cW7J zpc+R4#$bN-{U=`hYc1}T{!TBTSWE)Q1EBv808t6{2kqzIdi|BwSrQmd2D4j8i9rB4 z0L4l`)ln71oZwQOvU{7GpB^06=kJqG2BMpX=&JY!3Pqt3o2qNc8yUC0ThsI5o1chn zNB3)b$GbcIOR>KEjnpgvUSUH~qp9H8ce?NLqjcY>D*=2xXxKmZ`uR3b#OV*UZ$ zGi%0J{pce@YUg7IY&R!Evb>a8o+gGP!e->id%>G7uJ0FTq$#P*GKz65^_QHT-i4SE&DRF(p zFEw?W@%WcR{dzU0%?4uME9aCJ0I8h;0I5ZNEZv;G-~ZhF_4UnU-Z|cG3(mv}h>4Q` zB8rl3XD~5w!B~pC8wHa-e|JvZk20#-E#fMpn_jDZ>evSPZp<45^4 zo-nq;Sa=Es#(@f|qA^Mj4j=0BeGt2Z72zic(j`M3CuD@QysHGyo_$S!$DWLEBOMn! zsfqC0^wq>0)Dmo^_{~C_-gQ!z)xQJ4>p18-e86FM05DbRD*-?#rT;k$uxAHWm=Sp`sbI~6vMwe)H|0IQ;&t&0~wlJ0(^DK<0nEsk4`-(nUCu+jj8tiXyH zh?sz|35~uwuqka^Ns>_#q@_KqBvWF@>Z5Wz$x{mHD`W_e0uT}5@^i9vrfz<2*7qxb zc>v+k0oz&kNC=_dOZKGl9wB3Guk00000NkvXX Hu0mjftpn^Q literal 4244 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 delta 315 zcmV-B0mS~A1pES!BP9uNNLh0L01FcU01FcV0GgZ_00007bV*G`2h|J&6)hWd7q9Y> zS}T75^GQTOR7l6|l}!r5Kn#VyX-h@B_6&+Q(S_hSJdYP~;St=p7X&?l>lS}1<0e8F z#&%jNC>R(@GH-avOG)5wHD)}13dBzQE=OAo^qklgc<4al0Q$fTm?-i)u$6OD*fB5# zGVya@1MI5^2EZIxD1uzRJBMHdEP)J^%{< N002ovPDHLkV1gBDfTjQd diff --git a/resources/piano.png b/resources/piano.png index 3f3a8203ea760773208ca0c3b233d7d2f79f5760..276fe28aa136e0d001514f0a9bbe86ef248ea148 100644 GIT binary patch literal 944 zcmV;h15f;kP)|JkP1sYV7RnaCCIU;o%`d2x_$& z-EJ4dFfa^*t*tGTQYfY9^?Jv0 zbu7zbG#W7+4vFKK$z;OA!vg@G=P?)zNYj+rY(@|S00tn9AP8_>mn_S0T^G|diQ^d0 z^Qy45*40Kr2%;!rI-L>(0ZEeJx-O365QZVX@0S1pVEDd|=Xs=QitD;qmPHgr1VKO? z$3#(70bJKbYfTu2j7B2{g8{p{yPTh&GZ+k5TU+D){vOA1s)QRs5a9d%2SAb}gki{J zGWh_QPN$@4%FD|O7Z(@Y-QD4NUM1alJm&iPnyag;H-PW^xUNeSMNB4>N+Q>FnM@`m zNm4BykH3YM0ZSX^8rO;c7@Rw}^h=_#|>jBdBf{{B8u6tTR#OsCT! zNfO%aHfLvN)a&(1Cc`vMwAPrW$;QS8T5F_~v|25+)+nW_aLbY+rL5KoA!xN)7=}R< zMJT1PZMyLYtQi`G| zxV^nCBS?Wl0KWm>fK{OOMG7Yc{s6uUU>^7t_~mu;uK*N)2R!}nE%T@Uso+luTJb=@ S&2_y10000ElP8=xBvhG)Ja4^ zRCwC0lub(mNf3sg?w-s?h=?H&NIWPSJSd1Dif6&I{uA&1G5>;BQLkduc*v;JlbOkU z_a5AtRd@HWumweT7tPaEZ&$ZCJ3BLbdwcw!c6WD&HJMB}I5 z^PI9Q0dQRxDJ4}^A%s9mNl_FirI1ommL++flVuq)iXuGELOnmrLR}#){(@tu+>Jtu?;ylOzdI6n%lCC?X6)ilRVkjqAFk zX-XW&WLZXCF#qA2+I_~7>TmZzsD!Z2(l`uzOl;o*V%`}?nqwbrC*N)QCC6k2P7ARy24 zwv9eNKknn9#V~lCr@Sn_z z*lqjWeU6)?32hf6hy&lFGR##UU4u@=QZPDp;7!HS2RfXqy00<$l%Ccm+ zTrwC8xV*fiu4~rU*BOt;6h*=2=4K1Ny1HVyTrwJsI6XZjO;a{DHW&_v{dgKgXF?(SlYK}t!#-^Un(QmQSldHPbycApS}e!q`pS)^%-QVP%Wke=ru zrTowTLDMO}#~)y&6jfEVB{!SC>-#Lja*N Q{Qv*}07*qoM6N<$f-4$>+yDRo diff --git a/resources/play.png b/resources/play.png index 5b33768c87a0f27473e2c2eebc2c5e97af3d2d69..9e5c2573980751663c8b66575808526adadde8b7 100644 GIT binary patch delta 642 zcmV-|0)73!1lt9WBM$~*OGiWi{{a60|De66laU}E3f2J?6&p3Te6_8SNGpE=KuJVF zR7l6wl}&3EF%*WMoRb-+;0Jam_Cus}A@x6K*Zu^z{!tMZf<+J!aZ#<-R;yL}aXXnw zPTb_e_0mpn)s2BLgp=gSdGlrt{O`@p5TBltOP{If(B@6k%r#B3=)JFEj1G_~&|d+x zX_{s4{UcRf1CCQlaUz4i0yux5s_S}1L>`LB0};6agc#!iU{jEMQGft-RaMKXy6&92 zqpGW_dRIggI5M*Uq*GusXHeI5eM?o>MPw21A~G)`w?$+gI7}%W7J&T;psMS7NmcKQ z$imoBB63AUZmH^`neCa`(NHFXfU2sNRP~;7ZoxS>wySf_HLAMgy?N4Depl<w&r)+yVIWHa{nx`o7-^Av_5oJO`%l;aq?#mwH+(h7dN}wtX67 zd;xp{z5^p5jwkt9B$|I3TT1Dm>$*3i(daR-3A_hB0N;R<$xEI|qMS1&i`4i1P6**; z*L54fTVM;=0rr6-AWS~ILBLp=@@>1Wdv|hj@+`*qs+{~I@OeU-e)_Qr0jwm!kJk@q9YVac;mp zUPLad>WvuVT+UgFzCX*U$CB8Porg-M02MF?Tq@(f$kCl8$wdI;dh91krA_@g|9R2B cP{9ZI1(XRCgdi6Hr2qf`07*qoM6N<$g4EVBS^xk5 delta 512 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 literal 1075 zcmV-31kC%1P)h) z1Q5gd%lH0c1AqVh`~UU(um2xE|M>s*{kQ+u*L3~=b&lcxziWa2|2;qX|J9C(|Ci~p z_5+nNV8Z|b#KM3FFav$^4~UtWm>2|^)-kZ~0tJt+XJGihlR@N-DuW;|vj8r=00D&4 zU?xVOfy_)m+Zh=C-9Nw}AaR0$;R#UU4-mil&G78fErusgek{bLA0U937zhBM`3(Q> zO=e(|1ae-0lmi9ca5B6THfIo@abiC%eE7>hTcg_{$tYz5I}ee2BntYCz=`96xbLTo^voTu&^>PeBfoc{6>VqA|Z>x z#@dYG#q&p4^#TMC-pKp^;{yXL+e!w8&zwLGFbKY|F#P((%JADUi-8>&{{Q~}$Eg<} zfbbgp`@$p!b^{>>hT9;O|9}SbFkFA|ok27{5}587z{v_100 zjBExbb~dnUK{*mN1qlHog5mG~|L=YS1P}{u*Un^M6a@yuw{JiZb|B_wc+RHIpv))8 z@cYkSpdpZA0AvBsKyI*i!2V$P2jss42p|>|!=T{D<#h}kvOEk7AA!;!6`#2n9$bFF zARXBcHjo7v6uEkDcpFe)VU5o{=0R#}-U`7T+3HSHE1kjbhw9EVh91PE{ zJ!JT;n#b_w%^QY4z+eD}El~MC+>!SeAb_xDkUu|xu4D>gVBqy(`1MbN;o7zT44mo) z;Bo^L6fn%hh@lbczD?^J*|-VG zOg1wUGnskaT^^<yf;LZb(G);AJaq(QyEH5vUW!c-n3b1>gOkx0QEhE?hunFt| zz5fXi1VzI-*yBL8xG^$71W@{pWq>($#*88|&RSHY?@{zHdQ=hV2U-9apadjg+XXFj zC?Iz>IPB-Gg)EANP*vXiV&VOTmtOmSKq9fXR)4y6^|PCw0Ck{q8YE=kPWn1tFFpEN zee#hmO#&?9GPAje~n!lnj#PrGK%w(#mW=yfK5XMlUdbO``= zDC5A9sPxwgB1ajB>5|jJ;Zf;DKqY7*0Wt_tk4oh1(X|(+6PhUUZKfYUksZ&b2 zVrk=W$V4|Py~wlC3~$L3JWWFGJ-zOi+zgsnNz+v4=jV>yeFe64llVQy{PZlwc#QFg zcsj0y)gE3Qu_PEueXrKjwVvPVe{${fA3pSVxDM10OLWq5EYnGXm|g%l#5k-zL~*D( z#8faOi1lDRY8-LNqfHiozkp_coMqYNG)?c;YPEu-f-{b_jj!0M8j=K}xL?BRZfz2$--bvH++hPVCI;>wS6Ge)NpwZmgLC`lo z+P*L~6B*QTfBm8R39fwwL0JnjS!XP`@cMgzpSwF2z^u_^_F%-BD z+z2(#LooZm4$zAWhj)Q?!SQL0Juy8#30t`?FE{4lM&~E6s9u+WvM1{fT&(iNd)N6ju^AKNR00000NkvXXu0mjfyGgIk delta 695 zcmV;o0!aPS2h{~giBL{Q3K|Lk000U}NJLTq000&M000&U1^@s6#I$TX00009a7bBm z000XS000XS0e@s)kpKVy2XskIMF-Uk3l$L>D1i3OkyXm)m1=u=@kuvjc!v`_mzK;k&onVFfM zHqXz`_Y4nz0j#xLwz_}?K@%U4{|AdCu4Rh(}l->iP&{A&ibOQ)i5)7J2y5l>eOL2Qir{H zENAa5ZIjwOwN8z)E#cKsr`9cb?le6o08vTC3L>q4h$X1epoGJtK^L%dwp9iv$x>xA z_z8IM3HLC)$52>JS&ncxd~lq}KIfhacu9itP_H~=QQ|n(LSgbu?JBUVTZ9iCg^@hQ zc#QFgcq*=h)jD1sp+p!`G`y#7JvHn3vbWBg*Y9qgTG6QnmXRnzOuY$qh;djwKyj!# z#H2BQM2PiZJZcF*_}B+rXJ*`3%RiYr;fGt&EKEjA1o@M z9;}0!rLn!nlWq#2b3J^tWHu*q;iw>d`)*fe=BC}$IX|X`UBI0m_@T&?9;yQnMakTS z<<^g~16gid8AcVh2Fk!8mjW(tf002ovPDHLkV1n8BH8%hN diff --git a/resources/step_btn_remove.png b/resources/step_btn_remove.png index a51c30f5522b9b1c1250367ef4305bd839e0b352..248e9bc3a424c63326916dc46e4a78e39c4fd05a 100644 GIT binary patch delta 677 zcmV;W0$Tl`1lhS~Rj|NndYM(|KTthF981xb=z0KNi00R!YzL<~e)YXi`3w`ZN(3`7@y zfseosz*Zp;t+i{lT9vZtbUGwSatn9`>{U?`0~lkN1J{5q@C!&6BoG9L3-1AEfqHpk zZUPa&;R8!SGx3d@r^r}ia3VgUxKZ{vhlo$qaWupLnKdDx*X>Fwsu}T51$K5U@k)-$ zG+6_g^g>FTPFRG%j>=dB5-0xMfyjb?3amBbwvln5QP>4)5fo$-y+18piC03KswwU2 z{#wTtm7$DbWw(n`AWBdXC~?GTk2|M1w^rx+UkMBJi@&x#Q2Bb02 zO_F3oYyGrPQ0wo)hxfQ%j4Xj#!V{GU@*Hvtx$zUprjYLn*h#qxyaV=uEDodhb&@0- zz!ji*dzrPv_0^kJ#iRzJG^mhqamplx0!xhpM*}z!?3Xyq_3yw-;4^T%meJpOv3(Lg9=uq2G@sNVY$fVW>G*Co)usnxCERDdsUDDZ-HmP8{lA8cP|H$ zW*E(?!k^&61+*V-y*`l1%!|N#xK!%(Dg*?}v#`!JVXB;U{CD^R6R+{EzbN=A00000 LNkvXXu0mjfA($-M delta 513 zcmV+c0{;Eo1)u~-iBL{Q3K|Lk000U}NJLTq000&M000&U1^@s6#I$TX00009a7bBm z000XS000XS0e@s)kpKVy2XskIMF-Uk3l$P9%oi}1kyHm2rcn)2Y}{We%K7CbzA#O*c?gRW=@v@3nX~o822;0(kHF z*SZ5NgryvR(Dq;{rD_T<;d?j^-eXcC$yRPLLsD10O~K3H8&Ep1WvSH;$KUy?YZ!eWS?byyx-xDb9hM za0NISWqroi1D-*uXAIz%u&iORfW;Nz@F(wIToBcN4x!O#v?|r;^AWH1b{IZ-NKuf$ z4&=HfF$0Sb0tBC)tCMehdi!qw`6VCAc53A#b9iwM$A{Qii3Z>XqzW={jLC8IKnkIT z_m%{?E-!yS-Fp*UN$sJi8`tW>&*81(z>vAmGQO@abACPeaOBGZ$^r_P z+_qpa(ZvxXgeH>O6HnmB-$vE|c+%r0N8q%1|5wrgcPrhINGpE9XNC60ym)0pZu817#S-~9hyoUuw*4x zyfe=1dKUIP%mDj+-vFa&TfUnPaNjb21O(72Faey_HiIAlegaFN1Zu#$BzOkg0$0FT zBql>j56po(;6d*zppFSFZ~}ka0N0to@puE?fhQ4GK;sg54uB&`)VBbpzy)w7q7R@< z^&Lr;-;4q{)*NeXY_cg$YTpu`B)My?5WmB{D$??{16;n&c)M?__$TN%6cZfZI~iV9c&&$8;M1& delta 231 zcmV%C002ovPDHLkV1j1)Ud8|b diff --git a/resources/track_op_menu.png b/resources/track_op_menu.png index cc7f2d5e769d0e4e7e5e7bbf4e27886f861a53d6..ddf5f96995bf04da35c74984dd8bdb25b9f6f61a 100644 GIT binary patch delta 2030 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 #include #include -#include #else #include #include #include -#include #include -#define setCurrentIndex setCurrentItem -#define currentIndex currentItem - #endif @@ -65,6 +60,7 @@ #include "channel_track.h" #include "led_checkbox.h" #include "preset_preview_play_handle.h" +#include "combobox.h" @@ -197,7 +193,7 @@ const int CHORDS_GROUPBOX_HEIGHT = 65; const int ARP_GROUPBOX_X = CHORDS_GROUPBOX_X; const int ARP_GROUPBOX_Y = 10 + CHORDS_GROUPBOX_Y + CHORDS_GROUPBOX_HEIGHT; const int ARP_GROUPBOX_WIDTH = CHORDS_GROUPBOX_WIDTH; -const int ARP_GROUPBOX_HEIGHT = 200 - ARP_GROUPBOX_Y; +const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; @@ -211,7 +207,7 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : CHORDS_GROUPBOX_WIDTH, CHORDS_GROUPBOX_HEIGHT ); - m_chordsComboBox = new QComboBox( m_chordsGroupBox ); + m_chordsComboBox = new comboBox( m_chordsGroupBox ); m_chordsComboBox->setFont( pointSize<8>( m_chordsComboBox->font() ) ); m_chordsComboBox->setGeometry( 10, 25, 140, 22 ); @@ -262,7 +258,7 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : "not played at the same time. Typical arpeggios are " "major or minor triads. But there're a lot of other " "possible chords, you can select." ) ); - m_arpComboBox = new QComboBox( m_arpGroupBox ); + m_arpComboBox = new comboBox( m_arpGroupBox ); m_arpComboBox->setFont( pointSize<8>( m_arpComboBox->font() ) ); m_arpComboBox->setGeometry( 10, 25, 140, 22 ); @@ -334,15 +330,11 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : m_arpUpBtn = new pixmapButton( m_arpGroupBox ); - m_arpUpBtn->move( 70, 60 ); + m_arpUpBtn->move( 10, 74 ); m_arpUpBtn->setActiveGraphic( embed::getIconPixmap( "arp_up_on" ) ); m_arpUpBtn->setInactiveGraphic( embed::getIconPixmap( "arp_up_off" ) ); -#ifdef QT4 m_arpUpBtn->setChecked( TRUE ); -#else - m_arpUpBtn->setOn( TRUE ); -#endif -#ifndef QT4 +#ifdef QT3 m_arpUpBtn->setBackgroundMode( Qt::PaletteBackground ); #endif toolTip::add( m_arpUpBtn, tr( "arpeggio direction = up" ) ); @@ -350,11 +342,11 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : SLOT( arpUpToggled( bool ) ) ); m_arpDownBtn = new pixmapButton( m_arpGroupBox ); - m_arpDownBtn->move( 90, 60 ); + m_arpDownBtn->move( 30, 74 ); m_arpDownBtn->setActiveGraphic( embed::getIconPixmap( "arp_down_on" ) ); m_arpDownBtn->setInactiveGraphic( embed::getIconPixmap( "arp_down_off" ) ); -#ifndef QT4 +#ifdef QT3 m_arpDownBtn->setBackgroundMode( Qt::PaletteBackground ); #endif toolTip::add( m_arpDownBtn, tr( "arpeggio direction = down" ) ); @@ -362,12 +354,12 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : SLOT( arpDownToggled( bool ) ) ); m_arpUpAndDownBtn = new pixmapButton( m_arpGroupBox ); - m_arpUpAndDownBtn->move( 110, 60 ); + m_arpUpAndDownBtn->move( 50, 74 ); m_arpUpAndDownBtn->setActiveGraphic( embed::getIconPixmap( "arp_up_and_down_on" ) ); m_arpUpAndDownBtn->setInactiveGraphic( embed::getIconPixmap( "arp_up_and_down_off" ) ); -#ifndef QT4 +#ifdef QT3 m_arpUpAndDownBtn->setBackgroundMode( Qt::PaletteBackground ); #endif toolTip::add( m_arpUpAndDownBtn, @@ -376,12 +368,12 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : SLOT( arpUpAndDownToggled( bool ) ) ); m_arpRandomBtn = new pixmapButton( m_arpGroupBox ); - m_arpRandomBtn->move( 130, 60 ); + m_arpRandomBtn->move( 70, 74 ); m_arpRandomBtn->setActiveGraphic( embed::getIconPixmap( "arp_random_on" ) ); m_arpRandomBtn->setInactiveGraphic( embed::getIconPixmap( "arp_random_off" ) ); -#ifndef QT4 +#ifdef QT3 m_arpRandomBtn->setBackgroundMode( Qt::PaletteBackground ); #endif toolTip::add( m_arpRandomBtn, tr( "arpeggio direction = random" ) ); @@ -394,25 +386,25 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : m_arpDirections_group->addButton( m_arpUpAndDownBtn ); m_arpDirections_group->addButton( m_arpRandomBtn ); m_arpDirections_group->setExclusive( TRUE ); -#ifndef QT4 +#ifdef QT3 m_arpDirections_group->hide(); #endif -/* m_sortMode = new ledCheckBox( tr( "Sort-mode" ), m_arpGroupBox ); - m_sortMode->move( 10, 90 );*/ - QLabel * mode_lbl = new QLabel( tr( "Mode:" ), m_arpGroupBox ); - mode_lbl->setGeometry( 10, 90, 64, 10 ); + mode_lbl->setGeometry( 10, 104, 64, 10 ); mode_lbl->setFont( pointSize<7>( mode_lbl->font() ) ); - m_arpModeComboBox = new QComboBox( m_arpGroupBox ); + m_arpModeComboBox = new comboBox( m_arpGroupBox ); m_arpModeComboBox->setFont( pointSize<8>( m_arpModeComboBox->font() ) ); - m_arpModeComboBox->setGeometry( 70, 87, 80, 22 ); + m_arpModeComboBox->setGeometry( 10, 118, 128, 22 ); - m_arpModeComboBox->addItem( tr( "Free" ) ); - m_arpModeComboBox->addItem( tr( "Sort" ) ); - m_arpModeComboBox->addItem( tr( "Sync" ) ); - m_arpModeComboBox->setCurrentItem( 0 ); + m_arpModeComboBox->addItem( tr( "Free" ), + embed::getIconPixmap( "arp_free" ) ); + m_arpModeComboBox->addItem( tr( "Sort" ), + embed::getIconPixmap( "arp_sort" ) ); + m_arpModeComboBox->addItem( tr( "Sync" ), + embed::getIconPixmap( "arp_sync" ) ); + m_arpModeComboBox->setCurrentIndex( 0 ); } @@ -771,9 +763,5 @@ void arpAndChordsTabWidget::arpRandomToggled( bool _on ) -#undef setChecked -#undef currentIndex -#undef setCurrentIndex - #include "arp_and_chords_tab_widget.moc" diff --git a/src/core/bb_editor.cpp b/src/core/bb_editor.cpp index 5c88041c3f..a2b56ed777 100644 --- a/src/core/bb_editor.cpp +++ b/src/core/bb_editor.cpp @@ -1,7 +1,7 @@ /* * bb_editor.cpp - basic main-window for editing of beats and basslines * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -50,6 +50,7 @@ #include "templates.h" #include "debug.h" #include "tooltip.h" +#include "combobox.h" @@ -85,7 +86,8 @@ bbEditor::bbEditor() : setWindowIcon( embed::getIconPixmap( "bb_track" ) ); setWindowTitle( tr( "Beat+Bassline Editor" ) ); setMinimumWidth( TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH + - BBE_PPT + 2 * TCO_BORDER_WIDTH ); + BBE_PPT + 2 * TCO_BORDER_WIDTH + + DEFAULT_SCROLLBAR_SIZE ); if( lmmsMainWin::inst()->workspace() != NULL ) { setGeometry( 10, 340, minimumWidth(), 300 ); @@ -127,9 +129,16 @@ bbEditor::bbEditor() : QLabel * l = new QLabel( m_toolBar ); l->setPixmap( embed::getIconPixmap( "drum" ) ); + m_bbComboBox = new comboBox( m_toolBar ); + m_bbComboBox->setFixedSize( 200, 22 ); + connect( m_bbComboBox, SIGNAL( currentIndexChanged( int ) ), + this, SLOT( setCurrentBB( int ) ) ); + tb_layout->addSpacing( 5 ); tb_layout->addWidget( m_playButton ); tb_layout->addWidget( m_stopButton ); + tb_layout->addSpacing( 20 ); + tb_layout->addWidget( m_bbComboBox ); tb_layout->addStretch(); tb_layout->addWidget( l ); tb_layout->addSpacing( 15 ); @@ -155,10 +164,15 @@ csize bbEditor::currentBB( void ) const -void bbEditor::setCurrentBB( csize _bb ) +void bbEditor::setCurrentBB( int _bb ) { + if( m_bbComboBox->currentIndex() != _bb ) + { + m_bbComboBox->setCurrentIndex( _bb ); + } + // first make sure, all channels have a TCO at current BB - createTCOsForBB( _bb ); + createTCOsForBB( static_cast( _bb ) ); realignTracks(); @@ -169,7 +183,8 @@ void bbEditor::setCurrentBB( csize _bb ) bbTrack::findBBTrack( i )->trackLabel()->update(); } - emit positionChanged( m_currentPosition = midiTime( _bb, 0 ) ); + emit positionChanged( m_currentPosition = midiTime( + static_cast( _bb ), 0 ) ); } @@ -270,6 +285,22 @@ void bbEditor::updateBBTrack( trackContentObject * _tco ) +void bbEditor::updateComboBox( void ) +{ + m_bbComboBox->clear(); + + for( csize i = 0; i < numOfBBs(); ++i ) + { + bbTrack * bbt = bbTrack::findBBTrack( i ); + m_bbComboBox->addItem( bbt->trackLabel()->text(), + bbt->trackLabel()->pixmap() ); + } + m_bbComboBox->setCurrentIndex( currentBB() ); +} + + + + // close-handler for bb-editor-window because closing of bb-editor isn't allowed // instead of closing it's being hidden void bbEditor::closeEvent( QCloseEvent * _ce ) @@ -323,7 +354,8 @@ void bbEditor::resizeEvent( QResizeEvent * _re ) { setPixelsPerTact( width() - ( TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH + 2 * - TCO_BORDER_WIDTH ) ); + TCO_BORDER_WIDTH + + DEFAULT_SCROLLBAR_SIZE ) ); trackContainer::resizeEvent( _re ); m_toolBar->setFixedWidth( width() ); } @@ -331,6 +363,15 @@ void bbEditor::resizeEvent( QResizeEvent * _re ) +QRect bbEditor::scrollAreaRect( void ) const +{ + return( QRect( 0, 0, (int) pixelsPerTact(), + height() - m_toolBar->height() ) ); +} + + + + void bbEditor::play( void ) { if( songEditor::inst()->playing() ) @@ -431,6 +472,7 @@ void bbEditor::swapBB( csize _bb1, csize _bb2 ) { ( *it )->swapPositionOfTCOs( _bb1, _bb2 ); } + updateComboBox(); } diff --git a/src/core/envelope_tab_widget.cpp b/src/core/envelope_tab_widget.cpp index b7bdcf1b65..bac0ffd9b3 100644 --- a/src/core/envelope_tab_widget.cpp +++ b/src/core/envelope_tab_widget.cpp @@ -2,7 +2,7 @@ * envelope_tab_widget.cpp - widget for use in envelope/lfo/filter-tab of * channel-window * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -28,19 +28,14 @@ #ifdef QT4 -#include #include #include #else -#include #include #include -#define isChecked isOn -#define setChecked setOn - #endif @@ -54,6 +49,7 @@ #include "embed.h" #include "gui_templates.h" #include "channel_track.h" +#include "combobox.h" @@ -142,19 +138,27 @@ envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track ) : FILTER_GROUPBOX_WIDTH, FILTER_GROUPBOX_HEIGHT ); - m_filterComboBox = new QComboBox( m_filterGroupBox ); - m_filterComboBox->setGeometry( 20, 20, 100, 22 ); + m_filterComboBox = new comboBox( m_filterGroupBox ); + m_filterComboBox->setGeometry( 14, 22, 120, 22 ); m_filterComboBox->setFont( pointSize<8>( m_filterComboBox->font() ) ); - m_filterComboBox->addItem( tr( "LowPass" ) ); - m_filterComboBox->addItem( tr( "HiPass" ) ); - m_filterComboBox->addItem( tr( "BandPass csg" ) ); - m_filterComboBox->addItem( tr( "BandPass czpg" ) ); - m_filterComboBox->addItem( tr( "Notch" ) ); - m_filterComboBox->addItem( tr( "Allpass" ) ); - m_filterComboBox->addItem( tr( "Moog" ) ); - m_filterComboBox->addItem( tr( "2x LowPass" ) ); + m_filterComboBox->addItem( tr( "LowPass" ), + embed::getIconPixmap( "filter_lp" ) ); + m_filterComboBox->addItem( tr( "HiPass" ), + embed::getIconPixmap( "filter_hp" ) ); + m_filterComboBox->addItem( tr( "BandPass csg" ), + embed::getIconPixmap( "filter_bp" ) ); + m_filterComboBox->addItem( tr( "BandPass czpg" ), + embed::getIconPixmap( "filter_bp" ) ); + m_filterComboBox->addItem( tr( "Notch" ), + embed::getIconPixmap( "filter_notch" ) ); + m_filterComboBox->addItem( tr( "Allpass" ), + embed::getIconPixmap( "filter_ap" ) ); + m_filterComboBox->addItem( tr( "Moog" ), + embed::getIconPixmap( "filter_lp" ) ); + m_filterComboBox->addItem( tr( "2x LowPass" ), + embed::getIconPixmap( "filter_2lp" ) ); #ifdef QT4 m_filterComboBox->setWhatsThis( @@ -264,18 +268,14 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab, Uint32 _frames, mixer::inst()->sampleRate() ); } - if( /*m_filterState->isChecked()*/ m_filterGroupBox->isActive() ) + if( m_filterGroupBox->isActive() ) { int old_filter_cut = 0; int old_filter_res = 0; - basicFilters<>::filterTypes filter = basicFilters<>::getFilterType( m_filterComboBox-> -#ifdef QT4 - currentIndex() -#else - currentItem() -#endif - ); + basicFilters<>::filterTypes filter = + basicFilters<>::getFilterType( + m_filterComboBox->currentIndex() ); if( m_envLFOWidgets[VOLUME]->used() && m_envLFOWidgets[CUT]->used() && @@ -492,11 +492,7 @@ void envelopeTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { QDomElement etw_de = _doc.createElement( nodeName() ); -#ifdef QT4 etw_de.setAttribute( "ftype", m_filterComboBox->currentIndex() ); -#else - etw_de.setAttribute( "ftype", m_filterComboBox->currentItem() ); -#endif etw_de.setAttribute( "fcut", m_filterCutKnob->value() ); etw_de.setAttribute( "fres", m_filterResKnob->value() ); etw_de.setAttribute( "fwet", m_filterGroupBox->isActive() ); @@ -518,11 +514,7 @@ void envelopeTabWidget::saveSettings( QDomDocument & _doc, void envelopeTabWidget::loadSettings( const QDomElement & _this ) { -#ifdef QT4 m_filterComboBox->setCurrentIndex( _this.attribute( "ftype" ).toInt() ); -#else - m_filterComboBox->setCurrentItem( _this.attribute( "ftype" ).toInt() ); -#endif m_filterCutKnob->setValue( _this.attribute( "fcut" ).toFloat() ); m_filterResKnob->setValue( _this.attribute( "fres" ).toFloat() ); /* m_filterState->setChecked( _this.attribute( "fwet" ).toInt() );*/ @@ -550,9 +542,6 @@ void envelopeTabWidget::loadSettings( const QDomElement & _this ) -#undef isChecked -#undef setChecked - #include "envelope_tab_widget.moc" diff --git a/src/core/export_project_dialog.cpp b/src/core/export_project_dialog.cpp index bcb5256c05..51a51cdd30 100644 --- a/src/core/export_project_dialog.cpp +++ b/src/core/export_project_dialog.cpp @@ -1,7 +1,7 @@ /* * export_project_dialog.cpp - implementation of dialog for exporting project * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,8 +40,6 @@ #include #include #include -#include -#include #include #include #include @@ -54,6 +50,8 @@ #include "export_project_dialog.h" #include "song_editor.h" #include "lmms_main_win.h" +#include "combobox.h" +#include "led_checkbox.h" #include "embed.h" #include "audio_file_wave.h" @@ -87,7 +85,7 @@ const int LABEL_MARGIN = 6; const int LABEL_X = 10; const int LABEL_WIDTH = 48; const int TYPE_STUFF_Y = 10; -const int TYPE_HEIGHT = 26; +const int TYPE_HEIGHT = 22; const int TYPE_COMBO_WIDTH = 256; const int KBPS_STUFF_Y = TYPE_STUFF_Y + TYPE_HEIGHT + LABEL_MARGIN + 6; const int KBPS_HEIGHT = TYPE_HEIGHT; @@ -151,7 +149,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, m_typeLbl->setGeometry( LABEL_X, TYPE_STUFF_Y, LABEL_WIDTH, TYPE_HEIGHT ); - m_typeCombo = new QComboBox( this ); + m_typeCombo = new comboBox( this ); m_typeCombo->setGeometry( LABEL_X + LABEL_WIDTH+LABEL_MARGIN, TYPE_STUFF_Y, TYPE_COMBO_WIDTH, TYPE_HEIGHT ); @@ -165,13 +163,8 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, tr( fileEncodeDevices[idx].m_description ) ); ++idx; } -#ifdef QT4 m_typeCombo->setCurrentIndex( m_typeCombo->findText( tr( fileEncodeDevices[m_fileType].m_description ) ) ); -#else - m_typeCombo->setCurrentText( tr( - fileEncodeDevices[m_fileType].m_description ) ); -#endif // kbps-ui-stuff @@ -179,7 +172,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, m_kbpsLbl->setGeometry( LABEL_X, KBPS_STUFF_Y, LABEL_WIDTH, KBPS_HEIGHT ); - m_kbpsCombo = new QComboBox( this ); + m_kbpsCombo = new comboBox( this ); m_kbpsCombo->setGeometry( LABEL_X + LABEL_WIDTH + LABEL_MARGIN, KBPS_STUFF_Y, KBPS_COMBO_WIDTH, KBPS_HEIGHT ); @@ -191,21 +184,17 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, s_availableBitrates[idx] ) ); ++idx; } -#ifdef QT4 m_typeCombo->setCurrentIndex( m_typeCombo->findText( QString::number( 128 ) ) ); -#else - m_kbpsCombo->setCurrentText( QString::number( 128 ) ); -#endif - m_vbrCb = new QCheckBox( tr( "variable bitrate" ), this ); + m_vbrCb = new ledCheckBox( tr( "variable bitrate" ), this ); m_vbrCb->setGeometry( LABEL_X + LABEL_WIDTH + 3 * LABEL_MARGIN + KBPS_COMBO_WIDTH, KBPS_STUFF_Y + 3, 190, 20 ); m_vbrCb->setChecked( TRUE ); - m_hqmCb = new QCheckBox( tr( "use high-quality-mode (recommened)" ), + m_hqmCb = new ledCheckBox( tr( "use high-quality-mode (recommened)" ), this ); m_hqmCb->setGeometry( LABEL_X, HQ_MODE_CB_Y + 3, HQ_MODE_CB_WIDTH, HQ_MODE_CB_HEIGHT ); @@ -278,13 +267,17 @@ void exportProjectDialog::keyPressEvent( QKeyEvent * _ke ) -void exportProjectDialog::closeEvent (QCloseEvent * _ce) +void exportProjectDialog::closeEvent( QCloseEvent * _ce ) { if( songEditor::inst()->exporting() == TRUE ) { abortProjectExport(); _ce->ignore(); } + else + { + QDialog::closeEvent( _ce ); + } } @@ -426,6 +419,7 @@ void exportProjectDialog::cancelBtnClicked( void ) abortProjectExport(); return; } + reject(); } diff --git a/src/core/name_label.cpp b/src/core/name_label.cpp index 67387fd5c0..5cc82c56cd 100644 --- a/src/core/name_label.cpp +++ b/src/core/name_label.cpp @@ -2,7 +2,7 @@ * name_label.cpp - implementation of class nameLabel, a label which * is renamable by double-clicking it * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -30,10 +30,13 @@ #include #include +#include #else #include +#include +#include #endif @@ -43,13 +46,14 @@ #include "bb_editor.h" #include "bb_track.h" #include "gui_templates.h" +#include "config_mgr.h" -nameLabel::nameLabel( const QString & _initial_name, QWidget * _parent, - const QPixmap & _pm ) : +nameLabel::nameLabel( const QString & _initial_name, QWidget * _parent ) : QLabel( _initial_name, _parent ), - m_pm( _pm ) + m_pixmap(), + m_pixmapFile( "" ) { #ifdef QT3 setBackgroundMode( Qt::NoBackground ); @@ -65,17 +69,99 @@ nameLabel::~nameLabel() -const QPixmap * nameLabel::pixmap( void ) const +void nameLabel::setPixmap( const QPixmap & _pixmap ) { - return( &m_pm ); + m_pixmap = _pixmap; } -void nameLabel::setPixmap( const QPixmap & _pm ) +void nameLabel::setPixmapFile( const QString & _file ) { - m_pm = _pm; + m_pixmapFile = _file; + if( QFileInfo( m_pixmapFile ).isRelative() ) + { + m_pixmap = QPixmap( configManager::inst()->trackIconsDir() + + m_pixmapFile ); + } + else + { + m_pixmap = QPixmap( m_pixmapFile ); + } + emit( pixmapChanged() ); + update(); +} + + + + +void nameLabel::selectPixmap( void ) +{ +#ifdef QT4 + QFileDialog ofd( NULL, tr( "Select icon" ) ); +#else + QFileDialog ofd( QString::null, QString::null, NULL, "", TRUE ); + ofd.setWindowTitle( tr( "Select icon" ) ); +#endif + + QString dir; + if( m_pixmapFile != "" ) + { + QString f = m_pixmapFile; + if( QFileInfo( f ).isRelative() ) + { + f = configManager::inst()->trackIconsDir() + f; + } +#ifdef QT4 + dir = QFileInfo( f ).absolutePath(); +#else + dir = QFileInfo( f ).dirPath( TRUE ); +#endif + } + else + { + dir = configManager::inst()->trackIconsDir(); + } + // change dir to position of previously opened file + ofd.setDirectory( dir ); + ofd.setFileMode( QFileDialog::ExistingFiles ); + + // set filters +#ifdef QT4 + QStringList types; + types << tr( "All images (*.png *.jpg *.jpeg *.gif *.bmp)" ); + ofd.setFilters( types ); +#else + ofd.addFilter( tr( "All images (*.png *.jpg *.jpeg *.gif *.bmp)" ) ); + ofd.setSelectedFilter( tr( "All images (*.png *.jpg *.jpeg *.gif " + "*.bmp)" ) ); +#endif + if( m_pixmapFile != "" ) + { + // select previously opened file + ofd.selectFile( QFileInfo( m_pixmapFile ).fileName() ); + } + + if ( ofd.exec () == QDialog::Accepted ) + { + if( ofd.selectedFiles().isEmpty() ) + { + return; + } + QString pf = ofd.selectedFiles()[0]; + if( !QFileInfo( pf ).isRelative() ) + { +#if QT_VERSION >= 0x030100 + pf = pf.replace( configManager::inst()->trackIconsDir(), + "" ); +#else + pf = pf.replace( QRegExp( + configManager::inst()->trackIconsDir() ), "" ); +#endif + } + setPixmapFile( pf ); + } } @@ -90,53 +176,28 @@ void nameLabel::rename( void ) { setText( txt ); emit nameChanged( txt ); + emit nameChanged(); } } -void nameLabel::paintEvent( QPaintEvent * ) -{ -#ifdef QT4 - QPainter p( this ); - p.fillRect( rect(), palette().color( backgroundRole() ) ); -#else - QPixmap draw_pm( rect().size() ); - draw_pm.fill( this, rect().topLeft() ); - - QPainter p( &draw_pm, this ); -#endif - p.setFont( pointSize<8>( p.font() ) ); - - QFontMetrics fm( font() ); - - p.drawPixmap( 4, ( height() - m_pm.height() ) / 2, m_pm ); - p.setPen( QColor( 0, 224, 0 ) ); - bbTrack * bbt = bbTrack::findBBTrack( bbEditor::inst()->currentBB() ); - if( bbt != NULL && bbt->getTrackSettingsWidget() == - dynamic_cast( parentWidget() ) ) - { - p.setPen( QColor( 255, 255, 255 ) ); - } - p.drawText( m_pm.width() + 8, height() / 2 + fm.height() / 2 - 4, - text() ); - -#ifndef QT4 - // and blit all the drawn stuff on the screen... - bitBlt( this, rect().topLeft(), &draw_pm ); -#endif -} - - - - void nameLabel::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::RightButton ) { - rename(); + QSize s( m_pixmap.width(), m_pixmap.height() ); + s.scale( width(), height(), QSize::ScaleMin ); + if( _me->x() > 4 + s.width() ) + { + rename(); + } + else + { + selectPixmap(); + } } else { @@ -150,7 +211,67 @@ void nameLabel::mousePressEvent( QMouseEvent * _me ) void nameLabel::mouseDoubleClickEvent( QMouseEvent * _me ) { - rename(); + QSize s( m_pixmap.width(), m_pixmap.height() ); + s.scale( width(), height(), QSize::ScaleMin ); + if( _me->x() > 4 + s.width() ) + { + rename(); + } + else + { + selectPixmap(); + } +} + + + + +void nameLabel::paintEvent( QPaintEvent * ) +{ +#ifdef QT4 + QPainter p( this ); + p.fillRect( rect(), palette().color( backgroundRole() ) ); +#else + QPixmap draw_pm( size() ); + draw_pm.fill( this, rect().topLeft() ); + + QPainter p( &draw_pm, this ); +#endif + p.setFont( pointSize<8>( p.font() ) ); + + int x = 4; + if( m_pixmap.isNull() == FALSE ) + { + QPixmap pm = m_pixmap; + if( pm.height() > height() ) + { +#ifndef QT3 + pm = pm.scaledToHeight( height(), + Qt::SmoothTransformation ); +#else + pm.convertFromImage( pm.convertToImage().smoothScale( + pm.width(), height(), + QImage::ScaleMin ) ); +#endif + } + p.drawPixmap( x, ( height() - pm.height() ) / 2, pm ); + x += 4 + pm.width(); + } + + p.setPen( QColor( 0, 224, 0 ) ); + bbTrack * bbt = bbTrack::findBBTrack( bbEditor::inst()->currentBB() ); + if( bbt != NULL && bbt->getTrackSettingsWidget() == + dynamic_cast( parentWidget() ) ) + { + p.setPen( QColor( 255, 255, 255 ) ); + } + p.drawText( x, height() / 2 + p.fontMetrics().height() / 2 - 4, + text() ); + +#ifndef QT4 + // and blit all the drawn stuff on the screen... + bitBlt( this, rect().topLeft(), &draw_pm ); +#endif } diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index 2e2776ee31..4155938e35 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -42,12 +41,9 @@ #include #include #include -#include #include #include -#define setChecked setOn - #endif @@ -72,6 +68,8 @@ #include "midi.h" #include "tool_button.h" #include "text_float.h" +#include "combobox.h" + extern tones whiteKeys[]; // defined in piano_widget.cpp @@ -167,22 +165,22 @@ pianoRoll::pianoRoll( void ) : if( s_toolDraw == NULL ) { s_toolDraw = new QPixmap( embed::getIconPixmap( - "pr_tool_draw" ) ); + "edit_draw" ) ); } if( s_toolErase == NULL ) { s_toolErase= new QPixmap( embed::getIconPixmap( - "pr_tool_erase" ) ); + "edit_erase" ) ); } if( s_toolSelect == NULL ) { s_toolSelect = new QPixmap( embed::getIconPixmap( - "pr_tool_select" ) ); + "edit_select" ) ); } if( s_toolMove == NULL ) { s_toolMove = new QPixmap( embed::getIconPixmap( - "pr_tool_move" ) ); + "edit_move" ) ); } #ifdef QT4 @@ -272,27 +270,27 @@ pianoRoll::pianoRoll( void ) : SLOT( verScrolled( int ) ) ); // init edit-buttons at the top - m_drawButton = new toolButton( embed::getIconPixmap( "pr_tool_draw" ), + m_drawButton = new toolButton( embed::getIconPixmap( "edit_draw" ), tr( "Draw mode (D)" ), this, SLOT( drawButtonToggled() ), m_toolBar ); m_drawButton->setCheckable( TRUE ); m_drawButton->setChecked( TRUE ); - m_eraseButton = new toolButton( embed::getIconPixmap( "pr_tool_erase" ), + m_eraseButton = new toolButton( embed::getIconPixmap( "edit_erase" ), tr( "Erase mode (E)" ), this, SLOT( eraseButtonToggled() ), m_toolBar ); m_eraseButton->setCheckable( TRUE ); m_selectButton = new toolButton( embed::getIconPixmap( - "pr_tool_select" ), + "edit_select" ), tr( "Select mode (S)" ), this, SLOT( selectButtonToggled() ), m_toolBar ); m_selectButton->setCheckable( TRUE ); - m_moveButton = new toolButton( embed::getIconPixmap( "pr_tool_move" ), + m_moveButton = new toolButton( embed::getIconPixmap( "edit_move" ), tr( "Move selection mode (M)" ), this, SLOT( moveButtonToggled() ), m_toolBar ); @@ -392,20 +390,17 @@ pianoRoll::pianoRoll( void ) : zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) ); // setup zooming-stuff - m_zoomingComboBox = new QComboBox( m_toolBar ); - m_zoomingComboBox->setGeometry( 580, 4, 80, 24 ); + m_zoomingComboBox = new comboBox( m_toolBar ); + m_zoomingComboBox->setFixedSize( 80, 22 ); + m_zoomingComboBox->move( 580, 4 ); for( int i = 0; i < 6; ++i ) { m_zoomingComboBox->addItem( QString::number( 25 * static_cast( powf( 2.0f, i ) ) ) + "%" ); } -#ifdef QT4 m_zoomingComboBox->setCurrentIndex( m_zoomingComboBox->findText( "100%" ) ); -#else - m_zoomingComboBox->setCurrentText( "100%" ); -#endif connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), this, SLOT( zoomingChanged( const QString & ) ) ); @@ -573,10 +568,9 @@ inline void pianoRoll::drawNoteRect( QPainter & _p, Uint16 _x, Uint16 _y, void pianoRoll::update( void ) { - if( m_paintPixmap.isNull() == TRUE || - m_paintPixmap.size() != rect().size() ) + if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() ) { - m_paintPixmap = QPixmap( rect().size() ); + m_paintPixmap = QPixmap( size() ); } m_paintPixmap.fill( QColor( 0, 0, 0 ) ); QPainter p( &m_paintPixmap ); @@ -755,7 +749,7 @@ void pianoRoll::update( void ) // draw vertical raster int tact_16th = m_currentPosition / 4; - int offset = ( m_currentPosition % 4 ) * m_ppt / + const int offset = ( m_currentPosition % 4 ) * m_ppt / DEFAULT_STEPS_PER_TACT / 4; for( int x = WHITE_KEY_WIDTH - offset; x < width(); x += m_ppt / DEFAULT_STEPS_PER_TACT, ++tact_16th ) @@ -1964,18 +1958,11 @@ void pianoRoll::wheelEvent( QWheelEvent * _we ) { m_ppt /= 2; } -#ifdef QT4 // update combobox with zooming-factor m_zoomingComboBox->setCurrentIndex( m_zoomingComboBox->findText( QString::number( static_cast( m_ppt * 100 / DEFAULT_PR_PPT ) ) +"%" ) ); -#else - // update combobox with zooming-factor - m_zoomingComboBox->setCurrentText( QString::number( - static_cast( m_ppt * 100 / - DEFAULT_PR_PPT ) ) +"%" ); -#endif // update timeline m_timeLine->setPixelsPerTact( m_ppt ); update(); @@ -2446,8 +2433,6 @@ void pianoRoll::zoomingChanged( const QString & _zfac ) -#undef setChecked - #include "piano_roll.moc" diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index fdf5a93a55..22ccf9d67f 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -1,7 +1,7 @@ /* * song_editor.cpp - basic window for editing song * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -45,8 +45,8 @@ #include #include #include -#include #include +#include #else @@ -59,8 +59,8 @@ #include #include #include -#include #include +#include #endif @@ -88,6 +88,7 @@ #include "tool_button.h" #include "cpuload_widget.h" #include "text_float.h" +#include "combobox.h" #include "debug.h" @@ -96,8 +97,6 @@ extern QString file_to_load; -const int SCROLLBAR_SIZE = 16; - songEditor * songEditor::s_instanceOfMe = NULL; @@ -329,18 +328,28 @@ songEditor::songEditor() : this, SLOT( addSampleTrack() ), m_toolBar ); - m_insertBarButton = new toolButton( embed::getIconPixmap( - "insert_bar" ), - tr( "Insert bar " - "(Shift+Insert)" ), - this, SLOT( insertBar() ), - m_toolBar ); + m_drawModeButton = new toolButton( embed::getIconPixmap( + "edit_draw" ), + tr( "Draw mode" ), + NULL, NULL, m_toolBar ); + m_drawModeButton->setCheckable( TRUE ); + m_drawModeButton->setChecked( TRUE ); + + m_editModeButton = new toolButton( embed::getIconPixmap( + "edit_arrow" ), + tr( "Edit mode (select and move)" ), + NULL, NULL, m_toolBar ); + m_editModeButton->setCheckable( TRUE ); + + QButtonGroup * tool_button_group = new QButtonGroup( this ); + tool_button_group->addButton( m_drawModeButton ); + tool_button_group->addButton( m_editModeButton ); + tool_button_group->setExclusive( TRUE ); +#ifndef QT4 + tool_button_group->hide(); +#endif + - m_removeBarButton = new toolButton( embed::getIconPixmap( - "remove_bar" ), - tr( "Remove bar (Shift+Delete)" ), - this, SLOT( removeBar() ), - m_toolBar ); #ifdef QT4 #else QWhatsThis::add( m_playButton, tr( "Click here, if you want to play " @@ -354,13 +363,13 @@ songEditor::songEditor() : "song-position-marker will be " "set to the start of your song." ) ); - QWhatsThis::add( m_insertBarButton, tr( "If you click here, a " +/* QWhatsThis::add( m_insertBarButton, tr( "If you click here, a " "bar will " "be inserted at the " "current bar." ) ); QWhatsThis::add( m_removeBarButton, tr( "If you click here, the " "current bar will be " - "removed." ) ); + "removed." ) );*/ #endif @@ -368,20 +377,17 @@ songEditor::songEditor() : zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) ); // setup zooming-stuff - m_zoomingComboBox = new QComboBox( m_toolBar ); - m_zoomingComboBox->setGeometry( 580, 4, 80, 24 ); + m_zoomingComboBox = new comboBox( m_toolBar ); + m_zoomingComboBox->setFixedSize( 80, 22 ); + m_zoomingComboBox->move( 580, 4 ); for( int i = 0; i < 7; ++i ) { m_zoomingComboBox->addItem( QString::number( 25 * static_cast( powf( 2.0f, i ) ) ) + "%" ); } -#ifdef QT4 m_zoomingComboBox->setCurrentIndex( m_zoomingComboBox->findText( "100%" ) ); -#else - m_zoomingComboBox->setCurrentText( "100%" ); -#endif connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), this, SLOT( zoomingChanged( const QString & ) ) ); @@ -393,8 +399,8 @@ songEditor::songEditor() : tb_layout->addWidget( m_addBBTrackButton ); tb_layout->addWidget( m_addSampleTrackButton ); tb_layout->addSpacing( 10 ); - tb_layout->addWidget( m_insertBarButton ); - tb_layout->addWidget( m_removeBarButton ); + tb_layout->addWidget( m_drawModeButton ); + tb_layout->addWidget( m_editModeButton ); tb_layout->addSpacing( 10 ); tl->addToolButtons( m_toolBar ); tb_layout->addSpacing( 15 ); @@ -407,14 +413,14 @@ songEditor::songEditor() : m_leftRightScroll = new QScrollBar( Qt::Horizontal, cw ); m_leftRightScroll->setMinimum( 0 ); m_leftRightScroll->setMaximum( 0 ); -#ifdef QT4 +#ifndef QT3 m_leftRightScroll->setSingleStep( 1 ); m_leftRightScroll->setPageStep( 20 ); #else m_leftRightScroll->setSteps( 1, 20 ); #endif - connect( m_leftRightScroll, SIGNAL( valueChanged( int ) ), this, - SLOT( scrolled( int ) ) ); + connect( m_leftRightScroll, SIGNAL( valueChanged( int ) ), + this, SLOT( scrolled( int ) ) ); @@ -472,17 +478,31 @@ void songEditor::paintEvent( QPaintEvent * _pe ) +QRect songEditor::scrollAreaRect( void ) const +{ + if( centralWidget() == NULL ) + { + return( rect() ); + } + return( QRect( 0, 0, centralWidget()->width(), + centralWidget()->height() - m_toolBar->height() - + m_playPos[PLAY_SONG].m_timeLine->height() - + DEFAULT_SCROLLBAR_SIZE ) ); +} + + + + // responsible for moving scrollbars after resizing void songEditor::resizeEvent( QResizeEvent * _re ) { if( centralWidget() != NULL ) { m_leftRightScroll->setGeometry( 0, - centralWidget()->height() - 2 - - SCROLLBAR_SIZE, - centralWidget()->width() - - SCROLLBAR_SIZE, - SCROLLBAR_SIZE ); + centralWidget()->height() - + DEFAULT_SCROLLBAR_SIZE, + centralWidget()->width(), + DEFAULT_SCROLLBAR_SIZE ); m_playPos[PLAY_SONG].m_timeLine->setFixedWidth( centralWidget()->width() ); @@ -575,18 +595,11 @@ void songEditor::wheelEvent( QWheelEvent * _we ) { setPixelsPerTact( (int) pixelsPerTact() / 2 ); } -#ifdef QT4 // update combobox with zooming-factor m_zoomingComboBox->setCurrentIndex( m_zoomingComboBox->findText( QString::number( static_cast( pixelsPerTact() * 100 / DEFAULT_PIXELS_PER_TACT ) ) + "%" ) ); -#else - // update combobox with zooming-factor - m_zoomingComboBox->setCurrentText( QString::number( - static_cast( pixelsPerTact() * - 100 / DEFAULT_PIXELS_PER_TACT ) ) + "%" ); -#endif // update timeline m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( pixelsPerTact() ); @@ -1028,11 +1041,9 @@ void songEditor::processNextBuffer( void ) 64 / frames_per_tact) % 64 ); } - if( m_playPos[m_playMode].m_timeLine != NULL && - m_playPos[m_playMode].m_timeLineUpdate == TRUE && - m_exporting == FALSE ) + if( m_exporting == FALSE ) { - m_playPos[m_playMode].m_timeLine->updatePosition(); + updateTimeLinePosition(); } } @@ -1041,9 +1052,6 @@ void songEditor::processNextBuffer( void ) - - - void songEditor::play( void ) { if( m_playing == TRUE ) @@ -1147,7 +1155,9 @@ void songEditor::updateTimeLinePosition( void ) if( m_playPos[m_playMode].m_timeLine != NULL && m_playPos[m_playMode].m_timeLineUpdate == TRUE ) { - m_playPos[m_playMode].m_timeLine->updatePosition(); +/* QTimer::singleShot( 1, m_playPos[m_playMode].m_timeLine, + SLOT( updatePosition() ) );*/ + //m_playPos[m_playMode].m_timeLine->updatePosition(); } } diff --git a/src/core/timeline.cpp b/src/core/timeline.cpp index ee54d7bb42..07cd7b8023 100644 --- a/src/core/timeline.cpp +++ b/src/core/timeline.cpp @@ -112,10 +112,9 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt, m_pos.m_timeLine = this; - updatePosition(); QTimer * update_timer = new QTimer( this ); - connect( update_timer, SIGNAL( timeout() ), this, - SLOT( checkForUpdatedPosition() ) ); + connect( update_timer, SIGNAL( timeout() ), + this, SLOT( updatePosition() ) ); update_timer->start( 50 ); } @@ -184,6 +183,7 @@ void timeLine::updatePosition( const midiTime & ) { emit positionChanged( m_pos ); } + update(); } } @@ -215,18 +215,6 @@ void timeLine::toggleBehaviourAtStop( int _n ) -void timeLine::checkForUpdatedPosition( void ) -{ - if( m_changedPosition == TRUE ) - { - repaint(); - m_changedPosition = FALSE; - } -} - - - - void timeLine::paintEvent( QPaintEvent * ) { #ifdef QT4 diff --git a/src/core/track.cpp b/src/core/track.cpp index 935494a1e3..70effef793 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -43,9 +43,6 @@ #include #include -#define setChecked setOn -#define isChecked isOn - #endif @@ -73,6 +70,7 @@ const Sint16 RESIZE_GRIP_WIDTH = 4; const Uint16 TRACK_OP_BTN_WIDTH = 20; const Uint16 TRACK_OP_BTN_HEIGHT = 14; +const Uint16 MINIMAL_TRACK_HEIGHT = 32; textFloat * trackContentObject::s_textFloat = NULL; @@ -82,16 +80,15 @@ textFloat * trackContentObject::s_textFloat = NULL; // trackContentObject // =========================================================================== trackContentObject::trackContentObject( track * _track ) : - QWidget( _track->getTrackContentWidget() -#ifndef QT4 - , NULL, Qt::WDestructiveClose + selectableObject( _track->getTrackContentWidget() +#ifdef QT3 + , Qt::WDestructiveClose #endif ), m_track( _track ), m_startPosition(), m_length(), - m_moving( FALSE ), - m_resizing( FALSE ), + m_action( NONE ), m_autoResize( FALSE ), m_initialMouseX( 0 ) { @@ -172,9 +169,10 @@ float trackContentObject::pixelsPerTact( void ) { if( fixedTCOs() ) { - return( getTrack()->getTrackContentWidget()->width() - - 2 * TCO_BORDER_WIDTH ) / - tMax( length().getTact(), 1.0f ); + return( ( getTrack()->getTrackContentWidget()->width() - + 2 * TCO_BORDER_WIDTH - + DEFAULT_SCROLLBAR_SIZE ) / + tMax( length().getTact(), 1.0f ) ); } return( getTrack()->getTrackContainer()->pixelsPerTact() ); } @@ -229,7 +227,32 @@ void trackContentObject::leaveEvent( QEvent * _e ) void trackContentObject::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton && + if( m_track->getTrackContainer()->allowRubberband() == TRUE && + _me->button() == Qt::LeftButton ) + { + if( m_track->getTrackContainer()->rubberBandActive() == FALSE ) + { + if( lmmsMainWin::isCtrlPressed() == TRUE ) + { + setSelected( !isSelected() ); + } + else if( isSelected() == TRUE ) + { + m_action = MOVE_SELECTION; + m_initialMouseX = _me->x(); + } + } + else + { + selectableObject::mousePressEvent( _me ); + } + return; + } + else if( lmmsMainWin::isShiftPressed() == TRUE ) + { + selectableObject::mousePressEvent( _me ); + } + else if( _me->button() == Qt::LeftButton && lmmsMainWin::isCtrlPressed() == TRUE ) { multimediaProject mmp( multimediaProject::DRAG_N_DROP_DATA ); @@ -257,14 +280,14 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) if( _me->x() < width() - RESIZE_GRIP_WIDTH ) { - m_moving = TRUE; + m_action = MOVE; QCursor c( Qt::SizeAllCursor ); QApplication::setOverrideCursor( c ); s_textFloat->setTitle( tr( "Current position" ) ); } else if( m_autoResize == FALSE ) { - m_resizing = TRUE; + m_action = RESIZE; QCursor c( Qt::SizeHorCursor ); QApplication::setOverrideCursor( c ); s_textFloat->setTitle( tr( "Current length" ) ); @@ -289,9 +312,9 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) { const float ppt = m_track->getTrackContainer()->pixelsPerTact(); - if( m_moving == TRUE ) + if( m_action == MOVE ) { - int x = mapToParent( _me->pos() ).x() - m_initialMouseX; + const int x = mapToParent( _me->pos() ).x() - m_initialMouseX; movePosition( tMax( 0, (Sint32) m_track->getTrackContainer()-> currentPosition() + static_cast( x * 64 / ppt ) ) ); @@ -302,7 +325,38 @@ void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + QPoint( -2 - s_textFloat->width(), 8 ) ); } - else if( m_resizing == TRUE ) + else if( m_action == MOVE_SELECTION ) + { + const int dx = _me->x() - m_initialMouseX; + vvector so = + m_track->getTrackContainer()->selectedObjects(); + vvector tcos; + midiTime smallest_pos; + // find out smallest position of all selected objects for not + // moving an object before zero + for( vvector::iterator it = so.begin(); + it != so.end(); ++it ) + { + trackContentObject * tco = + dynamic_cast( *it ); + if( tco == NULL ) + { + continue; + } + tcos.push_back( tco ); + smallest_pos = tMin( smallest_pos, + (Sint32)tco->startPosition() + + static_cast( dx * 64 / ppt ) ); + } + for( vvector::iterator it = tcos.begin(); + it != tcos.end(); ++it ) + { + ( *it )->movePosition( ( *it )->startPosition() + + static_cast( dx * 64 / ppt ) - + smallest_pos ); + } + } + else if( m_action == RESIZE ) { changeLength( tMax( 64, static_cast( _me->x() * 64 / ppt ) ) ); @@ -344,10 +398,10 @@ void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) void trackContentObject::mouseReleaseEvent( QMouseEvent * _me ) { + m_action = NONE; s_textFloat->hide(); leaveEvent( NULL ); - m_moving = FALSE; - m_resizing = FALSE; + selectableObject::mouseReleaseEvent( _me ); } @@ -448,7 +502,6 @@ trackContentWidget::trackContentWidget( trackWidget * _parent ) : #else setPaletteBackgroundColor( QColor( 96, 96, 96 ) ); #endif - setMouseTracking( TRUE ); setAcceptDrops( TRUE ); } @@ -609,6 +662,7 @@ void trackContentWidget::updateTCOs( void ) for( tcoVector::iterator it = m_trackContentObjects.begin(); it != m_trackContentObjects.end(); ++it ) { + ( *it )->setFixedHeight( height() - 2 ); ( *it )->update(); } } @@ -638,7 +692,7 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) // value contains our XML-data so simply create a // multimediaProject which does the rest for us... multimediaProject mmp( value, FALSE ); - // at least save position before getting to moved to somewhere + // at least save position before getting moved to somewhere // the user doesn't expect... tco->loadSettings( mmp.content().firstChild().toElement() ); tco->movePosition( position ); @@ -653,7 +707,15 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) void trackContentWidget::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton && + if( getTrack()->getTrackContainer()->allowRubberband() == TRUE ) + { + QWidget::mousePressEvent( _me ); + } + else if( lmmsMainWin::isShiftPressed() == TRUE ) + { + QWidget::mousePressEvent( _me ); + } + else if( _me->button() == Qt::LeftButton && getTrack()->getTrackContainer()->fixedTCOs() == FALSE ) { const midiTime position = getPosition( _me->x() ); @@ -666,27 +728,33 @@ void trackContentWidget::mousePressEvent( QMouseEvent * _me ) -void trackContentWidget::mouseMoveEvent( QMouseEvent * _me ) +void trackContentWidget::paintEvent( QPaintEvent * _pe ) { - // if user moved TCO out of visible area, TCO doesn't receive - // mouse-events, so we have to do it here - while( QApplication::overrideCursor() != NULL ) +#ifdef QT4 + QPainter p( this ); + p.fillRect( rect(), QColor( 96, 96, 96 ) ); +#else + // create pixmap for whole widget + QPixmap pm( rect().size() ); + pm.fill( QColor( 96, 96, 96 ) ); + + // and a painter for it + QPainter p( &pm ); +#endif + const trackContainer * tc = getTrack()->getTrackContainer(); + const int offset = (int)( ( tc->currentPosition() % 4 ) * + tc->pixelsPerTact() ); + // draw vertical lines + p.setPen( QColor( 128, 128, 128 ) ); + for( int x = -offset; x < width(); x += (int) tc->pixelsPerTact() ) { - QApplication::restoreOverrideCursor(); + p.drawLine( x, 0, x, height() ); } -} - - - -void trackContentWidget::mouseReleaseEvent( QMouseEvent * _me ) -{ - // if user moved TCO out of visible area, TCO doesn't receive - // mouseRelease-events... - while( QApplication::overrideCursor() != NULL ) - { - QApplication::restoreOverrideCursor(); - } +#ifndef QT4 + // blit drawn pixmap to actual widget + bitBlt( this, rect().topLeft(), &pm ); +#endif } @@ -759,7 +827,7 @@ trackOperationsWidget::trackOperationsWidget( trackWidget * _parent ) : m_muteBtn = new pixmapButton( this ); m_muteBtn->setActiveGraphic( embed::getIconPixmap( "mute_on" ) ); m_muteBtn->setInactiveGraphic( embed::getIconPixmap( "mute_off" ) ); - m_muteBtn->move( 44, 8 ); + m_muteBtn->move( 44, 4 ); m_muteBtn->show(); connect( m_muteBtn, SIGNAL( toggled( bool ) ), this, SLOT( setMuted( bool ) ) ); @@ -814,7 +882,7 @@ void trackOperationsWidget::mousePressEvent( QMouseEvent * _me ) &m_trackWidget->getTrackSettingsWidget() ), this ); } - else if( _me->button() == Qt::LeftButton && _me->x() < 10 ) + else if( _me->button() == Qt::LeftButton ) { // track-widget (parent-widget) initiates track-move _me->ignore(); @@ -841,14 +909,8 @@ void trackOperationsWidget::paintEvent( QPaintEvent * _pe ) if( m_trackWidget->isMovingTrack() == FALSE ) { p.drawPixmap( 2, 2, *s_grip ); -/* if( m_trackOps->isVisible() == FALSE ) - {*/ - m_trackOps->show(); -/* } - if( m_muteBtn->isVisible() == FALSE ) - {*/ - m_muteBtn->show(); -// } + m_trackOps->show(); + m_muteBtn->show(); } else { @@ -895,9 +957,9 @@ void trackOperationsWidget::setMuted( bool _muted ) void trackOperationsWidget::muteBtnRightClicked( void ) { const bool m = muted(); // next function might modify our mute-state, - // so save it - m_trackWidget->getTrack()->getTrackContainer()->setMutedOfAllTracks( - m ); + // so save it now + m_trackWidget->getTrack()->getTrackContainer()-> + setMutedOfAllTracks( m ); setMuted( !m ); } @@ -916,8 +978,7 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) : m_trackOperationsWidget( this ), m_trackSettingsWidget( this ), m_trackContentWidget( this ), - m_movingTrack( FALSE ), - m_initialMouseX( -1 ) + m_action( NONE ) { #ifdef QT4 QPalette pal; @@ -937,11 +998,12 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) : m_trackSettingsWidget.setPalette( pal ); #else m_trackSettingsWidget.setPaletteBackgroundColor( QColor( 64, 64, 64 ) ); + + // set background-mode for flicker-free redraw setBackgroundMode( Qt::NoBackground ); #endif setAcceptDrops( TRUE ); - setMouseTracking( TRUE ); } @@ -954,6 +1016,15 @@ trackWidget::~trackWidget() +void trackWidget::repaint( void ) +{ + m_trackContentWidget.repaint(); + QWidget::repaint(); +} + + + + // resposible for moving track-content-widgets to appropriate position after // change of visible viewport void trackWidget::changePosition( const midiTime & _new_pos ) @@ -1022,15 +1093,30 @@ void trackWidget::dropEvent( QDropEvent * _de ) void trackWidget::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton ) + if( m_track->getTrackContainer()->allowRubberband() == TRUE ) { - m_movingTrack = TRUE; - m_initialMouseX = _me->x(); + QWidget::mousePressEvent( _me ); + } + else if( _me->button() == Qt::LeftButton ) + { + if( lmmsMainWin::isShiftPressed() == TRUE ) + { + m_action = RESIZE_TRACK; + QCursor::setPos( mapToGlobal( QPoint( _me->x(), + height() ) ) ); + QCursor c( Qt::SizeVerCursor); + QApplication::setOverrideCursor( c ); + } + else + { + m_action = MOVE_TRACK; - QCursor c( Qt::SizeAllCursor ); - QApplication::setOverrideCursor( c ); - - m_trackOperationsWidget.update(); + QCursor c( Qt::SizeAllCursor ); + QApplication::setOverrideCursor( c ); + // update because in move-mode, all elements in + // track-op-widgets are hidden as a visual feedback + m_trackOperationsWidget.update(); + } _me->accept(); } @@ -1045,7 +1131,11 @@ void trackWidget::mousePressEvent( QMouseEvent * _me ) void trackWidget::mouseMoveEvent( QMouseEvent * _me ) { - if( m_movingTrack == TRUE ) + if( m_track->getTrackContainer()->allowRubberband() == TRUE ) + { + QWidget::mouseMoveEvent( _me ); + } + else if( m_action == MOVE_TRACK ) { trackContainer * tc = m_track->getTrackContainer(); // look which track-widget the mouse-cursor is over @@ -1065,6 +1155,11 @@ void trackWidget::mouseMoveEvent( QMouseEvent * _me ) } } } + else if( m_action == RESIZE_TRACK ) + { + setFixedHeight( tMax( _me->y(), MINIMAL_TRACK_HEIGHT ) ); + m_track->getTrackContainer()->realignTracks(); + } } @@ -1072,12 +1167,14 @@ void trackWidget::mouseMoveEvent( QMouseEvent * _me ) void trackWidget::mouseReleaseEvent( QMouseEvent * _me ) { - m_movingTrack = FALSE; + m_action = NONE; while( QApplication::overrideCursor() != NULL ) { QApplication::restoreOverrideCursor(); } m_trackOperationsWidget.update(); + + QWidget::mouseReleaseEvent( _me ); } @@ -1226,6 +1323,7 @@ void FASTCALL track::saveSettings( QDomDocument & _doc, QDomElement & _parent ) QDomElement track_de = _doc.createElement( "track" ); track_de.setAttribute( "type", type() ); track_de.setAttribute( "muted", muted() ); + track_de.setAttribute( "height", m_trackWidget->height() ); _parent.appendChild( track_de ); // let actual track (channelTrack, bbTrack, sampleTrack etc.) save @@ -1275,6 +1373,12 @@ void FASTCALL track::loadSettings( const QDomElement & _this ) } node = node.nextSibling(); } + + if( _this.attribute( "height" ).toInt() >= MINIMAL_TRACK_HEIGHT ) + { + m_trackWidget->setFixedHeight( + _this.attribute( "height" ).toInt() ); + } } @@ -1376,13 +1480,6 @@ void FASTCALL track::swapPositionOfTCOs( csize _tco_num1, csize _tco_num2 ) -#ifndef QT4 - -#undef isChecked -#undef setChecked - -#endif - #include "track.moc" diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index b6458eb5b5..db5106e432 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -58,18 +58,22 @@ #include "config_mgr.h" #include "midi_file.h" #include "instrument.h" +#include "rubberband.h" trackContainer::trackContainer() : QMainWindow( lmmsMainWin::inst()->workspace() -#ifndef QT4 +#ifdef QT3 , 0, Qt::WStyle_Title #endif ), settings(), m_currentPosition( 0, 0 ), - m_ppt( DEFAULT_PIXELS_PER_TACT ) + m_scrollArea( new scrollArea( this ) ), + m_ppt( DEFAULT_PIXELS_PER_TACT ), + m_rubberBand( new rubberBand( m_scrollArea ) ), + m_origin() { #ifdef QT4 if( lmmsMainWin::inst()->workspace() != NULL ) @@ -78,8 +82,8 @@ trackContainer::trackContainer() : } #endif - m_scrollArea = new scrollArea( this ); m_scrollArea->show(); + m_rubberBand->hide(); setAcceptDrops( TRUE ); } @@ -281,23 +285,20 @@ void trackContainer::realignTracks( bool _complete_update ) for( trackWidgetVector::iterator it = m_trackWidgets.begin(); it != m_trackWidgets.end(); ++it ) { - if( _complete_update ) - { - ( *it )->hide(); - } ( *it )->show(); + ( *it )->repaint(); #ifdef QT4 ( *it )->move( 0, y ); #else m_scrollArea->moveChild( *it, 0, y ); #endif - ( *it )->resize( width(), ( *it )->height() ); + ( *it )->resize( width() - DEFAULT_SCROLLBAR_SIZE, + ( *it )->height() ); ( *it )->changePosition( m_currentPosition ); y += ( *it )->height(); } -#ifndef QT4 - m_scrollArea->resizeContents( m_scrollArea->parentWidget()->width(), - y ); +#ifdef QT3 + m_scrollArea->resizeContents( width() - DEFAULT_SCROLLBAR_SIZE, y ); #endif updateScrollArea(); } @@ -324,6 +325,14 @@ const trackWidget * trackContainer::trackWidgetAt( const int _y ) const +bool trackContainer::allowRubberband( void ) const +{ + return( FALSE ); +} + + + + unsigned int trackContainer::countTracks( track::trackTypes _tt ) const { unsigned int cnt = 0; @@ -390,14 +399,6 @@ void trackContainer::setPixelsPerTact( Uint16 _ppt ) -void trackContainer::resizeEvent( QResizeEvent * ) -{ - realignTracks(); -} - - - - void trackContainer::dragEnterEvent( QDragEnterEvent * _dee ) { stringPairDrag::processDragEnterEvent( _dee, @@ -464,13 +465,56 @@ void trackContainer::dropEvent( QDropEvent * _de ) +void trackContainer::mousePressEvent( QMouseEvent * _me ) +{ + if( allowRubberband() == TRUE ) + { + m_origin = m_scrollArea->mapFromParent( _me->pos() ); + m_rubberBand->setGeometry( QRect( m_origin, QSize() ) ); + m_rubberBand->show(); + } +} + + + + +void trackContainer::mouseMoveEvent( QMouseEvent * _me ) +{ + if( rubberBandActive() == TRUE ) + { + m_rubberBand->setGeometry( QRect( m_origin, + m_scrollArea->mapFromParent( _me->pos() ) ). + normalized() ); + } +} + + + + +void trackContainer::mouseReleaseEvent( QMouseEvent * _me ) +{ + m_rubberBand->hide(); +} + + + + + +void trackContainer::resizeEvent( QResizeEvent * ) +{ + realignTracks(); +} + + + + void trackContainer::updateScrollArea( void ) { - m_scrollArea->resize( tMax( m_scrollArea->parentWidget()->width() - + m_scrollArea->resize( width(), scrollAreaRect().height() ); +/* m_scrollArea->resize( tMax( m_scrollArea->parentWidget()->width() - m_scrollArea->x() - 2, 0 ), tMax( m_scrollArea->parentWidget()->height() - - m_scrollArea->y() - 2, 0 ) ); - //m_scrollArea->updateContents(); + m_scrollArea->y() - 2, 0 ) );*/ } @@ -486,6 +530,13 @@ trackContainer::scrollArea::scrollArea( trackContainer * _parent ) : Qt::ScrollBarAlwaysOff #else QScrollArea::AlwaysOff +#endif + ); + setVerticalScrollBarPolicy( +#ifdef QT4 + Qt::ScrollBarAlwaysOn +#else + QScrollArea::AlwaysOn #endif ); } diff --git a/src/lib/sample_buffer.cpp b/src/lib/sample_buffer.cpp index 2289e91e2d..5fb3ede856 100644 --- a/src/lib/sample_buffer.cpp +++ b/src/lib/sample_buffer.cpp @@ -1005,7 +1005,7 @@ QString sampleBuffer::openAudioFile( void ) const ofd.selectFile( QFileInfo( m_audioFile ).fileName() ); } - if ( ofd.exec () == QDialog::Accepted ) + if( ofd.exec () == QDialog::Accepted ) { if( ofd.selectedFiles().isEmpty() ) { diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index a09713c1b9..fe1a3057fd 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -1,7 +1,7 @@ /* - * bb_track.cpp - implementation of class bbTrack + * bb_track.cpp - implementation of class bbTrack and bbTCO * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -49,10 +49,11 @@ #include "name_label.h" #include "embed.h" #include "rename_dialog.h" +#include "templates.h" -QMap bbTrack::s_bbNums; +bbTrack::infoMap bbTrack::s_infoMap; bbTCO::bbTCO( track * _track, const QColor & _c ) : @@ -134,6 +135,11 @@ void bbTCO::paintEvent( QPaintEvent * ) { col = QColor( 160, 160, 160 ); } + if( isSelected() == TRUE ) + { + col = QColor( tMax( col.red() - 128, 0 ), + tMax( col.green() - 128, 0 ), 255 ); + } #ifdef QT4 QPainter p( this ); // TODO: set according brush/pen for gradient! @@ -154,10 +160,10 @@ void bbTCO::paintEvent( QPaintEvent * ) tact t = bbEditor::inst()->lengthOfBB( bbTrack::numOfBBTrack( getTrack() ) ); - if( length().getTact() > 1 && t > 0 ) + if( length() > 64 && t > 0 ) { - for( int x = TCO_BORDER_WIDTH + static_cast( t * - pixelsPerTact() ); x < width(); + for( int x = static_cast( t * pixelsPerTact() ); + x < width(); x += static_cast( t * pixelsPerTact() ) ) { p.setPen( col.light( 80 ) ); @@ -273,25 +279,33 @@ void bbTCO::changeColor( void ) -bbTrack::bbTrack( trackContainer * _tc ) - : track( _tc ) +bbTrack::bbTrack( trackContainer * _tc ) : + track( _tc ) { getTrackWidget()->setFixedHeight( 32 ); // drag'n'drop with bb-tracks only causes troubles (and makes no sense // too), so disable it getTrackWidget()->setAcceptDrops( FALSE ); - csize bbNum = s_bbNums.size(); - bbInfoStruct bis = { bbNum, "" }; - s_bbNums[this] = bis; + csize bbNum = s_infoMap.size(); + s_infoMap[this] = bbNum; + m_trackLabel = new nameLabel( tr( "Beat/Bassline %1" ).arg( bbNum ), - getTrackSettingsWidget(), - embed::getIconPixmap( "bb_track" ) ); - m_trackLabel->setGeometry( 1, 1, DEFAULT_SETTINGS_WIDGET_WIDTH-2, 29 ); + getTrackSettingsWidget() ); + m_trackLabel->setPixmap( embed::getIconPixmap( "bb_track" ) ); + m_trackLabel->setGeometry( 1, 1, DEFAULT_SETTINGS_WIDGET_WIDTH - 2, + 29 ); m_trackLabel->show(); - connect( m_trackLabel, SIGNAL( clicked() ), this, - SLOT( clickedTrackLabel() ) ); + connect( m_trackLabel, SIGNAL( clicked() ), + this, SLOT( clickedTrackLabel() ) ); + connect( m_trackLabel, SIGNAL( nameChanged() ), + bbEditor::inst(), SLOT( updateComboBox() ) ); + connect( m_trackLabel, SIGNAL( pixmapChanged() ), + bbEditor::inst(), SLOT( updateComboBox() ) ); + + bbEditor::inst()->setCurrentBB( bbNum ); + bbEditor::inst()->updateComboBox(); _tc->updateAfterTrackAdd(); } @@ -301,24 +315,24 @@ bbTrack::bbTrack( trackContainer * _tc ) bbTrack::~bbTrack() { - csize bb = s_bbNums[this].num; + csize bb = s_infoMap[this]; bbEditor::inst()->removeBB( bb ); - for( QMap::iterator it = - s_bbNums.begin(); it != s_bbNums.end(); ++it ) + for( infoMap::iterator it = s_infoMap.begin(); it != s_infoMap.end(); + ++it ) { #ifdef QT4 - if( it.value().num > bb ) + if( it.value() > bb ) { - --it.value().num; + --it.value(); } #else - if( it.data().num > bb ) + if( it.data() > bb ) { - --it.data().num; + --it.data(); } #endif } - s_bbNums.remove( this ); + s_infoMap.remove( this ); } @@ -340,7 +354,7 @@ bool FASTCALL bbTrack::play( const midiTime & _start, Uint32 _start_frame, { return( bbEditor::inst()->play( _start, _start_frame, _frames, _frame_base, - s_bbNums[this].num ) ); + s_infoMap[this] ) ); } vlist tcos; @@ -368,7 +382,7 @@ bool FASTCALL bbTrack::play( const midiTime & _start, Uint32 _start_frame, return( bbEditor::inst()->play( _start - lastPosition, _start_frame, _frames, _frame_base, - s_bbNums[this].num ) ); + s_infoMap[this] ) ); } return( FALSE ); } @@ -402,10 +416,11 @@ void bbTrack::saveTrackSpecificSettings( QDomDocument & _doc, { QDomElement bbt_de = _doc.createElement( nodeName() ); bbt_de.setAttribute( "name", m_trackLabel->text() ); -/* bbt_de.setAttribute( "current", s_bbNums[this].num == + bbt_de.setAttribute( "icon", m_trackLabel->pixmapFile() ); +/* bbt_de.setAttribute( "current", s_infoMap[this] == bbEditor::inst()->currentBB() );*/ _parent.appendChild( bbt_de ); - if( s_bbNums[this].num == 0 && + if( s_infoMap[this] == 0 && _parent.parentNode().nodeName() != "clone" ) { bbEditor::inst()->saveSettings( _doc, bbt_de ); @@ -418,6 +433,10 @@ void bbTrack::saveTrackSpecificSettings( QDomDocument & _doc, void bbTrack::loadTrackSpecificSettings( const QDomElement & _this ) { m_trackLabel->setText( _this.attribute( "name" ) ); + if( _this.attribute( "icon" ) != "" ) + { + m_trackLabel->setPixmapFile( _this.attribute( "icon" ) ); + } if( _this.firstChild().isElement() ) { bbEditor::inst()->loadSettings( @@ -428,7 +447,7 @@ void bbTrack::loadTrackSpecificSettings( const QDomElement & _this ) help at all.... if( _this.attribute( "current" ).toInt() ) { - bbEditor::inst()->setCurrentBB( s_bbNums[this].num ); + bbEditor::inst()->setCurrentBB( s_infoMap[this] ); }*/ } @@ -438,14 +457,13 @@ void bbTrack::loadTrackSpecificSettings( const QDomElement & _this ) // return pointer to bbTrack specified by _bb_num bbTrack * bbTrack::findBBTrack( csize _bb_num ) { - for( QMap::iterator it = - s_bbNums.begin(); - it != s_bbNums.end(); ++it ) + for( infoMap::iterator it = s_infoMap.begin(); it != s_infoMap.end(); + ++it ) { #ifdef QT4 - if( it.value().num == _bb_num ) + if( it.value() == _bb_num ) #else - if( it.data().num == _bb_num ) + if( it.data() == _bb_num ) #endif { return( it.key() ); @@ -461,7 +479,7 @@ csize bbTrack::numOfBBTrack( track * _track ) { if( dynamic_cast( _track ) != NULL ) { - return( s_bbNums[dynamic_cast( _track )].num ); + return( s_infoMap[dynamic_cast( _track )] ); } return( 0 ); } @@ -475,9 +493,9 @@ void bbTrack::swapBBTracks( track * _track1, track * _track2 ) bbTrack * t2 = dynamic_cast( _track2 ); if( t1 != NULL && t2 != NULL ) { - qSwap( s_bbNums[t1].num, s_bbNums[t2].num ); - bbEditor::inst()->swapBB( s_bbNums[t1].num, s_bbNums[t2].num ); - bbEditor::inst()->setCurrentBB( s_bbNums[t2].num ); + qSwap( s_infoMap[t1], s_infoMap[t2] ); + bbEditor::inst()->swapBB( s_infoMap[t1], s_infoMap[t2] ); + bbEditor::inst()->setCurrentBB( s_infoMap[t2] ); } } @@ -486,7 +504,7 @@ void bbTrack::swapBBTracks( track * _track1, track * _track2 ) void bbTrack::clickedTrackLabel( void ) { - bbEditor::inst()->setCurrentBB( s_bbNums[this].num ); + bbEditor::inst()->setCurrentBB( s_infoMap[this] ); bbEditor::inst()->show(); } diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 743edc3ddf..aa82e1f1b6 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -2,7 +2,7 @@ * pattern.cpp - implementation of class pattern which holds notes * * Copyright (c) 2004-2006 Tobias Doerffel - * Copyright (c) 2005 Danny McRae + * Copyright (c) 2005 Danny McRae * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -69,7 +69,6 @@ #include "string_pair_drag.h" -QPixmap * pattern::s_patternBg = NULL; QPixmap * pattern::s_stepBtnOn = NULL; QPixmap * pattern::s_stepBtnOverlay = NULL; QPixmap * pattern::s_stepBtnOff = NULL; @@ -78,9 +77,10 @@ QPixmap * pattern::s_frozen = NULL; - pattern::pattern ( channelTrack * _channel_track ) : trackContentObject( _channel_track ), + m_paintPixmap(), + m_needsUpdate( TRUE ), m_channelTrack( _channel_track ), m_patternType( BEAT_PATTERN ), m_name( _channel_track->name() ), @@ -98,6 +98,8 @@ pattern::pattern ( channelTrack * _channel_track ) : pattern::pattern( const pattern & _pat_to_copy ) : trackContentObject( _pat_to_copy.m_channelTrack ), + m_paintPixmap(), + m_needsUpdate( TRUE ), m_channelTrack( _pat_to_copy.m_channelTrack ), m_patternType( _pat_to_copy.m_patternType ), m_name( "" ), @@ -142,31 +144,30 @@ pattern::~pattern() void pattern::init( void ) { - if( s_patternBg == NULL ) - { - s_patternBg = new QPixmap( embed::getIconPixmap( - "pattern_bg" ) ); - } if( s_stepBtnOn == NULL ) { s_stepBtnOn = new QPixmap( embed::getIconPixmap( "step_btn_on_100" ) ); } + if( s_stepBtnOverlay == NULL ) { s_stepBtnOverlay = new QPixmap( embed::getIconPixmap( "step_btn_on_yellow" ) ); } + if( s_stepBtnOff == NULL ) { s_stepBtnOff = new QPixmap( embed::getIconPixmap( "step_btn_off" ) ); } + if( s_stepBtnOffLight == NULL ) { s_stepBtnOffLight = new QPixmap( embed::getIconPixmap( "step_btn_off_light" ) ); } + if( s_frozen == NULL ) { s_frozen = new QPixmap( embed::getIconPixmap( "frozen" ) ); @@ -174,14 +175,14 @@ void pattern::init( void ) ensureBeatNotes(); + changeLength( length() ); + #ifndef QT4 // set background-mode for flicker-free redraw setBackgroundMode( Qt::NoBackground ); #endif - setFixedHeight( s_patternBg->height() + 4 ); - changeLength( length() ); - + setFixedHeight( parentWidget()->height() - 2 ); setAutoResizeEnabled( FALSE ); toolTip::add( this, @@ -192,15 +193,6 @@ void pattern::init( void ) -void pattern::movePosition( const midiTime & _pos ) -{ - // patterns are always aligned on tact-boundaries - trackContentObject::movePosition( midiTime( _pos.getTact(), 0 ) ); -} - - - - midiTime pattern::length( void ) const { if( m_patternType == BEAT_PATTERN ) @@ -319,6 +311,10 @@ void pattern::clearNotes( void ) m_notes.clear(); checkType(); update(); + if( pianoRoll::inst()->currentPattern() == this ) + { + pianoRoll::inst()->update(); + } } @@ -474,6 +470,15 @@ void pattern::loadSettings( const QDomElement & _this ) +void pattern::update( void ) +{ + m_needsUpdate = TRUE; + changeLength( length() ); + trackContentObject::update(); +} + + + void pattern::openInPianoRoll( void ) { @@ -488,7 +493,6 @@ void pattern::openInPianoRoll( bool ) pianoRoll::inst()->setCurrentPattern( this ); pianoRoll::inst()->show(); pianoRoll::inst()->setFocus(); - return; } @@ -582,6 +586,7 @@ void pattern::unfreeze( void ) delete m_frozenPattern; m_frozenPattern = NULL; m_frozenPatternMutex.unlock(); + update(); } } @@ -870,22 +875,54 @@ void pattern::wheelEvent( QWheelEvent * _we ) void pattern::paintEvent( QPaintEvent * ) { + if( m_needsUpdate == FALSE ) + { + QPainter p( this ); + p.drawPixmap( 0, 0, m_paintPixmap ); + return; + } + changeLength( length() ); -#ifdef QT4 - QPainter p( this ); -#else - // create pixmap for whole widget - QPixmap pm( rect().size() ); + m_needsUpdate = FALSE; - // and a painter for it - QPainter p( &pm ); + if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() ) + { + m_paintPixmap = QPixmap( size() ); + } + + QPainter p( &m_paintPixmap ); +#ifdef QT4 + // TODO: gradient! +#else + for( int y = 1; y < height() / 2; ++y ) + { + const int gray = 96 - y * 192 / height(); + if( isSelected() == TRUE ) + { + p.setPen( QColor( 0, 0, 128 + gray ) ); + } + else + { + p.setPen( QColor( gray, gray, gray ) ); + } + p.drawLine( 1, y, width() - 1, y ); + } + for( int y = height() / 2; y < height() - 1; ++y ) + { + const int gray = ( y - height() / 2 ) * 192 / height(); + if( isSelected() == TRUE ) + { + p.setPen( QColor( 0, 0, 128 + gray ) ); + } + else + { + p.setPen( QColor( gray, gray, gray ) ); + } + p.drawLine( 1, y, width() - 1, y ); + } #endif - for( Sint16 x = 2; x < width() - 1; x += 2 ) - { - p.drawPixmap( x, 2, *s_patternBg ); - } p.setPen( QColor( 57, 69, 74 ) ); p.drawLine( 0, 0, width(), 0 ); p.drawLine( 0, 0, 0, height() ); @@ -896,7 +933,7 @@ void pattern::paintEvent( QPaintEvent * ) p.setPen( QColor( 0, 0, 0 ) ); p.drawRect( 1, 1, width() - 2, height() - 2 ); - float ppt = pixelsPerTact(); + const float ppt = pixelsPerTact(); if( m_patternType == pattern::MELODY_PATTERN ) { @@ -920,7 +957,7 @@ void pattern::paintEvent( QPaintEvent * ) { central_key = central_key / total_notes; - Sint16 central_y = s_patternBg->height() / 2; + Sint16 central_y = height() / 2; Sint16 y_base = central_y + TCO_BORDER_WIDTH -1; const Sint16 x_base = TCO_BORDER_WIDTH; @@ -929,12 +966,13 @@ void pattern::paintEvent( QPaintEvent * ) for( tact tact_num = 1; tact_num < length().getTact(); ++tact_num ) { - p.drawLine( x_base + static_cast( - ppt*tact_num ), - TCO_BORDER_WIDTH, - x_base + - static_cast( ppt * tact_num ), - height() - 2 * + p.drawLine( + x_base + static_cast( + ppt * tact_num ) - 1, + TCO_BORDER_WIDTH, + x_base + static_cast( + ppt * tact_num ) - 1, + height() - 2 * TCO_BORDER_WIDTH ); } if( getTrack()->muted() ) @@ -973,42 +1011,42 @@ void pattern::paintEvent( QPaintEvent * ) } } else if( m_patternType == pattern::BEAT_PATTERN && - ( ppt >= 192 || m_steps != DEFAULT_STEPS_PER_TACT ) ) + ( ppt >= 96 || m_steps != DEFAULT_STEPS_PER_TACT ) ) { QPixmap stepon; QPixmap stepoverlay; QPixmap stepoff; QPixmap stepoffl; - int steps = length() / BEATS_PER_TACT; - + const int steps = length() / BEATS_PER_TACT; + const int w = width() - 2 * TCO_BORDER_WIDTH; #ifdef QT4 - stepon = s_stepBtnOn->scaled( width() / steps, + stepon = s_stepBtnOn->scaled( w / steps, s_stepBtnOn->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); - stepoverlay = s_stepBtnOverlay->scaled( width() / steps, + stepoverlay = s_stepBtnOverlay->scaled( w / steps, s_stepBtnOn->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); - stepoff = s_stepBtnOff->scaled( width() / steps, + stepoff = s_stepBtnOff->scaled( w / steps, s_stepBtnOff->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); - stepoffl = s_stepBtnOffLight->scaled( width() / steps, + stepoffl = s_stepBtnOffLight->scaled( w / steps, s_stepBtnOffLight->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); #else stepon.convertFromImage( s_stepBtnOn->convertToImage().scale( - width() / steps, s_stepBtnOn->height() ) ); + w / steps, s_stepBtnOn->height() ) ); stepoverlay.convertFromImage( s_stepBtnOverlay->convertToImage().scale( - width() / steps, s_stepBtnOverlay->height() ) ); + w / steps, s_stepBtnOverlay->height() ) ); stepoff.convertFromImage( s_stepBtnOff->convertToImage().scale( - width() / steps, s_stepBtnOff->height() ) ); + w / steps, s_stepBtnOff->height() ) ); stepoffl.convertFromImage( s_stepBtnOffLight->convertToImage(). - scale( width() / steps, + scale( w / steps, s_stepBtnOffLight->height() ) ); #endif for( noteVector::iterator it = m_notes.begin(); @@ -1016,7 +1054,7 @@ void pattern::paintEvent( QPaintEvent * ) { Sint16 no = it - m_notes.begin(); Sint16 x = TCO_BORDER_WIDTH + static_cast( no * - width() / steps ); + w / steps ); Sint16 y = height() - s_stepBtnOff->height() - 1; Uint8 vol = ( *it )->getVolume(); @@ -1055,10 +1093,11 @@ void pattern::paintEvent( QPaintEvent * ) p.drawPixmap( 3, height() - s_frozen->height() - 4, *s_frozen ); } -#ifndef QT4 - // blit drawn pixmap to actual widget - bitBlt( this, rect().topLeft(), &pm ); -#endif + p.end(); + + p.begin( this ); + p.drawPixmap( 0, 0, m_paintPixmap ); + } @@ -1223,6 +1262,7 @@ patternFreezeThread::patternFreezeThread( pattern * _pattern ) : patternFreezeThread::~patternFreezeThread() { + m_pattern->update(); } diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index 48c88110a9..c1785a5325 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -2,7 +2,7 @@ * sample_track.cpp - implementation of class sampleTrack, a track which * provides arrangement of samples * - * Copyright (c) 2005 Tobias Doerffel + * Copyright (c) 2005-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -186,17 +186,29 @@ void sampleTCO::paintEvent( QPaintEvent * ) { #ifdef QT4 QPainter p( this ); + // TODO: set according brush/pen for gradient! + p.fillRect( rect(), QColor( 64, 64, 64 ) ); #else // create pixmap for whole widget QPixmap pm( size() ); // and a painter for it QPainter p( &pm ); -#endif - QPixmap bg = embed::getIconPixmap( "sample_track_bg" ); - for( Sint16 x = 1; x < width() - 1; x += 10 ) + + for( int y = 1; y < height() - 1; ++y ) { - p.drawPixmap( x, 1, bg ); + const int gray = 96 - y * 96 / height(); + if( isSelected() == TRUE ) + { + p.setPen( QColor( 0, 0, 128 + gray ) ); + } + else + { + p.setPen( QColor( gray, gray, gray ) ); + } + p.drawLine( 1, y, width() - 1, y ); } +#endif + p.setPen( QColor( 0, 0, 0 ) ); p.drawRect( 0, 0, width(), height() ); if( getTrack()->muted() ) @@ -348,9 +360,8 @@ sampleTrack::sampleTrack( trackContainer * _tc ) : getTrackWidget()->setFixedHeight( 32 ); m_trackLabel = new nameLabel( tr( "Sample track" ), - getTrackSettingsWidget(), - embed::getIconPixmap( - "sample_track" ) ); + getTrackSettingsWidget() ); + m_trackLabel->setPixmap( embed::getIconPixmap( "sample_track" ) ); m_trackLabel->setGeometry( 1, 1, DEFAULT_SETTINGS_WIDGET_WIDTH-2, 29 ); m_trackLabel->show(); @@ -438,6 +449,7 @@ void sampleTrack::saveTrackSpecificSettings( QDomDocument & _doc, { QDomElement st_de = _doc.createElement( nodeName() ); st_de.setAttribute( "name", m_trackLabel->text() ); + st_de.setAttribute( "icon", m_trackLabel->pixmapFile() ); _parent.appendChild( st_de ); } @@ -447,6 +459,10 @@ void sampleTrack::saveTrackSpecificSettings( QDomDocument & _doc, void sampleTrack::loadTrackSpecificSettings( const QDomElement & _this ) { m_trackLabel->setText( _this.attribute( "name" ) ); + if( _this.attribute( "icon" ) != "" ) + { + m_trackLabel->setPixmapFile( _this.attribute( "icon" ) ); + } } diff --git a/src/widgets/combobox.cpp b/src/widgets/combobox.cpp new file mode 100644 index 0000000000..433e508c9c --- /dev/null +++ b/src/widgets/combobox.cpp @@ -0,0 +1,294 @@ +/* + * combobox.cpp - implementation of LMMS-combobox + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#include "combobox.h" +#include "templates.h" +#include "embed.h" +#include "gui_templates.h" + +#ifndef QT3 + +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + + +QPixmap * comboBox::s_background = NULL; +QPixmap * comboBox::s_arrow = NULL; + +const int CB_ARROW_BTN_WIDTH = 20; + + +comboBox::comboBox( QWidget * _parent ) : + QWidget( _parent ), + m_menu( this ), + m_currentIndex( 0 ), + m_pressed( FALSE ) +{ + if( s_background == NULL ) + { + s_background = new QPixmap( embed::getIconPixmap( + "combobox_bg" ) ); + } + + if( s_arrow == NULL ) + { + s_arrow = new QPixmap( embed::getIconPixmap( + "combobox_arrow" ) ); + } + + setFont( pointSize<8>( font() ) ); + m_menu.setFont( pointSize<8>( m_menu.font() ) ); + +#ifndef QT3 + connect( &m_menu, SIGNAL( triggered( QAction * ) ), + this, SLOT( setItem( QAction * ) ) ); +#else + connect( &m_menu, SIGNAL( activated( int ) ), + this, SLOT( setItem( int ) ) ); +#endif + +#ifdef QT3 + setBackgroundMode( NoBackground ); +#endif +} + + + + +comboBox::~comboBox() +{ +} + + + + +void comboBox::addItem( const QString & _item, const QPixmap & _pixmap ) +{ + QPixmap pm = _pixmap; + if( pm.height() > 16 ) + { +#ifndef QT3 + pm = pm.scaledToHeight( 16, Qt::SmoothTransformation ); +#else + pm.convertFromImage( pm.convertToImage().smoothScale( + pm.width(), 16, + QImage::ScaleMin ) ); +#endif + } + m_items.push_back( qMakePair( _item, pm ) ); + m_menu.clear(); + for( vvector::iterator it = m_items.begin(); + it != m_items.end(); ++it ) + { + m_menu.addItem( ( *it ).second, ( *it ).first + // when using Qt3, we pass item-index as id for using + // it in setItem( int ) as index +#ifdef QT3 + , it - m_items.begin() +#endif + ); + } +} + + + + +int comboBox::findText( const QString & _txt ) const +{ + for( vvector::const_iterator it = m_items.begin(); + it != m_items.end(); ++it ) + { + if( ( *it ).first == _txt ) + { + return( it - m_items.begin() ); + } + } + return( -1 ); +} + + + + +void comboBox::setCurrentIndex( int _idx ) +{ + m_currentIndex = tLimit( _idx, 0, ( m_items.size() > 0 ) ? + m_items.size() - 1 : 0 ); + emit( currentIndexChanged( m_currentIndex ) ); + emit( activated( ( m_items.size() > 0 ) ? + m_items[m_currentIndex].first : "" ) ); + update(); +} + + + + +void comboBox::mousePressEvent( QMouseEvent * _me ) +{ + if( _me->x() > width() - CB_ARROW_BTN_WIDTH ) + { + m_pressed = TRUE; + update(); + + QPoint gpos = mapToGlobal( QPoint( 0, height() ) ); + if( gpos.y() + m_menu.sizeHint().height() < + qApp->desktop()->height() ) + { + m_menu.exec( gpos ); + } + else + { + m_menu.exec( mapToGlobal( QPoint( width(), 0 ) ) ); + } + m_pressed = FALSE; + update(); + } + else if( _me->button() == Qt::LeftButton ) + { + setCurrentIndex( currentIndex() + 1 ); + } + else if( _me->button() == Qt::RightButton ) + { + setCurrentIndex( currentIndex() - 1 ); + } +} + + + + +void comboBox::paintEvent( QPaintEvent * _pe ) +{ +#ifndef QT3 + QPainter p( this ); +#else + QPixmap draw_pm( rect().size() ); + QPainter p( &draw_pm, this ); +#endif + p.fillRect( rect(), QColor( 0, 0, 0 ) ); + + for( int x = 2; x < width() - 2; x += s_background->width() ) + { + p.drawPixmap( x, 2, *s_background ); + } + + p.setPen( QColor( 0, 0, 0 ) ); + p.drawLine( width() - 2, 1, width() - 2, height() - 2 ); + + // outer rect + p.setPen( QColor( 64, 64, 64 ) ); + p.drawRect( 0, 0, width(), height() ); + + // button-separator + p.setPen( QColor( 64, 64, 64 ) ); + p.drawLine( width() - CB_ARROW_BTN_WIDTH - 1, 0, width() - + CB_ARROW_BTN_WIDTH - 1, height() - 2 ); + p.setPen( QColor( 0, 0, 0 ) ); + p.drawLine( width() - CB_ARROW_BTN_WIDTH, 0, width() - + CB_ARROW_BTN_WIDTH, height() - 2 ); + + // brighter line at bottom/right + p.setPen( QColor( 160, 160, 160 ) ); + p.drawLine( width() - 1, 0, width() - 1, height() - 1 ); + p.drawLine( 0, height() - 1, width() - 1, height() - 1 ); + + const int dxy = ( m_pressed == TRUE ) ? 1 : 0; + p.drawPixmap( width() - CB_ARROW_BTN_WIDTH + 4 + dxy, 4 + dxy, + *s_arrow ); + + if( m_items.size() > 0 ) + { + p.setPen( QColor( 224, 224, 224 ) ); + p.setFont( font() ); + p.setClipRect( QRect( 5, 2, width() - CB_ARROW_BTN_WIDTH - 8, + height() - 2 ) ); + const QPixmap & item_pm = m_items[currentIndex()].second; + int tx = 4; + if( item_pm.isNull() == FALSE ) + { + p.drawPixmap( tx, 3, item_pm ); + tx += item_pm.width() + 2; + } + p.drawText( tx, p.fontMetrics().height(), + m_items[currentIndex()].first ); + } + +#ifdef QT3 + // and blit all the drawn stuff on the screen... + bitBlt( this, rect().topLeft(), &draw_pm ); +#endif +} + + + + +void comboBox::wheelEvent( QWheelEvent * _we ) +{ + setCurrentIndex( currentIndex() + ( ( _we->delta() < 0 ) ? 1 : -1 ) ); + _we->accept(); +} + + + +#ifndef QT3 + +void comboBox::setItem( QAction * _item ) +{ + setCurrentIndex( findText( _item->text() ) ); +} + + +void comboBox::setItem( int ) +{ +} + +#else + +void comboBox::setItem( QAction * ) +{ +} + + +void comboBox::setItem( int _item ) +{ + setCurrentIndex( _item ); +} + + +#endif + + + +#include "combobox.moc" + diff --git a/src/widgets/pixmap_button.cpp b/src/widgets/pixmap_button.cpp index 69f83b6332..f6401c2be9 100644 --- a/src/widgets/pixmap_button.cpp +++ b/src/widgets/pixmap_button.cpp @@ -88,11 +88,7 @@ void pixmapButton::paintEvent( QPaintEvent * ) p.drawPixmap( 0, 0, *m_bgPixmap ); } -#ifdef QT4 if( isChecked() || isDown() ) -#else - if( isOn() || isDown() ) -#endif { if( m_activePixmap != NULL ) { diff --git a/src/widgets/rubberband.cpp b/src/widgets/rubberband.cpp new file mode 100644 index 0000000000..5f5b7da911 --- /dev/null +++ b/src/widgets/rubberband.cpp @@ -0,0 +1,153 @@ +/* + * rubberband.cpp - rubberband - either own implementation for Qt3 or wrapper + * for Qt4 + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#include "rubberband.h" + +#ifdef QT3 + +#include +#include +#include +#include + +#endif + + + +rubberBand::rubberBand( QWidget * _parent ) : +#ifndef QT3 + QRubberBand( Rectangle, _parent ) +#else + QWidget( _parent ) +#endif +{ +#ifdef QT3 + setBackgroundColor( QColor( 0, 64, 255 ) ); +#endif +} + + + + +rubberBand::~rubberBand() +{ +} + + + + +vvector rubberBand::selectedObjects( void ) const +{ + vvector so = selectableObjects(); + for( vvector::iterator it = so.begin(); + it != so.end(); ) + { + if( ( *it )->isSelected() == FALSE ) + { + so.erase( it ); + } + else + { + ++it; + } + } + return( so ); +} + + + + +void rubberBand::resizeEvent( QResizeEvent * _re ) +{ + rubberBandBase::resizeEvent( _re ); +#ifdef QT3 + updateMask(); +#endif + vvector so = selectableObjects(); + for( vvector::iterator it = so.begin(); + it != so.end(); ++it ) + { + ( *it )->setSelected( QRect( pos(), size() ).intersects( + QRect( ( *it )->mapTo( parentWidget(), + QPoint() ), + ( *it )->size() ) ) ); + } +} + + + + +#ifdef QT3 + +bool rubberBand::event( QEvent * _e ) +{ + bool ret = QWidget::event( _e ); + if( isVisible() == TRUE ) + { + raise(); + } + return( ret ); +} + + + + +void rubberBand::updateMask( void ) +{ + QBitmap rb_mask( size(), TRUE ); + QPainter p( &rb_mask ); + p.setPen( Qt::color1 ); + p.drawRect( 0, 0, width() - 1, height() - 1 ); + p.end(); + setMask( rb_mask ); +} + +#endif + + + + +vvector rubberBand::selectableObjects( void ) const +{ + vvector so; + if( parentWidget() == NULL ) + { + return( so ); + } + QObjectList * l = parentWidget()->queryList( "selectableObject" ); + for( QObjectListIt it = *l; it.current() != NULL; ++it ) + { + so.push_back( static_cast( *it ) ); + } + delete l; + return( so ); +} + + + + +#include "rubberband.moc" + diff --git a/src/widgets/tab_bar.cpp b/src/widgets/tab_bar.cpp index da87deccf5..90ae6c84c6 100644 --- a/src/widgets/tab_bar.cpp +++ b/src/widgets/tab_bar.cpp @@ -1,7 +1,7 @@ /* * tab_bar.cpp - implementation of tab-bar * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -31,8 +31,6 @@ #ifndef QT4 #define value data -#define setChecked setOn -#define isChecked isOn #define removeWidget remove #endif @@ -256,8 +254,6 @@ bool tabBar::allHidden( void ) #undef value -#undef setChecked -#undef isChecked #undef removeWidget