]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Porting to Qt 4
authorvsr <vsr@opencascade.com>
Thu, 31 May 2007 13:36:37 +0000 (13:36 +0000)
committervsr <vsr@opencascade.com>
Thu, 31 May 2007 13:36:37 +0000 (13:36 +0000)
src/Qtx/QtxSplash.cxx
src/Qtx/QtxSplash.h

index d3244efc999968986216305ac89e8526d58f8d7b..09c8f1d37a389197391edb5ebd3cce904641ad3c 100644 (file)
 
 #include "QtxSplash.h"
 
-#include <qapplication.h>
-#include <qpainter.h>
-#include <qpixmap.h>
-#include <qmessagebox.h>
-
-const int _PROGRESS_EVENT = QEvent::User + 10;
-const int _PROGRESS_WIDTH = 10;
+#include <QApplication>
+#include <QPainter>
+#include <QMessageBox>
+#include <QDesktopWidget>
 
 /*!
-  Class ProgressEvent [ internal ].
+  \class ProgressEvent
+  \internal
+  \brief Progress change custom event.
 */
-class ProgressEvent: public QCustomEvent
+
+class ProgressEvent: public QEvent
 {
 public:
+  /*!
+    \brief Constructor.
+    \param msg progress message
+    \param progress current progress (for example, in %)
+  */
   ProgressEvent( const QString& msg, const int progress = 0 )
-    : QCustomEvent( id() ),
+    : QEvent( (QEvent::Type)id() ),
       myMessage( msg ),
       myProgress( progress )
   {}
-  QString    message()  const { return myMessage;       } 
-  int        progress() const { return myProgress;      }
-  static int id()             { return _PROGRESS_EVENT; }
+  /*!
+    \brief Get progress message.
+    \return message
+  */
+  QString    message()  const { return myMessage; } 
+  /*!
+    \brief Get current progress.
+    \return current progress
+  */
+  int        progress() const { return myProgress; }
+  /*!
+    \brief Get message identifier.
+    \return custom message ID
+  */
+  static int id()             { return QEvent::User + 10; }
 
 private:
   QString myMessage;
   int     myProgress;
 };
 
-// Only one instance of splash screen is allowed
+/*!
+  \class QtxSplash
+  \brief The QtxSplash widget provides a splash screen that can be shown during application startup..
+
+  A splash screen is a widget that is usually displayed when an application is being started. 
+  Splash screens are often used for applications that have long start up times to provide 
+  the user with feedback that the application is loading.
+
+  Only one instance of the QtxSplash widget can be created. To access to the splash screen widget,
+  use static method QtxSplash::splash(), which creates and instance of the QtxSplash widget if
+  necessary and returns pointer to it. You should not destroy yhis instance - it is done automatically
+  after application main window is shown. Just use methods finish() to make splash screen wait untill 
+  main window is shown.
+
+  The splash screen appears in the center of the screen. The most common usage is to show a splash 
+  screen before the main widget is displayed on the screen. 
+  For example,
+  \code
+  int main(int argc, char *argv[])
+  {
+    QApplication app(argc, argv);
+    QPixmap pixmap(":/splash.png");
+    QtxSplash* splash = QtxsSplash::splash(pixmap);
+    splash->show();
+    app.processEvents();
+    ... // do application loading and initialization
+    MainWindow window;
+    window.show();
+    splash->finish(&window);
+    return app.exec();
+  }
+  \endcode
+  
+  The user can hide the splash screen by clicking on it with the mouse. Since the splash screen is 
+  typically displayed before the event loop has started running, it is necessary to periodically call 
+  QApplication::processEvents() to receive the mouse clicks.
+  This feature can be switched off by using method setHideOnClick() with \c false parameter.
+
+  It is sometimes useful to update the splash screen with messages and/or progress information, 
+  for example, announcing connections established or modules loaded as the application starts up.
+  QtxSplash class provides the functionality to show status messages and(or) progress bar.
+
+  \code
+  QPixmap pixmap(":/splash.png");
+  QtxSplash* splash = QtxSplash::splash(pixmap);
+  splash->setProgress(0, 5);
+  splash->show();
+  app.processEvents();
+  // doing first step
+  splash->message("Step 1");
+  splash->ress(1);
+  qApp->processEvents();
+  // ... perform some actions
+  // doing second step
+  splash->message("Step 2");
+  splash->setProgress(2);
+  qApp->processEvents();
+  // ... perform some actions
+  ... et cetera
+  \endcode
+
+  There is a static function QtxSplash::setStatus() which allows to put next status message
+  and progress with one call. It can substitue two calls: message() and setProgress().
+
+  QtxSplash class provides alos a lot of functions to set-up its behavior. Set progress
+  bar width with setProgressWidth() method, its position and direction with setProgressFlags().
+  It can be single-colored or gradient-colored. Use setProgressColors() method for this. 
+  You can even set your own gradient scale with QLinearGradient and use it for the progress
+  bar coloring: setProgressGradient().
+
+  To change the progress bar and status message transparency, use setOpacity() function.
+  The methods setTextAlignment(), setTextColor() and setTextColors() can be used to change
+  the attributes of the status message.
+*/
+
+//! The only one instance of splash screen
 QtxSplash* QtxSplash::mySplash = 0;
 
 /*!
-  Construct a splash screen that will display the \a pixmap.
+  \brief Constructor.
+  \brief Construct a splash screen that will display the \a pixmap.
+  \param pixmap splash screen pixmap
 */
 QtxSplash::QtxSplash( const QPixmap& pixmap )
-  : QWidget( 0, 0, WStyle_Customize | WStyle_StaysOnTop | WX11BypassWM | WStyle_NoBorder )
-{
-  myAlignment    = AlignBottom | AlignRight;
-  myColor        = white;
-  myHideOnClick  = false;
-  myProgress     = 0;
-  myTotal        = 0;
-  myGradientType = Vertical;
-  myError        = 0;
-  myStartColor   = red;
-
+: QWidget( 0, Qt::SplashScreen ),
+  myAlignment( Qt::AlignBottom | Qt::AlignRight ),
+  myColor( Qt::white ),
+  myHideOnClick( false ),
+  myProgress( 0 ),
+  myTotal( 0 ),
+  myStartColor( Qt::red ),
+  myGradientType( Vertical ),
+  myProgressWidth( 10 ),
+  myProgressFlags( BottomSide | LeftToRight ),
+  myMargin( 5 ),
+  myOpacity( 1.0 ),
+  myError( 0 ),
+  myGradientUsed( false )
+{
+  setAttribute( Qt::WA_DeleteOnClose, true );
   setPixmap( pixmap );
 }
 
 /*!
-  Destructor.
+  \brief Destructor.
 */
 QtxSplash::~QtxSplash()
 {
@@ -79,8 +178,13 @@ QtxSplash::~QtxSplash()
 }
 
 /*!
-  Returns an only instance of splash screen.
-  If \a px is valid sets this pixmap to the splash screen.
+  \brief Get the only instance of the splash screen widget.
+
+  If the splash screen widget does not exist yet, it is created with specified
+  pixmap. Otherwise, pixmap \a px is set to existing widget.
+
+  \param px splash screen pixmap
+  \return splash screen widget
 */
 QtxSplash* QtxSplash::splash( const QPixmap& px )
 {
@@ -92,24 +196,32 @@ QtxSplash* QtxSplash::splash( const QPixmap& px )
 }
 
 /*!
-  Sends the status message and (optionally) progress to the splash screen.
-  Can be used, for example, from the progress thread.
+  \brief Send the status message and (optionally) current progress 
+  to the splash screen.
+
+  This function can be used, for example, from an external thread
+  which checks the application loading progress.
+
+  \param msg progress status message
+  \param progress current progress
+  \sa message(), setProgress()
 */
-void QtxSplash::setStatus( const QString& msg, 
-                          const int      progress )
+void QtxSplash::setStatus( const QString& msg, const int progress )
 {
   if ( mySplash ) {
     QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
-    qApp->processEvents();
+    QApplication::instance()->processEvents();
   }
 }
 
 /*!
-  Sets error status and shows error message box to the user.
+  \brief Set error status and show error message box to the user.
+  \param error error message
+  \param title message box title
+  \param code error code
 */
 void QtxSplash::error( const QString& error, const QString& title, const int code )
 {
-  printf("QtxSplash::error: %s\n",error.latin1());
   if ( mySplash ) {
     mySplash->setError( code );
     QMessageBox::critical( mySplash, 
@@ -117,23 +229,42 @@ void QtxSplash::error( const QString& error, const QString& title, const int cod
                           error,
                           tr( "&OK" ) );
   }
+  else {
+    printf( "QtxSplash::error: %s\n",error.toLatin1().constData() );
+  }
 }
 
 /*!
-  Sets the pixmap that will be used as the splash screen's image to
-  \a pixmap.
+  \brief Set the pixmap that will be used as the splash screen's image.
+  \param pixmap spash screen image pixmap
+  \sa pixmap()
 */
 void QtxSplash::setPixmap( const QPixmap& pixmap )
 {
-  myPixmap = pixmap;
+  if ( pixmap.hasAlpha() ) {
+    QPixmap opaque( pixmap.size() );
+    QPainter p( &opaque );
+    p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
+    p.drawPixmap( 0, 0, pixmap );
+    p.end();
+    myPixmap = opaque;
+  } 
+  else {
+    myPixmap = pixmap;
+  }
   QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
   resize( myPixmap.size() );
   move( QApplication::desktop()->screenGeometry().center() - r.center() );
-  repaint();
+  if ( !isVisible() )
+    drawContents();
+  else
+    repaint();
 }
 
 /*!
-  Returns the pixmap that is used in the splash screen.
+  \brief Get the pixmap that is used as the splash screen's image.
+  \return spash screen image pixmap
+  \sa setPixmap()
 */
 QPixmap QtxSplash::pixmap() const
 {
@@ -141,14 +272,19 @@ QPixmap QtxSplash::pixmap() const
 }
 
 /*!
-  Sets/clear the 'hide on mouse click' flag.
-  Default is FALSE.
+  \brief Set/clear the 'hide on mouse click' flag.
+
   When this flag is set, user can hide the splash screen window
   by clicking on it with mouse.
   But for this to work it is necessary to call periodically
   QApplication::processEvents() in order to allow event loop to process
   events because usually main application loop is not yet started
   at that moment.
+
+  By default this flag is set to \c false.
+
+  \param on new flag state
+  \sa hideOnClick()
 */
 void QtxSplash::setHideOnClick( const bool on )
 {
@@ -156,7 +292,9 @@ void QtxSplash::setHideOnClick( const bool on )
 }
 
 /*!
-  Returns the 'hide on mouse click' flag.
+  \brief Get the 'hide on mouse click' flag.
+  \return 'hide on mouse click' flag
+  \sa setHideOnClick()
 */
 bool QtxSplash::hideOnClick() const
 {
@@ -164,7 +302,9 @@ bool QtxSplash::hideOnClick() const
 }
 
 /*!
-  Sets total progress steps to \a total.
+  \brief Set total progress steps to \a total.
+  \param total total number of progress steps
+  \sa totalSteps(), setProgress(), progress()
 */
 void QtxSplash::setTotalSteps( const int total )
 {
@@ -173,8 +313,9 @@ void QtxSplash::setTotalSteps( const int total )
 }
 
 /*!
-  Return total progress steps number.
-  \sa setTotalSteps(), setProgress()
+  \brief Get total progress steps number.
+  \return total number of progress steps
+  \sa setTotalSteps(), setProgress(), progress()
 */
 int QtxSplash::totalSteps() const
 {
@@ -182,17 +323,20 @@ int QtxSplash::totalSteps() const
 }
     
 /*!
-  Sets progress to \a progress.
+  \brief Set current progress.
+  \param progress current progress
+  \sa progress(), setTotalSteps(), setTotalSteps(), 
 */
 void QtxSplash::setProgress( const int progress )
 {
-  myProgress = progress;
+  myProgress = progress > 0 ? progress : 0;
   repaint();
 }
 
 /*!
-  Return current progress.
-  \sa setProgress(), setTotalSteps()
+  \brief Get current progress.
+  \return current progress
+  \sa setProgress(), setTotalSteps(), setTotalSteps(), 
 */
 int QtxSplash::progress() const
 {
@@ -200,37 +344,129 @@ int QtxSplash::progress() const
 }
 
 /*!
-  Sets progress to \a progress and total progress steps to \a total.
+  \brief Set current progress to \a progress and total number of 
+  progress steps to \a total.
+  \param progress current progress
+  \param total total number of progress steps
 */
 void QtxSplash::setProgress( const int progress, const int total )
 {
   myTotal    = total;
-  myProgress = progress;
+  myProgress = progress > 0 ? progress : 0;
   repaint();
 }
 
 /*!
-  Sets progress bar colors to \a startColor and \a endColor.
-  If the colors differ the gradient color bar is drawed.
-  If the \a endColor is not valid, \a startColor is used instead.
-  \a gradientType sets the type of gradient to be used for progress
-  bar - horizontal or vertical. Default is vertical.
+  \brief Set margin (a border width).
+  \param margin new margin width
+  \sa margin()
 */
-void QtxSplash::setProgressColors( const QColor& startColor, 
-                                  const QColor& endColor,
-                                  const int     gradientType )
+void QtxSplash::setMargin( const int margin )
 {
-  myStartColor   = startColor;
+  myMargin = margin > 0 ? margin : 0;
+  repaint();
+}
+
+/*!
+  \brief Get margin (a border width).
+  \return current margin width
+  \sa setMargin()
+*/
+int QtxSplash::margin() const
+{
+  return myMargin;
+}
+
+/*!
+  \brief Set progress bar width.
+  \param width new progress bar width
+  \sa progressWidth()
+*/
+void QtxSplash::setProgressWidth( const int width )
+{
+  myProgressWidth = width > 0 ? width : 0;
+  repaint();
+}
+
+/*!
+  \brief Get progress bar width.
+  \return current progress bar width
+  \sa setProgressWidth()
+*/
+int QtxSplash::progressWidth() const
+{
+  return myProgressWidth;
+}
+
+/*!
+  \brief Set progress bar position and direction.
+
+  By default, progress bar is displayed at the bottom side and
+  shows progress from left to right.
+
+  \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
+  \sa progressFlags()
+*/
+void QtxSplash::setProgressFlags( const int flags )
+{
+  myProgressFlags = flags;
+  if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
+    myProgressFlags |= BottomSide;
+  if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
+    myProgressFlags |= LeftToRight ;
+  repaint();
+}
+
+/*!
+  \brief Get progress bar flags: position and direction.
+  \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
+  \sa setProgressFlags()
+*/
+int QtxSplash::progressFlags() const
+{
+  return myProgressFlags;
+}
+
+/*!
+  \brief Set progress bar colors.
+
+  If the colors differ the gradient color bar is drawn.
+  
+  If the \a endColor is not valid, \a startColor is used instead
+  (no gradient coloring).
+  
+  The parameter \a gradientType defines the type of gradient 
+  to be drawn - horizontal or vertical. Default is vertical.
+
+  Note, that methods setProgressGradient() and setProgresColors() are
+  alternative. Only the latest used is taken into account.
+
+  \param startColor start gradient color (or mono-color)
+  \param endColor end gradient color
+  \param gradientType gradient type (QtxSplash::GradientType)
+  \sa progressColors(), setProgressGradient()
+*/
+void QtxSplash::setProgressColors( const QColor&      startColor, 
+                                  const QColor&      endColor,
+                                   const GradientType gradientType )
+{
+  if ( startColor.isValid() )
+    myStartColor = startColor;
   myEndColor     = endColor;
   myGradientType = gradientType;
+  myGradientUsed = false;
   repaint();
 }
 
 /*!
-  Return progress colors and gradient type (horizontal or vertical).
+  \brief Get progress colors and gradient type.
+  \param startColor start gradient color (or mono-color)
+  \param endColor end gradient color
+  \return gradient type (QtxSplash::GradientType)
   \sa setProgressColors()
 */
-int QtxSplash::progressColors( QColor& startColor, QColor& endColor )
+QtxSplash::GradientType QtxSplash::progressColors( QColor& startColor, 
+                                                  QColor& endColor ) const
 {
   startColor = myStartColor;
   endColor   = myEndColor;
@@ -238,8 +474,77 @@ int QtxSplash::progressColors( QColor& startColor, QColor& endColor )
 }
 
 /*!
-  Sets message text alignment flags to \a alignment.
-  Default is AlignBottom | AlignRight.
+  \brief Set custom progress bar colors.
+
+  The gradient start and final stops are scaled to the actual progress
+  bar size. For example:
+  \code
+  QLinearGradient lg(0.5, 0, 1, 1);
+  lg.setColorAt(0.2, Qt::blue);
+  lg.setColorAt(0.6, Qt::red);
+  lg.setSpread(QGradient::RepeatSpread);
+  splash->setProgressGradient(lg);
+  \endcode
+  The above code creates linear gradient, which sets start stop to the
+  center of the progress bar; the final stop is always in the end of
+  the progress bar. The color scale (blue to red) is changed by the 
+  progress bar diagonal.
+
+  Note, that methods setProgressGradient() and setProgresColors() are
+  alternative. Only the latest used is taken into account.
+
+  \param gradient color gradient to be used for progress bar coloring
+  \sa progressGradient(), setProgresColors()
+*/
+void QtxSplash::setProgressGradient( const QLinearGradient& gradient )
+{
+  myGradient = gradient;
+  myGradientUsed = true;
+  repaint();
+}
+
+/*!
+  \brief Get custom progress bar colors.
+  \return color gradient used for progress bar coloring
+  \sa setProgressGradient()
+*/
+QLinearGradient QtxSplash::progressGradient() const
+{
+  return myGradient;
+}
+
+/*!
+  \brief Set progress bar and status text message opacity.
+
+  The value should be in the range 0.0 to 1.0, where 0.0 is fully 
+  transparent and 1.0 is fully opaque.
+
+  \param opacity new opacity value
+  \sa opacity()
+*/
+void QtxSplash::setOpacity( const double opacity )
+{
+  myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
+  repaint();
+}
+
+/*!
+  \brief Get progress bar and status text message opacity.
+  \return current opacity value
+  \sa setOpacity()
+*/
+double QtxSplash::opacity() const
+{
+  return myOpacity;
+}
+
+/*!
+  \brief Set message text alignment flags.
+
+  Default flags are Qt::AlignBottom | Qt::AlignRight.
+
+  \param alignment alignment flags (Qt::Alignment)
+  \sa textAlignment()
 */
 void QtxSplash::setTextAlignment( const int alignment )
 {
@@ -248,7 +553,8 @@ void QtxSplash::setTextAlignment( const int alignment )
 }
 
 /*!
-  Return message text alignment flags.
+  \brief Get message text alignment flags.
+  \return alignment flags (Qt::Alignment)
   \sa setTextAlignment()
 */
 int QtxSplash::textAlignment() const
@@ -257,19 +563,24 @@ int QtxSplash::textAlignment() const
 }
 
 /*!
-  Sets message text color to \a color.
-  Default is white.
+  \brief Set message text color.
+
+  Default message color is white.
+  
+  \param color message text color
   \sa setTextColors()
 */
 void QtxSplash::setTextColor( const QColor& color )
 {
-  myColor = color;
+  if ( myColor.isValid() )
+    myColor = color;
   myShadowColor = QColor();
   repaint();
 }
 
 /*!
-  Return message text color.
+  \brief Get message text color.
+  \return color message text color
   \sa setTextColor()
 */
 QColor QtxSplash::textColor() const
@@ -278,19 +589,24 @@ QColor QtxSplash::textColor() const
 }
 
 /*!
-  Sets message text color to \a color and text shadow color to \a shadow.
-  \sa setTextColor()
+  \brief Set message text color and text shadow color.
+  \param color message text color
+  \param shadow message text shadow color
+  \sa textColors(), textColor(), setTextColor()
 */
 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
 {
-  myColor       = color;
+  if ( myColor.isValid() )
+    myColor = color;
   myShadowColor = shadow;
   repaint();
 }
 
 /*!
-  Return message text color and text shadow color.
-  \sa setTextColors()
+  \brief Get message text color and text shadow color.
+  \param color message text color
+  \param shadow message text shadow color
+  \sa setTextColors(), textColor(), setTextColor()
 */
 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
 {
@@ -299,7 +615,8 @@ void QtxSplash::textColors( QColor& color, QColor& shadow ) const
 }
 
 /*!
-  Returns current status message.
+  \brief Get current status message.
+  \return status message
 */
 QString QtxSplash::message() const
 {
@@ -307,8 +624,13 @@ QString QtxSplash::message() const
 }
 
 /*!
-  Return error code. If no errors were occured returns 0.
-  Error code can be set by error( QString&, QString, int ).
+  \brief Get error code.
+
+  This function returns error code, set previoiusly with setError() or
+  error( QString&, QString, int ) methods.
+  If no error code has been set, 0 is returned.
+
+  \return last error code
 */
 int QtxSplash::error() const
 {
@@ -316,22 +638,26 @@ int QtxSplash::error() const
 }
 
 /*!
-    Makes the splash screen wait until the widget \a mainWin is displayed
-    before calling close() on itself.
+  \brief Wait until widget \a mainWin is displayed.
+
+  Makes the splash screen wait until the widget \a mainWin is displayed
+  and then hide and close splash window.
+
+  \param mainWin application main window 
 */
 void QtxSplash::finish( QWidget* mainWin )
 {
   if ( mainWin ) {
 #if defined(Q_WS_X11)
-    extern void qt_wait_for_window_manager( QWidget* w );
-    qt_wait_for_window_manager( mainWin );
+    extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
+    qt_x11_wait_for_window_manager(mainWin);
 #endif
   }
   close();
 }
 
 /*!
-  Repaint the splash screen.
+  \brief Repaint the splash screen.
 */
 void QtxSplash::repaint()
 {
@@ -341,8 +667,11 @@ void QtxSplash::repaint()
 }
 
 /*!
-  Draws the \a message text onto the splash screen with color \a
-  color and aligns the text according to the flags in \a alignment.
+  \brief Set status message for the splash screen and define its color 
+  and aligment flags.
+  \param msg status message
+  \param alignment message text alignment flags (Qt::Alignment)
+  \param color message text color
 */
 void QtxSplash::message( const QString& msg, 
                         int            alignment,
@@ -350,15 +679,15 @@ void QtxSplash::message( const QString& msg,
 {
   myMessage   = msg;
   myAlignment = alignment;
-  myColor     = color;
+  if ( color.isValid() )
+    myColor = color;
   repaint();
 }
 
 /*!
-  This is an overloaded member function, provided for convenience. 
-  It behaves essentially like the above function.
-  Draws the \a message text onto the splash screen with default color
-  and aligns the text according to the default alignment flags.
+  \overload
+  \brief Set status message for the splash screen.
+  \param msg status message
 */
 void QtxSplash::message( const QString& msg )
 {
@@ -367,7 +696,7 @@ void QtxSplash::message( const QString& msg )
 }
 
 /*!
-  Removes the message being displayed on the splash screen.
+  \brief Remove the message being displayed on the splash screen.
   \sa message()
 */
 void QtxSplash::clear()
@@ -377,131 +706,201 @@ void QtxSplash::clear()
 }
 
 /*!
-  Draw the contents of the splash screen using painter \a painter.
+  \brief Draw the contents of the splash screen.
+  \param painter painter
 */
-void QtxSplash::drawContents( QPainter* painter )
+void QtxSplash::drawContents( QPainter* p )
 {
-  QRect r = rect();
+  // draw progress bar
   if ( myTotal > 0 ) {
-    // draw progress bar outline rectangle
-    painter->setPen( palette().active().dark() );
-    painter->drawLine( r.x()+5, 
-                      r.height()-5-_PROGRESS_WIDTH,
-                      r.width()-5,
-                      r.height()-5-_PROGRESS_WIDTH );
-    painter->drawLine( r.x()+5,
-                      r.height()-5-_PROGRESS_WIDTH,
-                      r.x()+5,
-                      r.height()-5 );
-    painter->setPen( palette().active().light() );
-    painter->drawLine( r.x()+5,
-                      r.height()-5,
-                      r.width()-5,
-                      r.height()-5 );
-    painter->drawLine( r.width()-5,
-                      r.height()-5-_PROGRESS_WIDTH,
-                      r.width()-5,
-                      r.height()-5 );
-    // draw progress bar
-    if ( myGradientType == Horizontal ) {
-      int tng = r.width() - r.x() - 11;
-      int ng = (int) ( 1.0 * tng * ( myProgress > 0 ? myProgress : 0 ) / myTotal ); 
-      int h1, h2, s1, s2, v1, v2;
-      myStartColor.hsv( &h1, &s1, &v1 );
-      myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
-                            myStartColor.hsv( &h2, &s2, &v2 );
-      for ( int i = 0; i < ng; i++ ) {
-       painter->setPen( QColor( h1 + ((h2-h1)*i)/(tng-1),
-                                s1 + ((s2-s1)*i)/(tng-1),
-                                v1 + ((v2-v1)*i)/(tng-1), 
-                                QColor::Hsv ) );
-       painter->drawLine( r.x()+6+i,
-                          r.height()-5-_PROGRESS_WIDTH+1,
-                          r.x()+6+i,
-                          r.height()-6 );
-      }
-    }
-    else {
-      int ng = (int) ( 1.0 * (r.width() - r.x() - 11) * ( myProgress > 0 ? myProgress : 0 ) / myTotal ); 
-      int h1, h2, s1, s2, v1, v2;
-      myStartColor.hsv( &h1, &s1, &v1 );
-      myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
-                            myStartColor.hsv( &h2, &s2, &v2 );
-      for ( int i = 0; i < _PROGRESS_WIDTH-1; i++ ) {
-       painter->setPen( QColor( h1 + ((h2-h1)*i)/(_PROGRESS_WIDTH-2),
-                                s1 + ((s2-s1)*i)/(_PROGRESS_WIDTH-2),
-                                v1 + ((v2-v1)*i)/(_PROGRESS_WIDTH-2), 
-                                QColor::Hsv ) );
-       painter->drawLine( r.x()+6,
-                          r.height()-5-_PROGRESS_WIDTH+1+i,
-                          r.x()+6+ng-1,
-                          r.height()-5-_PROGRESS_WIDTH+1+i );
-      }
-    }
+    p->save();
+    drawProgressBar( p );
+    p->restore();
   }
-  // draw status
+
+  // draw status message
   if ( !myMessage.isEmpty() ) {
-    QFontMetrics f( font() );
-    int spacing = f.lineSpacing();
-    int shift = myTotal > 0 ? _PROGRESS_WIDTH : _PROGRESS_WIDTH; // : 0
-    int i = myMessage.length() - 1;
-    while( i >= 0 && myMessage[ i-- ] == '\n' )
-      shift += spacing;
-    QRect r1( r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10 - shift );
-    QRect r2 = r1;
-    if ( myAlignment & Qt::AlignLeft   ) r2.setLeft  ( r2.left()   + 1 );
-    if ( myAlignment & Qt::AlignTop    ) r2.setTop   ( r2.top()    + 1 );
-    if ( myAlignment & Qt::AlignRight  ) r2.setRight ( r2.right()  + 1 );
-    if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
-    if ( myShadowColor.isValid() ) {
-      painter->setPen( myShadowColor );
-      painter->drawText( r2, myAlignment, myMessage );
-    }
-    painter->setPen( myColor );
-    painter->drawText( r1, myAlignment, myMessage );
+    p->save();
+    drawMessage( p );
+    p->restore();
   }
 }
 
 /*!
-  Mouse press event.
+  \brief Process mouse button pressing event.
+
   Hides splash screen if the 'hide on mouse click' flag is set.
-  \sa setHideOnClick()
+
+  \param me mouse event (not used)
+  \sa hideOnClick(), setHideOnClick()
 */
-void QtxSplash::mousePressEvent( QMouseEvent* )
+void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
 {
   if ( myHideOnClick )
     hide();
 }
 
 /*!
-  Processes custom event sent by setStatus() method.
+  \brief Process custom event sent by setStatus() method.
+  \param ce custom event
   \sa setStatus().
 */
-void QtxSplash::customEvent( QCustomEvent* ce )
+void QtxSplash::customEvent( QEvent* ce )
 {
   if ( ce->type() == ProgressEvent::id() ) {
     ProgressEvent* pe = (ProgressEvent*)ce;
     pe->message().isEmpty() ? clear() : message( pe->message() );
     setProgress( pe->progress() );
-    qApp->processEvents();
+    QApplication::instance()->processEvents();
+  }
+}
+
+/*!
+  \brief Draw progress bar.
+  \param p painter
+*/
+void QtxSplash::drawProgressBar( QPainter* p )
+{
+  // get rect, margin, progress bar width
+  QRect r = rect();
+  int m   = margin();
+  int pw  = progressWidth();
+
+  // calculate drawing rect
+  // ... first set default position (if none or wrong position is set)
+  if ( myProgressFlags & BottomSide )
+    r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
+  else if ( myProgressFlags & TopSide )
+    r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
+  else if ( myProgressFlags & LeftSide )
+    r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
+  else if ( myProgressFlags & RightSide )
+    r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
+
+  QRect cr = r;
+  if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
+    cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+    if ( myProgressFlags & RightToLeft )
+      cr.translate( r.width() - cr.width(), 0 );
+  }
+  else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
+    cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+    if ( myProgressFlags & RightToLeft)
+      cr.translate( 0, r.height() - cr.height() );
+  }
+  int x1, x2, y1, y2;
+  if ( myGradientType == Horizontal ) {
+    x1 = r.left(); x2 = r.right(); y1 = y2 = 0;
+  }
+  else {
+    x1 = x2 = 0; y1 = r.top(); y2 = r.bottom();
+  }
+  QLinearGradient lg;
+  if ( myGradientUsed ) {
+    QPointF start = myGradient.start();
+    QPointF final = myGradient.finalStop();
+    qreal xd = final.x() - start.x();
+    qreal yd = final.y() - start.y();
+    lg.setStart( xd != 0 ? r.left() + r.width() * start.x() / xd : 0, 
+                 yd != 0 ? r.top() + r.height() * start.y() / yd : 0 );
+    lg.setFinalStop( xd != 0 ? r.right() : 0, yd != 0 ? r.bottom() : 0 );
+    lg.setStops( myGradient.stops() );
+    lg.setSpread( myGradient.spread() );
+  }
+  else {
+    lg.setStart( x1, y1 );
+    lg.setFinalStop( x2, y2 );
+    lg.setColorAt( 0, myStartColor );
+    lg.setColorAt( 1, myEndColor.isValid() ? myEndColor : myStartColor );
   }
+  p->setOpacity( myOpacity );
+  p->setClipRect( cr );
+  p->fillRect( r, lg ); 
+  p->setClipping( false );
+
+  // draw progress bar outline rectangle
+  p->setPen( palette().color( QPalette::Dark ) );
+  p->drawLine( r.left(), r.top(), r.right(), r.top() );
+  p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
+  p->setPen( palette().color( QPalette::Light ) );
+  p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
+  p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
+}
+
+/*!
+  \brief Draw status message.
+  \param p painter
+*/
+void QtxSplash::drawMessage( QPainter* p )
+{
+  // get rect, margin, progress bar width
+  QRect r = rect();
+  int m   = margin();
+  int pw  = progressWidth();
+
+  // calculate drawing rect
+  QFontMetrics f( font() );
+  int spacing = f.lineSpacing();
+  // ... base rect
+  QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
+  r1.setY( r1.y() - f.leading() );
+  // ... take into account progress bar
+  if ( 1 ) {              // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
+    if ( myProgressFlags & BottomSide )
+      r1.setHeight( r1.height() - pw );
+    else if ( myProgressFlags & TopSide )
+      r1.setY( r1.y() + pw );
+    else if ( myProgressFlags & LeftSide )
+      r1.setX( r1.x() + pw );
+    else if ( myProgressFlags & RightSide )
+      r1.setWidth( r1.width() - pw );
+  }
+  
+  // ... take into account trailing '\n' symbols
+  int shift = 0;
+  int i = myMessage.length() - 1;
+  while( i >= 0 && myMessage[ i-- ] == '\n' )
+    shift += spacing;
+  r1.setHeight( r1.height() - shift );
+
+  p->setOpacity( myOpacity );
+
+  // draw shadow status text
+  if ( myShadowColor.isValid() ) {
+    QRect r2 = r1;
+    if ( myAlignment & Qt::AlignLeft   ) r2.setLeft  ( r2.left()   + 1 );
+    if ( myAlignment & Qt::AlignTop    ) r2.setTop   ( r2.top()    + 1 );
+    if ( myAlignment & Qt::AlignRight  ) r2.setRight ( r2.right()  + 1 );
+    if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
+    p->setPen( myShadowColor );
+    p->drawText( r2, myAlignment, myMessage );
+  }
+
+  // draw foreground status text
+  p->setPen( myColor );
+  p->drawText( r1, myAlignment, myMessage );
 }
 
 /*!
-  Draws the splash screen window [ internal ].
+  \brief Draw the splash screen window contents.
 */
 void QtxSplash::drawContents()
 {
   QPixmap textPix = myPixmap;
-  QPainter painter( &textPix, this );
+  QPainter painter( &textPix );
+  painter.initFrom( this );
   drawContents( &painter );
-  setErasePixmap( textPix );
+  QPalette pal = palette();
+  pal.setBrush( backgroundRole(), QBrush( textPix ) );
+  setPalette( pal );
 }
 
 /*!
-  Sets error code [ internal ].
+  \brief Sets error code.
+  \param code error code
 */
 void QtxSplash::setError( const int code )
 {
   myError = code;
 }
+
index b6ade167c8a005ac40742da5568da6a4aaaab59e..4fe76699148b5bb338ae688e3d97752cb861ff0b 100644 (file)
@@ -24,8 +24,9 @@
 
 #include "Qtx.h"
 
-#include <qpixmap.h>
-#include <qwidget.h>
+#include <QWidget>
+#include <QPixmap>
+#include <QLinearGradient>
 
 #ifdef WIN32
 #pragma warning( disable:4251 )
 
 class QTX_EXPORT QtxSplash : public QWidget
 {
-    Q_OBJECT
+  Q_OBJECT
 
 private:
-    QtxSplash( const QPixmap& = QPixmap() );
+  QtxSplash( const QPixmap& );
 
 public:
-    enum { Horizontal, Vertical };
-
-    virtual ~QtxSplash();
-
-    static QtxSplash* splash( const QPixmap& = QPixmap() );
-    static void       setStatus( const QString&, const int = 0 );
-    static void       error( const QString&, const QString& = QString::null, const int = -1 );
-
-    void              setPixmap( const QPixmap& );
-    QPixmap           pixmap() const;
-
-    void              setHideOnClick( const bool );
-    bool              hideOnClick() const;
-
-    void              setTotalSteps( const int );
-    int               totalSteps() const;
-    void              setProgress( const int );
-    int               progress() const;
-    void              setProgress( const int, const int );
-    void              setProgressColors( const QColor&, 
-                                        const QColor& = QColor(),
-                                        const int     = Vertical );
-    int               progressColors( QColor&, QColor& );
-
-    void              setTextAlignment( const int );
-    int               textAlignment() const;
-
-    void              setTextColor( const QColor& );
-    QColor            textColor() const;
-    void              setTextColors( const QColor&, const QColor& = QColor() );
-    void              textColors( QColor&, QColor& ) const;
-    
-    QString           message() const;
-
-    int               error() const;
-
-    void              finish( QWidget* );
-    void              repaint();
-
+  //! Gradient type
+  typedef enum { 
+    Horizontal, //!< horizontal
+    Vertical    //!< vertical
+  } GradientType;
+  
+  //! Progress bar position and direction
+  typedef enum {
+    LeftSide     = 0x0001,      //!< progress bar is displayed at the left side
+    RightSide    = 0x0002,      //!< progress bar is displayed at the right side
+    TopSide      = 0x0004,      //!< progress bar is displayed at the top side
+    BottomSide   = 0x0008,      //!< progress bar is displayed at the bottom side
+    LeftToRight  = 0x0010,      //!< show progress from left to right (from top to bottom)
+    RightToLeft  = 0x0020       //!< show progress from right to left (from bottom to top)
+  } ProgressBarFlags;
+  
+  virtual ~QtxSplash();
+  
+  static QtxSplash* splash( const QPixmap& = QPixmap() );
+  
+  static void       setStatus( const QString&, const int = 0 );
+  static void       error( const QString&, const QString& = QString::null, const int = -1 );
+  
+  void              setPixmap( const QPixmap& );
+  QPixmap           pixmap() const;
+  
+  void              setHideOnClick( const bool );
+  bool              hideOnClick() const;
+  
+  void              setTotalSteps( const int );
+  int               totalSteps() const;
+  
+  void              setProgress( const int );
+  void              setProgress( const int, const int );
+  int               progress() const;
+  
+  void              setMargin( const int );
+  int               margin() const;
+  
+  void              setProgressWidth( const int );
+  int               progressWidth() const; 
+  
+  void              setProgressFlags( const int );
+  int               progressFlags() const;
+  
+  void              setProgressColors( const QColor&, 
+                                      const QColor& = QColor(),
+                                      const GradientType = Vertical );
+  GradientType      progressColors( QColor&, QColor& ) const;
+  
+  void              setProgressGradient( const QLinearGradient& );
+  QLinearGradient   progressGradient() const;
+  
+  void              setOpacity( const double );
+  double            opacity() const;
+  
+  void              setTextAlignment( const int );
+  int               textAlignment() const;
+  
+  void              setTextColor( const QColor& );
+  QColor            textColor() const;
+  void              setTextColors( const QColor&, const QColor& = QColor() );
+  void              textColors( QColor&, QColor& ) const;
+  
+  QString           message() const;
+  
+  int               error() const;
+  
+  void              finish( QWidget* );
+  void              repaint();
+  
 public slots:
-    void              message( const QString&, 
-                              const int,
-                              const QColor& = white );
-    void              message( const QString& );
-    void              clear();
-
+  void              message( const QString&, 
+                            const int,
+                            const QColor& = QColor() );
+  void              message( const QString& );
+  void              clear();
+  
 protected:
-    virtual void      mousePressEvent( QMouseEvent* );
-    virtual void      customEvent( QCustomEvent* );
-    virtual void      drawContents( QPainter* );
+  virtual void      mousePressEvent( QMouseEvent* );
+  virtual void      customEvent( QEvent* );
+  virtual void      drawContents( QPainter* );
+  
+  virtual void      drawProgressBar( QPainter* );
+  virtual void      drawMessage( QPainter* );
 
 private:
-    void              drawContents();
-    void              setError( const int );
+  void              drawContents();
+  void              setError( const int );
 
 private:
-    static QtxSplash* mySplash;
-
-    QPixmap           myPixmap;
-    QString           myMessage;
-    int               myAlignment;
-    QColor            myColor;
-    QColor            myShadowColor;
-    bool              myHideOnClick;
-    int               myProgress;
-    int               myTotal;
-    QColor            myStartColor;
-    QColor            myEndColor;
-    int               myGradientType;
-    int               myError;
+  static QtxSplash* mySplash;
+  
+  QPixmap           myPixmap;           //!< splash pixmap
+  QString           myMessage;          //!< current status message
+  int               myAlignment;        //!< text alignment flags (Qt::Alignment)
+  QColor            myColor;            //!< text color
+  QColor            myShadowColor;      //!< text shadow color
+  bool              myHideOnClick;      //!< 'hide on click' flag
+  int               myProgress;         //!< current progress
+  int               myTotal;            //!< total progress steps
+  QColor            myStartColor;       //!< progress bar gradient starting color
+  QColor            myEndColor;         //!< progress bar gradient ending color
+  GradientType      myGradientType;     //!< progress bar gradient direction
+  QLinearGradient   myGradient;         //!< progress bar custom gradient
+  int               myProgressWidth;    //!< progress bar width
+  int               myProgressFlags;    //!< progress bar flags (QtxSplash::ProgressBarFlags)
+  int               myMargin;           //!< margin (for progress bar and status message)
+  double            myOpacity;          //!< progress bar / status message opacity
+  int               myError;            //!< error code
+  bool              myGradientUsed;     //!< 'use custom gradient color scale' flag
 };
 
 #endif