]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxMenuButton.cxx
Salome HOME
Bug fix for SSPP10924
[modules/gui.git] / src / Qtx / QtxMenuButton.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
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.
7 // 
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/
18 //
19 // File:      QtxMenuButton.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxMenuButton.h"
23
24 #include <qstyle.h>
25 #include <qpainter.h>
26 #include <qpopupmenu.h>
27 #include <qpointarray.h>
28 #include <qapplication.h>
29
30 class QtxMenuButton::PopupMenu : public QPopupMenu
31 {
32 public:
33     PopupMenu( QtxMenuButton* mb ) : QPopupMenu( mb ), myMenuButton( mb ) {};
34     virtual ~PopupMenu() {};
35
36     virtual void setMinimumSize( int, int );
37
38 private:
39     QtxMenuButton* myMenuButton;
40 };
41
42 void QtxMenuButton::PopupMenu::setMinimumSize( int w, int h )
43 {
44     if ( myMenuButton->isAlignWidth() &&
45          ( myMenuButton->position() == Top || myMenuButton->position() == Bottom ) )
46         w = QMAX( w, myMenuButton->width() );
47
48     QPopupMenu::setMinimumSize( w, h );
49 }
50
51
52 QtxMenuButton::QtxMenuButton( int pos, QWidget* parent, const char* name )
53 : QPushButton( parent, name ),
54 myPos( pos )
55 {
56         initialize();
57 }
58
59 QtxMenuButton::QtxMenuButton( const QString& text, QWidget* parent, const char* name )
60 : QPushButton( parent, name ),
61 myPos( Bottom )
62 {
63         setText( text );
64         initialize();
65 }
66
67 QtxMenuButton::QtxMenuButton( int pos, const QString& text, QWidget* parent, const char* name )
68 : QPushButton( parent, name ),
69 myPos( pos )
70 {
71         setText( text );
72         initialize();
73 }
74
75 QtxMenuButton::QtxMenuButton( QWidget* parent, const char* name )
76 : QPushButton( parent, name ),
77 myPos( Bottom )
78 {
79         initialize();
80 }
81
82 QtxMenuButton::~QtxMenuButton()
83 {
84 }
85
86 void QtxMenuButton::initialize()
87 {
88         myArrow = true;
89     myAlign = true;
90
91         setAutoDefault( false );
92         myPopup = new PopupMenu( this );
93     myPopup->hide();
94
95         connect( myPopup, SIGNAL( activated( int ) ), this, SIGNAL( activated( int ) ) );
96         connect( this, SIGNAL( clicked() ), this, SLOT( onShowPopup() ) );
97 }
98
99 int QtxMenuButton::position() const
100 {
101         return myPos;
102 }
103
104 bool QtxMenuButton::isAlignWidth() const
105 {
106     return myAlign;
107 }
108
109 bool QtxMenuButton::isArrowEnabled() const
110 {
111         return myArrow;
112 }
113
114 void QtxMenuButton::setPosition( const int pos )
115 {
116         if ( myPos == pos )
117                 return;
118
119     myPos = pos;
120     if ( myPopup->isVisible() )
121         onShowPopup();
122 }
123
124 void QtxMenuButton::setAlignWidth( const bool on )
125 {
126     if ( myAlign == on )
127         return;
128
129     myAlign = on;
130     updateGeometry();
131 }
132
133 void QtxMenuButton::setArrowEnabled( const bool on )
134 {
135         if ( myArrow == on )
136                 return;
137
138     myArrow = on;
139     repaint();
140 }
141
142 void QtxMenuButton::clear()
143 {
144         if ( myPopup )
145                 myPopup->clear();
146         onShowPopup();
147         updateGeometry();
148 }
149
150 void QtxMenuButton::removeItem( int id )
151 {
152         if ( myPopup )
153                 removeItem( id );
154         updateGeometry();
155 }
156
157 int QtxMenuButton::insertSeparator( int id )
158 {
159         int res = -1;
160         if ( myPopup )
161                 res = myPopup->insertSeparator( id );
162     return res;
163 }
164
165 int QtxMenuButton::insertItem( const QString& t, int id, int index )
166 {
167         int resId = -1;
168         if ( myPopup )
169                 resId = myPopup->insertItem( t, id, index );
170
171         if ( resId != -1 )
172                 updateGeometry();
173
174         return resId;
175 }
176
177 int QtxMenuButton::insertItem( const QIconSet& is, const QString& t, int id, int index )
178 {
179         int resId = -1;
180         if ( myPopup )
181                 resId = myPopup->insertItem( is, t, id, index );
182
183         if ( resId != -1 )
184                 updateGeometry();
185
186         return resId;
187 }
188
189 void QtxMenuButton::onShowPopup()
190 {
191         if ( !myPopup || !myPopup->count() )
192         {
193                 myPopup->hide();
194                 return;
195         }
196
197         QPoint p = mapToGlobal( QPoint( 0, 0 ) );
198         int x = p.x();
199         int y = p.y() + 1;
200         int margin = 0;
201         int xoffset = 0;
202         int yoffset = 0;
203         switch ( position() )
204         {
205         case Left:
206                 xoffset = -1 * ( myPopup->sizeHint().width() + margin );
207                 break;
208         case Right:
209                 xoffset = width() + margin;
210                 break;
211         case Top:
212                 yoffset = -1 * ( myPopup->sizeHint().height() + margin );
213                 break;
214         case Bottom:
215         default:
216                 yoffset = height() + margin;
217                 break;
218         }
219         int dw = QApplication::desktop()->width();
220         int dh = QApplication::desktop()->height();
221         x = QMIN( QMAX( x + xoffset, 0 ), dw );
222         y = QMIN( QMAX( y + yoffset, 0 ), dh );
223
224         myPopup->exec( QPoint( x, y ) );
225 }
226
227 bool QtxMenuButton::event( QEvent* e )
228 {
229         if ( e->type() == QEvent::MouseButtonPress ||
230                  e->type() == QEvent::MouseButtonDblClick ||
231                  e->type() == QEvent::MouseButtonRelease )
232         {
233                 onShowPopup();
234                 return false;
235         }
236
237         return QPushButton::event( e );
238 }
239
240 QSize QtxMenuButton::sizeHint() const
241 {
242         QSize sz = QPushButton::sizeHint();
243         if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign )
244                 sz = QSize( QMAX( sz.width(), myPopup->sizeHint().width() ), sz.height() );
245
246         return sz;
247 }
248
249 QSize QtxMenuButton::minimumSizeHint() const
250 {
251         QSize sz = QPushButton::minimumSizeHint();
252         if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign )
253                 sz = QSize( QMAX( sz.width(), myPopup->sizeHint().width() ), sz.height() );
254
255         return sz;
256 }
257
258 void QtxMenuButton::resizeEvent( QResizeEvent* re )
259 {
260         if ( re )
261                 QPushButton::resizeEvent( re );
262
263         if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign )
264         myPopup->setMinimumWidth( re ? re->size().width() : width() );
265 }
266
267 QPopupMenu* QtxMenuButton::popup() const
268 {
269     return myPopup;
270 }
271
272 void QtxMenuButton::drawButtonLabel( QPainter* p )
273 {
274     QPushButton::drawButtonLabel( p );
275 /*
276         QStyle::SFlags flags = QStyle::Style_Default;
277         if ( isEnabled() )
278                 flags |= QStyle::Style_Enabled;
279         if ( hasFocus() )
280                 flags |= QStyle::Style_HasFocus;
281 */
282 #if QT_VER < 3
283     QRect r = rect();
284 #else
285         QRect r = style().subRect( QStyle::SR_PushButtonContents, this );
286 #endif
287
288         if ( myArrow && myPopup && myPopup->count() )
289         {
290                 int w = 7;
291                 int h = 7;
292                 int margin = 5;
293
294                 QRect ar( 0, 0, w, h );
295                 if ( position() == Left || position() == Top )
296                         r.moveBy( ar.width() + 2 * margin, 0 );
297                 else
298                         ar.moveBy( r.width() - ar.width() - 2 * margin, 0 );
299
300                 r.setWidth( r.width() - ar.width() - 2 * margin );
301     
302                 ar.moveBy( margin, ( height() - h ) / 2 );
303
304                 QPointArray arrow( 3 );
305                 switch ( position() )
306                 {
307                 case Left:
308                         arrow.putPoints( 0, 3, ar.left(), ar.top() + ar.height() / 2, ar.right(), ar.top(), ar.right(), ar.bottom() );
309                         break;
310                 case Right:
311                         arrow.putPoints( 0, 3, ar.left(), ar.top(), ar.left(), ar.bottom(), ar.right(), ar.top() + ar.height() / 2 );
312                         break;
313                 case Top:
314                         arrow.putPoints( 0, 3, ar.left(), ar.bottom(), ar.right(), ar.bottom(), ar.left() + ar.width() / 2, ar.top() );
315                         break;
316                 case Bottom:
317                 default:
318                         arrow.putPoints( 0, 3, ar.left(), ar.top(), ar.right(), ar.top(), ar.left() + ar.width() / 2, ar.bottom() );
319                         break;
320                 }
321
322                 p->setPen( colorGroup().text() );
323                 p->setBrush( colorGroup().text() );
324                 p->drawPolygon( arrow, true );
325         }
326
327 //      style().drawControl( QStyle::CE_PushButtonLabel, p, this, r, colorGroup(), flags );
328 }