1 // Copyright (C) 2007-2016 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
21 // Author: Sergey TELKOV
28 #include <QPaintEvent>
29 #include <QTextDocument>
30 #include <QWidgetAction>
31 #include <QLinearGradient>
32 #include <QAbstractTextDocumentLayout>
37 \brief Popup menu title item.
41 class QtxMenu::Title : public QWidget
44 Title( QWidget* = 0 );
48 void setIcon( const QIcon& );
51 void setText( const QString& );
53 Qt::Alignment alignment() const;
54 void setAlignment( const Qt::Alignment );
56 virtual QSize sizeHint() const;
57 virtual QSize minimumSizeHint() const;
60 virtual void paintEvent( QPaintEvent* );
65 Qt::Alignment myAlignment;
70 \param parent parent widget
73 QtxMenu::Title::Title( QWidget* parent )
83 QtxMenu::Title::~Title()
88 \brief Get title icon.
89 \return title item icon
92 QIcon QtxMenu::Title::icon() const
98 \brief Set title icon.
99 \param ico title item icon
102 void QtxMenu::Title::setIcon( const QIcon& ico )
108 \brief Get title menu text.
109 \return menu text for the title item
112 QString QtxMenu::Title::text() const
118 \brief Set title menu text.
119 \param txt menu text to be used for the title item
122 void QtxMenu::Title::setText( const QString& txt )
128 \brief Get title alignment flags.
129 \return title alignment flags
132 Qt::Alignment QtxMenu::Title::alignment() const
138 \brief Set title alignment flags.
139 \param a title alignment flags
142 void QtxMenu::Title::setAlignment( const Qt::Alignment a )
148 \brief Get recommended size for the title item widget.
149 \return title item widget size
152 QSize QtxMenu::Title::sizeHint() const
156 doc.setHtml( text() );
158 QSize sz = icon().isNull() ? QSize( 0, 0 ) : icon().actualSize( QSize( 16, 16 ) );
159 sz.setWidth( 2 * m + sz.width() + (int)doc.size().width() );
160 sz.setHeight( 2 * m + qMax( sz.height(), (int)doc.size().height() ) );
165 \brief Get recommended minimum size for the title item widget.
166 \return title item widget minimum size
169 QSize QtxMenu::Title::minimumSizeHint() const
175 \brief Paint the title item widget.
176 \param e paint event (not used)
179 void QtxMenu::Title::paintEvent( QPaintEvent* /*e*/ )
183 QString txt = text();
184 Qt::Alignment align = alignment();
187 base.setTop( base.top() + 1 );
188 base.setLeft( base.left() + 1 );
189 base.setRight( base.right() -1 );
190 base.setBottom( base.bottom() - 1 );
195 QSize isz = ico.isNull() ? QSize( 0, 0 ) : ico.actualSize( QSize( 16, 16 ) );
196 QSize sz( (int)doc.size().width(), (int)doc.size().height() );
199 QAbstractTextDocumentLayout::PaintContext ctx;
200 ctx.palette.setColor( QPalette::Text, palette().color( QPalette::Light ) );
202 QLinearGradient linearGrad( base.topLeft(), base.topRight() );
203 linearGrad.setColorAt( 0, palette().color( QPalette::Highlight ) );
204 linearGrad.setColorAt( 1, palette().color( QPalette::Window ) );
206 p.fillRect( base, linearGrad );
208 QPoint start = base.topLeft() + QPoint( m, m );
209 if ( align & Qt::AlignLeft )
210 start.setX( base.left() + m );
211 else if ( align & Qt::AlignRight )
212 start.setX( base.right() - m - isz.width() - sz.width() );
213 else if ( align & Qt::AlignHCenter )
214 start.setX( base.left() + ( base.width() - isz.width() - sz.width() ) / 2 );
216 if ( align & Qt::AlignTop )
217 start.setY( base.top() + m );
218 else if ( align & Qt::AlignBottom )
219 start.setY( base.bottom() - m - qMax( isz.height(), - sz.height() ) );
220 else if ( align & Qt::AlignVCenter )
221 start.setY( base.top() + ( base.height() - qMax( isz.height(), sz.height() ) ) / 2 );
225 ico.paint( &p, QRect( start, isz ) );
226 start.setX( start.x() + isz.width() );
230 p.translate( start );
231 doc.documentLayout()->draw( &p, ctx );
237 \brief The class QtxMenu represents the popup menu with the title.
239 The title for the popup menu can be set via setTitleText() method.
240 In addition, title item can contain the icon, which can be set using
241 setTitleIcon() method. Current title text and icon can be retrieved with
242 titleText() and titleIcon() methods.
244 The title text alignment flags can be changed using setTitleAlignment()
245 method and retrieved with titleAlignment() method.
247 By default, QtxMenu::TitleAuto mode is used. In this mode, the title item
248 is shown only if it is not empty. To show title always (even empty), pass
249 QtxMenu::TitleOn to the setTitleMode() method. To hide the title, use
250 setTitleMode() method with QtxMenu::TitleOff parameter.
255 \param parent parent widget
257 QtxMenu::QtxMenu( QWidget* parent )
261 myTitle = new Title( this );
262 myAction = new QWidgetAction( this );
263 myAction->setDefaultWidget( myTitle );
274 \brief Get title menu text.
275 \return menu text for the title item
277 QString QtxMenu::titleText() const
279 return myTitle->text();
283 \brief Get title icon.
284 \return title item icon
286 QIcon QtxMenu::titleIcon() const
288 return myTitle->icon();
292 \brief Get title item display mode.
293 \return popup menu title display mode (QtxMenu::TitleMode)
295 QtxMenu::TitleMode QtxMenu::titleMode() const
301 \brief Get title alignment flags.
302 \return title alignment flags
304 Qt::Alignment QtxMenu::titleAlignment() const
306 return myTitle->alignment();
310 \brief Set title menu text.
311 \param txt menu text to be used for the title item
313 void QtxMenu::setTitleText( const QString& txt )
315 if ( titleText() == txt )
318 myTitle->setText( txt );
324 \brief Set title icon.
325 \param ico title item icon
327 void QtxMenu::setTitleIcon( const QIcon& ico )
329 myTitle->setIcon( ico );
335 \brief Set title item display mode.
336 \param m popup menu title display mode (QtxMenu::TitleMode)
338 void QtxMenu::setTitleMode( const QtxMenu::TitleMode m )
349 \brief Set title alignment flags.
350 \param a title alignment flags
352 void QtxMenu::setTitleAlignment( const Qt::Alignment a )
354 if ( titleAlignment() == a )
357 myTitle->setAlignment( a );
363 \brief Append group title to the end of the menu.
364 \param text group title's text
366 void QtxMenu::addGroup( const QString& text )
368 Title* aTitle = new Title( this );
369 aTitle->setText( text );
371 QWidgetAction* anAction = new QWidgetAction( this );
372 anAction->setDefaultWidget( aTitle );
374 addAction( anAction );
378 \brief Append group title to the end of the menu.
379 \param icon group title's icon
380 \param text group title's text
382 void QtxMenu::addGroup( const QIcon& icon, const QString& text )
384 Title* aTitle = new Title( this );
385 aTitle->setText( text );
386 aTitle->setIcon( icon );
388 QWidgetAction* anAction = new QWidgetAction( this );
389 anAction->setDefaultWidget( aTitle );
391 addAction( anAction );
395 \brief Customize show/hide menu operation.
396 \param on new popup menu visibility state
398 void QtxMenu::setVisible( bool on )
403 QMenu::setVisible( on );
410 \brief Insert title item to the popup menu.
412 void QtxMenu::insertTitle()
414 if ( titleMode() == TitleOff || ( titleMode() == TitleAuto && titleText().trimmed().isEmpty() ) )
417 if ( actions().isEmpty() )
418 addAction( myAction );
420 insertAction( actions().first(), myAction );
424 \brief Remove title item from the popup menu.
426 void QtxMenu::removeTitle()
428 if ( actions().contains( myAction ) )
429 removeAction( myAction );
433 \brief Update title item.
435 void QtxMenu::updateTitle()
437 if ( !actions().contains( myAction ) )
447 void QtxMenu::paintEvent( QPaintEvent* e )
449 // Force menu resizing, see resizeAfterRepaint().
450 QMenu::paintEvent(e);
451 QTimer::singleShot( 0, this, SLOT( resizeAfterRepaint() ) );
454 void QtxMenu::resizeAfterRepaint()
456 // this slot is used as a workaround about annoying problem
457 // on some X window System desktops like KDE 5, Unity and other
458 // that causes setting incorrect menu's geometry
459 // after it appears on a screen.
460 resize( sizeHint() );