1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: QtxBackgroundTool.cxx
21 // Author: Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
23 #include "QtxBackgroundTool.h"
24 #include "QtxColorButton.h"
28 #include <QFileDialog>
29 #include <QHBoxLayout>
32 #include <QPushButton>
33 #include <QStackedWidget>
34 #include <QVBoxLayout>
38 \class QtxBackgroundTool
39 \brief Implementation of the widget managing background data
41 The background data can be specified as:
42 - image (by assigning the file name to be used as background texture)
43 - single color (by assigning any color)
44 - simple two-color gradient (with the gradient type id and two colors)
45 - complex gradient (by assigning arbitrary gradient data) (NOT IMPLEMENTED YET)
47 To enable / disable any background type, setModeAllowed() function can be used.
48 Widget's orientation can be specified via the constructor parameter of changed with
49 setOrientation() function.
51 To specify two-color gradient modes, use setGradient() function. By default, no gradient modes
52 are provided by the widget.
54 Arbitrary gradient mode is not implemented yet, it is remaining for future improvement.
56 Typical usage can be as follows:
59 QtxBackgroundTool* tool = new QtxBackgroundTool( Qt::Vertical, this );
60 // assign gradients types
62 sl << "Horizontal" << "Vertical" << "First diagonal" << "Second diagonal";
63 tool->setGradients(sl);
64 // disable image texture and custom gradient modes
65 tool->setModeAllowed(Qtx::ImageBackground, false);
66 tool->setModeAllowed(Qtx::CustomGradientBackground, false);
67 // initialize widget with the some background data
68 tool->setData( bgData );
71 \todo Complete support of custom gradient (QLinearGradient, QRadialGradient, QConicalGradient).
72 \sa Qtx::BackgroundData, QtxBackgroundDialog, Qtx::stringToBackground(), Qtx::backgroundToString()
78 Creates a background data widget with horizontal orientation.
80 \param parent parent widget
82 QtxBackgroundTool::QtxBackgroundTool( QWidget* parent )
83 : QWidget( parent ), myTextureAllowed( true ), myLastGradient( -1 )
85 init( Qt::Horizontal );
91 Creates a background data widget with specified orientation.
93 \param o widget orientation
94 \param parent parent widget
96 QtxBackgroundTool::QtxBackgroundTool( Qt::Orientation o, QWidget* parent )
97 : QWidget( parent ), myTextureAllowed( true ), myLastGradient( -1 )
103 \brief Perform internal initialization
105 void QtxBackgroundTool::init( Qt::Orientation o )
108 myModeCombo = new QComboBox( this );
109 // color / gradient sub-widgets container
110 myCContainer = new QStackedWidget( this );
111 // texture sub-widgets container
112 myTContainer = new QWidget( this );
115 QHBoxLayout* wrapLayout;
117 // add image controls
118 wrapLayout = new QHBoxLayout( myTContainer );
119 wrapLayout->setMargin( 0 );
120 wrapLayout->setSpacing( 5 );
121 myTextureCheck = new QCheckBox( tr( "Image" ), myTContainer );
122 myFileName = new QLineEdit( myTContainer );
123 myFileName->setMinimumWidth(100);
124 myBrowseBtn = new QPushButton( tr( "Browse..." ), myTContainer );
125 myTextureMode = new QComboBox( myTContainer );
126 wrapLayout->addWidget( myTextureCheck );
127 wrapLayout->addWidget( myFileName );
128 wrapLayout->addWidget( myBrowseBtn );
129 wrapLayout->addWidget( myTextureMode );
130 wrapLayout->setStretchFactor(myFileName, 10);
131 // add color controls
132 wrap = new QWidget( this );
133 wrapLayout = new QHBoxLayout( wrap );
134 wrapLayout->setMargin( 0 );
135 wrapLayout->setSpacing( 5 );
136 myFirstColor = new QtxColorButton( wrap );
137 mySecondColor = new QtxColorButton( wrap );
138 wrapLayout->addWidget( myFirstColor );
139 wrapLayout->addWidget( mySecondColor );
140 wrapLayout->setStretchFactor(myFirstColor, 5);
141 wrapLayout->setStretchFactor(mySecondColor, 5);
142 myCContainer->addWidget( wrap ); // Color
143 // add gradient controls ... NOT IMPLEMENTED YET
144 wrap = new QWidget( this );
145 wrapLayout = new QHBoxLayout( wrap );
146 wrapLayout->setMargin( 0 );
147 wrapLayout->setSpacing( 5 );
148 QLabel* foo = new QLabel( tr( "Not implemented yet" ), wrap );
149 foo->setAlignment( Qt::AlignCenter );
150 wrapLayout->addWidget( foo );
151 myCContainer->addWidget( wrap ); // Gradient
154 myFirstColor->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
155 mySecondColor->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
157 connect( myModeCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( updateState() ) );
158 connect( myTextureCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateState() ) );
159 connect( myBrowseBtn, SIGNAL( clicked() ), this, SLOT( browse() ) );
161 setModeAllowed( Qtx::ColorBackground );
162 setModeAllowed( Qtx::SimpleGradientBackground );
163 setModeAllowed( Qtx::CustomGradientBackground );
164 setTextureModeAllowed( Qtx::CenterTexture );
165 setTextureModeAllowed( Qtx::TileTexture );
166 setTextureModeAllowed( Qtx::StretchTexture );
168 setImageFormats( QString() );
175 QtxBackgroundTool::~QtxBackgroundTool()
180 \brief Get background data from the widget
181 \return background data
184 Qtx::BackgroundData QtxBackgroundTool::data() const
186 Qtx::BackgroundData bgData;
187 int idx = myModeCombo->currentIndex();
189 // get currently selected mode
190 int id = myModeCombo->itemData( idx, TypeRole ).toInt();
192 if ( isTextureAllowed() && myTextureMode->currentIndex() != -1 ) {
193 bgData.setTexture( myFileName->text().trimmed(),
194 Qtx::TextureMode( myTextureMode->itemData( myTextureMode->currentIndex() ).toInt() ) );
195 bgData.setTextureShown( myTextureCheck->isChecked() );
198 if ( isModeAllowed( Qtx::ColorBackground ) ) {
199 bgData.setColor( myFirstColor->color() );
201 // simple two-color gradient data
202 if ( isModeAllowed( Qtx::SimpleGradientBackground ) ) {
203 bgData.setGradient( myLastGradient, myFirstColor->color(), mySecondColor->color() );
205 // custom gradient data
206 if ( isModeAllowed( Qtx::CustomGradientBackground ) ) {
207 // bgData.setGradient( ... );
208 // NOT IMPLEMENTED YET
212 bgData.setMode( Qtx::BackgroundMode( id ) );
218 \brief Set background data from the widget
219 \param bgData background data being set to the widget
222 void QtxBackgroundTool::setData( const Qtx::BackgroundData& bgData )
224 Qtx::BackgroundMode m = bgData.mode();
226 int gtype = bgData.gradient( c1, c2 );
228 int tmode = bgData.texture( fileName );
229 bool tshown = bgData.isTextureShown();
232 myFileName->setText( fileName );
233 for ( int i = 0; i < myTextureMode->count(); i++ ) {
234 if ( myTextureMode->itemData( i ).toInt() == tmode ) {
235 myTextureMode->setCurrentIndex( i );
239 myTextureCheck->setChecked( tshown );
241 // color / simple gradient data
242 myFirstColor->setColor( c1 );
243 mySecondColor->setColor( c2 );
246 // ... NOT IMPLEMENTED YET
248 // set current mode index
250 for ( int i = 0; i < myModeCombo->count() && idx == -1; i++ ) {
251 int im = myModeCombo->itemData( i, TypeRole ).toInt();
252 // for simple gradient mode we also check gradient type
253 if ( m == Qtx::SimpleGradientBackground && im == Qtx::SimpleGradientBackground ) {
254 int it = myModeCombo->itemData( i, IdRole ).toInt();
255 if ( it == gtype ) idx = i;
257 // for other modes we just check mode itself
258 else if ( im == m ) {
262 // if background data is invalid, we set-up widget to the first available type
263 if ( idx == -1 && myModeCombo->count() > 0 ) idx = 0;
264 myModeCombo->setCurrentIndex( idx );
268 \brief Get allowed two-color gradients to the widget
269 \param gradients gradients names are returned via this parameter
270 \param ids gradients identifiers are returned via this parameter (empty list can be returned)
272 void QtxBackgroundTool::gradients( QStringList& gradList, QIntList& idList ) const
274 gradList = myGradients;
275 idList = myGradientsIds;
279 \brief Set allowed two-color gradients to the widget
280 \param gradients gradients names
281 \param ids optional gradients identifiers; if not specified, gradients are automatically numbered starting from 0
283 void QtxBackgroundTool::setGradients( const QStringList& gradList, const QIntList& idList )
285 Qtx::BackgroundData d = data(); // get current state
286 myGradients = gradList; // store new gradient data
287 myGradientsIds = idList; // ...
288 myLastGradient = -1; // ...
289 internalUpdate(); // re-initialize
290 setData( d ); // restore current state (if possible)
294 \brief Check if specific background mode is allowed
295 \param mode background mode
296 \return \c true if specified background mode is enabled or \c false otherwise
299 bool QtxBackgroundTool::isModeAllowed( Qtx::BackgroundMode mode ) const
301 return myTypesAllowed.contains( mode ) ? myTypesAllowed[ mode ] : false;
305 \brief Enable / disable specific background mode
306 \param mode background mode
307 \param on enable / disable flag (\c true by default)
310 void QtxBackgroundTool::setModeAllowed( Qtx::BackgroundMode mode, bool on )
312 if ( mode == Qtx::CustomGradientBackground )
313 return; // NOT IMPLEMENTED YET //
315 if ( isModeAllowed( mode ) != on ) {
316 Qtx::BackgroundData d = data(); // get current state
317 myTypesAllowed[ mode ] = on; // store new background mode state
318 internalUpdate(); // re-initialize
319 setData( d ); // restore current state (if possible)
324 \brief Check if specific texture mode is allowed
325 \param mode texture mode
326 \return \c true if specified texture mode is enabled or \c false otherwise
327 \sa setTextureModeAllowed(), setTextureAllowed()
329 bool QtxBackgroundTool::isTextureModeAllowed( Qtx::TextureMode mode ) const
331 return myTextureTypesAllowed.contains( mode ) ? myTextureTypesAllowed[ mode ] : false;
335 \brief Enable / disable specific texture mode
336 \param mode texture mode
337 \param on enable / disable flag (\c true by default)
338 \sa isTextureModeAllowed(), setTextureAllowed()
340 void QtxBackgroundTool::setTextureModeAllowed( Qtx::TextureMode mode, bool on )
342 if ( isTextureModeAllowed( mode ) != on ) {
343 Qtx::BackgroundData d = data(); // get current state
344 myTextureTypesAllowed[ mode ] = on; // store new texture mode
345 internalUpdate(); // re-initialize
346 setData( d ); // restore current state (if possible)
351 \brief Check if texture controls are allowed (shown)
352 \return \c true if texture controls are enabled or \c false otherwise
353 \sa setTextureAllowed(), setTextureModeAllowed()
355 bool QtxBackgroundTool::isTextureAllowed() const
357 return myTextureAllowed;
361 \brief Enable / disable texture controls
362 \param on enable / disable flag (\c true by default)
363 \sa isTextureAllowed(), setTextureModeAllowed()
365 void QtxBackgroundTool::setTextureAllowed( bool on )
367 if ( myTextureAllowed != on ) {
368 myTextureAllowed = on;
369 setOrientation( orientation() );
374 \brief Get allowed image formats
375 \return image formats
376 \sa setImageFormats()
378 QString QtxBackgroundTool::imageFormats() const
380 return myImageFormats;
384 \brief Set allowed image formats
385 \param formats image formats
388 void QtxBackgroundTool::setImageFormats( const QString& formats )
390 myImageFormats = formats.isEmpty() ? tr( "Images Files (*.bmp *.png *.jpg *.jpeg *.gif *.tiff)" ) : formats;
394 \brief Get widget editor orientation
398 Qt::Orientation QtxBackgroundTool::orientation() const
400 return qobject_cast<QVBoxLayout*>( layout() ) ? Qt::Vertical : Qt::Horizontal;
404 \brief Change widget orientation
405 \param orientation new widget orientation
408 void QtxBackgroundTool::setOrientation( Qt::Orientation orientation )
410 QBoxLayout* l = (orientation == Qt::Horizontal) ? (QBoxLayout*)(new QHBoxLayout) : (QBoxLayout*)(new QVBoxLayout);
413 l->addWidget( myModeCombo );
414 l->addWidget( myCContainer );
415 myTContainer->setVisible( isTextureAllowed() );
416 if ( isTextureAllowed() )
417 l->addWidget( myTContainer );
423 \brief Initialization: fill in the widget with items according to the
426 void QtxBackgroundTool::internalUpdate()
428 myModeCombo->clear();
429 if ( isModeAllowed( Qtx::ColorBackground ) ) {
430 myModeCombo->addItem( tr( "Single Color" ) );
431 myModeCombo->setItemData( 0, (int)Qtx::ColorBackground, TypeRole );
433 if ( isModeAllowed( Qtx::SimpleGradientBackground ) ) {
434 // if ( myGradients.count() > 0 && myModeCombo->count() > 0 )
435 // myModeCombo->insertSeparator( myModeCombo->count() );
436 for ( int i = 0; i < myGradients.count(); i++ ) {
437 myModeCombo->addItem( myGradients[i] );
438 int idx = myModeCombo->count()-1;
439 myModeCombo->setItemData( idx, (int)Qtx::SimpleGradientBackground, TypeRole );
440 myModeCombo->setItemData( idx, myGradientsIds.count() > i ? myGradientsIds[i] : i, IdRole );
443 if ( isModeAllowed( Qtx::CustomGradientBackground ) ) {
444 // if ( myModeCombo->count() > 0 )
445 // myModeCombo->insertSeparator( myModeCombo->count() );
446 myModeCombo->addItem( tr( "Custom" ) );
447 int idx = myModeCombo->count()-1;
448 myModeCombo->setItemData( idx, (int)Qtx::CustomGradientBackground, TypeRole );
451 myTextureMode->clear();
452 if ( isTextureModeAllowed( Qtx::CenterTexture ) )
453 myTextureMode->addItem( tr( "Center" ), Qtx::CenterTexture );
454 if ( isTextureModeAllowed( Qtx::TileTexture ) )
455 myTextureMode->addItem( tr( "Tile" ), Qtx::TileTexture );
456 if ( isTextureModeAllowed( Qtx::StretchTexture ) )
457 myTextureMode->addItem( tr( "Stretch" ), Qtx::StretchTexture );
463 \brief Update widget state
465 void QtxBackgroundTool::updateState()
467 int idx = myModeCombo->currentIndex();
470 id = myModeCombo->itemData( idx, TypeRole ).toInt();
472 case Qtx::ColorBackground:
473 myCContainer->setCurrentIndex( Color );
475 case Qtx::SimpleGradientBackground:
476 myCContainer->setCurrentIndex( Color );
477 myLastGradient = myModeCombo->itemData( idx, IdRole ).toInt();
479 case Qtx::CustomGradientBackground:
480 myCContainer->setCurrentIndex( Gradient );
484 myModeCombo->setEnabled( idx >= 0 );
485 myCContainer->setEnabled( idx >= 0 );
486 mySecondColor->setEnabled( id == Qtx::SimpleGradientBackground );
487 myTContainer->setEnabled( idx >= 0 );
488 myFileName->setEnabled( myTextureCheck->isChecked() );
489 myBrowseBtn->setEnabled( myTextureCheck->isChecked() );
490 myTextureMode->setEnabled( myTextureCheck->isChecked() );
494 \brief Called when "Browse..." button is pressed
496 void QtxBackgroundTool::browse()
498 QString fileName = QFileDialog::getOpenFileName( this, tr( "Select Picture" ), myFileName->text().trimmed(), myImageFormats );
499 if ( !fileName.isEmpty() )
500 myFileName->setText( fileName );
504 \class QtxBackgroundDialog
505 \brief Dialog box that can be used to set-up the background data
510 QtxBackgroundDialog dlg( this );
511 // assign gradients types
513 sl << "Horizontal" << "Vertical" << "First diagonal" << "Second diagonal";
514 dlg.setGradients(sl);
515 // disable image texture and custom gradient modes
516 dlg.setModeAllowed(Qtx::ImageBackground, false);
517 dlg.setModeAllowed(Qtx::CustomGradientBackground, false);
518 // initialize dialog box with the some background data
519 dlg.setData(backgroundData);
520 // execute dialog box and obtain result background data
522 Qtx::BackgroundData bgData = dlg.getBackgroundData();
526 Also it is possible to use static function:
528 Qtx::BackgroundData bgData = QtxBackgroundDialog::getBackground( this );
529 if ( bgData.isValid() )
530 doSomething( bgData );
536 \param parent parent widget
538 QtxBackgroundDialog::QtxBackgroundDialog( QWidget* parent )
539 : QtxDialog( parent, true, true, OK | Cancel )
546 \param bgData initial background data
547 \param parent parent widget
549 QtxBackgroundDialog::QtxBackgroundDialog( const Qtx::BackgroundData& bgData, QWidget* parent )
550 : QtxDialog( parent, true, true, OK | Cancel )
559 QtxBackgroundDialog::~QtxBackgroundDialog()
564 \brief Perform internal initialization
566 void QtxBackgroundDialog::init()
569 setWindowTitle( tr( "Change background" ) );
571 setDialogFlags( SetFocus );
572 // move "Cancel" button to the right
573 setButtonPosition( Right, Cancel );
574 // set OK button to be default (activated by Enter key)
575 qobject_cast<QPushButton*>( button( OK ) )->setDefault( true );
578 QVBoxLayout* main = new QVBoxLayout( mainFrame() );
579 main->setMargin( 0 );
580 main->setSpacing( 5 );
583 myTool = new QtxBackgroundTool( Qt::Vertical, mainFrame() );
584 main->addWidget( myTool );
588 \brief Set background data
589 \param bgData background data
591 void QtxBackgroundDialog::setData( const Qtx::BackgroundData& bgData )
593 myTool->setData( bgData );
597 \brief Get background data
598 \return background data
600 Qtx::BackgroundData QtxBackgroundDialog::data() const
602 return myTool->data();
606 \brief Set allowed two-color gradients to the widget
607 \param gradients gradients names
608 \param ids optional gradients identifiers; if not specified, gradients are automatically numbered starting from 0
610 void QtxBackgroundDialog::setGradients( const QStringList& gradList, const QIntList& idList )
612 myTool->setGradients( gradList, idList );
616 \brief Enable / disable specific background mode
617 \param mode background mode
618 \param on enable / disable flag
620 void QtxBackgroundDialog::setModeAllowed( Qtx::BackgroundMode mode, bool on )
622 myTool->setModeAllowed( mode, on );
626 \brief Enable / disable texture controls
627 \param on enable / disable flag
628 \sa setTextureModeAllowed()
630 void QtxBackgroundDialog::setTextureAllowed( bool on )
632 myTool->setTextureAllowed( on );
636 \brief Enable / disable specific texture mode
637 \param mode texture mode
638 \param on enable / disable flag (\c true by default)
639 \sa setTextureAllowed()
641 void QtxBackgroundDialog::setTextureModeAllowed( Qtx::TextureMode mode, bool on )
643 myTool->setTextureModeAllowed( mode, on );
647 \brief Set allowed image formats
648 \param formats image formats
650 void QtxBackgroundDialog::setImageFormats( const QString& formats )
652 myTool->setImageFormats( formats );
656 \brief This is a convenience static function that returns an background data selected by the user.
657 If the user presses Cancel, it returns an invalid background data.
660 - all background modes are enabled
661 - texture controls are shown
662 - all texture modes are enabled
663 - simple gradient types list is empty
664 - all image formats are supported
666 To customize the dialog box behavior, initialize it passing the corresponding options to the function.
668 \param bgData initial background data
669 \param parent parent widget
670 \param enableSolidColor "enable solid colored background mode" flag
671 \param enableGradient "enable simple gradient background mode" flag
672 \param enableCustom "enable custom gradient background mode" flag
673 \param enableTexture "show texture controls" flag
674 \param gradList list of simple gradients names
675 \param idList list of simple gradients identifiers
676 \param formats image formats
677 \return resulting background data chosen by the user or invalid data if users cancels operation
679 Qtx::BackgroundData QtxBackgroundDialog::getBackground( const Qtx::BackgroundData& bgData,
681 bool enableSolidColor,
685 const QStringList& gradList,
686 const QIntList& idList,
687 const QString& formats )
689 QtxBackgroundDialog dlg( parent );
690 dlg.setTextureAllowed( enableTexture );
691 dlg.setModeAllowed( Qtx::ColorBackground, enableSolidColor );
692 dlg.setModeAllowed( Qtx::SimpleGradientBackground, enableGradient );
693 dlg.setModeAllowed( Qtx::CustomGradientBackground, enableCustom );
694 dlg.setGradients( gradList, idList );
695 dlg.setImageFormats( formats );
696 dlg.setData( bgData );
697 Qtx::BackgroundData res;
699 if ( rc ) res = dlg.data();
704 \brief This is a convenience static function that returns an background data selected by the user.
705 If the user presses Cancel, it returns an invalid background data.
708 - all background modes are enabled
709 - texture controls are shown
710 - all texture modes are disabled
711 - simple gradient types list is empty
712 - all image formats are supported
714 To customize the dialog box behavior, initialize it passing the corresponding options to the function.
716 \param bgData initial background data
717 \param parent parent widget
718 \param tmList allowed texture modes
719 \param enableSolidColor "enable solid colored background mode" flag
720 \param enableGradient "enable simple gradient background mode" flag
721 \param enableCustom "enable custom gradient background mode" flag
722 \param enableTexture "show texture controls" flag
723 \param gradList list of simple gradients names
724 \param idList list of simple gradients identifiers
725 \param formats image formats
726 \return resulting background data chosen by the user or invalid data if users cancels operation
728 Qtx::BackgroundData QtxBackgroundDialog::getBackground( const Qtx::BackgroundData& bgData,
730 const QIntList& tmList,
731 bool enableSolidColor,
735 const QStringList& gradList,
736 const QIntList& idList,
737 const QString& formats )
739 QtxBackgroundDialog dlg( parent );
740 dlg.setTextureAllowed( enableTexture );
741 for ( int i = Qtx::CenterTexture; i <= Qtx::StretchTexture; i++ )
742 dlg.setTextureModeAllowed( (Qtx::TextureMode)i, tmList.contains( i ) );
743 dlg.setModeAllowed( Qtx::ColorBackground, enableSolidColor );
744 dlg.setModeAllowed( Qtx::SimpleGradientBackground, enableGradient );
745 dlg.setModeAllowed( Qtx::CustomGradientBackground, enableCustom );
746 dlg.setGradients( gradList, idList );
747 dlg.setImageFormats( formats );
748 dlg.setData( bgData );
749 Qtx::BackgroundData res;
751 if ( rc ) res = dlg.data();