From 5e6a719b7c42302910f575e7f67e2388d55fe2e3 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Mon, 19 Dec 2005 12:17:23 +0000 Subject: [PATCH] drag'n'drop-support everywhere git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@38 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 100 ++ Makefile.am | 2 +- TODO | 6 +- acinclude.m4 | 9 - configure.in | 51 +- include/bb_editor.h | 2 + include/bb_track.h | 2 +- include/envelope_and_lfo_widget.h | 20 +- include/file_browser.h | 59 +- include/kmultitabbar.h | 1 - include/ladspa_manager.h | 99 +- include/mmp.h | 4 +- include/oscillator.h | 36 +- include/pattern.h | 31 +- include/piano_roll.h | 4 - include/pixmap_button.h | 10 +- include/sample_buffer.h | 7 +- include/sample_track.h | 9 +- include/song_editor.h | 21 +- include/string_pair_drag.h | 2 +- include/text_float.h | 2 + include/timeline.h | 6 + include/track.h | 66 +- include/track_container.h | 2 +- .../audio_file_processor.cpp | 34 + .../audio_file_processor.h | 4 +- plugins/vestige/Makefile.am | 2 +- resources/hint.png | Bin 0 -> 1116 bytes resources/midi_file.png | Bin 0 -> 1307 bytes src/core/bb_editor.cpp | 12 + src/core/envelope_and_lfo_widget.cpp | 314 +++-- src/core/file_browser.cpp | 443 ++++--- src/core/mixer.cpp | 2 +- src/core/name_label.cpp | 2 +- src/core/note_play_handle.cpp | 2 +- src/core/piano_roll.cpp | 32 +- src/core/plugin.cpp | 71 +- src/core/plugin_browser.cpp | 4 +- src/core/song_editor.cpp | 99 +- src/core/timeline.cpp | 71 +- src/core/track.cpp | 460 +++++-- src/core/track_container.cpp | 31 +- src/lib/ladspa_manager.cpp | 420 ++++--- src/lib/mmp.cpp | 42 +- src/lib/sample_buffer.cpp | 176 ++- src/lib/string_pair_drag.cpp | 9 +- src/tracks/bb_track.cpp | 9 +- src/tracks/pattern.cpp | 1074 +++++++++-------- src/tracks/sample_track.cpp | 98 +- src/widgets/kmultitabbar.cpp | 3 +- src/widgets/text_float.cpp | 61 +- 51 files changed, 2492 insertions(+), 1534 deletions(-) create mode 100644 resources/hint.png create mode 100644 resources/midi_file.png diff --git a/ChangeLog b/ChangeLog index c45454b12..1f93ca95f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,103 @@ +2005-12-18 Tobias Doerffel + + * src/tracks/pattern.cpp: + use Sint32 instead of Sint16 for determining central key, otherwise we + might get overflows when having a lot of notes + + * src/tracks/sample_track.cpp: + draw zero-line if sample is shorter than TCO + + * src/core/track.cpp: + display text-float with current position/size when moving/resizing TCO + + * src/core/song_editor.cpp: + do correct positioning for text-floats for master-volume/-pitch + + * include/envelope_and_lfo_widget.h: + * src/core/envelope_and_lfo_widget.cpp: + added support for user-defined wave-shapes - the user just has to drag + an audio-sample into envelope/lfo-widget and that's all ;-) + + * src/tracks/pattern.cpp: + * src/tracks/sample_track.cpp: + make sound-buffer of frozen pattern draggable to sample in + sample-track + + * include/sample_buffer.h: + * src/lib/sample_buffer.cpp: + support for base64-encoding of sample-data into a QString + + * src/core/track_container.cpp: + import MIDI-file to itself when getting according drag'n'drop-request + + * plugins/audio_file_processor/audio_file_processor.h: + * plugins/audio_file_processor/audio_file_processor.cpp: + receive drop-events (set dragged sample etc.) + + * plugins/vestige/fstclient.h: + * plugins/vestige/fstclient.cpp: + renamed removeVSTPlugin::write/readValue to write/readValueS for + compiling even with buggy GCC 3.x + + * include/file_browser.h: + * src/core/file_browser.cpp: + made up all that drag'n'drop-stuff, you're now able to drag samples + and presets directly to according channel, sample etc. + +2005-12-17 Tobias Doerffel + + * include/bb_editor.h: + * include/pattern.h: + * src/core/bb_editor.cpp: + * src/tracks/pattern.cpp: + always update according bb-tracks when changing pattern/it's length + + * include/track.h: + * src/core/track.cpp: + * src/core/track_container.cpp: + drag'n'drop everywhere - now you can drag every track-content-object + (e.g. a pattern) to every other track-content-object of the same type + or to a free place in an according track or just in another + track-container + + * include/mmp.h: + * src/lib/mmp.cpp: + allow additionally to load data from given string instead of file + + * include/timeline.h: + * src/core/timeline.cpp: + - disable magnetic loop-points when pressing control + - set start-point directly to given position when pressing middle + mouse-button, do the same for end-point of shift is pressed at the + same time + + * include/piano_roll.h: + * include/song_editor.h: + * src/core/piano_roll.cpp: + * src/core/song_editor.cpp: + use modifier-key-states from lmmsMainWin instead of monitoring them on + it's own + + * include/lmms_main_win.h: + * src/core/lmms_main_win.cpp: + capture key-events and save states of shift, control- and alt-key + everytime it changes - other widgets can use this for querying whether + one of these modifier-keys is pressed + +2005-12-16 Tobias Doerffel + + * configure.in: + added better LADSPA-check and fixed some other small things + + * src/core/mixer.cpp: + query attribute "mididev" instead of "midiclient" for determining + selected MIDI-device - fixes bug with apparently non-selectable + MIDI-device/-client + + * src/core/plugin.cpp: + * src/lib/ladspa_manager.cpp: + load plugins using QLibrary instead of platform-dependent dl-functions + 2005-12-15 Tobias Doerffel * include/audio_alsa.h: diff --git a/Makefile.am b/Makefile.am index 4d565b15f..7ed930f04 100644 --- a/Makefile.am +++ b/Makefile.am @@ -280,7 +280,7 @@ lmms_SOURCES = \ -EXTRA_DIST = $(lmms_EMBEDDED_RESOURCES) +EXTRA_DIST = $(lmms_EMBEDDED_RESOURCES) aeffectx_h_fix.patch CLEANFILES = $(lmms_MOC) ./embedded_resources.h diff --git a/TODO b/TODO index 221aeab00..ad63cfa1c 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,16 @@ to be done as soon as possible: +- MIDI-program/MIDI-mapping/process program-/channel-change-events from MIDI-files - do not allow to connect output-port of channel to own input-port! - add note-len- and note-alignment-selectbox to piano-roll - fix audio/midi-settings stuff/translation - tooltips for controls in MIDI-tab -- sample-track: sane bg and wave-color -- dnd everywhere: presets, samples (afp/sample-track), TCO's, knob-values +- dnd: knob-values - DSSI-support - save/load parameters of VST-plugin - somehow avoid hidden plugin-descriptor-widgets plugin-browser if height of window is too small -> add scrollbar - use drawLineF() for drawing notes in pattern::paintEvent() in qt4-version - only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc. -- use midi-maps -- process program-/channel-change-events from MIDI-files - pre-listen when opening sample with QFileDialog - level-meters in output-graph and channel-track - panning-editing in piano-roll diff --git a/acinclude.m4 b/acinclude.m4 index 604d5f4d6..c5ca4133e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -265,12 +265,3 @@ AC_SUBST(QASSISTANTCLIENT_LDADD) ]) - -dnl **** Link C code with an assembly file **** -dnl -dnl Usage: WINE_TRY_ASM_LINK(asm-code,includes,function,[action-if-found,[action-if-not-found]]) -dnl -AC_DEFUN([WINE_TRY_ASM_LINK], -[AC_TRY_LINK([void ac_asm(void) { asm([$1]); } -[$2]],[$3],[$4],[$5])]) - diff --git a/configure.in b/configure.in index 751f0d0a7..eea727eb6 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.1-cvs20051215, tobydox/at/users.sourceforge.net) -AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051215) +AC_INIT(lmms, 0.1.1-cvs20051218, tobydox/at/users.sourceforge.net) +AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051218) AM_CONFIG_HEADER(config.h) @@ -22,7 +22,7 @@ gw_CHECK_QT # checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h dlfcn.h ladspa.h pthread.h sys/ipc.h sys/shm.h sys/time.h sys/select.h sys/types.h stdarg.h]) +AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h pthread.h sys/ipc.h sys/shm.h sys/time.h sys/select.h sys/types.h stdarg.h]) # checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -156,7 +156,7 @@ fi AM_CONDITIONAL(HAVE_LIBJACK, test ! -z "$HAVE_JACK_JACK_H") -# check for proper wine-installation and existing Steinberg headers +# check for proper WINE-installation and existing Steinberg headers AC_ARG_WITH(vst, AS_HELP_STRING([--with-vst], [enable support for builtin VST-plugin-hosting]), [ with_vst=yes ], [ with_vst=no ]) @@ -177,6 +177,20 @@ fi AM_CONDITIONAL(VST_SUPPORT, test ! -z "$WINEGCC") +# check for LADSPA-SDK +AC_ARG_WITH(src, + AS_HELP_STRING([--without-ladspa], + [disable support for LADSPA-support]), , + [ with_ladspa=yes ]) +AH_TEMPLATE(HAVE_LADSPA_H, [Define to 1 if you have the header file.]) +if test "x$with_ladspa" = "xyes" ; then + AC_CHECK_HEADER(ladspa.h, HAVE_LADSPA_H="true") +fi +if test ! -z "$HAVE_LADSPA_H" ; then + AC_DEFINE(HAVE_LADSPA_H) +fi + + # check for vorbis-lib AC_ARG_WITH(vorbis, AS_HELP_STRING([--without-vorbis], @@ -201,7 +215,7 @@ AM_CONDITIONAL(HAVE_LIBVORBIS, test ! -z "$OGG_SUPPORT") # check for libsamplerate -AC_ARG_WITH(src, +AC_ARG_WITH(libsrc, AS_HELP_STRING([--without-libsrc], [disable support for resampling via libsamplerate]), , [ with_libsrc=yes ]) @@ -217,7 +231,7 @@ AM_CONDITIONAL(HAVE_LIBSRC, test ! -z "$HAVE_SAMPLERATE_H") # libsndfile-stuff -AC_ARG_WITH(src, +AC_ARG_WITH(sndfile, AS_HELP_STRING([--without-libsf], [disable support for importing files via libsndfile]), , [ with_libsf=yes ]) @@ -364,7 +378,7 @@ lmmsdatadir="$datadir/$PACKAGE" AC_SUBST(lmmsdatadir) -CXXFLAGS="$CXXFLAGS -g0" +# CXXFLAGS="$CXXFLAGS -g0" if test $CXX == "g++" ; then CXXFLAGS="$CXXFLAGS -ansi -Wall -fno-exceptions" fi @@ -542,6 +556,24 @@ fi +# not yet... +#if test -z "$HAVE_LADSPA_H" ; then +# echo " ========================" +# echo " === LMMS - WARNING =======================================================" +# echo " ========================" +# echo " =" +# echo " = You don't seem to have installed LADSPA-SDK which is neccessary for" +# echo " = building LMMS with LADSPA support. LADSPA-support is very useful" +# echo " = as you're able to use a lot of LADSPA-effects inside LMMS." +# echo " = Consider installing the missing packages for using the full power of LMMS." +# echo " =" +# with_warnings="true" +#else +# PLUGINS_TO_BUILD="$PLUGINS_TO_BUILD\n\t\* LADSPA-plugins" +#fi + + + if test -z "$HAVE_SAMPLERATE_H" ; then echo " ========================" @@ -585,7 +617,8 @@ else echo " =" echo " = ftp://ext2asio:sdk1ext@ftp.pinnaclesys.com/SDK" echo " =" - echo " = and put the mentioned files into /usr/include/vst." + echo " = and put the mentioned files into /usr/include/vst. Make sure, they're" + echo " = patched with file aeffectx_h_fix.patch!" echo " = Otherwise (now!) configure will disable LMMS's support for built-in VST-" echo " = plugin-usage. If you do not intend to use VST-plugins with LMMS you can " echo " = ignore this warning." @@ -601,7 +634,7 @@ else echo " ========================" echo " =" echo " = You don't seem to have installed WINE or it's development-packages (headers," - echo " = (winegcc etc.) which is neccessary for building LMMS with built-in" + echo " = winegcc etc.) which are neccessary for building LMMS with built-in" echo " = VST-support." echo " = If you do not intend to use VST-plugins with LMMS you can ignore this " echo " = warning." diff --git a/include/bb_editor.h b/include/bb_editor.h index 13c28fe38..ca7188613 100644 --- a/include/bb_editor.h +++ b/include/bb_editor.h @@ -82,6 +82,8 @@ public: void FASTCALL swapBB( csize _bb1, csize _bb2 ); + void updateBBTrack( trackContentObject * _tco ); + protected: virtual void closeEvent( QCloseEvent * _ce ); diff --git a/include/bb_track.h b/include/bb_track.h index bd7075270..0c1f85a23 100644 --- a/include/bb_track.h +++ b/include/bb_track.h @@ -101,7 +101,7 @@ public: bbTrack( trackContainer * _tc ); virtual ~bbTrack(); - virtual trackTypes trackType( void ) const; + virtual trackTypes type( void ) const; virtual bool FASTCALL play( const midiTime & _start, Uint32 _start_frame, Uint32 _frames, Uint32 _frame_base, diff --git a/include/envelope_and_lfo_widget.h b/include/envelope_and_lfo_widget.h index ece8c9139..80070dbe2 100644 --- a/include/envelope_and_lfo_widget.h +++ b/include/envelope_and_lfo_widget.h @@ -48,10 +48,12 @@ #include "settings.h" #include "types.h" #include "spc_bg_hndl_widget.h" +#include "sample_buffer.h" class QPaintEvent; class QPixmap; + class envelopeTabWidget; class knob; class ledCheckBox; @@ -59,6 +61,7 @@ class pixmapButton; class tempoSyncKnob; + class envelopeAndLFOWidget : public QWidget, public settings, public specialBgHandlingWidget { @@ -97,8 +100,10 @@ public slots: protected: - void paintEvent( QPaintEvent * _pe ); - void mousePressEvent( QMouseEvent * _me ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void paintEvent( QPaintEvent * _pe ); float FASTCALL lfoLevel( Uint32 _frame, Uint32 _frame_offset ) const; @@ -109,10 +114,14 @@ protected slots: void lfoTriangleWaveCh( bool ); void lfoSawWaveCh( bool ); void lfoSquareWaveCh( bool ); + void lfoUserWaveCh( bool ); void x100Toggled( bool ); private: + static QPixmap * s_envGraph; + static QPixmap * s_lfoGraph; + static Uint32 s_lfoFrame; bool m_used; @@ -125,7 +134,6 @@ private: knob * m_sustainKnob; knob * m_releaseKnob; knob * m_amountKnob; - static QPixmap * s_envGraph; float m_sustainLevel; float m_amount; @@ -145,7 +153,7 @@ private: pixmapButton * m_triangleLfoBtn; pixmapButton * m_sawLfoBtn; pixmapButton * m_sqrLfoBtn; - static QPixmap * s_lfoGraph; + pixmapButton * m_usrLfoBtn; ledCheckBox * m_x100Cb; ledCheckBox * m_controlEnvAmountCb; @@ -156,13 +164,15 @@ private: float m_lfoAmount; bool m_lfoAmountIsZero; float * m_lfoShapeData; + sampleBuffer m_userWave; enum lfoShapes { SIN, TRIANGLE, SAW, - SQUARE + SQUARE, + USER } m_lfoShape; volatile bool m_busy; diff --git a/include/file_browser.h b/include/file_browser.h index 384e8a1ce..25a90a650 100644 --- a/include/file_browser.h +++ b/include/file_browser.h @@ -50,9 +50,11 @@ class fileItem; -class trackContainer; -class QPixmap; +class listView; class playHandle; +class QPixmap; +class trackContainer; + class fileBrowser : public sideBarWidget @@ -69,52 +71,61 @@ public slots: void reloadTree( void ); -protected: - void keyPressEvent( QKeyEvent * _ke ); - - protected slots: #ifdef QT4 - void itemPressed( int btn, Q3ListViewItem * _i, const QPoint & _pos, - int _col ); - void itemReleased( int btn, Q3ListViewItem * _i, const QPoint & _pos, - int _col ); - void itemDoubleClicked( Q3ListViewItem * _i, const QPoint & _pos, - int _col ); void contextMenuRequest( Q3ListViewItem * _i, const QPoint & _pos, int _col ); #else - void itemPressed( int btn, QListViewItem * _i, const QPoint & _pos, - int _col ); - void itemReleased( int btn, QListViewItem * _i, const QPoint & _pos, - int _col ); - void itemDoubleClicked( QListViewItem * _i, const QPoint & _pos, - int _col ); void contextMenuRequest( QListViewItem * _i, const QPoint & _pos, int _col ); #endif - void selectionChanged( void ); void sendToActiveChannel( void ); void openInNewChannelSE( void ); void openInNewChannelBBE( void ); - void renameItem( void ); private: + virtual void keyPressEvent( QKeyEvent * _ke ); void openInNewChannel( trackContainer * _tc ); - Q3ListView * m_l; + listView * m_l; fileItem * m_contextMenuItem; QString m_path; QString m_filter; + +} ; + + + + +class listView : public Q3ListView +{ + Q_OBJECT +public: + listView( QWidget * _parent ); + ~listView(); + + +protected: + virtual void contentsMouseDoubleClickEvent( QMouseEvent * _me ); + virtual void contentsMousePressEvent( QMouseEvent * _me ); + virtual void contentsMouseMoveEvent( QMouseEvent * _me ); + virtual void contentsMouseReleaseEvent( QMouseEvent * _me ); + + +private: + bool m_mousePressed; + QPoint m_pressPos; + playHandle * m_previewPlayHandle; } ; + class directory : public Q3ListViewItem { public: @@ -159,6 +170,7 @@ private: + class fileItem : public Q3ListViewItem { public: @@ -178,7 +190,7 @@ public: enum fileTypes { - SONG_FILE, PRESET_FILE, SAMPLE_FILE, UNKNOWN + PROJECT_FILE, PRESET_FILE, SAMPLE_FILE, MIDI_FILE, UNKNOWN } ; inline fileTypes type( void ) @@ -191,9 +203,10 @@ private: void initPixmapStuff( void ); void determineFileType( void ); - static QPixmap * s_songFilePixmap; + static QPixmap * s_projectFilePixmap; static QPixmap * s_presetFilePixmap; static QPixmap * s_sampleFilePixmap; + static QPixmap * s_midiFilePixmap; static QPixmap * s_unknownFilePixmap; QPixmap * m_pix; diff --git a/include/kmultitabbar.h b/include/kmultitabbar.h index 070f9924c..fee6bbcdb 100644 --- a/include/kmultitabbar.h +++ b/include/kmultitabbar.h @@ -34,7 +34,6 @@ class KMultiTabBarTab; #include #include -//#include #include #include #include diff --git a/include/ladspa_manager.h b/include/ladspa_manager.h index 002fe1c6d..3614b7782 100644 --- a/include/ladspa_manager.h +++ b/include/ladspa_manager.h @@ -87,90 +87,89 @@ public: } return( s_instanceOfMe ); } - + /* This identifier can be used as a unique, case-sensitive identifier for the plugin type within the plugin file. Plugin types should be identified by file and label rather than by index or plugin name, which may be changed in new plugin versions. Labels must not contain white-space characters. */ QString FASTCALL getLabel( const ladspaKey & _plugin ); - + /* Indicates that the plugin has a real-time dependency (e.g. listens to a MIDI device) and so its output must not be cached or subject to significant latency. */ bool FASTCALL hasRealTimeDependency( const ladspaKey & _plugin ); - + /* Indicates that the plugin may cease to work correctly if the host elects to use the same data location for both input and output (see connectPort). */ bool FASTCALL isInplaceBroken( const ladspaKey & _plugin ); - + /* Indicates that the plugin is capable of running not only in a conventional host but also in a 'hard real-time' environment. */ bool FASTCALL isRealTimeCapable( const ladspaKey & _plugin ); - + /* Returns the name of the plug-in */ QString FASTCALL getName( const ladspaKey & _plugin ); - + /* Returns the the plug-in's author */ QString FASTCALL getMaker( const ladspaKey & _plugin ); - + /* Returns the copyright for the plug-in */ QString FASTCALL getCopyright( const ladspaKey & _plugin ); - + /* This indicates the number of ports (input AND output) present on the plugin. */ Uint32 FASTCALL getPortCount( const ladspaKey & _plugin ); - - + + /* Indicates that the port is an input. */ bool FASTCALL isPortInput( const ladspaKey & _plugin, Uint32 _port ); - + /* Indicates that the port is an output. */ bool FASTCALL isPortOutput( const ladspaKey & _plugin, Uint32 _port ); - + /* Indicates that the port is an audio. */ bool FASTCALL isPortAudio( const ladspaKey & _plugin, Uint32 _port ); - + /* Indicates that the port is an control. */ bool FASTCALL isPortControl( const ladspaKey & _plugin, Uint32 _port ); - + /* Indicates that any bounds specified should be interpreted as multiples of the sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency (half the sample rate) could be requested by this hint in conjunction with LowerBound = 0 and UpperBound = 0.5. - Hosts that support bounds at all must support this hint to retain meaning. */ + Hosts that support bounds at all must support this hint to retain + meaning. */ bool FASTCALL areHintsSampleRateDependent( const ladspaKey & _plugin, - Uint32 _port ); - + Uint32 _port ); + /* Returns the lower boundary value for the given port. If no lower bound is provided by the plug-in, returns -999e-99. When areHintsSampleRateDependent() is also true then this value should be multiplied by the relevant sample rate. */ float FASTCALL getLowerBound( const ladspaKey & _plugin, Uint32 _port ); - + /* Returns the upper boundary value for the given port. If no upper bound is provided by the plug-in, returns -999e-99. When areHintsSampleRateDependent() is also true then this value should be multiplied by the relevant sample rate. */ float FASTCALL getUpperBound( const ladspaKey & _plugin, Uint32 _port ); - + /* Indicates whether the given port should be considered 0 or 1 boolean switch. */ bool FASTCALL isPortToggled( const ladspaKey & _plugin, Uint32 _port ); - + /* Retrieves any default setting hints offered by the plug-in for the given port. */ float FASTCALL getDefaultSetting( const ladspaKey & _plugin, - Uint32 _port ); - - + Uint32 _port ); + /* Indicates that it is likely that the user will find it more intuitive to view values using a logarithmic scale. This is particularly useful for frequencies and gains. */ bool FASTCALL isLogarithmic( const ladspaKey & _plugin, Uint32 _port ); - - + /* Indicates that a user interface would probably wish to provide a stepped control taking only integer values. Any bounds set should be slightly wider than the actual integer range required to avoid floating @@ -187,12 +186,14 @@ public: or interpreted by the host. It is expected that most plugin writers will not use this facility as LADSPA_Handle should be used to hold instance data. */ - const void * FASTCALL getImplementationData( const ladspaKey & _plugin ); + const void * FASTCALL getImplementationData( + const ladspaKey & _plugin ); /* Returns a pointer to the plug-in's descriptor from which control of the plug-in is accessible */ - const LADSPA_Descriptor * FASTCALL getDescriptor( const ladspaKey & _plugin ); + const LADSPA_Descriptor * FASTCALL getDescriptor( + const ladspaKey & _plugin ); /* The following methods are convenience functions for use during @@ -246,8 +247,9 @@ public: called again unless deactivate() is called first. Note that connectPort() may be called before or after a call to activate(). */ - void FASTCALL activate( const ladspaKey & _plugin, LADSPA_Handle _instance ); - + void FASTCALL activate( const ladspaKey & _plugin, + LADSPA_Handle _instance ); + /* This method calls a function pointer that runs an instance of a plugin for a block. Two parameters are required: the first is a handle to the particular instance to be run and the second @@ -260,7 +262,7 @@ public: activate() has been called again. */ void FASTCALL run( const ladspaKey & _plugin, LADSPA_Handle _instance, Uint32 _sample_count ); - + /* This method calls a function pointer that runs an instance of a plugin for a block. This has identical behaviour to run() except in the way data is output from the plugin. When run() is used, @@ -274,9 +276,10 @@ public: runAdding() is optional. When it is not provided by a plugin, this function pointer must be set to NULL. When it is provided, the function setRunAddingGain() must be provided also. */ - void FASTCALL runAdding( const ladspaKey & _plugin, LADSPA_Handle _instance, - Uint32 _sample_count ); - + void FASTCALL runAdding( const ladspaKey & _plugin, + LADSPA_Handle _instance, + Uint32 _sample_count ); + /* This method calls a function pointer that sets the output gain for use when runAdding() is called (see above). If this function is never called the gain is assumed to default to 1. Gain @@ -286,9 +289,10 @@ public: This function should be provided by the plugin if and only if the runAdding() function is provided. When it is absent this function pointer must be set to NULL. */ - void FASTCALL setRunAddingGain( const ladspaKey & _plugin, LADSPA_Handle _instance, - LADSPA_Data _gain ); - + void FASTCALL setRunAddingGain( const ladspaKey & _plugin, + LADSPA_Handle _instance, + LADSPA_Data _gain ); + /* This is the counterpart to activate() (see above). If there is nothing for deactivate() to do then the plugin writer may provide a NULL rather than an empty function. @@ -302,8 +306,9 @@ public: Deactivation is not similar to pausing as the plugin instance will be reinitialised when activate() is called to reuse it. */ - void FASTCALL deactivate( const ladspaKey & _plugin, LADSPA_Handle _instance ); - + void FASTCALL deactivate( const ladspaKey & _plugin, + LADSPA_Handle _instance ); + /* Once an instance of a plugin has been finished with it can be deleted using the following function. The instance handle passed ceases to be valid after this call. @@ -311,29 +316,29 @@ public: If activate() was called for a plugin instance then a corresponding call to deactivate() must be made before cleanup() is called. */ - void FASTCALL cleanup( const ladspaKey & _plugin, LADSPA_Handle _instance ); - + void FASTCALL cleanup( const ladspaKey & _plugin, + LADSPA_Handle _instance ); + private: - void FASTCALL addPlugins( void * _plugin_handle, - LADSPA_Descriptor_Function _descriptor_func, - const QString & _file ); + void FASTCALL addPlugins( LADSPA_Descriptor_Function _descriptor_func, + const QString & _file ); ladspaManager( void ); ~ladspaManager(); static ladspaManager * s_instanceOfMe; - + typedef struct ladspaManagerStorage { - void * pluginHandle; LADSPA_Descriptor_Function descriptorFunction; Uint32 index; } ladspaManagerDescription; - + typedef QMap ladspaManagerMapType; ladspaManagerMapType m_ladspaManagerMap; -}; + +} ; #endif diff --git a/include/mmp.h b/include/mmp.h index 690936d7a..529b134b0 100644 --- a/include/mmp.h +++ b/include/mmp.h @@ -51,6 +51,7 @@ public: SONG_PROJECT, SONG_PROJECT_TEMPLATE, CHANNEL_SETTINGS, + DRAG_N_DROP_DATA, EFFECT_SETTINGS, VIDEO_PROJECT, // will come later... BURN_PROJECT, // will come later... @@ -59,7 +60,8 @@ public: } ; - multimediaProject( const QString & _in_file_name ); + multimediaProject( const QString & _in_file_name, + bool _is_filename = TRUE ); multimediaProject( projectTypes _project_type ); ~multimediaProject(); diff --git a/include/oscillator.h b/include/oscillator.h index ebd72ce6d..782e34346 100644 --- a/include/oscillator.h +++ b/include/oscillator.h @@ -98,7 +98,7 @@ public: // phase (otherwise we'll get clicks in the audio-stream) const float v = m_sample * m_oscCoeff; m_freq = _new_freq; - recalcOscCoeff( phase( v ) ); + recalcOscCoeff( fraction( v ) ); } static oscillator * FASTCALL createOsc( waveShapes _wave_shape, @@ -112,14 +112,14 @@ public: // check whether v2 is in next period return( floorf( v2 ) > floorf( v1 ) ); } -#define FLOAT_TO_INT(in,out) \ +/*#define FLOAT_TO_INT(in,out) \ register const float round_const = -0.5f; \ __asm__ __volatile__ ("fadd %%st,%%st(0)\n" \ "fadd %2\n" \ "fistpl %0\n" \ - "shrl $1,%0" : "=m" (out) : "t" (in),"m"(round_const) : "st") ; + "shrl $1,%0" : "=m" (out) : "t" (in),"m"(round_const) : "st") ;*/ - static inline float phase( const float _sample ) + static inline float fraction( const float _sample ) { return( _sample - static_cast( _sample ) ); } @@ -134,7 +134,7 @@ public: static inline sampleType triangleSample( float _sample ) { - const float ph = phase( _sample ); + const float ph = fraction( _sample ); if( ph <= 0.25f ) { return( ph * 4.0f ); @@ -148,17 +148,17 @@ public: static inline sampleType sawSample( float _sample ) { - return( -1.0f + phase( _sample ) * 2.0f ); + return( -1.0f + fraction( _sample ) * 2.0f ); } static inline sampleType squareSample( float _sample ) { - return( ( phase( _sample ) > 0.5f ) ? -1.0f : 1.0f ); + return( ( fraction( _sample ) > 0.5f ) ? -1.0f : 1.0f ); } static inline sampleType moogSawSample( float _sample ) { - const float ph = phase( _sample ); + const float ph = fraction( _sample ); if( ph < 0.5f ) { return( -1.0f + ph * 4.0f ); @@ -168,7 +168,7 @@ public: static inline sampleType expSample( float _sample ) { - float ph = phase( _sample ); + float ph = fraction( _sample ); if( ph > 0.5f ) { ph = 1.0f - ph; @@ -181,14 +181,20 @@ public: return( 1.0f - 2.0f * ( ( float )rand() * ( 1.0f / RAND_MAX ) ) ); } + static inline sampleType userWaveSample( float _sample, + const sampleFrame * _user_wave, Uint32 _user_wave_frames ) + { + const float frame = fraction( _sample ) * _user_wave_frames; + const Uint32 f1 = static_cast( frame ); + const Uint32 f2 = ( f1 + 1 ) % _user_wave_frames; + return( linearInterpolate( _user_wave[f1][0], + _user_wave[f2][0], + fraction( frame ) ) ); + } inline sampleType userWaveSample( float _sample ) { - const float frame = phase( _sample ) * m_userWaveFrames; - const Uint32 f1 = static_cast( frame ); - const Uint32 f2 = ( f1 + 1 ) % m_userWaveFrames; - return( linearInterpolate( m_userWaveData[f1][0], - m_userWaveData[f2][0], - frame - floorf( frame ) ) ); + return( userWaveSample( _sample, m_userWaveData, + m_userWaveFrames ) ); } diff --git a/include/pattern.h b/include/pattern.h index 6584d6fb0..2828e1950 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -102,13 +102,20 @@ public: return( m_notes ); } + note * FASTCALL noteAt( int _note_num ); + + void FASTCALL setNoteAt( int _note_num, note _new_note ); + + // pattern-type stuff inline patternTypes type( void ) const { return( m_patternType ); } void FASTCALL setType( patternTypes _new_pattern_type ); + void checkType( void ); + // pattern-name functions inline const QString & name( void ) const { return( m_name ); @@ -121,12 +128,6 @@ public: } - inline channelTrack * getChannelTrack( void ) - { - return( m_channelTrack ); - } - - // functions which are part of freezing-feature inline bool freezing( void ) const { @@ -143,11 +144,7 @@ public: void FASTCALL playFrozenData( sampleFrame * _ab, Uint32 _start_frame, Uint32 _frames ); - - note * FASTCALL noteAt( int _note_num ); - void FASTCALL setNoteAt( int _note_num, note _new_note ); - void checkType( void ); - + // settings-management virtual void FASTCALL saveSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void FASTCALL loadSettings( const QDomElement & _this ); @@ -156,6 +153,11 @@ public: return( "pattern" ); } + inline channelTrack * getChannelTrack( void ) + { + return( m_channelTrack ); + } + protected slots: void openInPianoRoll( bool _c ); @@ -175,12 +177,13 @@ protected slots: protected: - void paintEvent( QPaintEvent * _pe ); - void mousePressEvent( QMouseEvent * _me ); - void mouseDoubleClickEvent( QMouseEvent * _me ); virtual void constructContextMenu( QMenu * ); + virtual void mouseDoubleClickEvent( QMouseEvent * _me ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void paintEvent( QPaintEvent * _pe ); void ensureBeatNotes( void ); + void updateBBTrack( void ); private: diff --git a/include/piano_roll.h b/include/piano_roll.h index e1de9538d..1783c050c 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -90,7 +90,6 @@ protected: void mouseReleaseEvent( QMouseEvent * _me ); void mouseMoveEvent( QMouseEvent * _me ); void keyPressEvent( QKeyEvent * _ke ); - void keyReleaseEvent( QKeyEvent * _ke ); void wheelEvent( QWheelEvent * _we ); int FASTCALL getKey( int _y ); @@ -211,9 +210,6 @@ private: midiTime m_lenOfNewNotes; - bool m_shiftPressed; - bool m_controlPressed; - int m_startKey; // first key when drawing int m_keyMouseOver; int m_lastKey; diff --git a/include/pixmap_button.h b/include/pixmap_button.h index cd9e13fac..ee4b0a109 100644 --- a/include/pixmap_button.h +++ b/include/pixmap_button.h @@ -52,10 +52,16 @@ class pixmapButton : public QPushButton public: pixmapButton( QWidget * _parent ); virtual ~pixmapButton(); - virtual void FASTCALL setActiveGraphic( const QPixmap & _pm ); - virtual void FASTCALL setInactiveGraphic( const QPixmap & _pm, + void FASTCALL setActiveGraphic( const QPixmap & _pm ); + void FASTCALL setInactiveGraphic( const QPixmap & _pm, bool _update = TRUE ); void FASTCALL setBgGraphic( const QPixmap & _pm ); +#ifndef QT4 + inline void setChecked( bool _on ) + { + setOn( _on ); + } +#endif signals: diff --git a/include/sample_buffer.h b/include/sample_buffer.h index 54ddd38ef..da910da99 100644 --- a/include/sample_buffer.h +++ b/include/sample_buffer.h @@ -67,7 +67,10 @@ public: DOTS } ; - sampleBuffer( const QString & _audio_file = "" ); + // constructor which either loads sample _audio_file or decodes + // base64-data out of string + sampleBuffer( const QString & _audio_file = "", + bool _is_base64_data = FALSE ); sampleBuffer( const sampleFrame * _data, Uint32 _frames ); ~sampleBuffer(); @@ -112,10 +115,12 @@ public: QString openAudioFile( void ) const; + QString toBase64( void ) const; public slots: void setAudioFile( const QString & _audio_file ); + void loadFromBase64( const QString & _data ); void setStartFrame( Uint32 _s ); void setEndFrame( Uint32 _e ); void setAmplification( float _a ); diff --git a/include/sample_track.h b/include/sample_track.h index 7cb6c8f81..8330240f0 100644 --- a/include/sample_track.h +++ b/include/sample_track.h @@ -77,8 +77,11 @@ public slots: protected: - void paintEvent( QPaintEvent * ); - void mouseDoubleClickEvent( QMouseEvent * ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + virtual void mouseDoubleClickEvent( QMouseEvent * ); + virtual void paintEvent( QPaintEvent * ); + midiTime getSampleLength( void ) const; @@ -122,7 +125,7 @@ public: sampleTrack( trackContainer * _tc ); virtual ~sampleTrack(); - virtual trackTypes trackType( void ) const; + virtual trackTypes type( void ) const; virtual bool FASTCALL play( const midiTime & _start, Uint32 _start_frame, Uint32 _frames, Uint32 _frame_base, diff --git a/include/song_editor.h b/include/song_editor.h index 091208c3e..ae14685a7 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -27,26 +27,12 @@ #ifndef _SONG_EDITOR_H #define _SONG_EDITOR_H -#include "qt3support.h" - -#ifdef QT4 - -#include - -#else - -#include - -#endif - - #include "track_container.h" #include "types.h" class QComboBox; class QLabel; -class QPixmap; class QScrollBar; class QSlider; @@ -301,6 +287,8 @@ private: volatile bool m_playing; volatile bool m_paused; + bool m_loadingProject; + playModes m_playMode; playPos m_playPos[PLAY_MODE_CNT]; @@ -325,11 +313,6 @@ private: void doActions( void ); - bool m_shiftPressed; - bool m_controlPressed; - - - friend class lmmsMainWin; diff --git a/include/string_pair_drag.h b/include/string_pair_drag.h index f81be1702..0568946f5 100644 --- a/include/string_pair_drag.h +++ b/include/string_pair_drag.h @@ -54,7 +54,7 @@ public: const QPixmap & _icon, QWidget * _w ); ~stringPairDrag(); - static void processDragEnterEvent( QDragEnterEvent * _dee, + static bool processDragEnterEvent( QDragEnterEvent * _dee, const QString & _allowed_keys ); static QString decodeKey( QDropEvent * _de ); static QString decodeValue( QDropEvent * _de ); diff --git a/include/text_float.h b/include/text_float.h index 431276376..a9711b760 100644 --- a/include/text_float.h +++ b/include/text_float.h @@ -76,6 +76,8 @@ protected: private: + void updateSize( void ); + QString m_title; QString m_text; QPixmap m_pixmap; diff --git a/include/timeline.h b/include/timeline.h index fb8d8939d..16db6770f 100644 --- a/include/timeline.h +++ b/include/timeline.h @@ -44,6 +44,7 @@ class QPixmap; class nStateButton; +class textFloat; class timeLine : public QWidget @@ -90,6 +91,7 @@ public: return( ( m_loopPos[0] < m_loopPos[1] ) ? m_loopPos[0] : m_loopPos[1] ); } + inline const midiTime & loopEnd( void ) const { return( ( m_loopPos[0] > m_loopPos[1] ) ? @@ -136,6 +138,7 @@ private: m_ppt / 64.0f ) ); } + static QPixmap * s_timeLinePixmap; static QPixmap * s_posMarkerPixmap; static QPixmap * s_loopPointPixmap; @@ -157,6 +160,9 @@ private: midiTime m_savedPos; + textFloat * m_hint; + + enum actions { NONE, MOVE_POS_MARKER, MOVE_LOOP_BEGIN, MOVE_LOOP_END diff --git a/include/track.h b/include/track.h index cc73f045e..201a2d052 100644 --- a/include/track.h +++ b/include/track.h @@ -57,14 +57,15 @@ #include "settings.h" +class QMenu; + +class pixmapButton; +class textFloat; class track; class trackContainer; class trackContentWidget; class trackWidget; -class pixmapButton; -class QMenu; -typedef QWidget trackSettingsWidget; typedef QWidget trackOperationsWidget; @@ -107,13 +108,17 @@ public slots: protected: - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void contextMenuEvent( QContextMenuEvent * _cme ); virtual void constructContextMenu( QMenu * ) { } + virtual void contextMenuEvent( QContextMenuEvent * _cme ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + virtual void leaveEvent( QEvent * _e ); + virtual void mouseMoveEvent( QMouseEvent * _me ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void mouseReleaseEvent( QMouseEvent * _me ); + void setAutoResizeEnabled( bool _e = FALSE ); float pixelsPerTact( void ); @@ -125,6 +130,8 @@ protected slots: private: + static textFloat * s_textFloat; + track * m_track; midiTime m_startPosition; midiTime m_length; @@ -172,6 +179,8 @@ public slots: 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 ); @@ -179,6 +188,9 @@ protected: private: + track * getTrack( void ); + midiTime getPosition( int _mouse_x ); + typedef vvector tcoVector; tcoVector m_trackContentObjects; @@ -190,6 +202,28 @@ private: + +class trackSettingsWidget : public QWidget +{ +public: + trackSettingsWidget( trackWidget * _parent ); + ~trackSettingsWidget(); + + +protected: + virtual void mousePressEvent( QMouseEvent * _me ); + + +private: + trackWidget * m_trackWidget; + +} ; + + + + + + // actual widget shown in trackContainer class trackWidget : public QWidget { @@ -202,26 +236,32 @@ public: { return( m_track ); } + inline track * getTrack( void ) { return( m_track ); } + inline const trackSettingsWidget & getTrackSettingsWidget( void ) const { return( m_trackSettingsWidget ); } + inline const trackContentWidget & getTrackContentWidget( void ) const { return( m_trackContentWidget ); } + inline trackSettingsWidget & getTrackSettingsWidget( void ) { return( m_trackSettingsWidget ); } + inline trackContentWidget & getTrackContentWidget( void ) { return( m_trackContentWidget ); } + bool muted( void ) const; @@ -236,8 +276,11 @@ public slots: protected: - virtual void resizeEvent( QResizeEvent * _re ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); virtual void paintEvent( QPaintEvent * _pe ); + virtual void resizeEvent( QResizeEvent * _re ); + midiTime FASTCALL endPosition( const midiTime & _pos_start ); @@ -285,7 +328,7 @@ public: } // pure virtual functions - virtual trackTypes trackType( void ) const = 0; + virtual trackTypes type( void ) const = 0; virtual bool FASTCALL play( const midiTime & _start, Uint32 _start_frame, @@ -322,22 +365,27 @@ public: { return( m_trackWidget ); } + inline trackContainer * getTrackContainer( void ) { return( m_trackContainer ); } + inline const trackSettingsWidget * getTrackSettingsWidget( void ) const { return( &m_trackWidget->getTrackSettingsWidget() ); } + inline const trackContentWidget * getTrackContentWidget( void ) const { return( &m_trackWidget->getTrackContentWidget() ); } + inline trackSettingsWidget * getTrackSettingsWidget( void ) { return( &m_trackWidget->getTrackSettingsWidget() ); } + inline trackContentWidget * getTrackContentWidget( void ) { return( &m_trackWidget->getTrackContentWidget() ); diff --git a/include/track_container.h b/include/track_container.h index f4c6424a7..2abee84ad 100644 --- a/include/track_container.h +++ b/include/track_container.h @@ -94,9 +94,9 @@ public: protected: - virtual void resizeEvent( QResizeEvent * ); virtual void dragEnterEvent( QDragEnterEvent * _dee ); virtual void dropEvent( QDropEvent * _de ); + virtual void resizeEvent( QResizeEvent * ); constTrackVector tracks( void ) const; trackVector tracks( void ); diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 040fbcb28..118709e33 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -57,6 +57,8 @@ #include "pixmap_button.h" #include "knob.h" #include "tooltip.h" +#include "string_pair_drag.h" +#include "mmp.h" #include "embed.cpp" @@ -277,6 +279,7 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) : setBackgroundMode( Qt::NoBackground ); #endif + setAcceptDrops( TRUE ); } @@ -413,6 +416,36 @@ void audioFileProcessor::deleteNotePluginData( notePlayHandle * _n ) +void audioFileProcessor::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, + QString( "samplefile,tco_%1" ).arg( track::SAMPLE_TRACK ) ); +} + + + + +void audioFileProcessor::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == "samplefile" ) + { + setAudioFile( stringPairDrag::decodeValue( _de ) ); + _de->accept(); + } + else if( type == QString( "tco_%1" ).arg( track::SAMPLE_TRACK ) ) + { + multimediaProject mmp( value, FALSE ); + setAudioFile( mmp.content().firstChild().toElement(). + attribute( "src" ) ); + _de->accept(); + } +} + + + + void audioFileProcessor::paintEvent( QPaintEvent * ) { #ifdef QT4 @@ -493,6 +526,7 @@ void audioFileProcessor::sampleUpdated( void ) m_graph.height() ); QPainter p( &m_graph ); #endif + p.setPen( QColor( 64, 255, 160 ) ); m_sampleBuffer.drawWaves( p, QRect( 2, 2, m_graph.width() - 4, m_graph.height() - 4 ), m_drawMethod ); diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 574ece097..8d9a4f87f 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -86,7 +86,9 @@ protected slots: protected: - void paintEvent( QPaintEvent * ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + virtual void paintEvent( QPaintEvent * ); private: diff --git a/plugins/vestige/Makefile.am b/plugins/vestige/Makefile.am index 01941200b..c87fd679d 100644 --- a/plugins/vestige/Makefile.am +++ b/plugins/vestige/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign 1.4 -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I. +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I. -I/usr/X11R6/include AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="vestige" diff --git a/resources/hint.png b/resources/hint.png new file mode 100644 index 0000000000000000000000000000000000000000..bd673cf1fb797e8ae5c75f6350728d0f2046e47f GIT binary patch literal 1116 zcmV-i1f%PbXF zR7l6AmEUVzMHI(BGjsPxc9ZUIn#Nk&YOT^A(x%W5B2_^p1@S?_7atcD@5~(^c7>Q`n^h0Y!<>Qh zIdkTm?C(hH=gvSrll}N`W@KBx9SW^U*;v_MXU)|& z&o?jKX*8?AGNAu8Ae-$;PQ1`J^30(}kM#;YJt{WukvM740ru8aTPgi;<()4s9eeNR z#yOx2glol79pWd>zP9<QlKSBi4Zu}a@Ty^<(RxY|`NgQ( z?jpS&z*=jAnTk1!ZCBC?1OnM~U@nL96vB$uTeK_v;}!q1wYCfd-E_<({6eH7^2{)h*fyV6CJqRH%#^8D0QhTuO2~g|(sngTb&1^RNU_PJUyM6n1k;~EJ;r|@EwK#qH^ug)r>F>+s z@(E*%_g@K6N&(+qV89_uSm#4{Q`|*8`$;n9u1_tmvkMZ#_*4G;Z zL4ekpbUH<)Qo(T?5(!PET19Ien@3{v!0s~EgzrGUfa_{}&tqt42(2}no145hI0ypP z1fVqvMWIk=N6dkI9%2$v6zSMR1YiQgaBe^O1H+7ukCDyxQ7n#;8yaGCbcE7m5mlNb znQR_0K0ZpZI7YQvMr+N~REbKp%!3Dh*Yw@d2Rv_s?7$#5Z+-@1K>}{w`h1Hw;QIAX zn``3%0Y{I{a`eMF5CaH@4<7~`8jbaiDZGmU3NZ#`y$Pc+2%xM70zxzMNqC?2wnD8H z6@cD{u>lg1vA0@aHbGfX8s&i6q2BhacDZh37_SLnF9gC-kjd=huUBjQ`pb_vZVIvH z?b@)d|3uQ|&p)1#Or?8AL5rbYuXF0u2|m8`3158q9lBMNBy_rTj_Yk^g&+7Ftjuus z>_@DxuXj&GEv;H{{mr+xdHwfSh_!$qTefdDl3S2A9Re$|#UtB(u?2M|lSToXo15*- z+0zMwARq_=_GMBLtp%|WAszaGFx)|;6n9l1JV*0-w;qu$iiFF2M;{0i_uA*}rH>4U zUe{{)w#{hVb6h7KXW~vysNSX(?`48GMdB)>6LLJ&>9Z<4x7KmbQJY8Y@47BZDSY4G zjXj^1%^o{;j7Fo;(;VGQ7xzvnMLM14&Ye5d>-B$tpjmXco6+(9{{Gt|BO`Mn z;_Oa0@#ySzIF7@{#)h-Hy87A}^E0q0BG1AK0PF{*fxdV6MIHdZ1FIqu{0lZt(upH> RbOQhY002ovPDHLkV1f+VZ`l9< literal 0 HcmV?d00001 diff --git a/src/core/bb_editor.cpp b/src/core/bb_editor.cpp index 699556865..5c88041c3 100644 --- a/src/core/bb_editor.cpp +++ b/src/core/bb_editor.cpp @@ -258,6 +258,18 @@ void bbEditor::removeBB( csize _bb ) +void bbEditor::updateBBTrack( trackContentObject * _tco ) +{ + bbTrack * t = bbTrack::findBBTrack( _tco->startPosition() / 64 ); + if( t != NULL ) + { + t->getTrackContentWidget()->updateTCOs(); + } +} + + + + // 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 ) diff --git a/src/core/envelope_and_lfo_widget.cpp b/src/core/envelope_and_lfo_widget.cpp index e6316a470..4dd7b556d 100644 --- a/src/core/envelope_and_lfo_widget.cpp +++ b/src/core/envelope_and_lfo_widget.cpp @@ -58,6 +58,11 @@ #include "gui_templates.h" #include "led_checkbox.h" #include "tempo_sync_knob.h" +#include "string_pair_drag.h" +#include "mmp.h" +#include "text_float.h" + + // how long should be each envelope-segment maximal (e.g. attack)? const float SECS_PER_ENV_SEGMENT = 5.0f; @@ -65,33 +70,32 @@ const float SECS_PER_ENV_SEGMENT = 5.0f; const float SECS_PER_LFO_OSCILLATION = 20.0f; -const int env_graph_x = 6; -const int env_graph_y = 6; +const int ENV_GRAPH_X = 6; +const int ENV_GRAPH_Y = 6; -const int env_knobs_y = 43; -const int env_knobs_lbl_y = env_knobs_y+35; -const int knob_x_spacing = 32; -const int predelay_knob_x = 6; -const int attack_knob_x = predelay_knob_x+knob_x_spacing; -const int hold_knob_x = attack_knob_x+knob_x_spacing; -const int decay_knob_x = hold_knob_x+knob_x_spacing; -const int sustain_knob_x = decay_knob_x+knob_x_spacing; -const int release_knob_x = sustain_knob_x+knob_x_spacing; -const int amount_knob_x = release_knob_x+knob_x_spacing; +const int ENV_KNOBS_Y = 43; +const int ENV_KNOBS_LBL_Y = ENV_KNOBS_Y+35; +const int KNOB_X_SPACING = 32; +const int PREDELAY_KNOB_X = 6; +const int ATTACK_KNOB_X = PREDELAY_KNOB_X+KNOB_X_SPACING; +const int HOLD_KNOB_X = ATTACK_KNOB_X+KNOB_X_SPACING; +const int DECAY_KNOB_X = HOLD_KNOB_X+KNOB_X_SPACING; +const int SUSTAIN_KNOB_X = DECAY_KNOB_X+KNOB_X_SPACING; +const int RELEASE_KNOB_X = SUSTAIN_KNOB_X+KNOB_X_SPACING; +const int AMOUNT_KNOB_X = RELEASE_KNOB_X+KNOB_X_SPACING; -const float time_unit_width = 36.0; +const float TIME_UNIT_WIDTH = 36.0; -const int lfo_graph_x = 6; -const int lfo_graph_y = env_knobs_lbl_y+14; -const int lfo_knob_y = lfo_graph_y-2; -const int lfo_knobs_lbl_y = lfo_knob_y+35; -const int lfo_predelay_knob_x = lfo_graph_x + 100; -const int lfo_attack_knob_x = lfo_predelay_knob_x+knob_x_spacing; -const int lfo_speed_knob_x = lfo_attack_knob_x+knob_x_spacing; -const int lfo_amount_knob_x = lfo_speed_knob_x+knob_x_spacing; -const int lfo_shapes_x = lfo_graph_x;//predelay_knob_x; -const int lfo_shapes_y = lfo_graph_y + 50; +const int LFO_GRAPH_X = 6; +const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; +const int LFO_KNOB_Y = LFO_GRAPH_Y-2; +const int LFO_PREDELAY_KNOB_X = LFO_GRAPH_X + 100; +const int LFO_ATTACK_KNOB_X = LFO_PREDELAY_KNOB_X+KNOB_X_SPACING; +const int LFO_SPEED_KNOB_X = LFO_ATTACK_KNOB_X+KNOB_X_SPACING; +const int LFO_AMOUNT_KNOB_X = LFO_SPEED_KNOB_X+KNOB_X_SPACING; +const int LFO_SHAPES_X = LFO_GRAPH_X;//PREDELAY_KNOB_X; +const int LFO_SHAPES_Y = LFO_GRAPH_Y + 50; QPixmap * envelopeAndLFOWidget::s_envGraph = NULL; @@ -132,7 +136,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_predelayKnob->setLabel( tr( "DEL" ) ); m_predelayKnob->setRange( 0.0, 1.0, 0.001 ); m_predelayKnob->setValue( 0.0, TRUE ); - m_predelayKnob->move( predelay_knob_x, env_knobs_y ); + m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y ); m_predelayKnob->setHintText( tr( "Predelay:" ) + " ", "" ); #ifdef QT4 m_predelayKnob->setWhatsThis( @@ -149,7 +153,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_attackKnob->setLabel( tr( "ATT" ) ); m_attackKnob->setRange( 0.0, 1.0, 0.001 ); m_attackKnob->setValue( 0.0, TRUE ); - m_attackKnob->move( attack_knob_x, env_knobs_y ); + m_attackKnob->move( ATTACK_KNOB_X, ENV_KNOBS_Y ); m_attackKnob->setHintText( tr( "Attack:" )+" ", "" ); #ifdef QT4 m_attackKnob->setWhatsThis( @@ -168,7 +172,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_holdKnob->setLabel( tr( "HOLD" ) ); m_holdKnob->setRange( 0.0, 1.0, 0.001 ); m_holdKnob->setValue( 0.5, TRUE ); - m_holdKnob->move( hold_knob_x, env_knobs_y ); + m_holdKnob->move( HOLD_KNOB_X, ENV_KNOBS_Y ); m_holdKnob->setHintText( tr( "Hold:" ) + " ", "" ); #ifdef QT4 m_holdKnob->setWhatsThis( @@ -186,7 +190,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_decayKnob->setLabel( tr( "DEC" ) ); m_decayKnob->setRange( 0.0, 1.0, 0.001 ); m_decayKnob->setValue( 0.5, TRUE ); - m_decayKnob->move( decay_knob_x, env_knobs_y ); + m_decayKnob->move( DECAY_KNOB_X, ENV_KNOBS_Y ); m_decayKnob->setHintText( tr( "Decay:" ) + " ", "" ); #ifdef QT4 m_decayKnob->setWhatsThis( @@ -205,7 +209,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_sustainKnob->setLabel( tr( "SUST" ) ); m_sustainKnob->setRange( 0.0, 1.0, 0.001 ); m_sustainKnob->setValue( 0.5, TRUE ); - m_sustainKnob->move( sustain_knob_x, env_knobs_y ); + m_sustainKnob->move( SUSTAIN_KNOB_X, ENV_KNOBS_Y ); m_sustainKnob->setHintText( tr( "Sustain:" ) + " ", "" ); #ifdef QT4 m_sustainKnob->setWhatsThis( @@ -223,7 +227,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_releaseKnob->setLabel( tr( "REL" ) ); m_releaseKnob->setRange( 0.0, 1.0, 0.001 ); m_releaseKnob->setValue( 0.1, TRUE ); - m_releaseKnob->move( release_knob_x, env_knobs_y ); + m_releaseKnob->move( RELEASE_KNOB_X, ENV_KNOBS_Y ); m_releaseKnob->setHintText( tr( "Release:" ) + " ", "" ); #ifdef QT4 m_releaseKnob->setWhatsThis( @@ -243,7 +247,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_amountKnob->setLabel( tr( "AMT" ) ); m_amountKnob->setRange( -1.0, 1.0, 0.005 ); m_amountKnob->setValue( 0.0, TRUE ); - m_amountKnob->move( amount_knob_x, env_graph_y ); + m_amountKnob->move( AMOUNT_KNOB_X, ENV_GRAPH_Y ); m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); #ifdef QT4 m_amountKnob->setWhatsThis( @@ -264,7 +268,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_lfoPredelayKnob->setLabel( tr( "DEL" ) ); m_lfoPredelayKnob->setRange( 0.0, 1.0, 0.001 ); m_lfoPredelayKnob->setValue( 0.0, TRUE ); - m_lfoPredelayKnob->move( lfo_predelay_knob_x, lfo_knob_y ); + m_lfoPredelayKnob->move( LFO_PREDELAY_KNOB_X, LFO_KNOB_Y ); m_lfoPredelayKnob->setHintText( tr( "LFO-predelay:" ) + " ", "" ); #ifdef QT4 m_lfoPredelayKnob->setWhatsThis( @@ -282,7 +286,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_lfoAttackKnob->setLabel( tr( "ATT" ) ); m_lfoAttackKnob->setRange( 0.0, 1.0, 0.001 ); m_lfoAttackKnob->setValue( 0.0, TRUE ); - m_lfoAttackKnob->move( lfo_attack_knob_x, lfo_knob_y ); + m_lfoAttackKnob->move( LFO_ATTACK_KNOB_X, LFO_KNOB_Y ); m_lfoAttackKnob->setHintText( tr( "LFO-attack:" ) + " ", "" ); #ifdef QT4 m_lfoAttackKnob->setWhatsThis( @@ -295,12 +299,12 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, connect( m_lfoAttackKnob, SIGNAL( valueChanged( float ) ), this, SLOT( updateAfterKnobChange( float ) ) ); - m_lfoSpeedKnob = new tempoSyncKnob( knobBright_26, this, tr( "LFO-speed" ) , - 20000.0 ); + m_lfoSpeedKnob = new tempoSyncKnob( knobBright_26, this, + tr( "LFO-speed" ), 20000.0 ); m_lfoSpeedKnob->setLabel( tr( "SPD" ) ); m_lfoSpeedKnob->setRange( 0.01, 1.0, 0.0001 ); m_lfoSpeedKnob->setValue( 0.1, TRUE ); - m_lfoSpeedKnob->move( lfo_speed_knob_x, lfo_knob_y ); + m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); m_lfoSpeedKnob->setHintText( tr( "LFO-speed:" ) + " ", "" ); #ifdef QT4 m_lfoSpeedKnob->setWhatsThis( @@ -318,7 +322,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_lfoAmountKnob->setLabel( tr( "AMT" ) ); m_lfoAmountKnob->setRange( -1.0, 1.0, 0.005 ); m_lfoAmountKnob->setValue( 0.0, TRUE ); - m_lfoAmountKnob->move( lfo_amount_knob_x, lfo_knob_y ); + m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); #ifdef QT4 m_lfoAmountKnob->setWhatsThis( @@ -334,23 +338,22 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_sinLfoBtn = new pixmapButton( this ); - m_sinLfoBtn->move( lfo_shapes_x, lfo_shapes_y ); + m_sinLfoBtn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); m_sinLfoBtn->setActiveGraphic( embed::getIconPixmap( "sin_wave_active" ) ); m_sinLfoBtn->setInactiveGraphic( embed::getIconPixmap( "sin_wave_inactive" ) ); -#ifdef QT4 m_sinLfoBtn->setChecked( TRUE ); +#ifdef QT4 m_sinLfoBtn->setWhatsThis( #else - m_sinLfoBtn->setOn( TRUE ); QWhatsThis::add( m_sinLfoBtn, #endif tr( "Click here if you want a sine-wave for current " "oscillator." ) ); m_triangleLfoBtn = new pixmapButton( this ); - m_triangleLfoBtn->move( lfo_shapes_x+15, lfo_shapes_y ); + m_triangleLfoBtn->move( LFO_SHAPES_X+15, LFO_SHAPES_Y ); m_triangleLfoBtn->setActiveGraphic( embed::getIconPixmap( "triangle_wave_active" ) ); m_triangleLfoBtn->setInactiveGraphic( embed::getIconPixmap( @@ -364,7 +367,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "oscillator." ) ); m_sawLfoBtn = new pixmapButton( this ); - m_sawLfoBtn->move( lfo_shapes_x+30, lfo_shapes_y ); + m_sawLfoBtn->move( LFO_SHAPES_X+30, LFO_SHAPES_Y ); m_sawLfoBtn->setActiveGraphic( embed::getIconPixmap( "saw_wave_active" ) ); m_sawLfoBtn->setInactiveGraphic( embed::getIconPixmap( @@ -378,7 +381,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "oscillator." ) ); m_sqrLfoBtn = new pixmapButton( this ); - m_sqrLfoBtn->move( lfo_shapes_x+45, lfo_shapes_y ); + m_sqrLfoBtn->move( LFO_SHAPES_X+45, LFO_SHAPES_Y ); m_sqrLfoBtn->setActiveGraphic( embed::getIconPixmap( "square_wave_active" ) ); m_sqrLfoBtn->setInactiveGraphic( embed::getIconPixmap( @@ -391,6 +394,21 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, tr( "Click here if you want a square-wave for current " "oscillator." ) ); + m_usrLfoBtn = new pixmapButton( this ); + m_usrLfoBtn->move( LFO_SHAPES_X+60, LFO_SHAPES_Y ); + m_usrLfoBtn->setActiveGraphic( embed::getIconPixmap( + "usr_wave_active" ) ); + m_usrLfoBtn->setInactiveGraphic( embed::getIconPixmap( + "usr_wave_inactive" ) ); +#ifdef QT4 + m_usrLfoBtn->setWhatsThis( +#else + QWhatsThis::add( m_usrLfoBtn, +#endif + tr( "Click here if you want a user-defined wave for current " + "oscillator. Afterwards drag an according sample-" + "file into LFO-graph." ) ); + connect( m_sinLfoBtn, SIGNAL( toggled( bool ) ), this, SLOT( lfoSinWaveCh( bool ) ) ); connect( m_triangleLfoBtn, SIGNAL( toggled( bool ) ), this, @@ -399,12 +417,15 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, SLOT( lfoSawWaveCh( bool ) ) ); connect( m_sqrLfoBtn, SIGNAL( toggled( bool ) ), this, SLOT( lfoSquareWaveCh( bool ) ) ); + connect( m_usrLfoBtn, SIGNAL( toggled( bool ) ), this, + SLOT( lfoUserWaveCh( bool ) ) ); QButtonGroup * lfo_shapes_algo_group = new QButtonGroup( this ); lfo_shapes_algo_group->addButton( m_sinLfoBtn ); lfo_shapes_algo_group->addButton( m_triangleLfoBtn ); lfo_shapes_algo_group->addButton( m_sawLfoBtn ); lfo_shapes_algo_group->addButton( m_sqrLfoBtn ); + lfo_shapes_algo_group->addButton( m_usrLfoBtn ); lfo_shapes_algo_group->setExclusive( TRUE ); #ifndef QT4 lfo_shapes_algo_group->hide(); @@ -412,7 +433,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_x100Cb = new ledCheckBox( tr( "FREQ x 100" ), this ); m_x100Cb->setFont( pointSize<6>( m_x100Cb->font() ) ); - m_x100Cb->move( lfo_predelay_knob_x, lfo_graph_y + 36 ); + m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); #ifdef QT4 m_x100Cb->setWhatsThis( #else @@ -427,7 +448,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, m_controlEnvAmountCb = new ledCheckBox( tr( "MODULATE ENV-AMOUNT" ), this ); - m_controlEnvAmountCb->move( lfo_predelay_knob_x, lfo_graph_y + 54 ); + m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); m_controlEnvAmountCb->setFont( pointSize<6>( m_controlEnvAmountCb->font() ) ); #ifdef QT4 @@ -445,6 +466,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, // set background-mode for flicker-free redraw setBackgroundMode( Qt::NoBackground ); #endif + setAcceptDrops( TRUE ); connect( mixer::inst(), SIGNAL( sampleRateChanged() ), this, SLOT( updateSampleVars() ) ); @@ -585,7 +607,8 @@ void envelopeAndLFOWidget::saveSettings( QDomDocument & , _parent.setAttribute( "ctlenvamt", QString::number( m_controlEnvAmountCb->isChecked() ) ); _parent.setAttribute( "lfosyncmode", QString::number( - ( int ) m_lfoSpeedKnob->getSyncMode() ) ); + ( int ) m_lfoSpeedKnob->getSyncMode() ) ); + _parent.setAttribute( "userwavefile", m_userWave.audioFile() ); } @@ -614,39 +637,28 @@ void envelopeAndLFOWidget::loadSettings( const QDomElement & _this ) m_lfoSpeedKnob->setSyncMode( ( tempoSyncKnob::tempoSyncMode ) _this.attribute( "lfosyncmode" ).toInt() ); + m_userWave.setAudioFile( _this.attribute( "userwavefile" ) ); switch( m_lfoShape ) { case SIN: -#ifdef QT4 m_sinLfoBtn->setChecked( TRUE ); -#else - m_sinLfoBtn->setOn( TRUE ); -#endif break; case TRIANGLE: -#ifdef QT4 m_triangleLfoBtn->setChecked( TRUE ); -#else - m_triangleLfoBtn->setOn( TRUE ); -#endif break; case SAW: -#ifdef QT4 m_sawLfoBtn->setChecked( TRUE ); -#else - m_sawLfoBtn->setOn( TRUE ); -#endif break; case SQUARE: -#ifdef QT4 m_sqrLfoBtn->setChecked( TRUE ); -#else - m_sqrLfoBtn->setOn( TRUE ); -#endif + break; + + case USER: + m_usrLfoBtn->setChecked( TRUE ); break; } @@ -659,6 +671,78 @@ void envelopeAndLFOWidget::loadSettings( const QDomElement & _this ) +void envelopeAndLFOWidget::mousePressEvent( QMouseEvent * _me ) +{ + if( _me->button() != Qt::LeftButton ) + { + return; + } + + if( QRect( ENV_GRAPH_X, ENV_GRAPH_Y, s_envGraph->width(), + s_envGraph->height() ).contains( _me->pos() ) == TRUE ) + { + if( m_amountKnob->value() < 1.0f ) + { + m_amountKnob->setValue( 1.0f ); + } + else + { + m_amountKnob->setValue( 0.0f ); + } + updateSampleVars(); + } + else if( QRect( LFO_GRAPH_X, LFO_GRAPH_Y, s_lfoGraph->width(), + s_lfoGraph->height() ).contains( _me->pos() ) == TRUE ) + { + if( m_lfoAmountKnob->value() < 1.0f ) + { + m_lfoAmountKnob->setValue( 1.0f ); + } + else + { + m_lfoAmountKnob->setValue( 0.0f ); + } + updateSampleVars(); + } +} + + + + +void envelopeAndLFOWidget::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, + QString( "samplefile,tco_%1" ).arg( + track::SAMPLE_TRACK ) ); +} + + + + +void envelopeAndLFOWidget::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == "samplefile" ) + { + m_userWave.setAudioFile( stringPairDrag::decodeValue( _de ) ); + m_usrLfoBtn->setChecked( TRUE ); + lfoUserWaveCh( TRUE ); + _de->accept(); + } + else if( type == QString( "tco_%1" ).arg( track::SAMPLE_TRACK ) ) + { + multimediaProject mmp( value, FALSE ); + m_userWave.setAudioFile( mmp.content().firstChild().toElement(). + attribute( "src" ) ); + m_usrLfoBtn->setChecked( TRUE ); + lfoUserWaveCh( TRUE ); + _de->accept(); + } +} + + + void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) { @@ -680,9 +764,9 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) p.setFont( pointSize<6>( p.font() ) ); // draw envelope-graph - p.drawPixmap( env_graph_x, env_graph_y, *s_envGraph ); + p.drawPixmap( ENV_GRAPH_X, ENV_GRAPH_Y, *s_envGraph ); // draw LFO-graph - p.drawPixmap( lfo_graph_x, lfo_graph_y, *s_lfoGraph ); + p.drawPixmap( LFO_GRAPH_X, LFO_GRAPH_Y, *s_lfoGraph ); p.setFont( pointSize<8>( p.font() ) ); @@ -697,19 +781,19 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) const QColor end_points_color( 0xFF, 0xBF, 0x22 ); const QColor end_points_bg_color( 0, 0, 2 ); - const int y_base = env_graph_y + s_envGraph->height() - 3; + const int y_base = ENV_GRAPH_Y + s_envGraph->height() - 3; const int avail_height = s_envGraph->height() - 6; - int x1 = env_graph_x + 2 + static_cast( m_predelayKnob->value() * - time_unit_width ); + int x1 = ENV_GRAPH_X + 2 + static_cast( m_predelayKnob->value() * + TIME_UNIT_WIDTH ); int x2 = x1 + static_cast( m_attackKnob->value() * - time_unit_width ); + TIME_UNIT_WIDTH ); p.drawLine( x1, y_base, x2, y_base - avail_height ); p.fillRect( x1 - 1, y_base - 2, 4, 4, end_points_bg_color ); p.fillRect( x1, y_base - 1, 2, 2, end_points_color ); x1 = x2; - x2 = x1 + static_cast( m_holdKnob->value() * time_unit_width ); + x2 = x1 + static_cast( m_holdKnob->value() * TIME_UNIT_WIDTH ); p.drawLine( x1, y_base - avail_height, x2, y_base - avail_height ); p.fillRect( x1 - 1, y_base - 2 - avail_height, 4, 4, @@ -718,7 +802,7 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) x1 = x2; x2 = x1 + static_cast( ( m_decayKnob->value() * m_sustainKnob->value() ) * - time_unit_width ); + TIME_UNIT_WIDTH ); p.drawLine( x1, y_base-avail_height, x2, static_cast( y_base - avail_height + @@ -727,7 +811,7 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) end_points_bg_color ); p.fillRect( x1, y_base - 1 - avail_height, 2, 2, end_points_color ); x1 = x2; - x2 = x1 + static_cast( m_releaseKnob->value() * time_unit_width ); + x2 = x1 + static_cast( m_releaseKnob->value() * TIME_UNIT_WIDTH ); p.drawLine( x1, static_cast( y_base - avail_height + m_sustainKnob->value() * @@ -744,10 +828,10 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) p.fillRect( x2, y_base - 1, 2, 2, end_points_color ); - int lfo_graph_w = s_lfoGraph->width() - 6; // substract border - int lfo_graph_h = s_lfoGraph->height() - 6; // substract border - int graph_x_base = lfo_graph_x + 3; - int graph_y_base = lfo_graph_y + 3 + lfo_graph_h / 2; + int LFO_GRAPH_W = s_lfoGraph->width() - 6; // substract border + int LFO_GRAPH_H = s_lfoGraph->height() - 6; // substract border + int graph_x_base = LFO_GRAPH_X + 3; + int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; const float frames_for_graph = SECS_PER_LFO_OSCILLATION * mixer::inst()->sampleRate() / 10; @@ -772,10 +856,10 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) #else int old_y = 0; #endif - for( int x = 0; x <= lfo_graph_w; ++x ) + for( int x = 0; x <= LFO_GRAPH_W; ++x ) { float val = 0.0; - float cur_sample = x*frames_for_graph/lfo_graph_w; + float cur_sample = x * frames_for_graph / LFO_GRAPH_W; if( static_cast( cur_sample ) > m_lfoPredelayFrames ) { float phase = ( cur_sample -= m_lfoPredelayFrames ) / @@ -795,6 +879,10 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) case SQUARE: val = oscillator::squareSample( phase ); break; + case USER: + val = oscillator::userWaveSample( phase, + m_userWave.data(), + m_userWave.frames() ); } if( (Uint32) cur_sample <= m_lfoAttackFrames ) { @@ -802,12 +890,12 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) } } #ifdef QT4 - float cur_y = -lfo_graph_h / 2.0f * val; + float cur_y = -LFO_GRAPH_H / 2.0f * val; p.drawLine( QLineF( graph_x_base + x - 1, graph_y_base + old_y, graph_x_base + x, graph_y_base + cur_y ) ); #else - int cur_y = static_cast( -lfo_graph_h / 2.0f * val ); + int cur_y = static_cast( -LFO_GRAPH_H / 2.0f * val ); p.drawLine( graph_x_base + x - 1, graph_y_base + old_y, graph_x_base + x, graph_y_base + cur_y ); #endif @@ -818,9 +906,9 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) int ms_per_osc = static_cast( SECS_PER_LFO_OSCILLATION * m_lfoSpeedKnob->value() * 1000.0f ); - p.drawText( lfo_graph_x + 4, lfo_graph_y + s_lfoGraph->height() - 6, + p.drawText( LFO_GRAPH_X + 4, LFO_GRAPH_Y + s_lfoGraph->height() - 6, tr( "ms/LFO:" ) ); - p.drawText( lfo_graph_x + 52, lfo_graph_y + s_lfoGraph->height() - 6, + p.drawText( LFO_GRAPH_X + 52, LFO_GRAPH_Y + s_lfoGraph->height() - 6, QString::number( ms_per_osc ) ); #ifndef QT4 @@ -832,44 +920,6 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) -void envelopeAndLFOWidget::mousePressEvent( QMouseEvent * _me ) -{ - if( _me->button() != Qt::LeftButton ) - { - return; - } - - if( QRect( env_graph_x, env_graph_y, s_envGraph->width(), - s_envGraph->height() ).contains( _me->pos() ) == TRUE ) - { - if( m_amountKnob->value() < 1.0f ) - { - m_amountKnob->setValue( 1.0f ); - } - else - { - m_amountKnob->setValue( 0.0f ); - } - updateSampleVars(); - } - else if( QRect( lfo_graph_x, lfo_graph_y, s_lfoGraph->width(), - s_lfoGraph->height() ).contains( _me->pos() ) == TRUE ) - { - if( m_lfoAmountKnob->value() < 1.0f ) - { - m_lfoAmountKnob->setValue( 1.0f ); - } - else - { - m_lfoAmountKnob->setValue( 0.0f ); - } - updateSampleVars(); - } -} - - - - void envelopeAndLFOWidget::updateSampleVars( void ) { if( !m_busy ) @@ -1023,7 +1073,12 @@ void envelopeAndLFOWidget::updateSampleVars( void ) m_lfoShapeData[frame] = oscillator::sawSample( phase ); break; - + case USER: + m_lfoShapeData[frame] = + oscillator::userWaveSample( phase, + m_userWave.data(), + m_userWave.frames() ); + break; case SIN: default: m_lfoShapeData[frame] = @@ -1113,8 +1168,25 @@ void envelopeAndLFOWidget::lfoSquareWaveCh( bool _on ) -#undef isChecked -#undef setChecked +void envelopeAndLFOWidget::lfoUserWaveCh( bool _on ) +{ + if( _on ) + { + if( m_userWave.frames() <= 1 ) + { + textFloat::displayMessage( tr( "Hint" ), + tr( "Drag a sample from somewhere and drop " + "it in this window." ), + embed::getIconPixmap( "hint" ), 3000 ); + } + m_lfoShape = USER; + } + songEditor::inst()->setModified(); + + update(); +} + + #include "envelope_and_lfo_widget.moc" diff --git a/src/core/file_browser.cpp b/src/core/file_browser.cpp index 0eecdc788..a68698306 100644 --- a/src/core/file_browser.cpp +++ b/src/core/file_browser.cpp @@ -36,6 +36,7 @@ #include #include +#include #endif @@ -52,6 +53,7 @@ #include "gui_templates.h" #include "instrument.h" #include "text_float.h" +#include "string_pair_drag.h" @@ -61,65 +63,23 @@ fileBrowser::fileBrowser( const QString & _path, const QString & _filter, sideBarWidget( _title, _pm, _parent ), m_contextMenuItem( NULL ), m_path( _path ), - m_filter( _filter ), - m_previewPlayHandle( NULL ) + m_filter( _filter ) { setWindowTitle( tr( "Browser" ) ); - m_l = new Q3ListView( contentParent() ); + m_l = new listView( contentParent() ); addContentWidget( m_l ); #ifdef QT4 - connect( m_l, SIGNAL( mouseButtonPressed( int, Q3ListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemPressed( int, Q3ListViewItem *, - const QPoint &, int ) ) ); - connect( m_l, SIGNAL( mouseButtonClicked( int, Q3ListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemReleased( int, Q3ListViewItem *, - const QPoint &, int ) ) ); - connect( m_l, SIGNAL( doubleClicked( Q3ListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemDoubleClicked( Q3ListViewItem *, - const QPoint &, int ) ) ); - connect( m_l, SIGNAL( contextMenuRequested( Q3ListViewItem *, const QPoint &, int ) ), this, SLOT( contextMenuRequest( Q3ListViewItem *, const QPoint &, int ) ) ); #else - connect( m_l, SIGNAL( mouseButtonPressed( int, QListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemPressed( int, QListViewItem *, - const QPoint &, int ) ) ); - connect( m_l, SIGNAL( mouseButtonClicked( int, QListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemReleased( int, QListViewItem *, - const QPoint &, int ) ) ); -/* connect( m_l, SIGNAL( pressed( QListViewItem * ) ), - this, SLOT( itemClicked( QListViewItem * ) ) );*/ - connect( m_l, SIGNAL( doubleClicked( QListViewItem *, - const QPoint &, int ) ), - this, SLOT( itemDoubleClicked( QListViewItem *, - const QPoint &, int ) ) ); - connect( m_l, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ), this, SLOT( contextMenuRequest( QListViewItem *, const QPoint &, int ) ) ); #endif - connect( m_l, SIGNAL( selectionChanged() ), this, - SLOT( selectionChanged() ) ); - - m_l->addColumn( tr( "Files" ) ); - m_l->setTreeStepSize( 12 ); - m_l->setDefaultRenameAction( Q3ListView::Accept ); - m_l->setSorting( -1 ); - //setColumnWidthMode (0, Manual); - //setColumnWidth (0, 196); - m_l->setShowToolTips( TRUE ); - //m_l->setGeometry (0, 0, 200, 600); - - m_l->setFont( pointSize<8>( m_l->font() ) ); QPushButton * reload_btn = new QPushButton( embed::getIconPixmap( @@ -196,148 +156,6 @@ void fileBrowser::keyPressEvent( QKeyEvent * _ke ) -#ifdef QT4 -void fileBrowser::itemPressed( int _btn, Q3ListViewItem * i, const QPoint &, int ) -#else -void fileBrowser::itemPressed( int _btn, QListViewItem * i, const QPoint &, int ) -#endif -{ - fileItem * f = dynamic_cast( i ); - if( f != NULL && _btn == Qt::LeftButton ) - { - if( m_previewPlayHandle != NULL ) - { - mixer::inst()->removePlayHandle( m_previewPlayHandle ); - m_previewPlayHandle = NULL; - } - if( f->type() == fileItem::SAMPLE_FILE ) - { - textFloat * tf = textFloat::displayMessage( - tr( "Loading sample" ), - tr( "Please wait, loading sample for " - "preview..." ), - embed::getIconPixmap( "sound_file", - 24, 24 ), 0 ); -#ifdef QT4 - qApp->processEvents( QEventLoop::AllEvents ); -#else - qApp->processEvents(); -#endif - samplePlayHandle * s = new samplePlayHandle( - f->fullName() ); - s->setDoneMayReturnTrue( FALSE ); - m_previewPlayHandle = s; - delete tf; - } - else if( f->type() == fileItem::PRESET_FILE ) - { - m_previewPlayHandle = new presetPreviewPlayHandle( - f->fullName() ); - } - if( m_previewPlayHandle != NULL ) - { - mixer::inst()->addPlayHandle( m_previewPlayHandle ); - } - } -} - - - - -#ifdef QT4 -void fileBrowser::itemReleased( int, Q3ListViewItem * i, const QPoint &, int ) -#else -void fileBrowser::itemReleased( int, QListViewItem * i, const QPoint &, int ) -#endif -{ - selectionChanged(); -} - - - - -void fileBrowser::selectionChanged( void ) -{ - if( m_previewPlayHandle != NULL ) - { - // if there're samples shorter than 3 seconds, we don't - // stop them if the user releases mouse-button... - samplePlayHandle * s = dynamic_cast( - m_previewPlayHandle ); - if( s != NULL ) - { - if( s->totalFrames() - s->framesDone() <= - static_cast( - mixer::inst()->sampleRate() * 3 ) ) - { - s->setDoneMayReturnTrue( TRUE ); - m_previewPlayHandle = NULL; - return; - } - } - mixer::inst()->removePlayHandle( m_previewPlayHandle ); - m_previewPlayHandle = NULL; - } -} - - - - -#ifdef QT4 -void fileBrowser::itemDoubleClicked( Q3ListViewItem * i, const QPoint &, int ) -#else -void fileBrowser::itemDoubleClicked( QListViewItem * i, const QPoint &, int ) -#endif -{ - fileItem * f = dynamic_cast( i ); - if( f != NULL ) - { - if( f->type() == fileItem::SAMPLE_FILE ) - { - // samples are per default opened in bb-editor because - // they're likely drum-samples etc. - channelTrack * ct = dynamic_cast( - track::create( - track::CHANNEL_TRACK, - bbEditor::inst() ) ); -#ifdef LMMS_DEBUG - assert( ct != NULL ); -#endif - instrument * afp = ct->loadInstrument( - "audiofileprocessor" ); - if( afp != NULL ) - { - afp->setParameter( "audiofile", f->fullName() ); - } - ct->toggledChannelButton( TRUE ); - } - else if( f->type() == fileItem::PRESET_FILE ) - { - // presets are per default opened in bb-editor - multimediaProject mmp( f->fullName() ); - track * t = track::create( track::CHANNEL_TRACK, - bbEditor::inst() ); - channelTrack * ct = dynamic_cast( t ); - if( ct != NULL ) - { - ct->loadTrackSpecificSettings( mmp.content(). - firstChild(). - toElement() ); - ct->toggledChannelButton( TRUE ); - } - } - else if( f->type() == fileItem::SONG_FILE ) - { - if( songEditor::inst()->mayChangeProject() == TRUE ) - { - songEditor::inst()->loadProject( - f->fullName() ); - } - } - } -} - - #ifdef QT4 void fileBrowser::contextMenuRequest( Q3ListViewItem * i, const QPoint &, int ) @@ -359,8 +177,6 @@ void fileBrowser::contextMenuRequest( QListViewItem * i, const QPoint &, int ) contextMenu->addAction( tr( "Open in new channel/B+B Editor" ), this, SLOT( openInNewChannelBBE() ) ); - //contextMenu->addSeparator (); - //contextMenu->addAction (tr("Rename"), this, SLOT(renameItem())); contextMenu->exec( QCursor::pos() ); m_contextMenuItem = NULL; delete contextMenu; @@ -487,9 +303,222 @@ void fileBrowser::openInNewChannelBBE( void ) -void fileBrowser::renameItem( void ) + + + + +listView::listView( QWidget * _parent ) : + Q3ListView( _parent ), + m_mousePressed( FALSE ), + m_pressPos(), + m_previewPlayHandle( NULL ) { - m_contextMenuItem->startRename( 0 ); + addColumn( tr( "Files" ) ); + setTreeStepSize( 12 ); + setSorting( -1 ); + setShowToolTips( TRUE ); + + setFont( pointSize<8>( font() ) ); +} + + + + +listView::~listView() +{ +} + + + + +void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me ) +{ + Q3ListView::contentsMouseDoubleClickEvent( _me ); + fileItem * f = dynamic_cast( itemAt( + contentsToViewport( _me->pos() ) ) ); + if( f != NULL ) + { + if( f->type() == fileItem::SAMPLE_FILE ) + { + // samples are per default opened in bb-editor because + // they're likely drum-samples etc. + channelTrack * ct = dynamic_cast( + track::create( + track::CHANNEL_TRACK, + bbEditor::inst() ) ); +#ifdef LMMS_DEBUG + assert( ct != NULL ); +#endif + instrument * afp = ct->loadInstrument( + "audiofileprocessor" ); + if( afp != NULL ) + { + afp->setParameter( "audiofile", f->fullName() ); + } + ct->toggledChannelButton( TRUE ); + } + else if( f->type() == fileItem::PRESET_FILE ) + { + // presets are per default opened in bb-editor + multimediaProject mmp( f->fullName() ); + track * t = track::create( track::CHANNEL_TRACK, + bbEditor::inst() ); + channelTrack * ct = dynamic_cast( t ); + if( ct != NULL ) + { + ct->loadTrackSpecificSettings( mmp.content(). + firstChild(). + toElement() ); + ct->toggledChannelButton( TRUE ); + } + } + else if( f->type() == fileItem::PROJECT_FILE ) + { + if( songEditor::inst()->mayChangeProject() == TRUE ) + { + songEditor::inst()->loadProject( + f->fullName() ); + } + } + } +} + + + + +void listView::contentsMousePressEvent( QMouseEvent * _me ) +{ + Q3ListView::contentsMousePressEvent( _me ); + if( _me->button() != Qt::LeftButton ) + { + return; + } + QPoint p( contentsToViewport( _me->pos() ) ); + Q3ListViewItem * i = itemAt( p ); + if ( i ) + { + if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) + + treeStepSize() * ( i->depth() + ( rootIsDecorated() ? + 1 : 0 ) ) + itemMargin() || + p.x() < header()->cellPos( + header()->mapToActual( 0 ) ) ) + { + m_pressPos = _me->pos(); + m_mousePressed = TRUE; + } + } + fileItem * f = dynamic_cast( i ); + if( f != NULL ) + { + if( m_previewPlayHandle != NULL ) + { + mixer::inst()->removePlayHandle( m_previewPlayHandle ); + m_previewPlayHandle = NULL; + } + if( f->type() == fileItem::SAMPLE_FILE ) + { + textFloat * tf = textFloat::displayMessage( + tr( "Loading sample" ), + tr( "Please wait, loading sample for " + "preview..." ), + embed::getIconPixmap( "sound_file", + 24, 24 ), 0 ); +#ifdef QT4 + qApp->processEvents( QEventLoop::AllEvents ); +#else + qApp->processEvents(); +#endif + samplePlayHandle * s = new samplePlayHandle( + f->fullName() ); + s->setDoneMayReturnTrue( FALSE ); + m_previewPlayHandle = s; + delete tf; + } + else if( f->type() == fileItem::PRESET_FILE ) + { + m_previewPlayHandle = new presetPreviewPlayHandle( + f->fullName() ); + } + if( m_previewPlayHandle != NULL ) + { + mixer::inst()->addPlayHandle( m_previewPlayHandle ); + } + } +} + + + + +void listView::contentsMouseMoveEvent( QMouseEvent * _me ) +{ + if( m_mousePressed == TRUE && + ( m_pressPos - _me->pos() ).manhattanLength() > + QApplication::startDragDistance() ) + { + contentsMouseReleaseEvent( NULL ); + fileItem * f = dynamic_cast( itemAt( + contentsToViewport( m_pressPos ) ) ); + if( f != NULL ) + { + switch( f->type() ) + { + case fileItem::PRESET_FILE: + new stringPairDrag( "presetfile", + f->fullName(), + embed::getIconPixmap( + "preset_file" ), + this ); + break; + + case fileItem::SAMPLE_FILE: + new stringPairDrag( "samplefile", + f->fullName(), + embed::getIconPixmap( + "sound_file" ), + this ); + break; + + case fileItem::MIDI_FILE: + new stringPairDrag( "midifile", + f->fullName(), + embed::getIconPixmap( + "midi_file" ), + this ); + break; + + default: + break; + } + } + } +} + + + + +void listView::contentsMouseReleaseEvent( QMouseEvent * _me ) +{ + m_mousePressed = FALSE; + if( m_previewPlayHandle != NULL ) + { + // if there're samples shorter than 3 seconds, we don't + // stop them if the user releases mouse-button... + samplePlayHandle * s = dynamic_cast( + m_previewPlayHandle ); + if( s != NULL ) + { + if( s->totalFrames() - s->framesDone() <= + static_cast( + mixer::inst()->sampleRate() * 3 ) ) + { + s->setDoneMayReturnTrue( TRUE ); + m_previewPlayHandle = NULL; + return; + } + } + mixer::inst()->removePlayHandle( m_previewPlayHandle ); + m_previewPlayHandle = NULL; + } } @@ -658,9 +687,10 @@ void directory::setup( void ) -QPixmap * fileItem::s_songFilePixmap = NULL; +QPixmap * fileItem::s_projectFilePixmap = NULL; QPixmap * fileItem::s_presetFilePixmap = NULL; QPixmap * fileItem::s_sampleFilePixmap = NULL; +QPixmap * fileItem::s_midiFilePixmap = NULL; QPixmap * fileItem::s_unknownFilePixmap = NULL; @@ -692,33 +722,46 @@ fileItem::fileItem( Q3ListViewItem * _parent, const QString & _name, void fileItem::initPixmapStuff( void ) { - if( s_songFilePixmap == NULL ) + if( s_projectFilePixmap == NULL ) { - s_songFilePixmap = new QPixmap( embed::getIconPixmap( + s_projectFilePixmap = new QPixmap( embed::getIconPixmap( "project_file", 16, 16 ) ); } + if( s_presetFilePixmap == NULL ) { s_presetFilePixmap = new QPixmap( embed::getIconPixmap( "preset_file", 16, 16 ) ); } + if( s_sampleFilePixmap == NULL ) { s_sampleFilePixmap = new QPixmap( embed::getIconPixmap( "sound_file", 16, 16 ) ); } + + if( s_midiFilePixmap == NULL ) + { + s_midiFilePixmap = new QPixmap( embed::getIconPixmap( + "midi_file", 16, 16 ) ); + } + if( s_unknownFilePixmap == NULL ) { s_unknownFilePixmap = new QPixmap( embed::getIconPixmap( - "unknown_file" ) ); + "unknown_file" ) ); } switch( m_type ) { - case SONG_FILE: m_pix = s_songFilePixmap; break; + case PROJECT_FILE: m_pix = s_projectFilePixmap; break; case PRESET_FILE: m_pix = s_presetFilePixmap; break; case SAMPLE_FILE: m_pix = s_sampleFilePixmap; break; - case UNKNOWN: m_pix = s_unknownFilePixmap; break; + case MIDI_FILE: m_pix = s_midiFilePixmap; break; + case UNKNOWN: + default: + m_pix = s_unknownFilePixmap; + break; } } @@ -734,7 +777,7 @@ void fileItem::determineFileType( void ) #endif if( ext == "mmp" || ext == "mpt" ) { - m_type = SONG_FILE; + m_type = PROJECT_FILE; } else if( ext == "xml" ) { @@ -742,7 +785,7 @@ void fileItem::determineFileType( void ) multimediaProject::typeOfFile( fullName() ); if( t == multimediaProject::SONG_PROJECT ) { - m_type = SONG_FILE; + m_type = PROJECT_FILE; } else if( t == multimediaProject::CHANNEL_SETTINGS ) { @@ -763,6 +806,10 @@ void fileItem::determineFileType( void ) { m_type = SAMPLE_FILE; } + else if( ext == "mid" ) + { + m_type = MIDI_FILE; + } else { m_type = UNKNOWN; diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 6c8b999a6..bf0bfda19 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -504,7 +504,7 @@ audioDevice * mixer::tryAudioDevices( void ) midiClient * mixer::tryMIDIClients( void ) { QString client_name = configManager::inst()->value( "mixer", - "midiclient" ); + "mididev" ); #ifdef ALSA_SUPPORT if( client_name == midiALSASeq::name() || client_name == "" ) diff --git a/src/core/name_label.cpp b/src/core/name_label.cpp index b96b72743..8ca723216 100644 --- a/src/core/name_label.cpp +++ b/src/core/name_label.cpp @@ -140,7 +140,7 @@ void nameLabel::mousePressEvent( QMouseEvent * _me ) else { emit clicked(); - //QLabel::mousePressEvent( _me ); + QLabel::mousePressEvent( _me ); } } diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 360f6cba4..f41fc7bd6 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -199,7 +199,7 @@ void notePlayHandle::play( void ) void notePlayHandle::checkValidity( void ) { if( m_channelTrack != NULL && - m_channelTrack->trackType() == track::NULL_TRACK ) + m_channelTrack->type() == track::NULL_TRACK ) { m_channelTrack = NULL; } diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index 241fb8d7a..6185130c7 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -140,8 +140,6 @@ pianoRoll::pianoRoll( void ) : m_notesEditHeight( 100 ), m_ppt( DEFAULT_PR_PPT ), m_lenOfNewNotes( midiTime( 0, 16 ) ), - m_shiftPressed( FALSE ), - m_controlPressed( FALSE ), m_startKey( INITIAL_START_KEY ), m_keyMouseOver( INITIAL_START_KEY ), m_lastKey( 0 ), @@ -1781,23 +1779,6 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) void pianoRoll::keyPressEvent( QKeyEvent * _ke ) { - if( _ke->key() == Qt::Key_Shift ) - { - m_shiftPressed = TRUE; - } - else - { - m_shiftPressed = FALSE; - } - if( _ke->key() == Qt::Key_Control ) - { - m_controlPressed = TRUE; - } - else - { - m_controlPressed = FALSE; - } - switch( _ke->key() ) { case Qt::Key_Up: @@ -1919,19 +1900,10 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) -void pianoRoll::keyReleaseEvent( QKeyEvent * ) -{ - m_shiftPressed = FALSE; - m_controlPressed = FALSE; -} - - - - void pianoRoll::wheelEvent( QWheelEvent * _we ) { _we->accept(); - if( m_controlPressed ) + if( lmmsMainWin::isCtrlPressed() == TRUE ) { if( _we->delta() > 0 ) { @@ -1958,7 +1930,7 @@ void pianoRoll::wheelEvent( QWheelEvent * _we ) m_timeLine->setPixelsPerTact( m_ppt ); update(); } - else if( m_shiftPressed ) + else if( lmmsMainWin::isShiftPressed() ) { m_leftRightScroll->setValue( m_leftRightScroll->value() - _we->delta() * 2 / 15 ); diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 4bc6fec44..b66fde8d5 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -23,25 +23,19 @@ */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_DLFCN_H -#include -#endif - #include "qt3support.h" #ifdef QT4 #include #include +#include #else #include #include +#include #endif @@ -87,15 +81,16 @@ QString plugin::getParameter( const QString & ) plugin * plugin::instantiate( const QString & _plugin_name, void * _data ) { -#ifdef HAVE_DLFCN_H +/*#ifdef HAVE_DLFCN_H void * handle = dlopen( QString( "lib" + _plugin_name + ".so" ). #ifdef QT4 toAscii().constData() #else ascii() #endif - , RTLD_NOW ); - if( handle == NULL ) + , RTLD_NOW );*/ + QLibrary plugin_lib( _plugin_name ); + if( /*handle == NULL*/ plugin_lib.load() == FALSE ) { QMessageBox::information( NULL, mixer::tr( "Plugin not found" ), @@ -105,13 +100,17 @@ plugin * plugin::instantiate( const QString & _plugin_name, void * _data ) QMessageBox::Default ); return( new dummyPlugin() ); } - dlerror(); + instantiationHook inst_hook = ( instantiationHook ) plugin_lib.resolve( + "lmms_plugin_main" ); +/* dlerror(); instantiationHook inst_hook = ( instantiationHook )( dlsym( handle, "lmms_plugin_main" ) ); char * error = dlerror(); if( error != NULL ) { - printf( "%s\n", error ); + printf( "%s\n", error );*/ + if( inst_hook == NULL ) + { QMessageBox::information( NULL, mixer::tr( "Error while loading plugin" ), mixer::tr( "Failed loading plugin \"%1\"!" @@ -120,11 +119,14 @@ plugin * plugin::instantiate( const QString & _plugin_name, void * _data ) QMessageBox::Default ); return( new dummyPlugin() ); } +#ifndef QT4 + plugin_lib.setAutoUnload( FALSE ); +#endif plugin * inst = inst_hook( _data ); //dlclose( handle ); return( inst ); -#endif - return( new dummyPlugin() ); +/*#endif + return( new dummyPlugin() );*/ } @@ -134,8 +136,8 @@ void plugin::getDescriptorsOfAvailPlugins( vvector & _plugin_descs ) { QDir directory( configManager::inst()->pluginDir() ); #ifdef QT4 - QFileInfoList list = directory.entryInfoList( QStringList( - "lib*.so" ) ); + QFileInfoList list = directory.entryInfoList( + QStringList( "lib*.so" ) ); #else const QFileInfoList * lp = directory.entryInfoList( "lib*.so" ); // if directory doesn't exist or isn't readable, we get NULL which would @@ -154,6 +156,16 @@ void plugin::getDescriptorsOfAvailPlugins( vvector & _plugin_descs ) #else const QFileInfo & f = **file; #endif + QLibrary plugin_lib( f.absoluteFilePath() ); + if( plugin_lib.load() == FALSE || + plugin_lib.resolve( "lmms_plugin_main" ) == NULL ) + { + continue; + } +#ifndef QT4 + plugin_lib.setAutoUnload( FALSE ); +#endif +/* void * handle = dlopen( f.absoluteFilePath(). #ifdef QT4 toAscii().constData(), @@ -173,11 +185,26 @@ void plugin::getDescriptorsOfAvailPlugins( vvector & _plugin_descs ) { printf( "plugin-loader: %s\n", msg ); continue; - } - QString desc_name = f.fileName().mid( 3 ).section( '.', 0, 0 ) + + }*/ + QString desc_name = f.fileName().section( '.', 0, 0 ) + "_plugin_descriptor"; - descriptor * plugin_desc = - (descriptor *) dlsym( handle, desc_name. + if( desc_name.left( 3 ) == "lib" ) + { + desc_name = desc_name.mid( 3 ); + } + descriptor * plugin_desc = (descriptor *) plugin_lib.resolve( + desc_name. +#ifdef QT4 + toAscii().constData() +#else + ascii() +#endif + ); + if( plugin_desc == NULL ) + { + continue; + } +/* (descriptor *) dlsym( handle, desc_name. #ifdef QT4 toAscii().constData() #else @@ -189,7 +216,7 @@ void plugin::getDescriptorsOfAvailPlugins( vvector & _plugin_descs ) { printf( "plugin-loader: %s\n", msg ); continue; - } + }*/ _plugin_descs.push_back( *plugin_desc ); //dlclose( handle ); } diff --git a/src/core/plugin_browser.cpp b/src/core/plugin_browser.cpp index eeac17e6a..dc3e67734 100644 --- a/src/core/plugin_browser.cpp +++ b/src/core/plugin_browser.cpp @@ -233,8 +233,8 @@ void pluginDescWidget::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton ) { - new stringPairDrag( "plugin", m_pluginDescriptor.name, m_logo, - this ); + new stringPairDrag( "instrument", m_pluginDescriptor.name, + m_logo, this ); m_mouseOver = FALSE; update(); } diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index dc248866c..bffdab9f1 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -109,13 +109,12 @@ songEditor::songEditor() : m_exporting( FALSE ), m_playing( FALSE ), m_paused( FALSE ), + m_loadingProject( FALSE ), m_playMode( PLAY_SONG ), m_trackToPlay( NULL ), m_patternToPlay( NULL ), m_loopPattern( FALSE ), - m_scrollBack( FALSE ), - m_shiftPressed( FALSE ), - m_controlPressed( FALSE ) + m_scrollBack( FALSE ) { // hack, because code called out of this function uses // songEditor::inst(), which assigns s_instanceOfMe this function @@ -211,7 +210,7 @@ songEditor::songEditor() : #endif m_masterVolumeSlider->setFixedSize( 26, 60 ); m_masterVolumeSlider->setTickInterval( 50 ); - toolTip::add( m_masterVolumeSlider, tr( "master output volume" ) ); + toolTip::add( m_masterVolumeSlider, tr( "master volume" ) ); connect( m_masterVolumeSlider, SIGNAL( valueChanged( int ) ), this, SLOT( masterVolumeChanged( int ) ) ); @@ -223,6 +222,8 @@ songEditor::songEditor() : SLOT( masterVolumeReleased() ) ); m_mvsStatus = new textFloat( m_masterVolumeSlider ); + m_mvsStatus->setTitle( tr( "Master volume" ) ); + m_mvsStatus->setPixmap( embed::getIconPixmap( "master_volume" ) ); lmmsMainWin::inst()->addWidgetToToolBar( master_vol_lbl ); lmmsMainWin::inst()->addWidgetToToolBar( m_masterVolumeSlider ); @@ -256,6 +257,8 @@ songEditor::songEditor() : SLOT( masterPitchReleased() ) ); m_mpsStatus = new textFloat( m_masterPitchSlider ); + m_mpsStatus->setTitle( tr( "Master pitch" ) ); + m_mpsStatus->setPixmap( embed::getIconPixmap( "master_pitch" ) ); lmmsMainWin::inst()->addWidgetToToolBar( master_pitch_lbl ); lmmsMainWin::inst()->addWidgetToToolBar( m_masterPitchSlider ); @@ -493,30 +496,15 @@ void songEditor::resizeEvent( QResizeEvent * _re ) void songEditor::keyPressEvent( QKeyEvent * _ke ) { - if( _ke->key() == Qt::Key_Shift ) - { - m_shiftPressed = TRUE; - } - else - { - m_shiftPressed = FALSE; - } - if( _ke->key() == Qt::Key_Control ) - { - m_controlPressed = TRUE; - } - else - { - m_controlPressed = FALSE; - } - - if( _ke->modifiers() & Qt::ShiftModifier && - _ke->key() == Qt::Key_Insert ) + if( /*_ke->modifiers() & Qt::ShiftModifier*/ + lmmsMainWin::isShiftPressed() == TRUE && + _ke->key() == Qt::Key_Insert ) { insertBar(); } - else if( _ke->modifiers() & Qt::ShiftModifier && - _ke->key() == Qt::Key_Delete ) + else if(/* _ke->modifiers() & Qt::ShiftModifier &&*/ + lmmsMainWin::isShiftPressed() == TRUE && + _ke->key() == Qt::Key_Delete ) { removeBar(); } @@ -557,7 +545,7 @@ void songEditor::keyPressEvent( QKeyEvent * _ke ) } else { - _ke->ignore(); + QWidget::keyPressEvent( _ke ); } } @@ -576,7 +564,7 @@ void songEditor::scrolled( int _new_pos ) void songEditor::wheelEvent( QWheelEvent * _we ) { - if( m_controlPressed ) + if( lmmsMainWin::isCtrlPressed() == TRUE ) { if( _we->delta() > 0 ) { @@ -592,12 +580,12 @@ void songEditor::wheelEvent( QWheelEvent * _we ) m_zoomingComboBox->setCurrentIndex( m_zoomingComboBox->findText( QString::number( static_cast( pixelsPerTact() * - 100 / DEFAULT_PIXELS_PER_TACT ) ) +"%" ) ); + 100 / DEFAULT_PIXELS_PER_TACT ) ) + "%" ) ); #else // update combobox with zooming-factor m_zoomingComboBox->setCurrentText( QString::number( static_cast( pixelsPerTact() * - 100 / DEFAULT_PIXELS_PER_TACT ) ) +"%" ); + 100 / DEFAULT_PIXELS_PER_TACT ) ) + "%" ); #endif // update timeline m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( @@ -605,7 +593,7 @@ void songEditor::wheelEvent( QWheelEvent * _we ) // and make sure, all TCO's are resized and relocated realignTracks( TRUE ); } - else if( m_shiftPressed ) + else if( lmmsMainWin::isShiftPressed() == TRUE ) { m_leftRightScroll->setValue( m_leftRightScroll->value() - _we->delta() / 30 ); @@ -623,10 +611,14 @@ void songEditor::wheelEvent( QWheelEvent * _we ) void songEditor::masterVolumeChanged( int _new_val ) { - if( m_mvsStatus->isVisible() == FALSE ) + masterVolumeMoved( _new_val ); + if( m_mvsStatus->isVisible() == FALSE && m_loadingProject == FALSE ) { - masterVolumeMoved( _new_val ); m_mvsStatus->reparent( m_masterVolumeSlider ); + m_mvsStatus->move( m_masterVolumeSlider->mapTo( + m_masterVolumeSlider->topLevelWidget(), + QPoint( 0, 0 ) ) + + QPoint( m_masterVolumeSlider->width() + 2, -2 ) ); m_mvsStatus->setVisibilityTimeOut( 1000 ); } mixer::inst()->setMasterGain( 2.0f - _new_val / 100.0f ); @@ -639,6 +631,10 @@ void songEditor::masterVolumeChanged( int _new_val ) void songEditor::masterVolumePressed( void ) { m_mvsStatus->reparent( m_masterVolumeSlider ); + m_mvsStatus->move( m_masterVolumeSlider->mapTo( + m_masterVolumeSlider->topLevelWidget(), + QPoint( 0, 0 ) ) + + QPoint( m_masterVolumeSlider->width() + 2, -2 ) ); m_mvsStatus->show(); masterVolumeMoved( m_masterVolumeSlider->value() ); } @@ -648,8 +644,7 @@ void songEditor::masterVolumePressed( void ) void songEditor::masterVolumeMoved( int _new_val ) { - m_mvsStatus->setText( tr( "Master output volume: %1%" ).arg( 200 - - _new_val ) ); + m_mvsStatus->setText( tr( "Value: %1%" ).arg( 200 - _new_val ) ); } @@ -665,10 +660,14 @@ void songEditor::masterVolumeReleased( void ) void songEditor::masterPitchChanged( int _new_val ) { - if( m_mpsStatus->isVisible() == FALSE ) + masterPitchMoved( _new_val ); + if( m_mpsStatus->isVisible() == FALSE && m_loadingProject == FALSE ) { - masterPitchMoved( _new_val ); m_mpsStatus->reparent( m_masterPitchSlider ); + m_mpsStatus->move( m_masterPitchSlider->mapTo( + m_masterPitchSlider->topLevelWidget(), + QPoint( 0, 0 ) ) + + QPoint( m_masterPitchSlider->width() + 2, -2 ) ); m_mpsStatus->setVisibilityTimeOut( 1000 ); } setModified(); @@ -680,6 +679,10 @@ void songEditor::masterPitchChanged( int _new_val ) void songEditor::masterPitchPressed( void ) { m_mpsStatus->reparent( m_masterPitchSlider ); + m_mpsStatus->move( m_masterPitchSlider->mapTo( + m_masterPitchSlider->topLevelWidget(), + QPoint( 0, 0 ) ) + + QPoint( m_masterPitchSlider->width() + 2, -2 ) ); m_mpsStatus->show(); masterPitchMoved( m_masterPitchSlider->value() ); } @@ -689,8 +692,7 @@ void songEditor::masterPitchPressed( void ) void songEditor::masterPitchMoved( int _new_val ) { - m_mpsStatus->setText( tr( "Master pitch: %1 semitones").arg( - -_new_val ) ); + m_mpsStatus->setText( tr( "Value: %1 semitones").arg( -_new_val ) ); } @@ -957,7 +959,7 @@ void songEditor::processNextBuffer( void ) while( total_frames_played < mixer::inst()->framesPerAudioBuffer() ) { Uint32 played_frames = mixer::inst()->framesPerAudioBuffer() - - total_frames_played; + total_frames_played; // did we play a whole tact? if( m_playPos[m_playMode].currentFrame() >= frames_per_tact ) @@ -1019,9 +1021,8 @@ void songEditor::processNextBuffer( void ) // update frame-counters total_frames_played += played_frames; - m_playPos[m_playMode].setCurrentFrame( - m_playPos[m_playMode].currentFrame() + - played_frames ); + m_playPos[m_playMode].setCurrentFrame( played_frames + + m_playPos[m_playMode].currentFrame() ); m_playPos[m_playMode].setTact64th( ( m_playPos[m_playMode].currentFrame() * 64 / frames_per_tact) % 64 ); @@ -1350,7 +1351,11 @@ void songEditor::clearProject( void ) //mixer::inst()->clear(); while( mixer::inst()->haveNoRunningNotes() == FALSE ) { -/* qApp->processEvents();*/ +#ifdef QT4 + QApplication::processEvents( QEventLoop::AllEvents ); +#else + qApp->processEvents(); +#endif } trackVector tv = tracks(); @@ -1385,9 +1390,11 @@ void songEditor::createNewProject( void ) "tripleoscillator" ); track::create( track::BB_TRACK, this ); + m_loadingProject = TRUE; setBPM( DEFAULT_BPM ); m_masterVolumeSlider->setValue( 100 ); m_masterPitchSlider->setValue( 0 ); + m_loadingProject = FALSE; m_fileName = m_oldFileName = ""; @@ -1419,6 +1426,8 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) m_fileName = _file_name; m_oldFileName = _file_name; + m_loadingProject = TRUE; + multimediaProject mmp( m_fileName ); // if file could not be opened, head-node is null and we create // new project @@ -1451,7 +1460,7 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) else { m_masterVolumeSlider->setValue( - DEFAULT_VOLUME ); + DEFAULT_VOLUME ); } } else if( node.nodeName() == "masterpitch" ) @@ -1485,6 +1494,8 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) m_modified = FALSE; m_leftRightScroll->setValue( 0 ); + m_loadingProject = FALSE; + lmmsMainWin::inst()->resetWindowTitle( "" ); } diff --git a/src/core/timeline.cpp b/src/core/timeline.cpp index e6c471247..ee54d7bb4 100644 --- a/src/core/timeline.cpp +++ b/src/core/timeline.cpp @@ -1,6 +1,5 @@ /* - * playpos_marker.cpp - class timeLine, representing a time-line with - * position marker + * timeline.cpp - class timeLine, representing a time-line with position marker * * Copyright (c) 2004-2005 Tobias Doerffel * @@ -48,6 +47,8 @@ #include "embed.h" #include "templates.h" #include "nstate_button.h" +#include "lmms_main_win.h" +#include "text_float.h" @@ -71,6 +72,7 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt, m_pos( _pos ), m_begin( _begin ), m_savedPos( -1 ), + m_hint( NULL ), m_action( NONE ), m_moveXOff( 0 ) { @@ -123,6 +125,7 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt, timeLine::~timeLine() { m_pos.m_timeLine = NULL; + delete m_hint; } @@ -244,8 +247,8 @@ void timeLine::paintEvent( QPaintEvent * ) const QPixmap & lpoint = loopPointsEnabled() ? *s_loopPointPixmap : *s_loopPointDisabledPixmap; - p.drawPixmap( markerX( m_loopPos[0] ), 7, lpoint ); - p.drawPixmap( markerX( m_loopPos[1] ), 7, lpoint ); + p.drawPixmap( markerX( loopBegin() ), 7, lpoint ); + p.drawPixmap( markerX( loopEnd() ), 7, lpoint ); tact tact_num = m_begin.getTact(); @@ -292,16 +295,41 @@ void timeLine::mousePressEvent( QMouseEvent * _me ) s_loopPointPixmap->width() ) { m_action = MOVE_LOOP_BEGIN; - m_moveXOff = s_loopPointPixmap->width() / 2; } else if( _me->x() >= markerX( loopEnd() ) && _me->x() <= markerX( loopEnd() ) + s_loopPointPixmap->width() ) { m_action = MOVE_LOOP_END; + } + if( m_action != NONE ) + { m_moveXOff = s_loopPointPixmap->width() / 2; } } + else if( _me->button() == Qt::MidButton ) + { + const midiTime t = m_begin + + static_cast( _me->x() * 64 / m_ppt ); + Uint8 pmin = 0; + Uint8 pmax = 1; + m_action = MOVE_LOOP_BEGIN; + if( m_loopPos[pmin] > m_loopPos[pmax] ) + { + qSwap( pmin, pmax ); + m_action = MOVE_LOOP_END; + } + if( lmmsMainWin::isShiftPressed() == TRUE ) + { + m_loopPos[pmax] = t; + m_action = ( m_action == MOVE_LOOP_BEGIN ) ? + MOVE_LOOP_END : MOVE_LOOP_BEGIN; + } + else + { + m_loopPos[pmin] = t; + } + } else { m_action = MOVE_POS_MARKER; @@ -314,6 +342,14 @@ void timeLine::mousePressEvent( QMouseEvent * _me ) m_moveXOff = s_posMarkerPixmap->width() / 2; } } + if( m_action == MOVE_LOOP_BEGIN || m_action == MOVE_LOOP_END ) + { + delete m_hint; + m_hint = textFloat::displayMessage( tr( "Hint" ), + tr( "Press to disable magnetic " + "loop-points." ), + embed::getIconPixmap( "hint" ), 0 ); + } mouseMoveEvent( _me ); } @@ -334,14 +370,27 @@ void timeLine::mouseMoveEvent( QMouseEvent * _me ) break; case MOVE_LOOP_BEGIN: - m_loopPos[0] = t.getTact() * 64; - update(); - break; - case MOVE_LOOP_END: - m_loopPos[1] = t.getTact() * 64; + { + Uint8 i = m_action - MOVE_LOOP_BEGIN; + if( lmmsMainWin::isCtrlPressed() == TRUE ) + { + // no ctrl-press-hint when having ctrl pressed + delete m_hint; + m_hint = NULL; + m_loopPos[i] = t; + } + else + { + m_loopPos[i] = t.getTact() * 64; + if( t.getTact64th() >= 32 ) + { + m_loopPos[i] += 64; + } + } update(); break; + } default: break; @@ -353,6 +402,8 @@ void timeLine::mouseMoveEvent( QMouseEvent * _me ) void timeLine::mouseReleaseEvent( QMouseEvent * _me ) { + delete m_hint; + m_hint = NULL; m_action = NONE; } diff --git a/src/core/track.cpp b/src/core/track.cpp index 93201dec5..ca84f4dc1 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -58,6 +58,10 @@ #include "pixmap_button.h" #include "debug.h" #include "tooltip.h" +#include "string_pair_drag.h" +#include "mmp.h" +#include "lmms_main_win.h" +#include "text_float.h" @@ -68,6 +72,8 @@ const Uint16 TRACK_OP_BTN_HEIGHT = 14; +textFloat * trackContentObject::s_textFloat = NULL; + // =========================================================================== // trackContentObject @@ -86,6 +92,13 @@ trackContentObject::trackContentObject( track * _track ) : m_autoResize( FALSE ), m_initialMouseX( 0 ) { + if( s_textFloat == NULL ) + { + s_textFloat = new textFloat( this ); + s_textFloat->setPixmap( embed::getIconPixmap( + "xclock", 24, 24 ) ); + } + #ifdef QT4 setAttribute( Qt::WA_DeleteOnClose ); setFocusPolicy( Qt::StrongFocus ); @@ -95,9 +108,10 @@ trackContentObject::trackContentObject( track * _track ) : show(); movePosition( 0 ); changeLength( 0 ); - setFixedHeight( parentWidget()->height()-2 ); -// if( useFixedWidth() ) -// setFixedWidth( _channel_track->getTrackContentWidget()->width() ); + + setFixedHeight( parentWidget()->height() - 2 ); + setAcceptDrops( TRUE ); + setMouseTracking( TRUE ); } @@ -129,7 +143,6 @@ void trackContentObject::movePosition( const midiTime & _pos ) // moving of TCO can result in change of song-length etc., // therefore we update the trackcontainer m_track->getTrackContainer()->update(); - setMouseTracking( TRUE ); } @@ -166,25 +179,103 @@ float trackContentObject::pixelsPerTact( void ) +void trackContentObject::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, "tco_" + + QString::number( m_track->type() ) ); +} + + + + +void trackContentObject::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == ( "tco_" + QString::number( m_track->type() ) ) ) + { + // 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 + // the user doesn't expect... + midiTime pos = startPosition(); + loadSettings( mmp.content().firstChild().toElement() ); + movePosition( pos ); + _de->accept(); + } +} + + + + +void trackContentObject::leaveEvent( QEvent * _e ) +{ + while( QApplication::overrideCursor() != NULL ) + { + QApplication::restoreOverrideCursor(); + } + if( _e != NULL ) + { + QWidget::leaveEvent( _e ); + } +} + + + void trackContentObject::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton && fixedTCOs() == FALSE ) + if( _me->button() == Qt::LeftButton && lmmsMainWin::isCtrlPressed() ) { - m_initialMouseX = _me->x() - TCO_BORDER_WIDTH; + multimediaProject mmp( multimediaProject::DRAG_N_DROP_DATA ); + saveSettings( mmp, mmp.content() ); +#ifdef QT4 + QPixmap thumbnail = QPixmap::grabWidget( this ).scaled( + 128, 128, + Qt::KeepAspectRatio, + Qt::SmoothTransformation ); +#else + QSize s( size() ); + s.scale( 128, 128, QSize::ScaleMin ); + QPixmap thumbnail = QPixmap::grabWidget( this ). + convertToImage().smoothScale( s ); +#endif + new stringPairDrag( "tco_" + + QString::number( m_track->type() ), + mmp.toString(), thumbnail, this ); + } + else if( _me->button() == Qt::LeftButton && + /* lmmsMainWin::isShiftPressed() == FALSE &&*/ + fixedTCOs() == FALSE ) + { + m_initialMouseX = _me->x(); - if( _me->x() < width()-RESIZE_GRIP_WIDTH ) + if( _me->x() < width() - RESIZE_GRIP_WIDTH ) { m_moving = TRUE; QCursor c( Qt::SizeAllCursor ); QApplication::setOverrideCursor( c ); + s_textFloat->setTitle( tr( "Current position" ) ); } else if( m_autoResize == FALSE ) { m_resizing = TRUE; QCursor c( Qt::SizeHorCursor ); QApplication::setOverrideCursor( c ); + s_textFloat->setTitle( tr( "Current length" ) ); } + s_textFloat->reparent( this ); + // setup text-float as if TCO was already moved/resized + mouseMoveEvent( _me ); + s_textFloat->show(); + } + else if( ( _me->button() == Qt::MidButton/* || + ( _me->button() == Qt::LeftButton && + lmmsMainWin::isShiftPressed() == TRUE )*/ ) && + fixedTCOs() == FALSE ) + { + close(); } } @@ -201,15 +292,25 @@ void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) currentPosition() + static_cast( x * 64 / ppt ) ) ); m_track->getTrackWidget()->changePosition(); + s_textFloat->setText( QString( "%1:%2" ). + arg( m_startPosition.getTact() + 1 ). + arg( m_startPosition.getTact64th() ) ); + s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + + QPoint( -2 - s_textFloat->width(), 8 ) ); } else if( m_resizing ) { changeLength( tMax( 64, static_cast( _me->x() * 64 / ppt ) ) ); + s_textFloat->setText( QString( "%1:%2" ). + arg( length().getTact() + 1 ). + arg( length().getTact64th() ) ); + s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + + QPoint( width() + 2, 8 ) ); } else { - if( _me->x() >= width()-RESIZE_GRIP_WIDTH ) + if( _me->x() > width() - RESIZE_GRIP_WIDTH ) { if( QApplication::overrideCursor() != NULL && QApplication::overrideCursor()->shape() != @@ -225,10 +326,7 @@ void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) } else { - while( QApplication::overrideCursor() != NULL ) - { - QApplication::restoreOverrideCursor(); - } + leaveEvent( NULL ); } } } @@ -238,10 +336,8 @@ void trackContentObject::mouseMoveEvent( QMouseEvent * _me ) void trackContentObject::mouseReleaseEvent( QMouseEvent * _me ) { - while( QApplication::overrideCursor() != NULL ) - { - QApplication::restoreOverrideCursor(); - } + s_textFloat->hide(); + leaveEvent( NULL ); m_moving = FALSE; m_resizing = FALSE; } @@ -255,7 +351,8 @@ void trackContentObject::contextMenuEvent( QContextMenuEvent * _cme ) if( fixedTCOs() == FALSE ) { contextMenu.addAction( embed::getIconPixmap( "cancel" ), - tr( "Delete" ), this, SLOT( close() ) ); + tr( "Delete (middle mousebutton)" ), + this, SLOT( close() ) ); #ifdef QT4 contextMenu.addSeparator(); #else @@ -344,6 +441,7 @@ trackContentWidget::trackContentWidget( trackWidget * _parent ) : setPaletteBackgroundColor( QColor( 96, 96, 96 ) ); #endif setMouseTracking( TRUE ); + setAcceptDrops( TRUE ); } @@ -364,9 +462,8 @@ trackContentObject * FASTCALL trackContentWidget::getTCO( csize _tco_num ) } printf( "called trackContentWidget::getTCO( %d, TRUE ), " " but TCO %d doesn't exist\n", _tco_num, _tco_num ); - //m_trackWidget->getTrack().addTCO( - // m_trackWidget->getTrack().createTCO() ); - return( NULL ); + return( getTrack()->addTCO( getTrack()->createTCO( _tco_num * 64 ) ) ); +// return( NULL ); } @@ -384,7 +481,7 @@ trackContentObject * FASTCALL trackContentWidget::addTCO( trackContentObject * _tco ) { m_trackContentObjects.push_back( _tco ); - _tco->move( 0, 1 );//(m_trackWidget->height()-_tco->height())/2 ); + _tco->move( 0, 1 ); m_trackWidget->changePosition(); songEditor::inst()->setModified(); return( _tco ); // just for convenience @@ -511,24 +608,49 @@ void trackContentWidget::updateTCOs( void ) +void trackContentWidget::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, "tco_" + + QString::number( getTrack()->type() ) ); +} + + + + +void trackContentWidget::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == ( "tco_" + QString::number( getTrack()->type() ) ) && + getTrack()->getTrackContainer()->fixedTCOs() == FALSE ) + { + const midiTime position = getPosition( _de->pos().x() ); + trackContentObject * tco = addTCO( getTrack()->createTCO( + position ) ); + // 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 + // the user doesn't expect... + tco->loadSettings( mmp.content().firstChild().toElement() ); + tco->movePosition( position ); + _de->accept(); + } +} + + + + + + void trackContentWidget::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton && - m_trackWidget->getTrack()->getTrackContainer()->fixedTCOs() == - FALSE ) + getTrack()->getTrackContainer()->fixedTCOs() == FALSE ) { - const midiTime position = midiTime( m_trackWidget->getTrack()-> - getTrackContainer()-> - currentPosition() + _me->x() * - 64 / - static_cast( - m_trackWidget-> - getTrack()-> - getTrackContainer()-> - pixelsPerTact() - ) ); - trackContentObject * tco = addTCO( m_trackWidget->getTrack()-> - createTCO( position ) ); + const midiTime position = getPosition( _me->x() ); + trackContentObject * tco = addTCO( getTrack()->createTCO( + position ) ); tco->movePosition( position ); } } @@ -570,6 +692,61 @@ void trackContentWidget::resizeEvent( QResizeEvent * _re ) +track * trackContentWidget::getTrack( void ) +{ + return( m_trackWidget->getTrack() ); +} + + + + +midiTime trackContentWidget::getPosition( int _mouse_x ) +{ + const trackContainer * tc = getTrack()->getTrackContainer(); + return( midiTime( tc->currentPosition() + _mouse_x * 64 / + static_cast( tc->pixelsPerTact() ) ) ); +} + + + + +// =========================================================================== +// trackSettingsWidget +// =========================================================================== + +trackSettingsWidget::trackSettingsWidget( trackWidget * _parent ) : + QWidget( _parent ), + m_trackWidget( _parent ) +{ +} + + + + +trackSettingsWidget::~trackSettingsWidget() +{ +} + + + + +void trackSettingsWidget::mousePressEvent( QMouseEvent * _me ) +{ + if( _me->button() == Qt::LeftButton && + m_trackWidget->getTrack()->type() != track::BB_TRACK ) + { + multimediaProject mmp( multimediaProject::DRAG_N_DROP_DATA ); + m_trackWidget->getTrack()->saveSettings( mmp, mmp.content() ); + new stringPairDrag( "track_" + + QString::number( m_trackWidget->getTrack()->type() ), + mmp.toString(), QPixmap::grabWidget( this ), this ); + } +} + + + + + // =========================================================================== // trackWidget @@ -677,6 +854,8 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) : #ifndef QT4 setBackgroundMode( Qt::NoBackground ); #endif + setAcceptDrops( TRUE ); + setMouseTracking( TRUE ); } @@ -689,62 +868,6 @@ trackWidget::~trackWidget() -void trackWidget::paintEvent( QPaintEvent * _pe ) -{ -#ifdef QT4 - QPainter p( this ); -#else - // create pixmap for whole widget - QPixmap pm( rect().size() ); - pm.fill( QColor( 128, 128, 128 ) ); - - // and a painter for it - QPainter p( &pm ); -#endif - p.setPen( QColor( 0, 0, 0 ) ); - p.drawLine( 0, height()-1, width()-1, height()-1 ); - -#ifndef QT4 - // blit drawn pixmap to actual widget - bitBlt( this, rect().topLeft(), &pm ); -#endif -} - - - - -void trackWidget::cloneTrack( void ) -{ - m_track->getTrackContainer()->cloneTrack( m_track ); -} - - - - -void trackWidget::removeTrack( void ) -{ - m_track->getTrackContainer()->removeTrack( m_track ); -} - - - - -void trackWidget::moveTrackUp( void ) -{ - m_track->getTrackContainer()->moveTrackUp( m_track ); -} - - - - -void trackWidget::moveTrackDown( void ) -{ - m_track->getTrackContainer()->moveTrackDown( m_track ); -} - - - - bool trackWidget::muted( void ) const { #ifdef QT4 @@ -757,39 +880,6 @@ bool trackWidget::muted( void ) const -void trackWidget::setMuted( bool _muted ) -{ -#ifdef QT4 - m_muteBtn->setChecked( _muted ); -#else - m_muteBtn->setOn( _muted ); -#endif - m_trackContentWidget.updateTCOs(); -} - - - - -void trackWidget::muteBtnRightClicked( void ) -{ - bool m = muted(); - m_track->getTrackContainer()->setMutedOfAllTracks( m ); - setMuted( !m ); -} - - - - -midiTime trackWidget::endPosition( const midiTime & _pos_start ) -{ - const float ppt = m_track->getTrackContainer()->pixelsPerTact(); - const int cww = m_trackContentWidget.width(); - return( _pos_start + static_cast( cww * 64 / ppt ) ); -} - - - - // resposible for moving track-content-widgets to appropriate position after // change of visible viewport void trackWidget::changePosition( const midiTime & _new_pos ) @@ -830,6 +920,111 @@ void trackWidget::changePosition( const midiTime & _new_pos ) +void trackWidget::cloneTrack( void ) +{ + m_track->getTrackContainer()->cloneTrack( m_track ); +} + + + + +void trackWidget::removeTrack( void ) +{ + m_track->getTrackContainer()->removeTrack( m_track ); +} + + + + +void trackWidget::moveTrackUp( void ) +{ + m_track->getTrackContainer()->moveTrackUp( m_track ); +} + + + + +void trackWidget::moveTrackDown( void ) +{ + m_track->getTrackContainer()->moveTrackDown( m_track ); +} + + + + +void trackWidget::setMuted( bool _muted ) +{ +#ifdef QT4 + m_muteBtn->setChecked( _muted ); +#else + m_muteBtn->setOn( _muted ); +#endif + m_trackContentWidget.updateTCOs(); +} + + + + +void trackWidget::muteBtnRightClicked( void ) +{ + bool m = muted(); + m_track->getTrackContainer()->setMutedOfAllTracks( m ); + setMuted( !m ); +} + + + + +void trackWidget::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, "track_" + + QString::number( m_track->type() ) ); +} + + + + +void trackWidget::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == ( "track_" + QString::number( m_track->type() ) ) ) + { + // value contains our XML-data so simply create a + // multimediaProject which does the rest for us... + multimediaProject mmp( value, FALSE ); + m_track->loadSettings( mmp.content().firstChild().toElement() ); + _de->accept(); + } +} + + + + +void trackWidget::paintEvent( QPaintEvent * _pe ) +{ +#ifdef QT4 + QPainter p( this ); +#else + // create pixmap for whole widget + QPixmap pm( rect().size() ); + pm.fill( QColor( 128, 128, 128 ) ); + + // and a painter for it + QPainter p( &pm ); +#endif + p.setPen( QColor( 0, 0, 0 ) ); + p.drawLine( 0, height() - 1, width() - 1, height() - 1 ); + +#ifndef QT4 + // blit drawn pixmap to actual widget + bitBlt( this, rect().topLeft(), &pm ); +#endif +} + + + + void trackWidget::resizeEvent( QResizeEvent * _re ) { m_trackOperationsWidget.setFixedSize( TRACK_OP_WIDTH, height() - 1 ); @@ -848,6 +1043,18 @@ void trackWidget::resizeEvent( QResizeEvent * _re ) +midiTime trackWidget::endPosition( const midiTime & _pos_start ) +{ + const float ppt = m_track->getTrackContainer()->pixelsPerTact(); + const int cww = m_trackContentWidget.width(); + return( _pos_start + static_cast( cww * 64 / ppt ) ); +} + + + + + + // =========================================================================== // track // =========================================================================== @@ -894,6 +1101,7 @@ track * FASTCALL track::create( trackTypes _tt, trackContainer * _tc ) + track * FASTCALL track::create( const QDomElement & _this, trackContainer * _tc ) { @@ -934,7 +1142,7 @@ void FASTCALL track::saveSettings( QDomDocument & _doc, QDomElement & _parent ) csize num_of_tcos = getTrackContentWidget()->numOfTCOs(); QDomElement track_de = _doc.createElement( "track" ); - track_de.setAttribute( "type", QString::number( trackType() ) ); + track_de.setAttribute( "type", QString::number( type() ) ); track_de.setAttribute( "muted", muted() ); _parent.appendChild( track_de ); @@ -955,7 +1163,7 @@ void FASTCALL track::saveSettings( QDomDocument & _doc, QDomElement & _parent ) void FASTCALL track::loadSettings( const QDomElement & _this ) { - if( _this.attribute( "type" ).toInt() != trackType() ) + if( _this.attribute( "type" ).toInt() != type() ) { qWarning( "Current track-type does not match track-type of " "settings-node!\n" ); diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index c01315733..0e79976e4 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -56,6 +56,7 @@ #include "channel_track.h" #include "mmp.h" #include "config_mgr.h" +#include "midi_file.h" @@ -309,7 +310,7 @@ unsigned int trackContainer::countTracks( track::trackTypes _tt ) const for( trackWidgetVector::const_iterator it = m_trackWidgets.begin(); it != m_trackWidgets.end(); ++it ) { - if( ( *it )->getTrack()->trackType() == _tt || + if( ( *it )->getTrack()->type() == _tt || _tt == track::TOTAL_TRACK_TYPES ) { ++cnt; @@ -379,7 +380,10 @@ void trackContainer::resizeEvent( QResizeEvent * ) void trackContainer::dragEnterEvent( QDragEnterEvent * _dee ) { - stringPairDrag::processDragEnterEvent( _dee, "preset,plugin" ); + stringPairDrag::processDragEnterEvent( _dee, + QString( "presetfile,instrument,midifile,track_%1,track_%2" ). + arg( track::CHANNEL_TRACK ). + arg( track::SAMPLE_TRACK ) ); } @@ -389,15 +393,16 @@ void trackContainer::dropEvent( QDropEvent * _de ) { QString type = stringPairDrag::decodeKey( _de ); QString value = stringPairDrag::decodeValue( _de ); - if( type == "plugin" ) + if( type == "instrument" ) { channelTrack * ct = dynamic_cast( track::create( track::CHANNEL_TRACK, this ) ); ct->loadInstrument( value ); ct->toggledChannelButton( TRUE ); + _de->accept(); } - else if( type == "preset" ) + else if( type == "presetfile" ) { multimediaProject mmp( value ); channelTrack * ct = dynamic_cast( @@ -406,6 +411,22 @@ void trackContainer::dropEvent( QDropEvent * _de ) ct->loadTrackSpecificSettings( mmp.content().firstChild(). toElement() ); ct->toggledChannelButton( TRUE ); + _de->accept(); + } + else if( type == "midifile" ) + { + midiFile mf( value ); + mf.importToTrackContainer( this ); + _de->accept(); + } + else if( type.left( 6 ) == "track_" ) + { + multimediaProject mmp( value, FALSE ); + track::create( mmp.content().firstChild().toElement(), this ); + // after adding a track, we have to make sure, actual editor + // can setup new track (e.g. adding TCO's (bbEditor does so)) + updateAfterTrackAdd(); + _de->accept(); } } @@ -415,7 +436,7 @@ void trackContainer::dropEvent( QDropEvent * _de ) void trackContainer::updateScrollArea( void ) { m_scrollArea->resize( tMax( m_scrollArea->parentWidget()->width() - - m_scrollArea->x()-2, 0 ), + m_scrollArea->x() - 2, 0 ), tMax( m_scrollArea->parentWidget()->height() - m_scrollArea->y() - 2, 0 ) ); //m_scrollArea->updateContents(); diff --git a/src/lib/ladspa_manager.cpp b/src/lib/ladspa_manager.cpp index 6c1662683..0780ae91b 100644 --- a/src/lib/ladspa_manager.cpp +++ b/src/lib/ladspa_manager.cpp @@ -33,21 +33,19 @@ #include #include +#include #else #include #include +#include #define value data #endif -#ifdef HAVE_DLFCN_H -#include -#endif - #include @@ -58,14 +56,11 @@ ladspaManager * ladspaManager::s_instanceOfMe = NULL; ladspaManager::ladspaManager( void ) { - LADSPA_Descriptor_Function descriptorFunction; - void * pluginHandle; - // TODO Need to move the search path definition to the config file to // have more control over where it tries to find the plugins. #ifdef QT4 QStringList ladspaDirectories = QString( getenv( "LADSPA_PATH" ) ). - split( ' ' ); + split( ':' ); #else QStringList ladspaDirectories = QStringList::split( ':', QString( getenv( "LADSPA_PATH" ) ) ); @@ -100,7 +95,8 @@ ladspaManager::ladspaManager( void ) #else const QFileInfo & f = **file; #endif - pluginHandle = dlopen( f.absoluteFilePath(). + QLibrary plugin_lib( f.absoluteFilePath() ); +/* pluginHandle = dlopen( f.absoluteFilePath(). #ifdef QT4 toAscii().constData(), #else @@ -109,18 +105,22 @@ ladspaManager::ladspaManager( void ) RTLD_LAZY ); if( pluginHandle ) { - dlerror(); - descriptorFunction - = ( LADSPA_Descriptor_Function ) - dlsym( pluginHandle, + dlerror();*/ + if( plugin_lib.load() == TRUE ) + { + LADSPA_Descriptor_Function descriptorFunction = + ( LADSPA_Descriptor_Function ) plugin_lib.resolve( "ladspa_descriptor" ); - if( dlerror() == NULL && descriptorFunction ) + if( /*dlerror() == NULL &&*/ + descriptorFunction != NULL ) { - addPlugins( pluginHandle, - descriptorFunction, - f.fileName() ); +#ifndef QT4 + plugin_lib.setAutoUnload( FALSE ); +#endif + addPlugins( descriptorFunction, + f.fileName() ); } - else +/* else { dlclose( ( void * ) f.absoluteFilePath(). @@ -130,7 +130,7 @@ ladspaManager::ladspaManager( void ) ascii() #endif ); - } + }*/ } } } @@ -141,20 +141,21 @@ ladspaManager::ladspaManager( void ) ladspaManager::~ladspaManager() { - for( ladspaManagerMapType::Iterator it = m_ladspaManagerMap.begin(); + // we trust in auto-unloading-mechanisms of OS +/* for( ladspaManagerMapType::Iterator it = m_ladspaManagerMap.begin(); it != m_ladspaManagerMap.end(); ++it ) { dlclose( it.value()->pluginHandle ); } - m_ladspaManagerMap.clear(); + m_ladspaManagerMap.clear();*/ } -void FASTCALL ladspaManager::addPlugins( void * _plugin_handle, - LADSPA_Descriptor_Function _descriptor_func, - const QString & _file ) +void FASTCALL ladspaManager::addPlugins( + LADSPA_Descriptor_Function _descriptor_func, + const QString & _file ) { const LADSPA_Descriptor * descriptor; long pluginIndex = 0; @@ -163,7 +164,6 @@ void FASTCALL ladspaManager::addPlugins( void * _plugin_handle, { ladspaManagerDescription * plugIn = new ladspaManagerDescription; - plugIn->pluginHandle = _plugin_handle; plugIn->descriptorFunction = _descriptor_func; plugIn->index = pluginIndex; @@ -180,10 +180,11 @@ QString FASTCALL ladspaManager::getLabel( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( QString( descriptor->Label ) ); } else @@ -199,10 +200,11 @@ bool FASTCALL ladspaManager::hasRealTimeDependency( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_REALTIME( descriptor->Properties ) ); } else @@ -218,10 +220,11 @@ bool FASTCALL ladspaManager::isInplaceBroken( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_INPLACE_BROKEN( descriptor->Properties ) ); } else @@ -237,10 +240,11 @@ bool FASTCALL ladspaManager::isRealTimeCapable( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_HARD_RT_CAPABLE( descriptor->Properties ) ); } else @@ -256,10 +260,11 @@ QString FASTCALL ladspaManager::getName( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( QString( descriptor->Name ) ); } else @@ -275,10 +280,11 @@ QString FASTCALL ladspaManager::getMaker( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( QString( descriptor->Maker ) ); } else @@ -294,10 +300,11 @@ QString FASTCALL ladspaManager::getCopyright( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( QString( descriptor->Copyright ) ); } else @@ -313,10 +320,11 @@ Uint32 FASTCALL ladspaManager::getPortCount( const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( descriptor->PortCount ); } else @@ -329,15 +337,16 @@ Uint32 FASTCALL ladspaManager::getPortCount( const ladspaKey & _plugin ) bool FASTCALL ladspaManager::isPortInput( const ladspaKey & _plugin, - Uint32 _port ) + Uint32 _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_PORT_INPUT ( descriptor->PortDescriptors[_port] ) ); @@ -352,15 +361,16 @@ bool FASTCALL ladspaManager::isPortInput( const ladspaKey & _plugin, bool FASTCALL ladspaManager::isPortOutput( const ladspaKey & _plugin, - Uint32 _port ) + Uint32 _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_PORT_OUTPUT ( descriptor->PortDescriptors[_port] ) ); @@ -374,15 +384,17 @@ bool FASTCALL ladspaManager::isPortOutput( const ladspaKey & _plugin, -bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin, Uint32 _port ) +bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin, + Uint32 _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_PORT_AUDIO ( descriptor->PortDescriptors[_port] ) ); @@ -397,15 +409,16 @@ bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin, Uint32 _por bool FASTCALL ladspaManager::isPortControl( const ladspaKey & _plugin, - Uint32 _port ) + Uint32 _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_PORT_CONTROL ( descriptor->PortDescriptors[_port] ) ); @@ -426,14 +439,14 @@ bool FASTCALL ladspaManager::areHintsSampleRateDependent( if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - return( LADSPA_IS_HINT_SAMPLE_RATE - ( hintDescriptor ) ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + return( LADSPA_IS_HINT_SAMPLE_RATE ( hintDescriptor ) ); } else { @@ -450,14 +463,14 @@ float FASTCALL ladspaManager::getLowerBound( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - if( LADSPA_IS_HINT_BOUNDED_BELOW - ( hintDescriptor ) ) + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + if( LADSPA_IS_HINT_BOUNDED_BELOW( hintDescriptor ) ) { return( descriptor->PortRangeHints[_port].LowerBound ); } @@ -480,14 +493,14 @@ float FASTCALL ladspaManager::getUpperBound( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - if( LADSPA_IS_HINT_BOUNDED_ABOVE - ( hintDescriptor ) ) + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + if( LADSPA_IS_HINT_BOUNDED_ABOVE( hintDescriptor ) ) { return( descriptor->PortRangeHints[_port].LowerBound ); } @@ -506,19 +519,19 @@ float FASTCALL ladspaManager::getUpperBound( const ladspaKey & _plugin, bool FASTCALL ladspaManager::isPortToggled( const ladspaKey & _plugin, - Uint32 _port ) + Uint32 _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - return( LADSPA_IS_HINT_TOGGLED - ( hintDescriptor ) ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + return( LADSPA_IS_HINT_TOGGLED( hintDescriptor ) ); } else { @@ -535,21 +548,23 @@ float FASTCALL ladspaManager::getDefaultSetting( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; switch( hintDescriptor & LADSPA_HINT_DEFAULT_MASK ) { case LADSPA_HINT_DEFAULT_NONE: return( -999e-99 ); case LADSPA_HINT_DEFAULT_MINIMUM: - return( descriptor->PortRangeHints[_port].LowerBound ); + return( descriptor->PortRangeHints[_port]. + LowerBound ); case LADSPA_HINT_DEFAULT_LOW: if( LADSPA_IS_HINT_LOGARITHMIC - ( hintDescriptor )) + ( hintDescriptor ) ) { return( exp( log( descriptor->PortRangeHints[_port].LowerBound ) * 0.75 @@ -620,14 +635,14 @@ bool FASTCALL ladspaManager::isLogarithmic( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - return( LADSPA_IS_HINT_LOGARITHMIC - ( hintDescriptor ) ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + return( LADSPA_IS_HINT_LOGARITHMIC( hintDescriptor ) ); } else { @@ -644,14 +659,14 @@ bool FASTCALL ladspaManager::isInteger( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - LADSPA_PortRangeHintDescriptor hintDescriptor - = descriptor->PortRangeHints[_port].HintDescriptor; - return( LADSPA_IS_HINT_INTEGER - ( hintDescriptor ) ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + return( LADSPA_IS_HINT_INTEGER( hintDescriptor ) ); } else { @@ -668,11 +683,12 @@ QString FASTCALL ladspaManager::getPortName( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + return( QString( descriptor->PortNames[_port] ) ); } else @@ -684,15 +700,16 @@ QString FASTCALL ladspaManager::getPortName( const ladspaKey & _plugin, -const void * FASTCALL ladspaManager::getImplementationData( const ladspaKey & - _plugin ) +const void * FASTCALL ladspaManager::getImplementationData( + const ladspaKey & _plugin ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( descriptor->ImplementationData ); } else @@ -709,10 +726,11 @@ const LADSPA_Descriptor * FASTCALL ladspaManager::getDescriptor( { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); return( descriptor ); } else @@ -729,11 +747,13 @@ LADSPA_Handle FASTCALL ladspaManager::instantiate( const ladspaKey & _plugin, { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - return( ( descriptor->instantiate ) ( descriptor, _sample_rate ) ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + return( ( descriptor->instantiate ) + ( descriptor, _sample_rate ) ); } else { @@ -752,13 +772,15 @@ void FASTCALL ladspaManager::connectPort( const ladspaKey & _plugin, if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); if( descriptor->connect_port != NULL ) { - ( descriptor->connect_port ) ( _instance, _port, _data_location ); + ( descriptor->connect_port ) + ( _instance, _port, _data_location ); } } } @@ -771,10 +793,11 @@ void FASTCALL ladspaManager::activate( const ladspaKey & _plugin, { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); if( descriptor->activate != NULL ) { ( descriptor->activate ) ( _instance ); @@ -785,15 +808,17 @@ void FASTCALL ladspaManager::activate( const ladspaKey & _plugin, -void FASTCALL ladspaManager::run( const ladspaKey & _plugin, LADSPA_Handle _instance, - Uint32 _sample_count ) +void FASTCALL ladspaManager::run( const ladspaKey & _plugin, + LADSPA_Handle _instance, + Uint32 _sample_count ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); if( descriptor->run != NULL ) { ( descriptor->run ) ( _instance, _sample_count ); @@ -805,17 +830,18 @@ void FASTCALL ladspaManager::run( const ladspaKey & _plugin, LADSPA_Handle _inst void FASTCALL ladspaManager::runAdding( const ladspaKey & _plugin, - LADSPA_Handle _instance, - Uint32 _sample_count ) + LADSPA_Handle _instance, + Uint32 _sample_count ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - if( descriptor->run_adding!=NULL - && descriptor->set_run_adding_gain!=NULL ) + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + if( descriptor->run_adding != NULL && + descriptor->set_run_adding_gain != NULL ) { ( descriptor->run_adding ) ( _instance, _sample_count ); } @@ -826,19 +852,21 @@ void FASTCALL ladspaManager::runAdding( const ladspaKey & _plugin, void FASTCALL ladspaManager::setRunAddingGain( const ladspaKey & _plugin, - LADSPA_Handle _instance, - LADSPA_Data _gain ) + LADSPA_Handle _instance, + LADSPA_Data _gain ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); - if( descriptor->run_adding!=NULL - && descriptor->set_run_adding_gain!=NULL ) + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + if( descriptor->run_adding != NULL && + descriptor->set_run_adding_gain != NULL ) { - ( descriptor->set_run_adding_gain ) ( _instance, _gain ); + ( descriptor->set_run_adding_gain ) + ( _instance, _gain ); } } } @@ -851,10 +879,11 @@ void FASTCALL ladspaManager::deactivate( const ladspaKey & _plugin, { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); if( descriptor->deactivate != NULL ) { ( descriptor->deactivate ) ( _instance ); @@ -866,14 +895,15 @@ void FASTCALL ladspaManager::deactivate( const ladspaKey & _plugin, void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin, - LADSPA_Handle _instance ) + LADSPA_Handle _instance ) { if( m_ladspaManagerMap.contains( _plugin ) ) { - LADSPA_Descriptor_Function descriptorFunction - = m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor - = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); if( descriptor->cleanup != NULL ) { ( descriptor->cleanup ) ( _instance ); diff --git a/src/lib/mmp.cpp b/src/lib/mmp.cpp index 725f0c8f1..eb2a6cb9b 100644 --- a/src/lib/mmp.cpp +++ b/src/lib/mmp.cpp @@ -54,6 +54,7 @@ multimediaProject::typeDescStruct { multimediaProject::SONG_PROJECT, "song" }, { multimediaProject::SONG_PROJECT_TEMPLATE, "songtemplate" }, { multimediaProject::CHANNEL_SETTINGS, "channelsettings" }, + { multimediaProject::DRAG_N_DROP_DATA, "dnddata" }, { multimediaProject::EFFECT_SETTINGS, "effectsettings" }, { multimediaProject::VIDEO_PROJECT, "video" }, { multimediaProject::BURN_PROJECT, "burn" }, @@ -86,19 +87,22 @@ multimediaProject::multimediaProject( projectTypes _project_type ) : -multimediaProject::multimediaProject( const QString & _in_file_name ) : +multimediaProject::multimediaProject( const QString & _in_file_name, + bool _is_filename ) : QDomDocument(), m_content(), m_head() { QFile in_file( _in_file_name ); -#ifdef QT4 - if( !in_file.open( QIODevice::ReadOnly ) ) -#else - if( !in_file.open( IO_ReadOnly ) ) -#endif + if( _is_filename == TRUE ) { - QMessageBox::critical( NULL, +#ifdef QT4 + if( !in_file.open( QIODevice::ReadOnly ) ) +#else + if( !in_file.open( IO_ReadOnly ) ) +#endif + { + QMessageBox::critical( NULL, songEditor::tr( "Could not open file" ), songEditor::tr( "Could not open " "file %1. You probably " @@ -109,15 +113,17 @@ multimediaProject::multimediaProject( const QString & _in_file_name ) : "access to the file " "and try again." ).arg( _in_file_name ) ); - return; + return; + } } - QString error_msg; int line; int col; - if( !setContent( &in_file, &error_msg, &line, &col ) ) + if( _is_filename == TRUE ) { - QMessageBox::critical( NULL, songEditor::tr( "Error in " + if( !setContent( &in_file, &error_msg, &line, &col ) ) + { + QMessageBox::critical( NULL, songEditor::tr( "Error in " "multimedia-project" ), songEditor::tr( "The multimedia-" "project %1 seems to " @@ -127,9 +133,19 @@ multimediaProject::multimediaProject( const QString & _in_file_name ) : "possible data from " "this file." ).arg( _in_file_name ) ); - return; + return; + } + in_file.close(); + } + else + { + if( !setContent( _in_file_name, &error_msg, &line, &col ) ) + { + printf( "multimediaProject: error parsing XML-data " + "directly given to constructor!\n" ); + return; + } } - in_file.close(); QDomElement root = documentElement(); diff --git a/src/lib/sample_buffer.cpp b/src/lib/sample_buffer.cpp index 67df4a7a4..84d39ac16 100644 --- a/src/lib/sample_buffer.cpp +++ b/src/lib/sample_buffer.cpp @@ -79,9 +79,10 @@ -sampleBuffer::sampleBuffer( const QString & _audio_file ) : +sampleBuffer::sampleBuffer( const QString & _audio_file, + bool _is_base64_data ) : QObject(), - m_audioFile( _audio_file ), + m_audioFile( ( _is_base64_data == TRUE ) ? "" : _audio_file ), m_origData( NULL ), m_origFrames( 0 ), m_data( NULL ), @@ -99,6 +100,10 @@ sampleBuffer::sampleBuffer( const QString & _audio_file ) : #ifdef HAVE_SAMPLERATE_H initResampling(); #endif + if( _is_base64_data == TRUE ) + { + loadFromBase64( _audio_file ); + } update(); } @@ -769,8 +774,9 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame, void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm ) { - _p.setClipRect( _dr ); - _p.setPen (QColor(0x22, 0xFF, 0x44)); +// _p.setClipRect( _dr ); +// _p.setPen( QColor( 0x22, 0xFF, 0x44 ) ); + //_p.setPen( QColor( 64, 224, 160 ) ); #ifdef QT4 // TODO: save and restore aa-settings _p.setRenderHint( QPainter::Antialiasing ); @@ -778,12 +784,12 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm ) const int w = _dr.width(); const int h = _dr.height(); - const Uint16 y_base = h/2+_dr.y(); - const float y_space = h/2; + const Uint16 y_base = h / 2 + _dr.y(); + const float y_space = h / 2; if( m_data == NULL || m_frames == 0 ) { - _p.drawLine( _dr.x(), y_base, _dr.x()+w, y_base ); + _p.drawLine( _dr.x(), y_base, _dr.x() + w, y_base ); return; } else if( _dm == LINE_CONNECT ) @@ -819,11 +825,11 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm ) { const int x = static_cast( frame / (float) m_frames * w ) + - _dr.x(); + _dr.x(); for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) { const Uint16 y = y_base + - static_cast( m_data[frame][chnl]*y_space ); + static_cast( m_data[frame][chnl] * y_space ); _p.drawLine( old_x, old_y[chnl], x, y ); old_y[chnl] = y; } @@ -840,12 +846,11 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm ) for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) { _p.drawPoint( x, y_base + - static_cast( - m_data[frame][chnl]*y_space ) ); + static_cast( m_data[frame][chnl] * y_space ) ); } } } - _p.setClipping( FALSE ); +// _p.setClipping( FALSE ); } @@ -948,6 +953,85 @@ QString sampleBuffer::openAudioFile( void ) const +QString sampleBuffer::toBase64( void ) const +{ + if( m_data == NULL || m_frames == 0 ) + { + return( "" ); + } +#ifdef QT4 + return( QByteArray::toBase64( QByteArray( m_data, m_frames ) ) ); +#else + // code mostly taken from + // qt-x11-opensource-src-4.0.1/src/corelib/tools/qbytearray.cpp + + const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" + "ghijklmn" "opqrstuv" "wxyz0123" "456789+/"; + const char padchar = '='; + int padlen = 0; + + Uint32 ssize = m_frames * sizeof( sampleFrame ); + Uint32 dsize = ( ( ssize * 4 ) / 3 ) + 3; + const Uint8 * src = (const Uint8 *) m_data; + char * ptr = new char[dsize + 1]; + char * out = ptr; + + Uint32 i = 0; + while( i < ssize ) + { + int chunk = 0; + chunk |= int( src[i++] ) << 16; + if( i == dsize ) + { + padlen = 2; + } + else + { + chunk |= int( src[i++] ) << 8; + if( i == ssize ) + { + padlen = 1; + } + else + { + chunk |= int( src[i++] ); + } + } + + int j = ( chunk & 0x00fc0000 ) >> 18; + int k = ( chunk & 0x0003f000 ) >> 12; + int l = ( chunk & 0x00000fc0 ) >> 6; + int m = ( chunk & 0x0000003f ); + *out++ = alphabet[j]; + *out++ = alphabet[k]; + if( padlen > 1 ) + { + *out++ = padchar; + } + else + { + *out++ = alphabet[l]; + } + if( padlen > 0 ) + { + *out++ = padchar; + } + else + { + *out++ = alphabet[m]; + } + } + // terminate string + ptr[dsize] = 0; + QString s( ptr ); + delete[] ptr; + return( s ); +#endif +} + + + + void sampleBuffer::setAudioFile( const QString & _audio_file ) { m_audioFile = _audio_file; @@ -970,6 +1054,74 @@ void sampleBuffer::setAudioFile( const QString & _audio_file ) +void sampleBuffer::loadFromBase64( const QString & _data ) +{ + delete[] m_origData; + + m_origFrames = _data.length() * 3 / ( 4 * sizeof( sampleFrame ) ); + m_origData = new sampleFrame[m_origFrames]; +#ifdef QT4 + QByteArray data = QByteArray::fromBase64( _audio_file.toAscii() ); + memcpy( m_origData, data.data(), data.size() ); +#else + // code mostly taken from + // qt-x11-opensource-src-4.0.1/src/corelib/tools/qbytearray.cpp + unsigned int buf = 0; + int nbits = 0; + const char * src = _data.ascii(); + char * dst = (char *) m_origData; + csize ssize = _data.length(); + int offset = 0; + + for( csize i = 0; i < ssize; ++i ) + { + int ch = src[i]; + int d; + + if( ch >= 'A' && ch <= 'Z' ) + { + d = ch - 'A'; + } + else if( ch >= 'a' && ch <= 'z' ) + { + d = ch - 'a' + 26; + } + else if( ch >= '0' && ch <= '9' ) + { + d = ch - '0' + 52; + } + else if( ch == '+' ) + { + d = 62; + } + else if( ch == '/' ) + { + d = 63; + } + else + { + d = -1; + } + + if( d != -1 ) + { + buf = ( buf << 6 ) | d; + nbits += 6; + if( nbits >= 8 ) + { + nbits -= 8; + dst[offset++] = buf >> nbits; + buf &= ( 1 << nbits ) - 1; + } + } + } +#endif + update(); +} + + + + void sampleBuffer::setStartFrame( Uint32 _s ) { // don't set this parameter while playing diff --git a/src/lib/string_pair_drag.cpp b/src/lib/string_pair_drag.cpp index 94b9ee685..71c1e3080 100644 --- a/src/lib/string_pair_drag.cpp +++ b/src/lib/string_pair_drag.cpp @@ -49,10 +49,10 @@ stringPairDrag::stringPairDrag( const QString & _key, const QString & _value, QMimeData * m = new QMimeData(); m->setData( "lmms/stringpair", txt.toAscii() ); setMimeData( m ); - start( /*Qt::CopyAction*/ Qt::IgnoreAction ); + start( Qt::IgnoreAction ); #else setEncodedData( txt.utf8() ); - drag(); + drag( QDragObject::DragDefault ); #endif } @@ -67,7 +67,7 @@ stringPairDrag::~stringPairDrag() -void stringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee, +bool stringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee, const QString & _allowed_keys ) { #ifdef QT4 @@ -79,12 +79,15 @@ void stringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee, if( _allowed_keys.split( ',' ).contains( txt.section( ':', 0, 0 ) ) ) { _dee->acceptProposedAction(); + return( TRUE ); } + return( FALSE ); #else QString txt = _dee->encodedData( "lmms/stringpair" ); bool accepted = QStringList::split( ',', _allowed_keys ).contains( txt.section( ':', 0, 0 ) ); _dee->accept( accepted ); + return( accepted ); #endif } diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index a205cffe5..f379e13e8 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -86,7 +86,7 @@ bbTCO::~bbTCO() void bbTCO::movePosition( const midiTime & _pos ) { - // bb-playlist-entries are always aligned on tact-boundaries + // bb-playlist-entries are always aligned at tact-boundaries trackContentObject::movePosition( midiTime( _pos.getTact(), 0 ) ); } @@ -95,7 +95,7 @@ void bbTCO::movePosition( const midiTime & _pos ) void bbTCO::changeLength( const midiTime & _length ) { - // the length of bb-playlist-entries is always a multiple of one tact + // the length of a bb-playlist-entry is always a multiple of one tact trackContentObject::changeLength( midiTime( _length.getTact(), 0 ) ); } @@ -298,6 +298,9 @@ 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, "" }; @@ -342,7 +345,7 @@ bbTrack::~bbTrack() -track::trackTypes bbTrack::trackType( void ) const +track::trackTypes bbTrack::type( void ) const { return( BB_TRACK ); } diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 80f7b8abc..195894aa7 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -64,6 +64,8 @@ #include "audio_sample_recorder.h" #include "song_editor.h" #include "tooltip.h" +#include "bb_editor.h" +#include "string_pair_drag.h" QPixmap * pattern::s_patternBg = NULL; @@ -191,344 +193,276 @@ void pattern::movePosition( const midiTime & _pos ) -void pattern::constructContextMenu( QMenu * _cm ) +midiTime pattern::length( void ) const { -#ifdef QT4 - QAction * a = new QAction( embed::getIconPixmap( "piano" ), - tr( "Open in piano-roll" ), _cm ); - _cm->insertAction( _cm->actions()[0], a ); - connect( a, SIGNAL( triggered( bool ) ), this, - SLOT( openInPianoRoll( bool ) ) ); -#else - _cm->insertItem( embed::getIconPixmap( "piano" ), - tr( "Open in piano-roll" ), - this, SLOT( openInPianoRoll() ), - 0, -1, 0 ); -#endif -#ifdef QT4 - _cm->insertSeparator( _cm->actions()[1] ); -#else - _cm->insertSeparator( 1 ); -#endif - - _cm->addSeparator(); - - _cm->addAction( embed::getIconPixmap( "edit_erase" ), - tr( "Clear all notes" ), this, SLOT( clear() ) ); - _cm->addSeparator(); - - _cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ), - this, SLOT( resetName() ) ); - _cm->addAction( embed::getIconPixmap( "rename" ), tr( "Change name" ), - this, SLOT( changeName() ) ); - _cm->addSeparator(); - - _cm->addAction( embed::getIconPixmap( "freeze" ), - ( m_frozenPattern != NULL )? tr( "Refreeze" ) : tr( "Freeze" ), - this, SLOT( freeze() ) ); - _cm->addAction( embed::getIconPixmap( "unfreeze" ), tr( "Unfreeze" ), - this, SLOT( unfreeze() ) ); - - _cm->addSeparator(); - -#ifdef QT4 - QMenu * add_step_menu = _cm->addMenu( - embed::getIconPixmap( "step_btn_add" ), - tr( "Add steps" ) ); - QMenu * remove_step_menu = _cm->addMenu( - embed::getIconPixmap( "step_btn_remove" ), - tr( "Remove steps" ) ); - connect( add_step_menu, SIGNAL( triggered( QAction * ) ), - this, SLOT( addSteps( QAction * ) ) ); - connect( remove_step_menu, SIGNAL( triggered( QAction * ) ), - this, SLOT( removeSteps( QAction * ) ) ); -#else - QMenu * add_step_menu = new QMenu( this ); - QMenu * remove_step_menu = new QMenu( this ); -#endif - for( int i = 1; i <= 16; i *= 2 ) + if( m_patternType == BEAT_PATTERN ) { - const QString label = ( i == 1 ) ? - tr( "1 step" ) : - tr( "%1 steps" ).arg( i ); -#ifdef QT4 - add_step_menu->addAction( label ); - remove_step_menu->addAction( label ); -#else - int menu_id = add_step_menu->addAction( label, this, - SLOT( addSteps( int ) ) ); - add_step_menu->setItemParameter( menu_id, i ); - menu_id = remove_step_menu->addAction( label, this, - SLOT( removeSteps( int ) ) ); - remove_step_menu->setItemParameter( menu_id, i ); -#endif + if( m_steps % DEFAULT_STEPS_PER_TACT == 0 ) + { + return( m_steps * BEATS_PER_TACT ); + } + return( ( m_steps / DEFAULT_STEPS_PER_TACT + 1 ) * + DEFAULT_STEPS_PER_TACT * BEATS_PER_TACT ); } -#ifndef QT4 - _cm->addMenu( embed::getIconPixmap( "step_btn_add" ), - tr( "Add steps" ), add_step_menu ); - _cm->addMenu( embed::getIconPixmap( "step_btn_remove" ), - tr( "Remove steps" ), remove_step_menu ); -#endif + + Sint32 max_length = 0; + + for( noteVector::const_iterator it = m_notes.begin(); + it != m_notes.end(); + ++it ) + { + max_length = tMax( max_length, ( *it )->endPos() ); + } + if( max_length % 64 == 0 ) + { + return( midiTime( tMax( max_length, 64 ) ) ); + } + return( midiTime( tMax( midiTime( max_length ).getTact() + 1, 1 ), + 0 ) ); } -void pattern::ensureBeatNotes( void ) +note * pattern::addNote( const note & _new_note ) { - // make sure, that all step-note exist - for( int i = 0; i < m_steps; ++i ) + note * new_note = new note( _new_note ); + + if( m_notes.size() == 0 || m_notes.back()->pos() <= new_note->pos() ) { - bool found = FALSE; - for( noteVector::iterator it = m_notes.begin(); - it != m_notes.end(); ++it ) - { - if( ( *it )->pos() == i * BEATS_PER_TACT && - ( *it )->length() <= 0 ) - { - found = TRUE; - break; - } - } - if( found == FALSE ) - { - addNote( note( midiTime( 0 ), midiTime( i * - BEATS_PER_TACT ) ) ); - } + m_notes.push_back( new_note ); } -} + else + { + // simple algorithm for inserting the note between two + // notes with smaller and greater position + // maybe it could be optimized by starting in the middle and + // going forward or backward but note-inserting isn't that + // time-critical since it is usually not done while playing... + long new_note_abs_time = new_note->pos(); + noteVector::iterator it = m_notes.begin(); + while( it != m_notes.end() && + ( *it )->pos() < new_note_abs_time ) + { + ++it; + } + m_notes.insert( it, new_note ); + } - -void pattern::paintEvent( QPaintEvent * ) -{ + checkType(); + update(); changeLength( length() ); -#ifdef QT4 - QPainter p( this ); -#else - // create pixmap for whole widget - QPixmap pm( rect().size() ); + updateBBTrack(); - // and a painter for it - QPainter p( &pm ); -#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() ); - p.setPen( QColor( 120, 130, 140 ) ); - p.drawLine( 0, height() - 1, width() - 1, height() - 1 ); - p.drawLine( width() - 1, 0, width() - 1, height() - 1 ); - - p.setPen( QColor( 0, 0, 0 ) ); - p.drawRect( 1, 1, width() - 2, height() - 2 ); - - float ppt = pixelsPerTact(); - - if( m_patternType == pattern::MELODY_PATTERN ) - { - Sint16 central_key = 0; - if( m_notes.size() > 0 ) - { - // first determine the central tone so that we can - // display the area where most of the m_notes are - Sint16 total_notes = 0; - for( noteVector::iterator it = m_notes.begin(); - it != m_notes.end(); ++it ) - { - if( ( *it )->length() > 0 ) - { - central_key += ( *it )->key(); - ++total_notes; - } - } - - if( total_notes > 0 ) - { - central_key = central_key / total_notes; - - Sint16 central_y = s_patternBg->height() / 2; - Sint16 y_base = central_y+TCO_BORDER_WIDTH-1; - - const Sint16 x_base = TCO_BORDER_WIDTH; - - p.setPen( QColor( 0, 0, 0 ) ); - 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 * - TCO_BORDER_WIDTH ); - } - if( getTrack()->muted() ) - { - p.setPen( QColor( 160, 160, 160 ) ); - } - else if( m_frozenPattern != NULL ) - { - p.setPen( QColor( 0x00, 0xE0, 0xFF ) ); - } - else - { - p.setPen( QColor( 0xFF, 0xB0, 0x00 ) ); - } - - for( noteVector::iterator it = m_notes.begin(); - it != m_notes.end(); ++it ) - { - Sint16 y_pos = central_key - - ( *it )->key(); - - if( ( *it )->length() > 0 && - y_pos > -central_y && - y_pos < central_y ) - { - Sint16 x1 = 2 * x_base + - static_cast( ( *it )->pos() * ppt / 64 ); - Sint16 x2 = x1 + - static_cast( ( *it )->length() * ppt / 64 ); - p.drawLine( x1, y_base+y_pos, - x2, - y_base+y_pos ); - - } - } - } - } - } - else if( m_patternType == pattern::BEAT_PATTERN && - ( ppt >= 192 || m_steps != DEFAULT_STEPS_PER_TACT ) ) - { - QPixmap stepon; - QPixmap stepoff; - QPixmap stepoffl; - int steps = length() / BEATS_PER_TACT; -#ifdef QT4 - stepon = s_stepBtnOn->scaled( width() / steps, - s_stepBtnOn->height(), - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation ); - stepoff = s_stepBtnOff->scaled( width() / steps, - s_stepBtnOff->height(), - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation ); - stepoffl = s_stepBtnOffLight->scaled( width() / steps, - s_stepBtnOffLight->height(), - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation ); -#else - stepon.convertFromImage( s_stepBtnOn->convertToImage().scale( - width() / steps, s_stepBtnOn->height() ) ); - stepoff.convertFromImage( s_stepBtnOff->convertToImage().scale( - width() / steps, s_stepBtnOff->height() ) ); - stepoffl.convertFromImage( s_stepBtnOffLight->convertToImage(). - scale( width() / steps, - s_stepBtnOffLight->height() ) ); -#endif - for( noteVector::iterator it = m_notes.begin(); - it != m_notes.end(); ++it ) - { - Sint16 no = it - m_notes.begin(); - Sint16 x = TCO_BORDER_WIDTH + static_cast( no * - width() / steps ); - Sint16 y = height() - s_stepBtnOn->height() - 1; - if( ( *it )->length() < 0 ) - { - p.drawPixmap( x, y, stepon ); - } - else if( ( no / BEATS_PER_TACT ) % 2 ) - { - p.drawPixmap( x, y, stepoff ); - } - else - { - p.drawPixmap( x, y, stepoffl ); - } - } - } - - p.setFont( pointSize<7>( p.font() ) ); - p.setPen( QColor( 32, 240, 32 ) ); - p.drawText( 2, 9, m_name ); - if( m_frozenPattern != NULL ) - { - p.setPen( QColor( 0, 224, 255 ) ); - p.drawRect( 0, 0, width(), height() - 1 ); - p.drawPixmap( 3, height() - s_frozen->height() - 4, *s_frozen ); - } - -#ifndef QT4 - // blit drawn pixmap to actual widget - bitBlt( this, rect().topLeft(), &pm ); -#endif + return( new_note ); } -void pattern::mousePressEvent( QMouseEvent * _me ) +void pattern::removeNote( const note * _note_to_del ) { - if( _me->button() != Qt::LeftButton ) + noteVector::iterator it = m_notes.begin(); + while( it != m_notes.end() ) { - _me->ignore(); - return; + if( *it == _note_to_del ) + { + delete *it; + m_notes.erase( it ); + break; + } + ++it; } - if( m_patternType == pattern::BEAT_PATTERN && - ( pixelsPerTact() >= 192 || - m_steps != DEFAULT_STEPS_PER_TACT ) && - _me->y() > height() - s_stepBtnOn->height() ) + checkType(); + update(); + changeLength( length() ); + + updateBBTrack(); +} + + + + +note * pattern::rearrangeNote( const note * _note_to_proc ) +{ + // just rearrange the position of the note by removing it and adding + // a copy of it -> addNote inserts it at the correct position + note copy_of_note( *_note_to_proc ); + removeNote( _note_to_proc ); + + return( addNote( copy_of_note ) ); +} + + + + +void pattern::clearNotes( void ) +{ + for( noteVector::iterator it = m_notes.begin(); it != m_notes.end(); + ++it ) { - int step = ( _me->x() - TCO_BORDER_WIDTH ) * - length() / BEATS_PER_TACT / width(); - if( step >= m_steps ) + delete *it; + } + + m_notes.clear(); + checkType(); + update(); +} + + + + +note * pattern::noteAt( int _note_num ) +{ + if( (csize) _note_num < m_notes.size() ) + { + return( m_notes[_note_num] ); + } + return( NULL ); +} + + + + +void pattern::setNoteAt( int _note_num, note _new_note ) +{ + if( static_cast( _note_num ) < m_notes.size() ) + { + delete m_notes[_note_num]; + m_notes[_note_num] = new note( _new_note ); + checkType(); + update(); + } +} + + + + +void pattern::setType( patternTypes _new_pattern_type ) +{ + if( _new_pattern_type == BEAT_PATTERN || + _new_pattern_type == MELODY_PATTERN ) + { + m_patternType = _new_pattern_type; + } +} + + + + +void pattern::checkType( void ) +{ + noteVector::iterator it = m_notes.begin(); + while( it != m_notes.end() ) + { + if( ( *it )->length() > 0 ) { + setType( pattern::MELODY_PATTERN ); return; } - note * n = m_notes[step]; - if( n->length() < 0 ) - { - n->setLength( 0 ); - } - else - { - n->setLength( -64 ); - } - songEditor::inst()->setModified(); - update(); - return; + ++it; } - trackContentObject::mousePressEvent( _me ); + setType( pattern::BEAT_PATTERN ); } -void pattern::mouseDoubleClickEvent( QMouseEvent * _me ) +void pattern::playFrozenData( sampleFrame * _ab, Uint32 _start_frame, + Uint32 _frames ) { - if( _me->button() != Qt::LeftButton ) + m_frozenPatternMutex.lock(); + if( m_frozenPattern != NULL ) { - _me->ignore(); - return; + m_frozenPattern->play( _ab, _start_frame, _frames ); } - if( m_patternType == pattern::MELODY_PATTERN || - !( m_patternType == pattern::BEAT_PATTERN && - ( pixelsPerTact() >= 192 || - m_steps != DEFAULT_STEPS_PER_TACT ) && - _me->y() > height() - s_stepBtnOn->height() ) ) + m_frozenPatternMutex.unlock(); +} + + + + +void pattern::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +{ + QDomElement pattern_de = _doc.createElement( nodeName() ); + pattern_de.setAttribute( "type", QString::number( m_patternType ) ); + pattern_de.setAttribute( "name", m_name ); + // as the target of copied/dragged pattern is always an existing + // pattern, we must not store actual position, instead we store -1 + // which tells loadSettings() not to mess around with position + if( _parent.nodeName() == "clipboard" || + _parent.nodeName() == "dnddata" ) { - openInPianoRoll(); - } + pattern_de.setAttribute( "pos", QString::number( -1 ) ); + } + else + { + pattern_de.setAttribute( "pos", QString::number( + startPosition() ) ); + } + pattern_de.setAttribute( "len", QString::number( length() ) ); + pattern_de.setAttribute( "frozen", QString::number( + m_frozenPattern != NULL ) ); + _parent.appendChild( pattern_de ); + + // now save settings of all notes + for( noteVector::iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + if( ( *it )->length() ) + { + ( *it )->saveSettings( _doc, pattern_de ); + } + } +} + + + + +void pattern::loadSettings( const QDomElement & _this ) +{ + unfreeze(); + + m_patternType = static_cast( _this.attribute( "type" + ).toInt() ); + m_name = _this.attribute( "name" ); + if( _this.attribute( "pos" ).toInt() >= 0 ) + { + movePosition( _this.attribute( "pos" ).toInt() ); + } + changeLength( midiTime( _this.attribute( "len" ).toInt() ) ); + + clearNotes(); + + QDomNode node = _this.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() ) + { + note * n = new note(); + n->loadSettings( node.toElement() ); + m_notes.push_back( n ); + } + node = node.nextSibling(); + } + + m_steps = _this.attribute( "steps" ).toInt(); + if( m_steps == 0 ) + { + m_steps = DEFAULT_STEPS_PER_TACT; + } + + ensureBeatNotes(); +/* if( _this.attribute( "frozen" ).toInt() ) + { + freeze(); + }*/ + update(); + updateBBTrack(); } @@ -716,274 +650,366 @@ void pattern::removeSteps( int _n ) -void pattern::playFrozenData( sampleFrame * _ab, Uint32 _start_frame, - Uint32 _frames ) +void pattern::constructContextMenu( QMenu * _cm ) { - m_frozenPatternMutex.lock(); - if( m_frozenPattern != NULL ) +#ifdef QT4 + QAction * a = new QAction( embed::getIconPixmap( "piano" ), + tr( "Open in piano-roll" ), _cm ); + _cm->insertAction( _cm->actions()[0], a ); + connect( a, SIGNAL( triggered( bool ) ), this, + SLOT( openInPianoRoll( bool ) ) ); +#else + _cm->insertItem( embed::getIconPixmap( "piano" ), + tr( "Open in piano-roll" ), + this, SLOT( openInPianoRoll() ), + 0, -1, 0 ); +#endif +#ifdef QT4 + _cm->insertSeparator( _cm->actions()[1] ); +#else + _cm->insertSeparator( 1 ); +#endif + + _cm->addSeparator(); + + _cm->addAction( embed::getIconPixmap( "edit_erase" ), + tr( "Clear all notes" ), this, SLOT( clear() ) ); + _cm->addSeparator(); + + _cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ), + this, SLOT( resetName() ) ); + _cm->addAction( embed::getIconPixmap( "rename" ), tr( "Change name" ), + this, SLOT( changeName() ) ); + _cm->addSeparator(); + + _cm->addAction( embed::getIconPixmap( "freeze" ), + ( m_frozenPattern != NULL )? tr( "Refreeze" ) : tr( "Freeze" ), + this, SLOT( freeze() ) ); + _cm->addAction( embed::getIconPixmap( "unfreeze" ), tr( "Unfreeze" ), + this, SLOT( unfreeze() ) ); + + _cm->addSeparator(); + +#ifdef QT4 + QMenu * add_step_menu = _cm->addMenu( + embed::getIconPixmap( "step_btn_add" ), + tr( "Add steps" ) ); + QMenu * remove_step_menu = _cm->addMenu( + embed::getIconPixmap( "step_btn_remove" ), + tr( "Remove steps" ) ); + connect( add_step_menu, SIGNAL( triggered( QAction * ) ), + this, SLOT( addSteps( QAction * ) ) ); + connect( remove_step_menu, SIGNAL( triggered( QAction * ) ), + this, SLOT( removeSteps( QAction * ) ) ); +#else + QMenu * add_step_menu = new QMenu( this ); + QMenu * remove_step_menu = new QMenu( this ); +#endif + for( int i = 1; i <= 16; i *= 2 ) { - m_frozenPattern->play( _ab, _start_frame, _frames ); + const QString label = ( i == 1 ) ? + tr( "1 step" ) : + tr( "%1 steps" ).arg( i ); +#ifdef QT4 + add_step_menu->addAction( label ); + remove_step_menu->addAction( label ); +#else + int menu_id = add_step_menu->addAction( label, this, + SLOT( addSteps( int ) ) ); + add_step_menu->setItemParameter( menu_id, i ); + menu_id = remove_step_menu->addAction( label, this, + SLOT( removeSteps( int ) ) ); + remove_step_menu->setItemParameter( menu_id, i ); +#endif } - m_frozenPatternMutex.unlock(); +#ifndef QT4 + _cm->addMenu( embed::getIconPixmap( "step_btn_add" ), + tr( "Add steps" ), add_step_menu ); + _cm->addMenu( embed::getIconPixmap( "step_btn_remove" ), + tr( "Remove steps" ), remove_step_menu ); +#endif } - -midiTime pattern::length( void ) const +void pattern::mouseDoubleClickEvent( QMouseEvent * _me ) { - if( m_patternType == BEAT_PATTERN ) + if( _me->button() != Qt::LeftButton ) { - if( m_steps % DEFAULT_STEPS_PER_TACT == 0 ) + _me->ignore(); + return; + } + if( m_patternType == pattern::MELODY_PATTERN || + !( m_patternType == pattern::BEAT_PATTERN && + ( pixelsPerTact() >= 192 || + m_steps != DEFAULT_STEPS_PER_TACT ) && + _me->y() > height() - s_stepBtnOn->height() ) ) + { + openInPianoRoll(); + } +} + + + + +void pattern::mousePressEvent( QMouseEvent * _me ) +{ +/* if( _me->button() != Qt::LeftButton ) + { + return; + }*/ + + if( _me->button() == Qt::LeftButton && + m_patternType == pattern::BEAT_PATTERN && + ( pixelsPerTact() >= 192 || + m_steps != DEFAULT_STEPS_PER_TACT ) && + _me->y() > height() - s_stepBtnOn->height() ) + { + int step = ( _me->x() - TCO_BORDER_WIDTH ) * + length() / BEATS_PER_TACT / width(); + if( step >= m_steps ) { - return( m_steps * BEATS_PER_TACT ); - } - return( ( m_steps / DEFAULT_STEPS_PER_TACT + 1 ) * - DEFAULT_STEPS_PER_TACT * BEATS_PER_TACT ); - } - - Sint32 max_length = 0; - - for( noteVector::const_iterator it = m_notes.begin(); - it != m_notes.end(); - ++it ) - { - max_length = tMax( max_length, ( *it )->endPos() ); - } - if( max_length % 64 == 0 ) - { - return( midiTime( tMax( max_length, 64 ) ) ); - } - return( midiTime( tMax( midiTime( max_length ).getTact() + 1, 1 ), - 0 ) ); -} - - - - -note * pattern::addNote( const note & _new_note ) -{ - note * new_note = new note( _new_note ); - - if( m_notes.size() == 0 || m_notes.back()->pos() <= new_note->pos() ) - { - m_notes.push_back( new_note ); - } - else - { - // simple algorithm for inserting the note between two - // notes with smaller and greater position - // maybe it could be optimized by starting in the middle and - // going forward or backward but note-inserting isn't that - // time-critical since it is usually not done while playing... - long new_note_abs_time = new_note->pos(); - noteVector::iterator it = m_notes.begin(); - - while( it != m_notes.end() && - ( *it )->pos() < new_note_abs_time ) - { - ++it; - } - - m_notes.insert( it, new_note ); - } - - checkType(); - update(); - changeLength( length() ); - - return( new_note ); -} - - - - -void pattern::removeNote( const note * _note_to_del ) -{ - noteVector::iterator it = m_notes.begin(); - while( it != m_notes.end() ) - { - if( *it == _note_to_del ) - { - delete *it; - m_notes.erase( it ); - break; - } - ++it; - } - - checkType(); - update(); - changeLength( length() ); -} - - - - -note * pattern::rearrangeNote( const note * _note_to_proc ) -{ - // just rearrange the position of the note by removing it and adding - // a copy of it -> addNote inserts it at the correct position - note copy_of_note( *_note_to_proc ); - removeNote( _note_to_proc ); - - return( addNote( copy_of_note ) ); -} - - - - -void pattern::clearNotes( void ) -{ - for( noteVector::iterator it = m_notes.begin(); it != m_notes.end(); - ++it ) - { - delete *it; - } - - m_notes.clear(); - checkType(); - update(); -} - - - - -void pattern::setType( patternTypes _new_pattern_type ) -{ - if( _new_pattern_type == BEAT_PATTERN || - _new_pattern_type == MELODY_PATTERN ) - { - m_patternType = _new_pattern_type; - } -} - - - - -note * pattern::noteAt( int _note_num ) -{ - if( (csize) _note_num < m_notes.size() ) - { - return( m_notes[_note_num] ); - } - return( NULL ); -} - - - - -void pattern::setNoteAt( int _note_num, note _new_note ) -{ - if( static_cast( _note_num ) < m_notes.size() ) - { - delete m_notes[_note_num]; - m_notes[_note_num] = new note( _new_note ); - checkType(); - update(); - } -} - - - - -void pattern::checkType( void ) -{ - noteVector::iterator it = m_notes.begin(); - while( it != m_notes.end() ) - { - if( ( *it )->length() > 0 ) - { - setType( pattern::MELODY_PATTERN ); return; } - ++it; + note * n = m_notes[step]; + if( n->length() < 0 ) + { + n->setLength( 0 ); + } + else + { + n->setLength( -64 ); + } + songEditor::inst()->setModified(); + update(); } - setType( pattern::BEAT_PATTERN ); -} - - - - - -void pattern::saveSettings( QDomDocument & _doc, QDomElement & _parent ) -{ - QDomElement pattern_de = _doc.createElement( nodeName() ); - pattern_de.setAttribute( "type", QString::number( m_patternType ) ); - pattern_de.setAttribute( "name", m_name ); - if( _parent.nodeName() == "clipboard" ) + else if( m_frozenPattern != NULL && _me->button() == Qt::LeftButton && + lmmsMainWin::isShiftPressed() == TRUE ) { - pattern_de.setAttribute( "pos", QString::number( -1 ) ); + new stringPairDrag( "sampledata", + m_frozenPattern->toBase64(), + embed::getIconPixmap( "freeze" ), + this ); } else { - pattern_de.setAttribute( "pos", QString::number( - startPosition() ) ); - } - pattern_de.setAttribute( "len", QString::number( length() ) ); - pattern_de.setAttribute( "frozen", QString::number( - m_frozenPattern != NULL ) ); - _parent.appendChild( pattern_de ); - - // now save settings of all notes - for( noteVector::iterator it = m_notes.begin(); - it != m_notes.end(); ++it ) - { - if( ( *it )->length() ) - { - ( *it )->saveSettings( _doc, pattern_de ); - } + trackContentObject::mousePressEvent( _me ); } } -void pattern::loadSettings( const QDomElement & _this ) +void pattern::paintEvent( QPaintEvent * ) { - unfreeze(); + changeLength( length() ); - m_patternType = static_cast( _this.attribute( "type" - ).toInt() ); - m_name = _this.attribute( "name" ); - if( _this.attribute( "pos" ).toInt() >= 0 ) +#ifdef QT4 + QPainter p( this ); +#else + // create pixmap for whole widget + QPixmap pm( rect().size() ); + + // and a painter for it + QPainter p( &pm ); +#endif + + for( Sint16 x = 2; x < width() - 1; x += 2 ) { - movePosition( _this.attribute( "pos" ).toInt() ); + p.drawPixmap( x, 2, *s_patternBg ); } - changeLength( midiTime( _this.attribute( "len" ).toInt() ) ); + p.setPen( QColor( 57, 69, 74 ) ); + p.drawLine( 0, 0, width(), 0 ); + p.drawLine( 0, 0, 0, height() ); + p.setPen( QColor( 120, 130, 140 ) ); + p.drawLine( 0, height() - 1, width() - 1, height() - 1 ); + p.drawLine( width() - 1, 0, width() - 1, height() - 1 ); - clearNotes(); + p.setPen( QColor( 0, 0, 0 ) ); + p.drawRect( 1, 1, width() - 2, height() - 2 ); - QDomNode node = _this.firstChild(); - while( !node.isNull() ) + float ppt = pixelsPerTact(); + + if( m_patternType == pattern::MELODY_PATTERN ) { - if( node.isElement() ) + Sint32 central_key = 0; + if( m_notes.size() > 0 ) { - note * n = new note(); - n->loadSettings( node.toElement() ); - m_notes.push_back( n ); - } - node = node.nextSibling(); - } + // first determine the central tone so that we can + // display the area where most of the m_notes are + Sint32 total_notes = 0; + for( noteVector::iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + if( ( *it )->length() > 0 ) + { + central_key += ( *it )->key(); + ++total_notes; + } + } - m_steps = _this.attribute( "steps" ).toInt(); - if( m_steps == 0 ) + if( total_notes > 0 ) + { + central_key = central_key / total_notes; + + Sint16 central_y = s_patternBg->height() / 2; + Sint16 y_base = central_y + TCO_BORDER_WIDTH -1; + + const Sint16 x_base = TCO_BORDER_WIDTH; + + p.setPen( QColor( 0, 0, 0 ) ); + 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 * + TCO_BORDER_WIDTH ); + } + if( getTrack()->muted() ) + { + p.setPen( QColor( 160, 160, 160 ) ); + } + else if( m_frozenPattern != NULL ) + { + p.setPen( QColor( 0x00, 0xE0, 0xFF ) ); + } + else + { + p.setPen( QColor( 0xFF, 0xB0, 0x00 ) ); + } + + for( noteVector::iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + Sint8 y_pos = central_key - + ( *it )->key(); + + if( ( *it )->length() > 0 && + y_pos > -central_y && + y_pos < central_y ) + { + Sint16 x1 = 2 * x_base + + static_cast( ( *it )->pos() * ppt / 64 ); + Sint16 x2 = x1 + + static_cast( ( *it )->length() * ppt / 64 ); + p.drawLine( x1, y_base + y_pos, + x2, y_base + y_pos ); + + } + } + } + } + } + else if( m_patternType == pattern::BEAT_PATTERN && + ( ppt >= 192 || m_steps != DEFAULT_STEPS_PER_TACT ) ) { - m_steps = DEFAULT_STEPS_PER_TACT; + QPixmap stepon; + QPixmap stepoff; + QPixmap stepoffl; + int steps = length() / BEATS_PER_TACT; +#ifdef QT4 + stepon = s_stepBtnOn->scaled( width() / steps, + s_stepBtnOn->height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation ); + stepoff = s_stepBtnOff->scaled( width() / steps, + s_stepBtnOff->height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation ); + stepoffl = s_stepBtnOffLight->scaled( width() / steps, + s_stepBtnOffLight->height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation ); +#else + stepon.convertFromImage( s_stepBtnOn->convertToImage().scale( + width() / steps, s_stepBtnOn->height() ) ); + stepoff.convertFromImage( s_stepBtnOff->convertToImage().scale( + width() / steps, s_stepBtnOff->height() ) ); + stepoffl.convertFromImage( s_stepBtnOffLight->convertToImage(). + scale( width() / steps, + s_stepBtnOffLight->height() ) ); +#endif + for( noteVector::iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + Sint16 no = it - m_notes.begin(); + Sint16 x = TCO_BORDER_WIDTH + static_cast( no * + width() / steps ); + Sint16 y = height() - s_stepBtnOn->height() - 1; + if( ( *it )->length() < 0 ) + { + p.drawPixmap( x, y, stepon ); + } + else if( ( no / BEATS_PER_TACT ) % 2 ) + { + p.drawPixmap( x, y, stepoff ); + } + else + { + p.drawPixmap( x, y, stepoffl ); + } + } } - ensureBeatNotes(); -/* if( _this.attribute( "frozen" ).toInt() ) + p.setFont( pointSize<7>( p.font() ) ); + p.setPen( QColor( 32, 240, 32 ) ); + p.drawText( 2, 9, m_name ); + if( m_frozenPattern != NULL ) { - freeze(); - }*/ - update(); + p.setPen( QColor( 0, 224, 255 ) ); + p.drawRect( 0, 0, width(), height() - 1 ); + p.drawPixmap( 3, height() - s_frozen->height() - 4, *s_frozen ); + } + +#ifndef QT4 + // blit drawn pixmap to actual widget + bitBlt( this, rect().topLeft(), &pm ); +#endif } +void pattern::ensureBeatNotes( void ) +{ + // make sure, that all step-note exist + for( int i = 0; i < m_steps; ++i ) + { + bool found = FALSE; + for( noteVector::iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + if( ( *it )->pos() == i * BEATS_PER_TACT && + ( *it )->length() <= 0 ) + { + found = TRUE; + break; + } + } + if( found == FALSE ) + { + addNote( note( midiTime( 0 ), midiTime( i * + BEATS_PER_TACT ) ) ); + } + } +} + + + + +void pattern::updateBBTrack( void ) +{ + if( getTrack()->getTrackContainer() == bbEditor::inst() ) + { + bbEditor::inst()->updateBBTrack( this ); + } +} + diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index b99081110..d000e0bf0 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -49,6 +49,7 @@ #include "buffer_allocator.h" #include "tooltip.h" #include "audio_port.h" +#include "string_pair_drag.h" @@ -130,35 +131,38 @@ void sampleTCO::updateLength( int ) -void sampleTCO::paintEvent( QPaintEvent * ) +void sampleTCO::dragEnterEvent( QDragEnterEvent * _dee ) { -#ifdef QT4 - QPainter p( this ); - p.fillRect( rect(), QColor( 0, 64, 255 ) ); -#else - // create pixmap for whole widget - QPixmap pm( rect().size() ); - pm.fill( QColor( 0, 64, 255 ) ); - // and a painter for it - QPainter p( &pm ); -#endif - - if( getTrack()->muted() ) + if( stringPairDrag::processDragEnterEvent( _dee, + "samplefile,sampledata" ) == FALSE ) { - p.setPen( QColor( 160, 160, 160 ) ); + trackContentObject::dragEnterEvent( _dee ); + } +} + + + + +void sampleTCO::dropEvent( QDropEvent * _de ) +{ + if( stringPairDrag::decodeKey( _de ) == "samplefile" ) + { + setSampleFile( stringPairDrag::decodeValue( _de ) ); + _de->accept(); + } + else if( stringPairDrag::decodeKey( _de ) == "sampledata" ) + { + m_sampleBuffer.loadFromBase64( + stringPairDrag::decodeValue( _de ) ); + songEditor::inst()->setModified(); + updateLength(); + update(); + _de->accept(); } else { - p.setPen( QColor( 0, 0, 128 ) ); + trackContentObject::dropEvent( _de ); } - p.drawRect( 0, 0, width(), height() ); - m_sampleBuffer.drawWaves( p, QRect( 1, 1, tMax( tMin( width() - 3, - static_cast( getSampleLength() * - pixelsPerTact() / 64 ) ), 1 ), - height() - 4 ) ); -#ifndef QT4 - bitBlt( this, rect().topLeft(), &pm ); -#endif } @@ -177,6 +181,49 @@ void sampleTCO::mouseDoubleClickEvent( QMouseEvent * ) +void sampleTCO::paintEvent( QPaintEvent * ) +{ +#ifdef QT4 + QPainter p( this ); +#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 ) + { + p.drawPixmap( x, 1, bg ); + } + p.setPen( QColor( 0, 0, 0 ) ); + p.drawRect( 0, 0, width(), height() ); + if( getTrack()->muted() ) + { + p.setPen( QColor( 128, 128, 128 ) ); + } + else + { + p.setPen( QColor( 64, 224, 160 ) ); + } + QRect r = QRect( 1, 1, + tMax( static_cast( getSampleLength() * + pixelsPerTact() / 64 ), 1 ), height() - 4 ); + p.setClipRect( QRect( 1, 1, width() - 2, height() - 2 ) ); + m_sampleBuffer.drawWaves( p, r ); + if( r.width() < width() - 1 ) + { + p.drawLine( r.x() + r.width(), r.y() + r.height() / 2, + width() - 2, r.y() + r.height() / 2 ); + } +#ifndef QT4 + bitBlt( this, rect().topLeft(), &pm ); +#endif +} + + + + midiTime sampleTCO::getSampleLength( void ) const { return( static_cast( m_sampleBuffer.frames() / @@ -187,7 +234,8 @@ midiTime sampleTCO::getSampleLength( void ) const -void FASTCALL sampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void FASTCALL sampleTCO::saveSettings( QDomDocument & _doc, + QDomElement & _parent ) { QDomElement sampletco_de = _doc.createElement( nodeName() ); if( _parent.nodeName() == "clipboard" ) @@ -312,7 +360,7 @@ sampleTrack::~sampleTrack() -track::trackTypes sampleTrack::trackType( void ) const +track::trackTypes sampleTrack::type( void ) const { return( SAMPLE_TRACK ); } diff --git a/src/widgets/kmultitabbar.cpp b/src/widgets/kmultitabbar.cpp index 4b3adba04..2166bf37c 100644 --- a/src/widgets/kmultitabbar.cpp +++ b/src/widgets/kmultitabbar.cpp @@ -111,6 +111,8 @@ KMultiTabBarInternal::KMultiTabBarInternal(QWidget *parent, Qt::Orientation o):Q box->setFixedHeight(24); setFixedHeight(24); } + mainLayout->setMargin( 0 ); + mainLayout->setSpacing( 0 ); addChild(box); setFrameStyle(NoFrame); #ifndef QT4 @@ -220,7 +222,6 @@ void KMultiTabBarInternal::resizeEvent(QResizeEvent *ev) { if ( (m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) ){ box->setGeometry(0,0,width(),height()); - printf("resizevent\n"); int lines=1; int space; int tmp=0; diff --git a/src/widgets/text_float.cpp b/src/widgets/text_float.cpp index a027bcc74..9a52c0eec 100644 --- a/src/widgets/text_float.cpp +++ b/src/widgets/text_float.cpp @@ -63,6 +63,8 @@ textFloat::textFloat( QWidget * _parent ) : reparent( parentWidget() ); resize( 20, 20 ); hide(); + + setFont( pointSize<8>( font() ) ); } @@ -71,7 +73,7 @@ textFloat::textFloat( QWidget * _parent ) : void textFloat::setTitle( const QString & _title ) { m_title = _title; - repaint(); + updateSize(); } @@ -80,7 +82,7 @@ void textFloat::setTitle( const QString & _title ) void textFloat::setText( const QString & _text ) { m_text = _text; - repaint(); + updateSize(); } @@ -89,7 +91,7 @@ void textFloat::setText( const QString & _text ) void textFloat::setPixmap( const QPixmap & _pixmap ) { m_pixmap = _pixmap; - repaint(); + updateSize(); } @@ -105,8 +107,7 @@ void textFloat::reparent( QWidget * _new_parent ) // Get position and reparent to either top level or dialog // - while( _new_parent->parentWidget() && !_new_parent->isTopLevel() - && + while( _new_parent->parentWidget() && !_new_parent->isTopLevel() && #ifdef QT4 !_new_parent->windowType() == Qt::Dialog #else @@ -162,7 +163,7 @@ textFloat * textFloat::displayMessage( const QString & _msg, int _timeout, } else { - tf->move( 32, mw->height() - 24 - _add_y_margin ); + tf->move( 32, mw->height() - 28 - _add_y_margin ); } tf->setText( _msg ); tf->show(); @@ -208,27 +209,9 @@ void textFloat::paintEvent( QPaintEvent * _pe ) p.setFont( pointSize<8>( p.font() ) ); - QFontMetrics metrics( p.fontMetrics() ); - QRect textBound = metrics.boundingRect( m_text ); - if( m_title != "" ) - { - QFont f = p.font(); - f.setBold( TRUE ); - int title_w = QFontMetrics( f ).boundingRect( m_title ).width(); - if( title_w > textBound.width() ) - { - textBound.setWidth( textBound.width() + title_w ); - } - textBound.setHeight( textBound.height() * 2 + 10 ); - } - if( m_pixmap.isNull() == FALSE ) - { - textBound.setWidth( textBound.width() + m_pixmap.width() + 10 ); - } - resize( textBound.width() + 5, textBound.height() + 5 ); p.drawRect( rect() ); - p.setPen( Qt::black ); +// p.setPen( Qt::black ); // small message? if( m_title == "" ) { @@ -263,5 +246,33 @@ void textFloat::mousePressEvent( QMouseEvent * ) } + + +void textFloat::updateSize( void ) +{ + QFontMetrics metrics( font() ); + QRect textBound = metrics.boundingRect( m_text ); + if( m_title != "" ) + { + QFont f = font(); + f.setBold( TRUE ); + int title_w = QFontMetrics( f ).boundingRect( m_title ).width(); + if( title_w > textBound.width() ) + { + textBound.setWidth( title_w ); + } + textBound.setHeight( textBound.height() * 2 + 14 ); + } + if( m_pixmap.isNull() == FALSE ) + { + textBound.setWidth( textBound.width() + m_pixmap.width() + 10 ); + } + resize( textBound.width() + 5, textBound.height() + 5 ); + //move( QPoint( parentWidget()->width() + 5, 5 ) ); + repaint(); +} + + + #undef setParent