Plugged memleaks in sf2player and lcdSpinbox, reapplied lmmsStyle, enhanced drawing of LCDs, added ignore property for SVN

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@800 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Paul Giblock
2008-03-17 06:14:06 +00:00
parent 33937e8799
commit ca8d394905
11 changed files with 553 additions and 120 deletions

6
.svnignore Normal file
View File

@@ -0,0 +1,6 @@
Makefile.in
*.moc
.libs
embedded_resources.h
.deps
Makefile

166
ChangeLog
View File

@@ -1,3 +1,167 @@
2008-03-16 Paul Giblock <drfaygo/at/gmail/dot/com>
* Makefile.am:
Added lmmsStyle to the Makefile again.
* src/widgets/lcd_spinbox.cpp:
* include/lcd_spinbox.h:
- Added separate function for deriving control size
- Added property for side-margins
- Fixed memory leak with the pixmap
- Added yours truly to the copyright
* src/core/lmms_style.cpp:
* include/lmms_style.h:
- Re-added lmmsStyle. I don't know why these files disappeared
- Getting ready to draw pretty borders
* plugins/sf2_player/sf2_player.cpp:
* plugins/sf2_player/sf2_player.h:
- Hopefully plugged some leaks caused by the leaky fluidSynth. It seems
to run fine, but only time will tell
- Added sfont file sharing between instances of sf2Player
- Added synthMutex to keep play() from freezing while we are recreating
the synth due to a file load.
* src/widgets/combobox.cpp:
Draw styled border. Don't worry, the style will be improved
* src/core/fx_mixer.cpp:
Improved drawing of LCD Channel numbers.
* .:
* m4:
* buildtools:
* plugins:
* plugins/ladspa_effect:
* plugins/ladspa_effect/caps:
* plugins/ladspa_effect/caps/waves:
* plugins/ladspa_effect/caps/dsp:
* plugins/ladspa_effect/caps/dsp/tonestack:
* plugins/patman:
* plugins/lb302:
* plugins/organic:
* plugins/bass_booster:
* plugins/bit_invader:
* plugins/vst_effect:
* plugins/vibed:
* plugins/triple_oscillator:
* plugins/singerbot:
* plugins/live_tool:
* plugins/audio_file_processor:
* plugins/stk:
* plugins/stk/mallets:
* plugins/stk/voices:
* plugins/stk/voices/flute:
* plugins/stk/voices/resonate:
* plugins/stk/voices/include:
* plugins/stk/voices/wurley:
* plugins/stk/voices/src:
* plugins/stk/voices/percflute:
* plugins/stk/voices/rhodey:
* plugins/stk/voices/tubebell:
* plugins/stk/voices/bowed:
* plugins/stk/voices/clarinet:
* plugins/stk/voices/moog:
* plugins/stk/voices/metal:
* plugins/stk/voices/b3:
* plugins/stk/voices/blow_hole:
* plugins/stk/voices/brass:
* plugins/stk/voices/fmvoices:
* plugins/stk/voices/bandedwg:
* plugins/stk/voices/blow_bottle:
* plugins/plucked_string_synth:
* plugins/stereo_enhancer:
* plugins/sf2_player:
* plugins/vestige:
* plugins/vst_base:
* plugins/ladspa_browser:
* plugins/kicker:
* plugins/polyb302:
* plugins/flp_import:
* plugins/flp_import/unrtf:
* plugins/midi_import:
* include:
* src:
* src/audio:
* src/midi:
* src/lib:
* src/widgets:
* src/tracks:
* src/3rdparty:
* src/3rdparty/samplerate:
* src/core:
* data:
* data/locale:
* data/track_icons:
* data/midi-maps:
* data/samples:
* data/samples/effects:
* data/samples/stringsnpads:
* data/samples/basses:
* data/samples/shapes:
* data/samples/latin:
* data/samples/bassloopes:
* data/samples/drums:
* data/samples/instruments:
* data/samples/misc:
* data/samples/drumsynth:
* data/samples/drumsynth/effects:
* data/samples/drumsynth/misc_synth:
* data/samples/drumsynth/tr606:
* data/samples/drumsynth/cr78:
* data/samples/drumsynth/magnetboy:
* data/samples/drumsynth/tr808:
* data/samples/drumsynth/tr909:
* data/samples/drumsynth/misc_fx:
* data/samples/drumsynth/misc:
* data/samples/drumsynth/electro:
* data/samples/drumsynth/linn:
* data/samples/drumsynth/ferraro:
* data/samples/drumsynth/r_b:
* data/samples/drumsynth/misc_bass:
* data/samples/drumsynth/tr77:
* data/samples/drumsynth/misc_perc:
* data/samples/drumsynth/latin:
* data/samples/drumsynth/instrument:
* data/samples/drumsynth/misc_electro:
* data/samples/drumsynth/acoustic:
* data/samples/drumsynth/misc_hats:
* data/samples/drumsynth/farfisa:
* data/samples/drumsynth/jorgensohn:
* data/samples/drumsynth/cr8000:
* data/samples/drumsynth/misc_claps:
* data/samples/beats:
* data/presets:
* data/presets/AudioFileProcessor:
* data/presets/LB302:
* data/presets/Organic:
* data/presets/PluckedStringSynth:
* data/presets/VeSTige:
* data/presets/BitInvader:
* data/presets/Vibed:
* data/presets/TripleOscillator:
* data/themes:
* data/themes/blue_scene:
* data/themes/blue_scene/plugins:
* data/themes/default:
* data/projects:
* data/projects/covers:
* data/projects/recorded_loops:
* data/projects/cool_songs:
* data/projects/tutorials:
* data/projects/demos:
* data/projects/misc:
* data/projects/templates:
Added svn:ignore property for temporary buildtime files. Prevents
dozens of items showing in diff and status. The file
.svnignore describes which files are ignored.
* .svnignore:
Can change this file to ignore more stuff. Reapply by running:
svn -R propset svn:ignore -F .svnignore .
2008-03-16 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* src/widgets/visualization_widget.cpp:
@@ -341,7 +505,7 @@
* src/core/main.cpp:
* Makefile.am:
added lmmsStyle to aim for a consistant interface. Some Qt themes
make LMMS look really bad. Hopefully, overtime, we can make a style
make LMMS look really bad. Hopefully, over time, we can make a style
the unifies all our gui elements
* src/core/track.cpp:

View File

@@ -180,6 +180,7 @@ lmms_SOURCES = \
$(srcdir)/src/core/ladspa_2_lmms.cpp \
$(srcdir)/src/core/ladspa_manager.cpp \
$(srcdir)/src/core/ladspa_control.cpp \
$(srcdir)/src/core/lmms_style.cpp \
$(srcdir)/src/core/main_window.cpp \
$(srcdir)/src/core/main.cpp \
$(srcdir)/src/core/meter_dialog.cpp \

View File

@@ -64,6 +64,7 @@ public:
public slots:
virtual void setEnabled( bool _on );
virtual void setMarginWidth( int _width );
virtual void update( void );
@@ -74,9 +75,11 @@ protected:
virtual void mouseReleaseEvent( QMouseEvent * _me );
virtual void wheelEvent( QWheelEvent * _we );
virtual void paintEvent( QPaintEvent * _me );
virtual void updateSize();
private:
static const int charsPerPixmap = 12;
QMap<int, QString> m_textForValue;
@@ -89,6 +92,7 @@ private:
int m_cellWidth;
int m_cellHeight;
int m_numDigits;
int m_marginWidth;
QPoint m_origMousePos;

View File

@@ -39,6 +39,11 @@ public:
virtual ~lmmsStyle()
{
}
virtual void drawPrimitive( PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget = 0 ) const;
};
#endif

View File

@@ -22,6 +22,7 @@
*
*/
#include <QTextStream>
#include <QtGui/QLayout>
#include <QtGui/QLabel>
@@ -65,6 +66,14 @@ plugin::descriptor sf2player_plugin_descriptor =
}
// Static map of current sfonts
QMap<QString, sf2Font*> sf2Instrument::s_fonts;
// Static functor to fluid's built-in free function. Used when we want
// to really delete the soundfont, instead of just changing refCount
int (* sf2Instrument::s_origFree)( fluid_sfont_t * );
sf2Instrument::sf2Instrument( instrumentTrack * _instrument_track ) :
instrument( _instrument_track, &sf2player_plugin_descriptor ),
m_fontId( 0 ),
@@ -75,44 +84,47 @@ sf2Instrument::sf2Instrument( instrumentTrack * _instrument_track ) :
for( int i = 0; i < 128; ++i )
{
m_notesRunning[i] = 0;
}
}
m_settings = new_fluid_settings();
/* Set the synthesizer settings, if necessary */
// This is just our starting instance of synth. It is recreated
// everytime we load a new soundfont.
m_synth = new_fluid_synth( m_settings );
// Install our callbacks
fluid_sfloader_t * pLoader
= (fluid_sfloader_t *) malloc( sizeof( fluid_sfloader_t ) );
//fluid_settings_setstr(settings, "audio.driver", "jack");
//adriver = new_fluid_audio_driver(settings, synth);
pLoader->data = (void *) this;
pLoader->load = sf2Instrument::sfloaderLoad;
pLoader->free = sf2Instrument::sfloaderFree;
fluid_synth_add_sfloader( m_synth, pLoader );
instrumentPlayHandle * iph = new instrumentPlayHandle( this );
engine::getMixer()->addPlayHandle( iph );
connect( &m_bankNum, SIGNAL( dataChanged() ),
this, SLOT( updatePatch() ) );
this, SLOT( updatePatch() ) );
connect( &m_patchNum, SIGNAL( dataChanged() ),
this, SLOT( updatePatch() ) );
}
this, SLOT( updatePatch() ) );
}
sf2Instrument::~sf2Instrument()
{
engine::getMixer()->removePlayHandles( getInstrumentTrack() );
delete_fluid_synth( m_synth );
delete_fluid_settings( m_settings );
engine::getMixer()->removePlayHandles( getInstrumentTrack() );
delete_fluid_synth( m_synth );
delete_fluid_settings( m_settings );
}
void sf2Instrument::saveSettings( QDomDocument & _doc,
QDomElement & _this )
QDomElement & _this )
{
_this.setAttribute( "src", m_filename );
m_patchNum.saveSettings( _doc, _this, "patch" );
@@ -121,7 +133,6 @@ void sf2Instrument::saveSettings( QDomDocument & _doc,
void sf2Instrument::loadSettings( const QDomElement & _this )
{
openFile( _this.attribute( "src" ) );
@@ -131,41 +142,68 @@ void sf2Instrument::loadSettings( const QDomElement & _this )
QString sf2Instrument::nodeName( void ) const
{
return( sf2player_plugin_descriptor.name );
}
void sf2Instrument::openFile( const QString & _sf2File )
{
if( m_filename != "")
// Remove synth from this fluidSynth (but not necessarily memory)
if ( m_filename != "" )
{
fluid_synth_sfunload( m_synth, m_fontId, TRUE);
// Recreate synth
m_synthMutex.lock();
delete_fluid_synth( m_synth );
m_synth = new_fluid_synth( m_settings );
m_synthMutex.unlock();
// No need to explicitly delete font. Deleting fluidSynth calls free
// on all fonts. This, causes sfloaderFreeFont to run.
}
m_fontId = fluid_synth_sfload( m_synth, _sf2File.toLocal8Bit(), TRUE );
const char * sf2Ascii = qPrintable( _sf2File );
m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, TRUE );
if( m_fontId >= 0)
QString sf2Key = qPrintable( _sf2File );
// Add to map, if doesn't exist.
// We can't do this in callback because fluid hasn't created the sfont yet
if( !s_fonts.contains( sf2Key ) && fluid_synth_sfcount( m_synth ) > 0 )
{
m_patchNum.setValue(0);
m_bankNum.setValue(0);
// Grab this sf from the top of the stack
fluid_sfont_t * sfont = fluid_synth_get_sfont( m_synth, 0 );
// Hold on to real free function for executing later.
s_origFree = sfont->free;
sfont->free = sf2Instrument::sfloaderFreeFont;
// Finally, add font
s_fonts.insert( sf2Key, new sf2Font( sfont ) );
}
if( m_fontId >= 0 )
{
m_patchNum.setValue( 0 );
m_bankNum.setValue( 0 );
m_filename = _sf2File;
emit fileChanged();
}
}
void sf2Instrument::updatePatch( void )
{
printf("update patch\n");
if( m_bankNum.value() >= 0 && m_patchNum.value() >= 0 ) {
fluid_synth_program_select( m_synth, 1, m_fontId,
m_bankNum.value(), m_patchNum.value() );
}
}
void sf2Instrument::playNote( notePlayHandle * _n, bool )
@@ -174,7 +212,8 @@ void sf2Instrument::playNote( notePlayHandle * _n, bool )
const f_cnt_t tfp = _n->totalFramesPlayed();
int midiNote = (int)floor( ( log2( _n->frequency() ) - LOG440 ) * 12+69-58)+0.5;
int midiNote = (int)floor( 12 * ( log2( _n->frequency() ) - LOG440 ) - 4 );
// out of range?
if( midiNote <= 0 || midiNote >= 128 )
{
@@ -184,30 +223,33 @@ void sf2Instrument::playNote( notePlayHandle * _n, bool )
if ( tfp == 0 )
{
_n->m_pluginData = new int( midiNote );
m_synthMutex.lock();
fluid_synth_noteon( m_synth, 1, midiNote, _n->getVolume() );
m_synthMutex.unlock();
m_notesRunningMutex.lock();
++m_notesRunning[midiNote];
m_notesRunningMutex.unlock();
}
else if( _n->released() )
{
// Doesn't happen with release frames = 0
// Doesn't happen with release frames = 0
}
}
void sf2Instrument::play( bool _try_parallelizing )
{
const fpp_t frames = engine::getMixer()->framesPerPeriod();
sampleFrame * buf = new sampleFrame[frames];
// Assumes stereo and float sample_t
m_synthMutex.lock();
fluid_synth_write_float( m_synth, frames, buf, 0, 2, buf, 1, 2 );
m_synthMutex.unlock();
getInstrumentTrack()->processAudioBuffer( buf, frames, NULL );
@@ -216,6 +258,71 @@ void sf2Instrument::play( bool _try_parallelizing )
int sf2Instrument::sfloaderFree( fluid_sfloader_t * _loader )
{
if( _loader != NULL )
{
free( _loader );
}
return 0;
}
int sf2Instrument::sfloaderFreeFont( fluid_sfont_t * _sfont )
{
QString key = QString( _sfont->get_name(_sfont) );
sf2Font * f = sf2Instrument::s_fonts[key];
--(f->refCount);
// No more references
if( f->refCount <= 0 )
{
QTextStream cout( stdout, QIODevice::WriteOnly );
cout << "Really deleting " << key << endl;
sf2Instrument::s_fonts.remove( key );
delete f;
// Let fluidsynth free the font, as if we were not here
return s_origFree( _sfont );
}
// Make fluid think we freed the sfont
return 0;
}
fluid_sfont_t * sf2Instrument::sfloaderLoad(
fluid_sfloader_t * _loader, const char *_filename )
{
if( _loader == NULL )
{
return NULL;
}
QString filename = _filename;
if( sf2Instrument::s_fonts.contains( filename ) )
{
QTextStream cout( stdout, QIODevice::WriteOnly );
cout << "Using existing reference to " << filename << endl;
sf2Font * font = sf2Instrument::s_fonts[ filename ];
font->refCount++;
return font->fluidFont;
}
// fluidsynth will call next (default) loader...
return NULL;
}
void sf2Instrument::deleteNotePluginData( notePlayHandle * _n )
{
int * midiNote = static_cast<int *>( _n->m_pluginData );
@@ -224,7 +331,9 @@ void sf2Instrument::deleteNotePluginData( notePlayHandle * _n )
m_notesRunningMutex.unlock();
if( n <= 0 )
{
m_synthMutex.lock();
fluid_synth_noteoff( m_synth, 1, *midiNote );
m_synthMutex.unlock();
}
delete midiNote;
@@ -238,9 +347,8 @@ pluginView * sf2Instrument::instantiateView( QWidget * _parent )
sf2InstrumentView::sf2InstrumentView( instrument * _instrument,
QWidget * _parent ) :
QWidget * _parent ) :
instrumentView( _instrument, _parent )
{
QVBoxLayout * vl = new QVBoxLayout( this );
@@ -250,36 +358,36 @@ sf2InstrumentView::sf2InstrumentView( instrument * _instrument,
m_fileDialogButton = new pixmapButton( this, NULL );
m_fileDialogButton->setCursor( QCursor( Qt::PointingHandCursor ) );
m_fileDialogButton->setActiveGraphic( embed::getIconPixmap(
"project_open_down" ) );
"project_open_down" ) );
m_fileDialogButton->setInactiveGraphic( embed::getIconPixmap(
"project_open" ) );
"project_open" ) );
connect( m_fileDialogButton, SIGNAL( clicked() ),
this, SLOT( showFileDialog() ) );
this, SLOT( showFileDialog() ) );
toolTip::add( m_fileDialogButton, tr( "Open other SoundFont file" ) );
m_fileDialogButton->setWhatsThis(
tr( "Click here to open another SF2 file" ) );
tr( "Click here to open another SF2 file" ) );
// Patch Button
m_patchDialogButton = new pixmapButton( this, NULL );
m_patchDialogButton->setCursor( QCursor( Qt::PointingHandCursor ) );
m_patchDialogButton->setActiveGraphic( embed::getIconPixmap(
"track_op_menu" ) );
"track_op_menu" ) );
m_patchDialogButton->setInactiveGraphic( embed::getIconPixmap(
"track_op_menu" ) );
"track_op_menu" ) );
connect( m_patchDialogButton, SIGNAL( clicked() ),
this, SLOT( showPatchDialog() ) );
this, SLOT( showPatchDialog() ) );
toolTip::add( m_patchDialogButton, tr( "Choose the patch" ) );
// LCDs
m_bankNumLcd = new lcdSpinBox( 3, this, "Bank" );
m_bankNumLcd->setLabel( "Bank:" );
m_bankNumLcd->setLabel( "BANK" );
m_bankNumLcd->addTextForValue( -1, "---" );
m_bankNumLcd->setEnabled( FALSE );
m_patchNumLcd = new lcdSpinBox( 3, this, "Patch" );
m_patchNumLcd->setLabel( "Patch:" );
m_patchNumLcd->setLabel( "PATCH" );
m_patchNumLcd->addTextForValue( -1, "---" );
m_patchNumLcd->setEnabled( FALSE );
@@ -293,17 +401,16 @@ sf2InstrumentView::sf2InstrumentView( instrument * _instrument,
// Next row
hl = new QHBoxLayout();
m_filenameLabel = new QLabel( this );
hl->addWidget( m_filenameLabel );
m_filenameLabel = new QLabel( this );
hl->addWidget( m_filenameLabel );
vl->addLayout( hl );
setAutoFillBackground( TRUE );
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
"artwork" ) );
"artwork" ) );
setPalette( pal );
updateFilename();
@@ -311,12 +418,12 @@ sf2InstrumentView::sf2InstrumentView( instrument * _instrument,
sf2InstrumentView::~sf2InstrumentView()
{
}
void sf2InstrumentView::modelChanged( void )
{
sf2Instrument * k = castModel<sf2Instrument>();
@@ -324,22 +431,24 @@ void sf2InstrumentView::modelChanged( void )
m_patchNumLcd->setModel( &k->m_patchNum );
connect(k, SIGNAL( fileChanged( void ) ),
this, SLOT( updateFilename( void ) ) );
this, SLOT( updateFilename( void ) ) );
updateFilename();
}
void sf2InstrumentView::updateFilename( void )
{
m_filenameLabel->setText("File: " +
m_filenameLabel->setText( "File: " +
castModel<sf2Instrument>()->m_filename +
"\nPatch: TODO");
"\nPatch: TODO" );
update();
}
void sf2InstrumentView::showFileDialog( void )
{
sf2Instrument * k = castModel<sf2Instrument>();
@@ -361,7 +470,7 @@ void sf2InstrumentView::showFileDialog( void )
if( QFileInfo( f ).exists() == FALSE )
{
f = configManager::inst()->factorySamplesDir() +
k->m_filename;
k->m_filename;
}
}
ofd.setDirectory( QFileInfo( f ).absolutePath() );
@@ -381,27 +490,30 @@ void sf2InstrumentView::showFileDialog( void )
engine::getSong()->setModified();
}
}
}
// Single instance of the patch dialog
patchesDialog * sf2InstrumentView::s_patchDialog = NULL;
void sf2InstrumentView::showPatchDialog( void ) {
sf2Instrument * k = castModel<sf2Instrument>();
if( s_patchDialog == NULL ) {
printf("Creating patchDialog\n");
s_patchDialog = new patchesDialog(this);
if( s_patchDialog == NULL )
{
s_patchDialog = new patchesDialog( this );
}
s_patchDialog->setup( k->m_synth, 1, k->getInstrumentTrack()->name(),
s_patchDialog->setup( k->m_synth, 1, k->getInstrumentTrack()->name(),
&k->m_bankNum, &k->m_patchNum );
s_patchDialog->exec();
}
extern "C"
{
@@ -409,7 +521,7 @@ extern "C"
plugin * lmms_plugin_main( model *, void * _data )
{
return( new sf2Instrument(
static_cast<instrumentTrack *>( _data ) ) );
static_cast<instrumentTrack *>( _data ) ) );
}

View File

@@ -36,6 +36,7 @@
#include "fluidsynth.h"
class sf2InstrumentView;
class sf2Font;
class notePlayHandle;
class patchesDialog;
@@ -51,12 +52,12 @@ public:
virtual void play( bool _try_parallelizing );
virtual void FASTCALL playNote( notePlayHandle * _n,
bool _try_parallelizing );
bool _try_parallelizing );
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
virtual void FASTCALL saveSettings( QDomDocument & _doc,
QDomElement & _parent );
QDomElement & _parent );
virtual void FASTCALL loadSettings( const QDomElement & _this );
virtual QString nodeName( void ) const;
@@ -71,13 +72,11 @@ public:
return( FALSE );
}
virtual bool supportsParallelizing( void ) const
{
return( FALSE );
}
virtual pluginView * instantiateView( QWidget * _parent );
@@ -87,22 +86,34 @@ public slots:
private:
fluid_settings_t* m_settings;
static QMap<QString, sf2Font*> s_fonts;
static int (* s_origFree)( fluid_sfont_t * );
fluid_settings_t* m_settings;
fluid_synth_t* m_synth;
fluid_audio_driver_t* m_adriver;
int m_fontId;
QMutex m_notesRunningMutex;
int m_notesRunning[128];
QString m_filename;
// Protect the array of active notes
QMutex m_notesRunningMutex;
// Protect synth when we are re-creating it.
QMutex m_synthMutex;
int m_notesRunning[128];
lcdSpinBoxModel m_bankNum;
lcdSpinBoxModel m_patchNum;
private:
// Our special callback functions
static int sfloaderFree( fluid_sfloader_t * _loader );
static fluid_sfont_t * sfloaderLoad(
fluid_sfloader_t * _loader, const char * _filename );
static int sfloaderFreeFont( fluid_sfont_t * _soundFont );
friend class sf2InstrumentView;
signals:
@@ -113,6 +124,21 @@ signals:
// A soundfont in our font-map
class sf2Font
{
public:
sf2Font( fluid_sfont_t * f ) :
fluidFont( f ),
refCount( 1 )
{};
fluid_sfont_t * fluidFont;
int refCount;
};
class sf2InstrumentView : public instrumentView
{
Q_OBJECT

View File

@@ -369,7 +369,9 @@ fxMixerView::fxMixerView() :
lcdSpinBox * l = new lcdSpinBox( 2, cv->m_fxLine );
l->model()->setRange( i, i );
l->model()->setValue( i );
l->update();
l->move( 2, 4 );
l->setMarginWidth( 1 );
cv->m_fader = new fader( &m->m_fxChannels[i]->m_volumeModel,
cv->m_fxLine );
cv->m_fader->move( 15-cv->m_fader->width()/2, 80 );

110
src/core/lmms_style.cpp Normal file
View File

@@ -0,0 +1,110 @@
#include <QtGui/QPlastiqueStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QPainter>
#include <QtGui/QWidget>
#include <QtGui/QFrame>
#include "lmms_style.h"
void lmmsStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget) const
{
QPlastiqueStyle::drawPrimitive( element, option, painter, widget );
/*
if( element == QStyle::PE_Frame ) {
printf("Frame\n");
QFrame::Shadow shadow = QFrame::Plain;
if (option->state & State_Sunken)
shadow = QFrame::Sunken;
else if (option->state & State_Raised)
shadow = QFrame::Raised;
QPen oldPen = painter->pen();
QBrush border;
QBrush corner;
QBrush innerTopLeft;
QBrush innerBottomRight;
if (shadow != QFrame::Plain && (option->state & QStyle::State_HasFocus)) {
border = option->palette.highlight();
qBrushSetAlphaF(&border, 0.8);
corner = option->palette.highlight();
qBrushSetAlphaF(&corner, 0.5);
innerTopLeft = qBrushDark(option->palette.highlight(), 125);
innerBottomRight = option->palette.highlight();
qBrushSetAlphaF(&innerBottomRight, 0.65);
} else {
border = option->palette.shadow();
qBrushSetAlphaF(&border, 0.4);
corner = option->palette.shadow();
qBrushSetAlphaF(&corner, 0.25);
innerTopLeft = option->palette.shadow();
innerBottomRight = option->palette.highlight();
if (shadow == QFrame::Sunken) {
qBrushSetAlphaF(&innerTopLeft, 0.23);
qBrushSetAlphaF(&innerBottomRight, 0.075);
} else {
qBrushSetAlphaF(&innerTopLeft, 0.075);
qBrushSetAlphaF(&innerBottomRight, 0.23);
}
}
QLine lines[4];
QPoint points[8];
// Opaque corner lines
painter->setPen(QPen(border, 0));
lines[0] = QLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
lines[1] = QLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
lines[2] = QLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
lines[3] = QLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
painter->drawLines(lines, 4);
// Opaque corner dots
points[0] = QPoint(rect.left() + 1, rect.top() + 1);
points[1] = QPoint(rect.left() + 1, rect.bottom() - 1);
points[2] = QPoint(rect.right() - 1, rect.top() + 1);
points[3] = QPoint(rect.right() - 1, rect.bottom() - 1);
painter->drawPoints(points, 4);
// Shaded corner dots
painter->setPen(QPen(corner, 0));
points[0] = QPoint(rect.left(), rect.top() + 1);
points[1] = QPoint(rect.left(), rect.bottom() - 1);
points[2] = QPoint(rect.left() + 1, rect.top());
points[3] = QPoint(rect.left() + 1, rect.bottom());
points[4] = QPoint(rect.right(), rect.top() + 1);
points[5] = QPoint(rect.right(), rect.bottom() - 1);
points[6] = QPoint(rect.right() - 1, rect.top());
points[7] = QPoint(rect.right() - 1, rect.bottom());
painter->drawPoints(points, 8);
// Shadows
if (shadow != QFrame::Plain) {
painter->setPen(QPen(innerTopLeft, 0));
lines[0] = QLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, rect.top() + 1);
lines[1] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
painter->drawLines(lines, 2);
painter->setPen(QPen(innerBottomRight, 0));
lines[0] = QLine(rect.left() + 2, rect.bottom() - 1, rect.right() - 2, rect.bottom() - 1);
lines[1] = QLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
painter->drawLines(lines, 2);
}
painter->setPen(oldPen);
}
else {
QPlastiqueStyle::drawPrimitive( element, option, painter, widget );
}
// brighter line at bottom/right
p.setPen( QColor( 160, 160, 160 ) );
p.drawLine( width() - 1, 0, width() - 1, height() - 1 );
p.drawLine( 0, height() - 1, width() - 1, height() - 1 );
*/
}

View File

@@ -182,7 +182,7 @@ void comboBox::paintEvent( QPaintEvent * _pe )
// Border
QStyleOptionFrame opt;
opt.initFrom( this );
opt.state = QStyle::State_Sunken;
opt.state = 0;
style()->drawPrimitive( QStyle::PE_Frame, &opt, &p, this );

View File

@@ -4,6 +4,7 @@
* lcd_spinbox.cpp - class lcdSpinBox, an improved QLCDNumber
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Paul Giblock <pgllama/at/gmail.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -34,7 +35,6 @@
#include <QtGui/QFontMetrics>
#include <QtGui/QStyleOptionFrameV2>
#include "automatable_model_templates.h"
#include "caption_menu.h"
#include "embed.h"
@@ -43,29 +43,29 @@
lcdSpinBox::lcdSpinBox( int _num_digits, QWidget * _parent,
const QString & _name ) :
const QString & _name ) :
QWidget( _parent ),
autoModelView( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ),
m_label(),
m_numDigits( _num_digits ),
m_origMousePos()
{
{
setEnabled( TRUE );
setAccessibleName( _name );
m_lcdPixmap = new QPixmap( embed::getIconPixmap( "lcd_19green" ) );
int margin = 1; //QStyle::PM_DefaultFrameWidth;
m_cellWidth = m_lcdPixmap->size().width() / lcdSpinBox::charsPerPixmap;
m_cellHeight = m_lcdPixmap->size().height() / 2;
setFixedSize( m_cellWidth * (_num_digits+1) + (2*margin),
m_cellHeight + (2*margin) );
m_marginWidth = m_cellWidth / 2;
updateSize();
}
lcdSpinBox::lcdSpinBox( int _num_digits, const QString & _lcd_style,
lcdSpinBox::lcdSpinBox( int _num_digits, const QString & _lcd_style,
QWidget * _parent, const QString & _name ) :
QWidget( _parent ),
autoModelView( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ),
@@ -77,23 +77,22 @@ lcdSpinBox::lcdSpinBox( int _num_digits, const QString & _lcd_style,
setAccessibleName( _name );
// We should make a factory for these or something.
m_lcdPixmap = new QPixmap( embed::getIconPixmap( QString( "lcd_" +
_lcd_style ).toAscii().constData() ) );
int margin = 1; //QStyle::PM_DefaultFrameWidth;
m_cellWidth = m_lcdPixmap->size().width() / lcdSpinBox::charsPerPixmap;
m_cellHeight = m_lcdPixmap->size().height() / 2;
setFixedSize( m_cellWidth * (_num_digits+1) + (2*margin),
m_cellHeight + (2*margin) );
m_marginWidth = m_cellWidth / 2;
updateSize();
}
lcdSpinBox::~lcdSpinBox()
{
delete m_lcdPixmap;
}
@@ -102,17 +101,17 @@ void lcdSpinBox::paintEvent( QPaintEvent * _me )
QRect ur = _me->rect();
QPainter p( this );
QSize cellSize( m_cellWidth, m_cellHeight );
QRect cellRect( 0, 0, m_cellWidth, m_cellHeight );
int margin = 1;// QStyle::PM_DefaultFrameWidth;
int lcdWidth = m_cellWidth * (m_numDigits+1) + (margin*2);
int margin = 1; // QStyle::PM_DefaultFrameWidth;
int lcdWidth = m_cellWidth * m_numDigits + (margin*m_marginWidth)*2;
p.translate( width() / 2 - lcdWidth / 2, 0 );
p.save();
p.translate( margin, margin );
// Left Margin
@@ -120,8 +119,8 @@ void lcdSpinBox::paintEvent( QPaintEvent * _me )
QRect( QPoint( charsPerPixmap*m_cellWidth,
isEnabled()?0:m_cellHeight ),
cellSize ) );
p.translate( (m_cellWidth+1) / 2, 0 );
p.translate( m_marginWidth, 0 );
// Padding
for( int i=0; i < m_numDigits - m_display.length(); i++ )
@@ -150,7 +149,7 @@ void lcdSpinBox::paintEvent( QPaintEvent * _me )
}
// Right Margin
p.drawPixmap( QRect( 0, 0, m_cellWidth / 2, m_cellHeight ), *m_lcdPixmap,
p.drawPixmap( QRect( 0, 0, m_marginWidth-1, m_cellHeight ), *m_lcdPixmap,
QRect( charsPerPixmap*m_cellWidth, isEnabled()?0:m_cellHeight,
m_cellWidth / 2, m_cellHeight ) );
@@ -161,7 +160,7 @@ void lcdSpinBox::paintEvent( QPaintEvent * _me )
QStyleOptionFrame opt;
opt.initFrom( this );
opt.state = QStyle::State_Sunken;
opt.rect = QRect( 0, 0, m_cellWidth * (m_numDigits+1) + (margin*2),
opt.rect = QRect( 0, 0, m_cellWidth * m_numDigits + (margin+m_marginWidth)*2 - 1,
m_cellHeight + (margin*2) );
style()->drawPrimitive( QStyle::PE_Frame, &opt, &p, this );
@@ -185,7 +184,6 @@ void lcdSpinBox::paintEvent( QPaintEvent * _me )
}
void lcdSpinBox::update( void )
{
QString s = m_textForValue[model()->value()];
@@ -201,36 +199,50 @@ void lcdSpinBox::update( void )
*/
}
m_display = s;
QWidget::update();
}
void lcdSpinBox::setLabel( const QString & _txt )
{
int margin = 1;
m_label = _txt;
setFixedSize( m_cellWidth * (m_numDigits+1) + (2*margin),
m_cellHeight + (2*margin) );
setFixedSize( tMax<int>( m_cellWidth*(m_numDigits+1) + (2*margin),
QFontMetrics( pointSize<6>( font() ) ).width( m_label ) ),
m_cellHeight + (2*margin) + 10 );
update();
updateSize();
}
void lcdSpinBox::setEnabled( bool _on )
{
QWidget::setEnabled( _on );
}
void lcdSpinBox::setMarginWidth( int _width )
{
m_marginWidth = _width;
updateSize();
}
void lcdSpinBox::updateSize()
{
int margin = 1;
if (m_label.isEmpty()) {
setFixedSize( m_cellWidth * m_numDigits + 2*(margin+m_marginWidth),
m_cellHeight + (2*margin) );
}
else {
setFixedSize( tMax<int>(
m_cellWidth * m_numDigits + 2*(margin+m_marginWidth),
QFontMetrics( pointSize<6>( font() ) ).width( m_label ) ),
m_cellHeight + (2*margin) + 10 );
}
update();
}
void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me )
@@ -258,8 +270,6 @@ void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me )
}
void lcdSpinBox::mousePressEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton && _me->y() < m_cellHeight + 2 )
@@ -271,8 +281,6 @@ void lcdSpinBox::mousePressEvent( QMouseEvent * _me )
}
void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me )
{
if( _me->buttons() & Qt::LeftButton )
@@ -289,8 +297,6 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me )
}
void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me )
{
model()->addJournalEntryFromOldToCurVal();
@@ -300,8 +306,6 @@ void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me )
}
void lcdSpinBox::wheelEvent( QWheelEvent * _we )
{
_we->accept();
@@ -312,7 +316,6 @@ void lcdSpinBox::wheelEvent( QWheelEvent * _we )
#include "lcd_spinbox.moc"