diff --git a/ChangeLog b/ChangeLog index d2003ec84a..dd508e3ec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,41 @@ +2005-09-28 Tobias Doerffel + + * include/song_editor.h: + * src/core/song_editor.cpp: + added combo-box for selecting zooming-factor + + * include/piano_roll.h: + * src/core/piano_roll.cpp: + added combo-box for selecting zooming-factor + + * include/led_checkbox.h: + * src/widgets/led_checkbox.cpp: + added methods for querying and setting state + + * src/core/arp_and_chords_tab_widget.cpp: + * src/core/envelope_tab_widget.cpp: + better alignment of widgets inside each of this tabs + + * src/tracks/channel_track.cpp: + finished improving GUI of channel-track-window by using tabWidget + instead of tabBar for plugin-, env/lfo- and arp-widgets + + * include/envelope_and_lfo_widget.h: + * src/core/envelope_and_lfo_widget.cpp: + use ledCheckBox'es instead of pixmapButton's with QLabel's + + * include/tab_widget.h: + * src/widgets/tab_widget.cpp: + made tabWidget more powerful: + - use indexed tabs + - different painting if no caption was defined + - switch tabs if wheel-events occurs + 2005-09-27 Tobias Doerffel + * src/tracks/channel_track.cpp: + began improving GUI of channel-track-window + * projects/cool_songs/TobyDox-TheFourthDimension.xml: added another song... diff --git a/TODO b/TODO index 6666f89c6a..2668e16a54 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ -- make channel-track-window use tab-widget instead of tab-bar -- capture wheel-event in tab-widget for switching pages -- add select-boxes for zooming in song-editor and piano-roll - use own scrollview for capturing wheel-events +- add note-len- and note-alignment-selectbox to piano-roll +- only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc. - make usable with Qt4 - make LMMS an ALSA-sequencer-client - adchannel-toolbutton -> popup-menu with available soundgenerator-plugins diff --git a/include/envelope_and_lfo_widget.h b/include/envelope_and_lfo_widget.h index b9760d9c19..0a1d7ecf08 100644 --- a/include/envelope_and_lfo_widget.h +++ b/include/envelope_and_lfo_widget.h @@ -49,11 +49,12 @@ #include "spc_bg_hndl_widget.h" -class envelopeTabWidget; -class pixmapButton; -class knob; class QPaintEvent; class QPixmap; +class envelopeTabWidget; +class knob; +class ledCheckBox; +class pixmapButton; @@ -145,8 +146,8 @@ private: pixmapButton * m_sqrLfoBtn; static QPixmap * s_lfoGraph; - pixmapButton * m_x100Btn; - pixmapButton * m_controlEnvAmountBtn; + ledCheckBox * m_x100Cb; + ledCheckBox * m_controlEnvAmountCb; Uint32 m_lfoPredelayFrames; Uint32 m_lfoAttackFrames; diff --git a/include/led_checkbox.h b/include/led_checkbox.h index 53711a436c..7e2281aacb 100644 --- a/include/led_checkbox.h +++ b/include/led_checkbox.h @@ -53,6 +53,29 @@ public: ledColors _color = YELLOW ); virtual ~ledCheckBox(); +#ifdef QT4 + inline virtual bool isChecked( void ) const + { + return( checkState() == Qt::Checked ); + } +#else + inline virtual bool isOn( void ) const + { + return( state() == On ); + } +#endif +#ifdef QT4 + inline virtual void setChecked( bool _on ) +#else + inline virtual void setOn( bool _on ) +#endif + { + if( _on != isChecked() ) + { + toggle(); + } + } + protected: virtual void paintEvent( QPaintEvent * _pe ); diff --git a/include/piano_roll.h b/include/piano_roll.h index f5abd7d601..1f48b478ba 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -44,9 +44,10 @@ #include "note.h" -class QScrollBar; +class QComboBox; class QPainter; class QPixmap; +class QScrollBar; class crystalButton; class pattern; @@ -122,6 +123,8 @@ protected slots: void updatePosition( const midiTime & _t ); + void zoomingChanged( const QString & _zfac ); + private: @@ -180,6 +183,9 @@ private: crystalButton * m_copyButton; crystalButton * m_pasteButton; + QComboBox * m_zoomingComboBox; + + pattern * m_pattern; QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; diff --git a/include/song_editor.h b/include/song_editor.h index c70f62a6a3..07ff27ce33 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -44,12 +44,14 @@ #include "types.h" +class QComboBox; class QLabel; class QPixmap; class QPushButton; class QScrollBar; class QSlider; class QToolButton; + class exportProjectDialog; class lcdSpinBox; class pattern; @@ -243,6 +245,8 @@ protected slots: void updatePosition( const midiTime & _t ); + void zoomingChanged( const QString & _zfac ); + private: songEditor(); @@ -288,6 +292,7 @@ private: QToolButton * m_insertTactButton; QToolButton * m_removeTactButton; + QComboBox * m_zoomingComboBox; QString m_fileName; diff --git a/include/tab_widget.h b/include/tab_widget.h index 72f4b8153c..32576c3cc7 100644 --- a/include/tab_widget.h +++ b/include/tab_widget.h @@ -30,30 +30,52 @@ #ifdef QT4 #include -#include +#include #else #include -#include +#include + +#include "spc_bg_hndl_widget.h" #endif + class tabWidget : public QWidget +#ifndef QT4 + , public specialBgHandlingWidget +#endif { Q_OBJECT public: tabWidget( const QString & _caption, QWidget * _parent ); ~tabWidget(); - void addTab( QWidget * _w, const QString & _name ); + void addTab( QWidget * _w, const QString & _name, int _idx = -1 ); + + inline void setActiveTab( int _idx ) + { + if( m_widgets.contains( _idx ) ) + { + m_activeTab = _idx; + m_widgets[m_activeTab].w->raise(); + update(); + } + } + + inline int activeTab( void ) const + { + return( m_activeTab ); + } protected: virtual void mousePressEvent( QMouseEvent * _me ); virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ); + virtual void wheelEvent( QWheelEvent * _we ); private: @@ -63,10 +85,10 @@ private: QString name; // name for widget int nwidth; // width of name when painting } ; - typedef vvector widgetStack; + typedef QMap widgetStack; widgetStack m_widgets; - int m_curWidget; + int m_activeTab; QString m_caption; } ; diff --git a/include/track_container.h b/include/track_container.h index 7b221f3451..985f80d23a 100644 --- a/include/track_container.h +++ b/include/track_container.h @@ -1,5 +1,6 @@ /* - * track_container.h - base-class for all track-containers like Playlist-Editor, BB-Editor... + * track_container.h - base-class for all track-containers like Song-Editor, + * BB-Editor... * * Linux MultiMedia Studio * Copyright (c) 2004-2005 Tobias Doerffel @@ -46,6 +47,8 @@ #include "settings.h" +const Uint16 DEFAULT_PIXELS_PER_TACT = 16; + class trackContainer : public QMainWindow, public settings { diff --git a/src/core/arp_and_chords_tab_widget.cpp b/src/core/arp_and_chords_tab_widget.cpp index bff450677d..2167dbe43d 100644 --- a/src/core/arp_and_chords_tab_widget.cpp +++ b/src/core/arp_and_chords_tab_widget.cpp @@ -183,9 +183,9 @@ arpAndChordsTabWidget::chord arpAndChordsTabWidget::s_chords[] = } ; -const int CHORDS_GROUPBOX_X = 5; +const int CHORDS_GROUPBOX_X = 4; const int CHORDS_GROUPBOX_Y = 5; -const int CHORDS_GROUPBOX_WIDTH = 240; +const int CHORDS_GROUPBOX_WIDTH = 238; const int CHORDS_GROUPBOX_HEIGHT = 65; const int ARP_GROUPBOX_X = CHORDS_GROUPBOX_X; const int ARP_GROUPBOX_Y = 10 + CHORDS_GROUPBOX_Y + CHORDS_GROUPBOX_HEIGHT; diff --git a/src/core/envelope_and_lfo_widget.cpp b/src/core/envelope_and_lfo_widget.cpp index 5fb594e45a..f8d6c0b35c 100644 --- a/src/core/envelope_and_lfo_widget.cpp +++ b/src/core/envelope_and_lfo_widget.cpp @@ -58,6 +58,7 @@ #include "debug.h" #include "tooltip.h" #include "gui_templates.h" +#include "led_checkbox.h" // how long should be each envelope-segment maximal (e.g. attack)? @@ -66,8 +67,8 @@ const float SECS_PER_ENV_SEGMENT = 5.0f; const float SECS_PER_LFO_OSCILLATION = 20.0f; -const int env_graph_x = 8; -const int env_graph_y = 8; +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; @@ -83,7 +84,7 @@ const int amount_knob_x = release_knob_x+knob_x_spacing; const float time_unit_width = 36.0; -const int lfo_graph_x = 8; +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; @@ -409,54 +410,34 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, lfo_shapes_algo_group->hide(); #endif - m_x100Btn = new pixmapButton( this ); - m_x100Btn->move( lfo_predelay_knob_x, lfo_graph_y + 36 ); - m_x100Btn->setBgGraphic( specialBgHandlingWidget::getBackground( - m_x100Btn ) ); - -/* m_x100Btn->setActiveGraphic( embed::getIconPixmap( "x100_active" ) ); - m_x100Btn->setInactiveGraphic( embed::getIconPixmap( - "x100_inactive" ) );*/ - m_x100Btn->setBgGraphic( - specialBgHandlingWidget::getBackground( m_x100Btn ) ); + 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 ); #ifdef QT4 - m_x100Btn->setWhatsThis( + m_x100Cb->setWhatsThis( #else - QWhatsThis::add( m_x100Btn, + QWhatsThis::add( m_x100Cb, #endif tr( "Click here if the frequency of this LFO should be " "multiplied with 100." ) ); - toolTip::add( m_x100Btn, tr( "multiply LFO-frequency with 100" ) ); - connect( m_x100Btn, SIGNAL( toggled( bool ) ), this, + toolTip::add( m_x100Cb, tr( "multiply LFO-frequency with 100" ) ); + connect( m_x100Cb, SIGNAL( toggled( bool ) ), this, SLOT( x100Toggled( bool ) ) ); - QLabel * x100_lbl = new QLabel( tr( "FREQ x 100" ), this ); - x100_lbl->setFont( pointSize<6>( x100_lbl->font() ) ); - x100_lbl->move( m_x100Btn->x() + 16, m_x100Btn->y() ); - x100_lbl->setFixedHeight( 10 ); - m_controlEnvAmountBtn = new pixmapButton( this ); - m_controlEnvAmountBtn->move( lfo_predelay_knob_x, lfo_graph_y + 54 ); - m_controlEnvAmountBtn->setBgGraphic( - specialBgHandlingWidget::getBackground( - m_controlEnvAmountBtn ) ); -/* m_controlEnvAmountBtn->setActiveGraphic( embed::getIconPixmap( - "control_env_amount_active" ) ); - m_controlEnvAmountBtn->setInactiveGraphic( embed::getIconPixmap( - "control_env_amount_inactive" ) );*/ + m_controlEnvAmountCb = new ledCheckBox( tr( "MODULATE ENV-AMOUNT" ), + this ); + m_controlEnvAmountCb->move( lfo_predelay_knob_x, lfo_graph_y + 54 ); + m_controlEnvAmountCb->setFont( pointSize<6>( + m_controlEnvAmountCb->font() ) ); #ifdef QT4 - m_controlEnvAmountBtn ->setWhatsThis( + m_controlEnvAmountCb ->setWhatsThis( #else - QWhatsThis::add( m_controlEnvAmountBtn, + QWhatsThis::add( m_controlEnvAmountCb, #endif tr( "Click here to make the envelope-amount controlled by this " "LFO." ) ); - QLabel * cea_lbl = new QLabel( tr( "MODULATE ENV-AMOUNT" ), this ); - cea_lbl->setFont( pointSize<6>( cea_lbl->font() ) ); - cea_lbl->move( m_controlEnvAmountBtn->x() + 16, - m_controlEnvAmountBtn->y() ); - cea_lbl->setFixedSize( 110, 10 ); - toolTip::add( m_controlEnvAmountBtn, + toolTip::add( m_controlEnvAmountCb, tr( "control envelope-amount by this LFO" ) ); @@ -534,7 +515,7 @@ float FASTCALL envelopeAndLFOWidget::level( Uint32 _frame, } if( _frame < m_pahdFrames ) { - if( m_controlEnvAmountBtn->isChecked() ) + if( m_controlEnvAmountCb->isChecked() ) { return( m_pahdEnv[_frame] * ( 0.5f + lfoLevel( _frame, _frame_offset ) ) ); @@ -550,7 +531,7 @@ float FASTCALL envelopeAndLFOWidget::level( Uint32 _frame, _frame -= _release_begin; if( _frame < m_rFrames ) { - if( m_controlEnvAmountBtn->isChecked() ) + if( m_controlEnvAmountCb->isChecked() ) { return( m_rEnv[_frame] * ( 0.5f + lfoLevel( _frame, _frame_offset ) ) ); @@ -566,7 +547,7 @@ float FASTCALL envelopeAndLFOWidget::level( Uint32 _frame, return( 0.0f ); } } - if( m_controlEnvAmountBtn->isChecked() ) + if( m_controlEnvAmountCb->isChecked() ) { return( m_sustainLevel * ( 0.5f + lfoLevel( _frame, _frame_offset ) ) ); @@ -600,9 +581,9 @@ void envelopeAndLFOWidget::saveSettings( QDomDocument & , _parent.setAttribute( "lamt", QString::number( m_lfoAmountKnob->value() ) ); _parent.setAttribute( "x100", QString::number( - m_x100Btn->isChecked() ) ); + m_x100Cb->isChecked() ) ); _parent.setAttribute( "ctlenvamt", QString::number( - m_controlEnvAmountBtn->isChecked() ) ); + m_controlEnvAmountCb->isChecked() ) ); } @@ -625,8 +606,8 @@ void envelopeAndLFOWidget::loadSettings( const QDomElement & _this ) m_lfoAttackKnob->setValue( _this.attribute( "latt" ).toFloat() ); m_lfoSpeedKnob->setValue( _this.attribute( "lspd" ).toFloat() ); m_lfoAmountKnob->setValue( _this.attribute( "lamt" ).toFloat() ); - m_x100Btn->setChecked( _this.attribute( "x100" ).toInt() ); - m_controlEnvAmountBtn->setChecked( _this.attribute( + m_x100Cb->setChecked( _this.attribute( "x100" ).toInt() ); + m_controlEnvAmountCb->setChecked( _this.attribute( "ctlenvamt" ).toInt() ); switch( m_lfoShape ) @@ -760,7 +741,7 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) float osc_frames = m_lfoOscillationFrames; - if( m_x100Btn->isChecked() ) + if( m_x100Cb->isChecked() ) { osc_frames *= 100.0f; } @@ -972,7 +953,7 @@ void envelopeAndLFOWidget::updateSampleVars( void ) m_lfoOscillationFrames = static_cast( frames_per_lfo_oscillation * m_lfoSpeedKnob->value() ); - if( m_x100Btn->isChecked() ) + if( m_x100Cb->isChecked() ) { m_lfoOscillationFrames /= 100; } diff --git a/src/core/envelope_tab_widget.cpp b/src/core/envelope_tab_widget.cpp index a8582c67b7..fc62160ff0 100644 --- a/src/core/envelope_tab_widget.cpp +++ b/src/core/envelope_tab_widget.cpp @@ -56,7 +56,7 @@ const int TARGETS_TABWIDGET_X = 4; const int TARGETS_TABWIDGET_Y = 5; -const int TARGETS_TABWIDGET_WIDTH = 240; +const int TARGETS_TABWIDGET_WIDTH = 238; const int TARGETS_TABWIDGET_HEIGTH = 175; const int FILTER_GROUPBOX_X = TARGETS_TABWIDGET_X; diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index cd88151071..934ee009e4 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -32,12 +32,14 @@ #include #include #include +#include #else #include #include #include +#include #define setChecked setOn @@ -111,6 +113,8 @@ pianoRoll::pianoRollKeyTypes pianoRoll::prKeyOrder[] = } ; +const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * MAX_BEATS_PER_TACT; + pianoRoll::pianoRoll( void ) : QWidget( lmmsMainWin::inst()->workspace() ), @@ -122,7 +126,7 @@ pianoRoll::pianoRoll( void ) : m_moveStartKey( 0 ), m_moveStartTact64th( 0 ), m_notesEditHeight( 100 ), - m_ppt( KEY_LINE_HEIGHT * MAX_BEATS_PER_TACT ), + m_ppt( DEFAULT_PR_PPT ), m_lenOfNewNotes( midiTime( 0, 16 ) ), m_shiftPressed( FALSE ), m_controlPressed( FALSE ), @@ -413,6 +417,21 @@ pianoRoll::pianoRoll( void ) : "pasted at the first visible tact." ) ); + + // setup zooming-stuff + m_zoomingComboBox = new QComboBox( this ); + m_zoomingComboBox->setGeometry( 580, 10, 60, 20 ); + for( int i = 0; i < 6; ++i ) + { + m_zoomingComboBox->insertItem( QString::number( 25 * + static_cast( powf( 2.0f, i ) ) ) + + "%" ); + } + m_zoomingComboBox->setCurrentText( "100%" ); + connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), + this, SLOT( zoomingChanged( const QString & ) ) ); + + // setup our actual window setWindowIcon( embed::getIconPixmap( "piano" ) ); resize( INITIAL_PIANOROLL_WIDTH, INITIAL_PIANOROLL_HEIGHT ); @@ -1910,6 +1929,11 @@ void pianoRoll::wheelEvent( QWheelEvent * _we ) { m_ppt /= 2; } + // update combobox with zooming-factor + m_zoomingComboBox->setCurrentText( QString::number( + static_cast( m_ppt * 100 / + DEFAULT_PR_PPT ) ) +"%" ); + // update timeline m_timeLine->setPixelsPerTact( m_ppt ); update(); } @@ -2343,6 +2367,20 @@ void pianoRoll::updatePosition( const midiTime & _t ) + +void pianoRoll::zoomingChanged( const QString & _zfac ) +{ + m_ppt = _zfac.left( _zfac.length() - 1 ).toInt() * DEFAULT_PR_PPT / 100; +#ifdef LMMS_DEBUG + assert( m_ppt > 0 ); +#endif + m_timeLine->setPixelsPerTact( m_ppt ); + update(); + +} + + + #undef setChecked diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index 3c0064f1af..ba8c21b14b 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #else @@ -58,6 +59,7 @@ #include #include #include +#include #endif @@ -116,13 +118,13 @@ songEditor::songEditor() : m_controlPressed( FALSE ) { // hack, because code called out of this function uses - // songEditor::inst(), which assigns s_instanceOfMe after return - // of this function... + // songEditor::inst(), which assigns s_instanceOfMe this function + // returns... s_instanceOfMe = this; setWindowTitle( tr( "Song-Editor" ) ); setWindowIcon( embed::getIconPixmap( "songeditor" ) ); - setGeometry( 10, 10, 640, 300 ); + setGeometry( 10, 10, 680, 300 ); show(); #ifdef QT4 @@ -442,9 +444,26 @@ songEditor::songEditor() : "removed." ) ); #endif + edit_tb->addSeparator(); + + // setup zooming-stuff + m_zoomingComboBox = new QComboBox( edit_tb ); + m_zoomingComboBox->setGeometry( 580, 10, 60, 20 ); + for( int i = 0; i < 7; ++i ) + { + m_zoomingComboBox->insertItem( QString::number( 25 * + static_cast( powf( 2.0f, i ) ) ) + + "%" ); + } + m_zoomingComboBox->setCurrentText( "100%" ); + connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), + this, SLOT( zoomingChanged( const QString & ) ) ); + + + m_projectNotes = new projectNotes(); m_projectNotes->resize( 300, 200 ); - m_projectNotes->move( 640, 10 ); + m_projectNotes->move( 700, 10 ); m_projectNotes->show(); @@ -601,8 +620,14 @@ void songEditor::wheelEvent( QWheelEvent * _we ) { setPixelsPerTact( (int) pixelsPerTact() / 2 ); } + // update combobox with zooming-factor + m_zoomingComboBox->setCurrentText( QString::number( + static_cast( pixelsPerTact() * + 100 / DEFAULT_PIXELS_PER_TACT ) ) +"%" ); + // update timeline m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( pixelsPerTact() ); + // and make sure, all TCO's are resized and relocated realignTracks( TRUE ); } else if( m_shiftPressed ) @@ -717,6 +742,17 @@ void songEditor::updatePosition( const midiTime & _t ) +void songEditor::zoomingChanged( const QString & _zfac ) +{ + setPixelsPerTact( _zfac.left( _zfac.length() - 1 ).toInt() * + DEFAULT_PIXELS_PER_TACT / 100 ); + m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( pixelsPerTact() ); + realignTracks( TRUE ); +} + + + + void songEditor::setBPM( int _new_bpm ) { m_bpmSpinBox->setValue( tLimit( _new_bpm, MIN_BPM, MAX_BPM ) ); diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index e5d3be4048..25627f27c7 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -54,8 +54,6 @@ -const Uint16 DEFAULT_PIXELS_PER_TACT = 16; - trackContainer::trackContainer() : QMainWindow( lmmsMainWin::inst()->workspace() diff --git a/src/widgets/led_checkbox.cpp b/src/widgets/led_checkbox.cpp index 04f9cc6234..0561a08674 100644 --- a/src/widgets/led_checkbox.cpp +++ b/src/widgets/led_checkbox.cpp @@ -35,9 +35,6 @@ #include #include -#define setChecked setOn -#define isChecked isOn - #endif @@ -103,11 +100,7 @@ void ledCheckBox::paintEvent( QPaintEvent * ) #endif p.drawPixmap( 0, 0, specialBgHandlingWidget::getBackground( this ) ); -#ifdef QT4 - if( checkState() == Qt::Checked ) -#else - if( state() == On ) -#endif + if( isChecked() == TRUE ) { p.drawPixmap( 0, 0, *m_ledOnPixmap ); } @@ -125,6 +118,3 @@ void ledCheckBox::paintEvent( QPaintEvent * ) } -#undef setChecked -#undef isChecked - diff --git a/src/widgets/tab_widget.cpp b/src/widgets/tab_widget.cpp index 5b146a3a4f..de98aadede 100644 --- a/src/widgets/tab_widget.cpp +++ b/src/widgets/tab_widget.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #else @@ -45,7 +46,10 @@ tabWidget::tabWidget( const QString & _caption, QWidget * _parent ) : QWidget( _parent ), - m_curWidget( 0 ), +#ifndef QT4 + specialBgHandlingWidget( QColor( 96, 96, 96 ) ), +#endif + m_activeTab( 0 ), m_caption( _caption ) { setFont( pointSize<7>( font() ) ); @@ -55,7 +59,7 @@ tabWidget::tabWidget( const QString & _caption, QWidget * _parent ) : setPalette( pal ); #else setPaletteBackgroundColor( QColor( 96, 96, 96 ) ); - //setBackgroundMode( Qt::NoBackground ); + setBackgroundMode( Qt::NoBackground ); #endif } @@ -68,14 +72,25 @@ tabWidget::~tabWidget() -void tabWidget::addTab( QWidget * _w, const QString & _name ) + +void tabWidget::addTab( QWidget * _w, const QString & _name, int _idx ) { - widgetDesc d = { _w, _name, fontMetrics().width( _name ) + 10 } ; - m_widgets.push_back( d ); - // make sure new tab doesn't overlap current widget - m_widgets[m_curWidget].w->raise(); + widgetDesc d = { _w, _name, fontMetrics().width( _name ) + 10 } ; + if( _idx < 0 || m_widgets.contains( _idx ) == TRUE ) + { + while( m_widgets.contains( ++_idx ) == TRUE ) + { + } + } + m_widgets[_idx] = d; _w->setFixedSize( width() - 4, height() - 14 ); _w->move( 2, 12 ); + + if( m_widgets.contains( m_activeTab ) ) + { + // make sure new tab doesn't overlap current widget + m_widgets[m_activeTab].w->raise(); + } } @@ -85,18 +100,20 @@ void tabWidget::mousePressEvent( QMouseEvent * _me ) { if( _me->y() > 1 && _me->y() < 13 ) { - int cx = 14 + fontMetrics().width( m_caption ); + int cx = ( ( m_caption == "" ) ? 4 : 14 ) + + fontMetrics().width( m_caption ); for( widgetStack::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { - if( _me->x() >= cx && _me->x() <= cx + it->nwidth ) + if( _me->x() >= cx && + _me->x() <= cx + ( *it ).nwidth ) { - it->w->raise(); - m_curWidget = it - m_widgets.begin(); + ( *it ).w->raise(); + m_activeTab = it.key(); update(); return; } - cx += it->nwidth; + cx += ( *it ).nwidth; } } } @@ -109,7 +126,7 @@ void tabWidget::resizeEvent( QResizeEvent * ) for( widgetStack::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { - it->w->setFixedSize( width() - 4, height() - 14 ); + ( *it ).w->setFixedSize( width() - 4, height() - 14 ); } } @@ -127,6 +144,8 @@ void tabWidget::paintEvent( QPaintEvent * _pe ) QPainter p( &pm ); #endif + bool big_tab_captions = ( m_caption == "" ); + int add = big_tab_captions ? 1 : 0; p.setPen( QColor( 64, 64, 64 ) ); p.drawRect( 0, 0, width(), height() ); @@ -138,31 +157,43 @@ void tabWidget::paintEvent( QPaintEvent * _pe ) p.setPen( QColor( 0, 0, 0 ) ); p.drawRect( 1, 1, width() - 2, height() - 2 ); - p.fillRect( 2, 2, width() - 4, 9, QColor( 30, 45, 60 ) ); - p.drawLine( 2, 11, width() - 3, 11 ); + p.fillRect( 2, 2, width() - 4, 9 + add, QColor( 30, 45, 60 ) ); + p.drawLine( 2, 11 + add, width() - 3, 11 + add ); - p.setPen( QColor( 255, 255, 255 ) ); - p.setFont( font() ); - p.drawText( 5, 10, m_caption ); + if( !big_tab_captions ) + { + p.setPen( QColor( 255, 255, 255 ) ); + p.setFont( font() ); + p.drawText( 5, 10, m_caption ); + } - int cx = 14 + fontMetrics().width( m_caption ); + int cx = ( big_tab_captions ? 4 : 14 ) + + fontMetrics().width( m_caption ); - p.setFont( pointSize<6>( p.font() ) ); + QColor cap_col( 160, 160, 160 ); + if( big_tab_captions ) + { + p.setFont( pointSize<7>( p.font() ) ); + cap_col = QColor( 224, 224, 224 ); + } + else + { + p.setFont( pointSize<6>( p.font() ) ); + } + p.setPen( cap_col ); - p.setPen( QColor( 160, 160, 160 ) ); for( widgetStack::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { - if( it - m_widgets.begin() == m_curWidget ) + if( it.key() == m_activeTab ) { p.setPen( QColor( 32, 48, 64 ) ); - p.fillRect( cx, 2, it->nwidth - 6, 9, - QColor( 160, 160, 160 ) ); + p.fillRect( cx, 2, ( *it ).nwidth - 6, 9, cap_col ); } - p.drawText( cx + 3, 9, it->name ); - p.setPen( QColor( 160, 160, 160 ) ); - cx += it->nwidth; + p.drawText( cx + 3, 9 + add, ( *it ).name ); + p.setPen( cap_col ); + cx += ( *it ).nwidth; } #ifndef QT4 @@ -173,5 +204,23 @@ void tabWidget::paintEvent( QPaintEvent * _pe ) +void tabWidget::wheelEvent( QWheelEvent * _we ) +{ + int dir = ( _we->delta() > 0 ) ? 1 : -1; + int tab = m_activeTab; + while( tab > -1 && static_cast( tab ) < m_widgets.count() ) + { + tab += dir; + if( m_widgets.contains( tab ) ) + { + break; + } + } + setActiveTab( tab ); +} + + + + #include "tab_widget.moc"