source: vendor/trolltech/current/src/widgets/qtoolbar.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 23.0 KB
Line 
1/****************************************************************************
2** $Id: qtoolbar.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QToolBar class
5**
6** Created : 980315
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qtoolbar.h"
39#ifndef QT_NO_TOOLBAR
40
41#include "qmainwindow.h"
42#include "qtooltip.h"
43#include "qcursor.h"
44#include "qlayout.h"
45#include "qframe.h"
46#include "qobjectlist.h"
47#include "qpainter.h"
48#include "qdrawutil.h"
49#include "qtoolbutton.h"
50#include "qpopupmenu.h"
51#include "qcombobox.h"
52#include "qtimer.h"
53#include "qwidgetlist.h"
54#include "qstyle.h"
55
56static const char * const arrow_v_xpm[] = {
57 "7 9 3 1",
58 " c None",
59 ". c #000000",
60 "+ c none",
61 ".+++++.",
62 "..+++..",
63 "+..+..+",
64 "++...++",
65 ".++.++.",
66 "..+++..",
67 "+..+..+",
68 "++...++",
69 "+++.+++"};
70
71static const char * const arrow_h_xpm[] = {
72 "9 7 3 1",
73 " c None",
74 ". c #000000",
75 "+ c none",
76 "..++..+++",
77 "+..++..++",
78 "++..++..+",
79 "+++..++..",
80 "++..++..+",
81 "+..++..++",
82 "..++..+++"};
83
84class QToolBarExtensionWidget;
85
86class QToolBarPrivate
87{
88public:
89 QToolBarPrivate() : moving( FALSE ) {
90 }
91
92 bool moving;
93 QToolBarExtensionWidget *extension;
94 QPopupMenu *extensionPopup;
95};
96
97
98class QToolBarSeparator : public QWidget
99{
100 Q_OBJECT
101public:
102 QToolBarSeparator( Orientation, QToolBar *parent, const char* name=0 );
103
104 QSize sizeHint() const;
105 Orientation orientation() const { return orient; }
106public slots:
107 void setOrientation( Orientation );
108protected:
109 void styleChange( QStyle& );
110 void paintEvent( QPaintEvent * );
111
112private:
113 Orientation orient;
114};
115
116class QToolBarExtensionWidget : public QWidget
117{
118 Q_OBJECT
119
120public:
121 QToolBarExtensionWidget( QWidget *w );
122 void setOrientation( Orientation o );
123 QToolButton *button() const { return tb; }
124
125protected:
126 void resizeEvent( QResizeEvent *e ) {
127 QWidget::resizeEvent( e );
128 layOut();
129 }
130
131private:
132 void layOut();
133 QToolButton *tb;
134 Orientation orient;
135
136};
137
138QToolBarExtensionWidget::QToolBarExtensionWidget( QWidget *w )
139 : QWidget( w, "qt_dockwidget_internal" )
140{
141 tb = new QToolButton( this, "qt_toolbar_ext_button" );
142 tb->setAutoRaise( TRUE );
143 setOrientation( Horizontal );
144}
145
146void QToolBarExtensionWidget::setOrientation( Orientation o )
147{
148 orient = o;
149 if ( orient == Horizontal )
150 tb->setPixmap( QPixmap( (const char **)arrow_h_xpm ) );
151 else
152 tb->setPixmap( QPixmap( (const char **)arrow_v_xpm ) );
153 layOut();
154}
155
156void QToolBarExtensionWidget::layOut()
157{
158 tb->setGeometry( 2, 2, width() - 4, height() - 4 );
159}
160
161QToolBarSeparator::QToolBarSeparator(Orientation o , QToolBar *parent,
162 const char* name )
163 : QWidget( parent, name )
164{
165 connect( parent, SIGNAL(orientationChanged(Orientation)),
166 this, SLOT(setOrientation(Orientation)) );
167 setOrientation( o );
168 setBackgroundMode( parent->backgroundMode() );
169 setBackgroundOrigin( ParentOrigin );
170 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
171}
172
173
174
175void QToolBarSeparator::setOrientation( Orientation o )
176{
177 orient = o;
178}
179
180void QToolBarSeparator::styleChange( QStyle& )
181{
182 setOrientation( orient );
183}
184
185QSize QToolBarSeparator::sizeHint() const
186{
187 int extent = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent,
188 this );
189 if ( orient == Horizontal )
190 return QSize( extent, 0 );
191 else
192 return QSize( 0, extent );
193}
194
195void QToolBarSeparator::paintEvent( QPaintEvent * )
196{
197 QPainter p( this );
198 QStyle::SFlags flags = QStyle::Style_Default;
199
200 if ( orientation() == Horizontal )
201 flags |= QStyle::Style_Horizontal;
202
203 style().drawPrimitive( QStyle::PE_DockWindowSeparator, &p, rect(),
204 colorGroup(), flags );
205}
206
207#include "qtoolbar.moc"
208
209
210/*!
211 \class QToolBar qtoolbar.h
212 \brief The QToolBar class provides a movable panel containing
213 widgets such as tool buttons.
214
215 \ingroup application
216 \mainclass
217
218 A toolbar is a panel that contains a set of controls, usually
219 represented by small icons. It's purpose is to provide quick
220 access to frequently used commands or options. Within a
221 QMainWindow the user can drag toolbars within and between the
222 \link QDockArea dock areas\endlink. Toolbars can also be dragged
223 out of any dock area to float freely as top-level windows.
224
225 QToolBar is a specialization of QDockWindow, and so provides all
226 the functionality of a QDockWindow.
227
228 To use QToolBar you simply create a QToolBar as a child of a
229 QMainWindow, create a number of QToolButton widgets (or other
230 widgets) in left to right (or top to bottom) order and call
231 addSeparator() when you want a separator. When a toolbar is
232 floated the caption used is the label given in the constructor
233 call. This can be changed with setLabel().
234
235 \quotefile action/application.cpp
236 \skipto new QToolBar
237 \printuntil fileSaveAction
238
239 This extract from the \l application/application.cpp example shows
240 the creation of a new toolbar as a child of a QMainWindow and
241 adding two QActions.
242
243 You may use most widgets within a toolbar, with QToolButton and
244 QComboBox being the most common.
245
246 If you create a new widget on an already visible QToolBar, this
247 widget will automatically become visible without needing a show()
248 call. (This differs from every other Qt widget container. We
249 recommend calling show() anyway since we hope to fix this anomaly
250 in a future release.)
251
252 QToolBars, like QDockWindows, are located in \l{QDockArea}s or
253 float as top-level windows. QMainWindow provides four QDockAreas
254 (top, left, right and bottom). When you create a new toolbar (as
255 in the example above) as a child of a QMainWindow the toolbar will
256 be added to the top dock area. You can move it to another dock
257 area (or float it) by calling QMainWindow::moveDockWindow(). QDock
258 areas lay out their windows in \link qdockarea.html#lines
259 Lines\endlink.
260
261 If the main window is resized so that the area occupied by the
262 toolbar is too small to show all its widgets a little arrow button
263 (which looks like a right-pointing chevron, '»') will appear
264 at the right or bottom of the toolbar depending on its
265 orientation. Clicking this button pops up a menu that shows the
266 'overflowing' items. QToolButtons are represented in the menu using
267 their textLabel property, other QButton subclasses are represented
268 using their text property, and QComboBoxes are represented as submenus,
269 with the caption text being used in the submenu item.
270
271 Usually a toolbar will get precisely the space it needs. However,
272 with setHorizontalStretchable(), setVerticalStretchable() or
273 setStretchableWidget() you can tell the main window to expand the
274 toolbar to fill all available space in the specified orientation.
275
276 The toolbar arranges its buttons either horizontally or vertically
277 (see orientation() for details). Generally, QDockArea will set the
278 orientation correctly for you, but you can set it yourself with
279 setOrientation() and track any changes by connecting to the
280 orientationChanged() signal.
281
282 You can use the clear() method to remove all items from a toolbar.
283
284 \img qdockwindow.png Toolbar (dock window)
285 \caption A floating QToolbar (dock window)
286
287 \sa QToolButton QMainWindow \link http://www.iarchitect.com/visual.htm Parts of Isys on Visual Design\endlink \link guibooks.html#fowler GUI Design Handbook: Tool Bar\endlink.
288*/
289
290/*!
291 \fn QToolBar::QToolBar( const QString &label,
292 QMainWindow *, ToolBarDock = Top,
293 bool newLine = FALSE, const char * name = 0 );
294 \obsolete
295*/
296
297/*!
298 Constructs an empty toolbar.
299
300 The toolbar is called \a name and is a child of \a parent and is
301 managed by \a parent. It is initially located in dock area \a dock
302 and is labeled \a label. If \a newLine is TRUE the toolbar will be
303 placed on a new line in the dock area.
304*/
305
306QToolBar::QToolBar( const QString &label,
307 QMainWindow * parent, QMainWindow::ToolBarDock dock,
308 bool newLine, const char * name )
309 : QDockWindow( InDock, parent, name, 0, TRUE )
310{
311 mw = parent;
312 init();
313
314 if ( parent )
315 parent->addToolBar( this, label, dock, newLine );
316}
317
318
319/*!
320 Constructs an empty horizontal toolbar.
321
322 The toolbar is called \a name and is a child of \a parent and is
323 managed by \a mainWindow. The \a label and \a newLine parameters
324 are passed straight to QMainWindow::addDockWindow(). \a name and
325 the widget flags \a f are passed on to the QDockWindow constructor.
326
327 Use this constructor if you want to create torn-off (undocked,
328 floating) toolbars or toolbars in the \link QStatusBar status
329 bar\endlink.
330*/
331
332QToolBar::QToolBar( const QString &label, QMainWindow * mainWindow,
333 QWidget * parent, bool newLine, const char * name,
334 WFlags f )
335 : QDockWindow( InDock, parent, name, f, TRUE )
336{
337 mw = mainWindow;
338 init();
339
340 clearWFlags( WType_Dialog | WStyle_Customize | WStyle_NoBorder );
341 reparent( parent, QPoint( 0, 0 ), FALSE );
342
343 if ( mainWindow )
344 mainWindow->addToolBar( this, label, QMainWindow::DockUnmanaged, newLine );
345}
346
347
348/*!
349 \overload
350
351 Constructs an empty toolbar called \a name, with parent \a parent,
352 in its \a parent's top dock area, without any label and without
353 requiring a newline.
354*/
355
356QToolBar::QToolBar( QMainWindow * parent, const char * name )
357 : QDockWindow( InDock, parent, name, 0, TRUE )
358{
359 mw = parent;
360 init();
361
362 if ( parent )
363 parent->addToolBar( this, QString::null, QMainWindow::DockTop );
364}
365
366/*!
367 \internal
368
369 Common initialization code. Requires that \c mw and \c o are set.
370 Does not call QMainWindow::addDockWindow().
371*/
372void QToolBar::init()
373{
374 d = new QToolBarPrivate;
375 d->extension = 0;
376 d->extensionPopup = 0;
377 sw = 0;
378
379 setBackgroundMode( PaletteButton);
380 setFocusPolicy( NoFocus );
381 setFrameStyle( QFrame::ToolBarPanel | QFrame::Raised);
382 boxLayout()->setSpacing(style().pixelMetric(QStyle::PM_ToolBarItemSpacing));
383}
384
385/*!
386 \reimp
387*/
388
389QToolBar::~QToolBar()
390{
391 delete d;
392 d = 0;
393}
394
395/*!
396 \reimp
397*/
398
399void QToolBar::setOrientation( Orientation o )
400{
401 QDockWindow::setOrientation( o );
402 if (d->extension)
403 d->extension->setOrientation( o );
404 QObjectList *childs = queryList( "QToolBarSeparator" );
405 if ( childs ) {
406 QObject *ob = 0;
407 for ( ob = childs->first(); ob; ob = childs->next() ) {
408 QToolBarSeparator* w = (QToolBarSeparator*)ob;
409 w->setOrientation( o );
410 }
411 }
412 delete childs;
413}
414
415/*!
416 Adds a separator to the right/bottom of the toolbar.
417*/
418
419void QToolBar::addSeparator()
420{
421 (void) new QToolBarSeparator( orientation(), this, "toolbar separator" );
422}
423
424/*!
425 \reimp
426*/
427
428void QToolBar::styleChange( QStyle& )
429{
430 QObjectList *childs = queryList( "QWidget" );
431 if ( childs ) {
432 QObject *ob = 0;
433 for ( ob = childs->first(); ob; ob = childs->next() ) {
434 QWidget *w = (QWidget*)ob;
435 if ( ::qt_cast<QToolButton*>(w) || ::qt_cast<QToolBarSeparator*>(w) )
436 w->setStyle( &style() );
437 }
438 }
439 delete childs;
440 boxLayout()->setSpacing(style().pixelMetric(QStyle::PM_ToolBarItemSpacing));
441}
442
443/*!
444 \reimp.
445*/
446
447void QToolBar::show()
448{
449 QDockWindow::show();
450 if ( mw )
451 mw->triggerLayout( FALSE );
452 checkForExtension( size() );
453}
454
455
456/*!
457 \reimp
458*/
459
460void QToolBar::hide()
461{
462 QDockWindow::hide();
463 if ( mw )
464 mw->triggerLayout( FALSE );
465}
466
467/*!
468 Returns a pointer to the QMainWindow which manages this toolbar.
469*/
470
471QMainWindow * QToolBar::mainWindow() const
472{
473 return mw;
474}
475
476
477/*!
478 Sets the widget \a w to be expanded if this toolbar is requested
479 to stretch.
480
481 The request to stretch might occur because QMainWindow
482 right-justifies the dock area the toolbar is in, or because this
483 toolbar's isVerticalStretchable() or isHorizontalStretchable() is
484 set to TRUE.
485
486 If you call this function and the toolbar is not yet stretchable,
487 setStretchable() is called.
488
489 \sa QMainWindow::setRightJustification(), setVerticalStretchable(),
490 setHorizontalStretchable()
491*/
492
493void QToolBar::setStretchableWidget( QWidget * w )
494{
495 sw = w;
496 boxLayout()->setStretchFactor( w, 1 );
497
498 if ( !isHorizontalStretchable() && !isVerticalStretchable() ) {
499 if ( orientation() == Horizontal )
500 setHorizontalStretchable( TRUE );
501 else
502 setVerticalStretchable( TRUE );
503 }
504}
505
506
507/*!
508 \reimp
509*/
510
511bool QToolBar::event( QEvent * e )
512{
513 bool r = QDockWindow::event( e );
514 // After the event filters have dealt with it, do our stuff.
515 if ( e->type() == QEvent::ChildInserted ) {
516 QObject * child = ((QChildEvent*)e)->child();
517 if ( child && child->isWidgetType() && !((QWidget*)child)->isTopLevel()
518 && child->parent() == this
519 && qstrcmp("qt_dockwidget_internal", child->name()) != 0 ) {
520 boxLayout()->addWidget( (QWidget*)child );
521 if ( isVisible() ) {
522 if ( ((QWidget*)child)->testWState( WState_CreatedHidden ) )
523 ((QWidget*)child)->show();
524 checkForExtension( size() );
525 }
526 }
527 if ( child && child->isWidgetType() && ((QWidget*)child) == sw )
528 boxLayout()->setStretchFactor( (QWidget*)child, 1 );
529 } else if ( e->type() == QEvent::Show ) {
530 layout()->activate();
531 } else if ( e->type() == QEvent::LayoutHint && place() == OutsideDock ) {
532 adjustSize();
533 }
534 return r;
535}
536
537
538/*!
539 \property QToolBar::label
540 \brief the toolbar's label.
541
542 If the toolbar is floated the label becomes the toolbar window's
543 caption. There is no default label text.
544*/
545
546void QToolBar::setLabel( const QString & label )
547{
548 l = label;
549 setCaption( l );
550}
551
552QString QToolBar::label() const
553{
554 return l;
555}
556
557
558/*!
559 Deletes all the toolbar's child widgets.
560*/
561
562void QToolBar::clear()
563{
564 if ( !children() )
565 return;
566 QObjectListIt it( *children() );
567 QObject * obj;
568 while( (obj=it.current()) != 0 ) {
569 ++it;
570 if ( obj->isWidgetType() &&
571 qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 )
572 delete obj;
573 }
574}
575
576/*!
577 \reimp
578*/
579
580QSize QToolBar::minimumSize() const
581{
582 if ( orientation() == Horizontal )
583 return QSize( 0, QDockWindow::minimumSize().height() );
584 return QSize( QDockWindow::minimumSize().width(), 0 );
585}
586
587/*!
588 \reimp
589*/
590
591QSize QToolBar::minimumSizeHint() const
592{
593 if ( orientation() == Horizontal )
594 return QSize( 0, QDockWindow::minimumSizeHint().height() );
595 return QSize( QDockWindow::minimumSizeHint().width(), 0 );
596}
597
598void QToolBar::createPopup()
599{
600 if (!d->extensionPopup) {
601 d->extensionPopup = new QPopupMenu( this, "qt_dockwidget_internal" );
602 connect( d->extensionPopup, SIGNAL( aboutToShow() ), this, SLOT( createPopup() ) );
603 }
604
605 if (!d->extension) {
606 d->extension = new QToolBarExtensionWidget( this );
607 d->extension->setOrientation(orientation());
608 d->extension->button()->setPopup( d->extensionPopup );
609 d->extension->button()->setPopupDelay( -1 );
610 }
611
612 d->extensionPopup->clear();
613 // clear doesn't delete submenus, so do this explicitly
614 QObjectList *childlist = d->extensionPopup->queryList( "QPopupMenu", 0, FALSE, TRUE );
615 childlist->setAutoDelete(TRUE);
616 delete childlist;
617
618 childlist = queryList( "QWidget", 0, FALSE, TRUE );
619 QObjectListIt it( *childlist );
620 bool hide = FALSE;
621 bool doHide = FALSE;
622 int id;
623 while ( it.current() ) {
624 int j = 2;
625 if ( !it.current()->isWidgetType() || it.current() == d->extension->button() ||
626 qstrcmp( "qt_dockwidget_internal", it.current()->name() ) == 0 ) {
627 ++it;
628 continue;
629 }
630 QWidget *w = (QWidget*)it.current();
631#ifndef QT_NO_COMBOBOX
632 if ( ::qt_cast<QComboBox*>(w) )
633 j = 1;
634#endif
635 hide = FALSE;
636 QPoint p = w->parentWidget()->mapTo( this, w->geometry().bottomRight() );
637 if ( orientation() == Horizontal ) {
638 if ( p.x() > ( doHide ? width() - d->extension->width() / j : width() ) )
639 hide = TRUE;
640 } else {
641 if ( p.y() > ( doHide ? height()- d->extension->height() / j : height() ) )
642 hide = TRUE;
643 }
644 if ( hide && w->isVisible() ) {
645 doHide = TRUE;
646 if ( ::qt_cast<QToolButton*>(w) ) {
647 QToolButton *b = (QToolButton*)w;
648 QString s = b->textLabel();
649 if ( s.isEmpty() )
650 s = b->text();
651 if ( b->popup() && b->popupDelay() == 0 )
652 id = d->extensionPopup->insertItem( b->iconSet(), s, b->popup() );
653 else
654 id = d->extensionPopup->insertItem( b->iconSet(), s, b, SLOT( emulateClick() ) ) ;
655 if ( b->isToggleButton() )
656 d->extensionPopup->setItemChecked( id, b->isOn() );
657 if ( !b->isEnabled() )
658 d->extensionPopup->setItemEnabled( id, FALSE );
659 } else if ( ::qt_cast<QButton*>(w) ) {
660 QButton *b = (QButton*)w;
661 QString s = b->text();
662 if ( s.isEmpty() )
663 s = "";
664 if ( b->pixmap() )
665 id = d->extensionPopup->insertItem( *b->pixmap(), s, b, SLOT( emulateClick() ) );
666 else
667 id = d->extensionPopup->insertItem( s, b, SLOT( emulateClick() ) );
668 if ( b->isToggleButton() )
669 d->extensionPopup->setItemChecked( id, b->isOn() );
670 if ( !b->isEnabled() )
671 d->extensionPopup->setItemEnabled( id, FALSE );
672#ifndef QT_NO_COMBOBOX
673 } else if ( ::qt_cast<QComboBox*>(w) ) {
674 QComboBox *c = (QComboBox*)w;
675 if ( c->count() != 0 ) {
676#ifndef QT_NO_WIDGET_TOPEXTRA
677 QString s = c->caption();
678#else
679 QString s;
680#endif
681 if ( s.isEmpty() )
682 s = c->currentText();
683 uint maxItems = 0;
684 QPopupMenu *cp = new QPopupMenu(d->extensionPopup);
685 d->extensionPopup->insertItem( s, cp );
686 connect( cp, SIGNAL( activated(int) ), c, SLOT( internalActivate(int) ) );
687 for ( int i = 0; i < c->count(); ++i ) {
688 QString tmp = c->text( i );
689 cp->insertItem( tmp, i );
690 if ( c->currentText() == tmp )
691 cp->setItemChecked( i, TRUE );
692 if ( !maxItems ) {
693 if ( cp->count() == 10 ) {
694 int h = cp->sizeHint().height();
695 maxItems = QApplication::desktop()->height() * 10 / h;
696 }
697 } else if ( cp->count() >= maxItems - 1 ) {
698 QPopupMenu* sp = new QPopupMenu(d->extensionPopup);
699 cp->insertItem( tr( "More..." ), sp );
700 cp = sp;
701 connect( cp, SIGNAL( activated(int) ), c, SLOT( internalActivate(int) ) );
702 }
703 }
704 }
705#endif //QT_NO_COMBOBOX
706 }
707 }
708 ++it;
709 }
710 delete childlist;
711}
712
713
714/*!
715 \reimp
716*/
717
718void QToolBar::resizeEvent( QResizeEvent *e )
719{
720 checkForExtension( e->size() );
721}
722
723void QToolBar::checkForExtension( const QSize &sz )
724{
725 if (!isVisible())
726 return;
727
728 bool tooSmall;
729 if ( orientation() == Horizontal )
730 tooSmall = sz.width() < sizeHint().width();
731 else
732 tooSmall = sz.height() < sizeHint().height();
733
734 if ( tooSmall ) {
735 createPopup();
736 if ( d->extensionPopup->count() ) {
737 if ( orientation() == Horizontal )
738 d->extension->setGeometry( width() - 20, 1, 20, height() - 2 );
739 else
740 d->extension->setGeometry( 1, height() - 20, width() - 2, 20 );
741 d->extension->show();
742 d->extension->raise();
743 } else {
744 delete d->extension;
745 d->extension = 0;
746 delete d->extensionPopup;
747 d->extensionPopup = 0;
748 }
749 } else {
750 delete d->extension;
751 d->extension = 0;
752 delete d->extensionPopup;
753 d->extensionPopup = 0;
754 }
755}
756
757
758/*!
759 \reimp
760*/
761
762void QToolBar::setMinimumSize( int, int )
763{
764}
765
766/* from chaunsee:
767
7681. Tool Bars should contain only high-frequency functions. Avoid putting
769things like About and Exit on a tool bar unless they are frequent functions.
770
7712. All tool bar buttons must have some keyboard access method (it can be a
772menu or shortcut key or a function in a dialog box that can be accessed
773through the keyboard).
774
7753. Make tool bar functions as efficient as possible (the common example is to
776Print in Microsoft applications, it doesn't bring up the Print dialog box, it
777prints immediately to the default printer).
778
7794. Avoid turning tool bars into graphical menu bars. To me, a tool bar should
780be efficient. Once you make almost all the items in a tool bar into graphical
781pull-down menus, you start to lose efficiency.
782
7835. Make sure that adjacent icons are distinctive. There are some tool bars
784where you see a group of 4-5 icons that represent related functions, but they
785are so similar that you can't differentiate among them. These tool bars are
786often a poor attempt at a "common visual language".
787
7886. Use any de facto standard icons of your platform (for windows use the
789cut, copy and paste icons provided in dev kits rather than designing your
790own).
791
7927. Avoid putting a highly destructive tool bar button (delete database) by a
793safe, high-frequency button (Find) -- this will yield 1-0ff errors).
794
7958. Tooltips in many Microsoft products simply reiterate the menu text even
796when that is not explanatory. Consider making your tooltips slightly more
797verbose and explanatory than the corresponding menu item.
798
7999. Keep the tool bar as stable as possible when you click on different
800objects. Consider disabling tool bar buttons if they are used in most, but not
801all contexts.
802
80310. If you have multiple tool bars (like the Microsoft MMC snap-ins have),
804put the most stable tool bar to at the left with less stable ones to the
805right. This arrangement (stable to less stable) makes the tool bar somewhat
806more predictable.
807
80811. Keep a single tool bar to fewer than 20 items divided into 4-7 groups of
809items.
810*/
811#endif
Note: See TracBrowser for help on using the repository browser.