1/**
2 * KStyle for KDE4
3 * Copyright (C) 2004-2005 Maksim Orlovich <maksim@kde.org>
4 * Copyright (C) 2005,2006 Sandro Giessl <giessl@kde.org>
5 *
6 * Based in part on the following software:
7 * KStyle for KDE3
8 * Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
9 * Portions (C) 1998-2000 TrollTech AS
10 * Keramik for KDE3,
11 * Copyright (C) 2002 Malte Starostik <malte@kde.org>
12 * (C) 2002-2003 Maksim Orlovich <maksim@kde.org>
13 * Portions (C) 2001-2002 Karol Szwed <gallium@kde.org>
14 * (C) 2001-2002 Fredrik Höglund <fredrik@kde.org>
15 * (C) 2000 Daniel M. Duley <mosfet@kde.org>
16 * (C) 2000 Dirk Mueller <mueller@kde.org>
17 * (C) 2001 Martijn Klingens <klingens@kde.org>
18 * (C) 2003 Sandro Giessl <sandro@giessl.com>
19 * This library is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Library General Public
21 * License as published by the Free Software Foundation; either
22 * version 2 of the License, or (at your option) any later version.
23 *
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Library General Public License for more details.
28 *
29 * You should have received a copy of the GNU Library General Public License
30 * along with this library; see the file COPYING.LIB. If not, write to
31 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
32 * Boston, MA 02110-1301, USA.
33 */
34
35#ifndef KDE_KSTYLE_H
36#define KDE_KSTYLE_H
37
38#include <kdeui_export.h>
39
40#include <QtGui/QCommonStyle>
41#include <QtGui/QPalette>
42#include <QtGui/QStylePlugin>
43#include <typeinfo>
44
45class QStyleOptionProgressBar;
46class QStyleOptionTab;
47
48class KStylePrivate;
49/**
50 * Makes style coding more convenient.
51 *
52 * @todo and allows to style KDE specific widgets.
53 *
54 * KStyle strives to ease style development by implementing various QStyle
55 * methods. These implementations are based on
56 * -# the concept of Layout Properties. These properties can be set using
57 * setWidgetLayoutProp(). KStyle uses this information to respect various
58 * metrics (like space between primitives or margins around widget contents)
59 * or turn specific features on or off.
60 * -# the concept of KStyle Primitives. These can be implemented by overriding
61 * drawKStylePrimitive() and providing drawing methods for specific
62 * primitives. Often, the drawing of more complex widgets consists of
63 * several primitives.
64 *
65 * In the following modules, information about related members is collected:
66 * - \ref OptionGroup
67 * - \ref WidgetGroup
68 *
69 * @author Maksim Orlovich (maksim\@kde.org)
70 * @author Sandro Giessl (giessl\@kde.org)
71 *
72 * @see KStyleFactory for how to implement the style plugin interface.
73 */
74// TODO: From 'Qt4 Themes' discussion on kde-devel
75// - Remi Villatel: extend QStyle enums for KColorButton, KColorCombo, KKeyButton, split PE_HeaderSection into KPopupTitle, PopupMenuTitle, TaskContainer)
76// - RV: KLineEdit "plays with its colors" - related to KStyle?
77// - RV: KMulitTabBarTab ... does it need support from KStyle (instead of manual button rotation etc.)? Or is it dumped already?
78// - RV: KTabCtl draws itself mimicking QDrawShadeThingies
79// - RV: fixed colors (e.g. Konqueror, KToolbarButton label text ->KPE_ToolbarButton?): To prevent hacks like "preventing any PaletteChange()"... mor related to KDE4 color schemes... I guess
80// - LM: User interface guidelines... related to KStyle?
81// - e.g. drawFancyPE() in kdeui for KDE widgets: check "qobject_cast<KStyle*>(style())", or fallback drawing...
82// TODO: implement standardIcon().. and what about standardPalette()?
83// TODO: maybe the arrow in CE_PushButtonLabel should be painted in CE_PushButtonBevel like QCommonStyle
84
85class KDEUI_EXPORT KStyle: public QCommonStyle
86{
87 Q_OBJECT
88
89public:
90 KStyle();
91 ~KStyle();
92
93 /**
94 * Returns the default widget style.
95 */
96 static QString defaultStyle();
97 /**
98 * Runtime element extension
99 * This is just convenience and does /not/ require the using widgets style to inherit KStyle
100 * (i.e. calling this while using cleanlooks won't segfault or so but just return 0)
101 * Returns a unique id for an element string (e.g. "CE_CapacityBar")
102 *
103 * For simplicity, only StyleHints, ControlElements and their SubElements are supported
104 * If you don't need extended SubElement functionality, just drop it
105 *
106 * @param element The style element, represented as string.
107 * Naming convention: "appname.(2-char-element-type)_element"
108 * where the 2-char-element-type is of {SH, CE, SE}
109 * (widgets in kdelibs don't have to pass the appname)
110 * examples: "CE_CapacityBar", "amarok.CE_Analyzer"
111 * @param widget Your widget ("this") passing this is mandatory, passing NULL will just return 0
112 * @returns a unique id for the @p element string or 0, if the element is not supported by the
113 * widgets current style
114 *
115 * Important notes:
116 * 1) If your string lacks the matching "SH_", "CE_" or "SE_" token the element
117 * request will be ignored (return is 0)
118 * 2) Try to avoid custom elements and use default ones (if possible) to get better style support
119 * and keep UI coherency
120 * 3) If you cache this value (good idea, this requires a map lookup) don't (!) forget to catch
121 * style changes in QWidget::changeEvent()
122 */
123 static StyleHint customStyleHint(const QString &element, const QWidget *widget);
124 static ControlElement customControlElement(const QString &element, const QWidget *widget);
125 static SubElement customSubElement(const QString &element, const QWidget *widget);
126
127protected:
128
129 /**
130 * Runtime element extension, allows inheriting styles to add support custom elements
131 * merges supporting inherit chains
132 * Supposed to be called e.g. in your constructor.
133 *
134 * NOTICE: in order to have this work, your style must provide
135 * an "X-KDE-CustomElements" classinfo, i.e.
136 * class MyStyle : public KStyle
137 * {
138 * Q_OBJECT
139 * Q_CLASSINFO ("X-KDE-CustomElements", "true")
140 *
141 * public:
142 * .....
143 * }
144 *
145 * @param element The style element, represented as string.
146 * Suggested naming convention: appname.(2-char-element-type)_element
147 * where the 2-char-element-type is of {SH, CE, SE}
148 * widgets in kdelibs don't have to pass the appname
149 * examples: "CE_CapacityBar", "amarok.CE_Analyzer"
150 *
151 * Important notes:
152 * 1) If your string lacks the matching "SH_", "CE_" or "SE_" token the element
153 * request will be ignored (return is 0)
154 * 2) To keep UI coherency, don't support any nonsense in your style, but convince app developers
155 * to use standard elements - if available
156 */
157 StyleHint newStyleHint(const QString &element);
158 ControlElement newControlElement(const QString &element);
159 SubElement newSubElement(const QString &element);
160
161 /** @name Helper Methods
162 * These are methods helping with QRect handling, for example.
163 */
164//@{
165 /**
166 Draws inside the rectangle using a thinkness 0 pen. This is what drawRect in Qt3 used to do.
167 */
168 void drawInsideRect(QPainter* p, const QRect& r) const;
169
170 /**
171 Returns a w x h QRect center inside the 'in' rectangle
172 */
173 QRect centerRect(const QRect &in, int w, int h) const;
174
175 /**
176 Return a size-dimension QRect centered inside the 'in' rectangle
177 */
178 QRect centerRect(const QRect &in, const QSize &size) const;
179//@}
180
181/**
182 * \defgroup OptionGroup KStyle option representation
183 * Things related to the representation of options passed when drawing things.
184 */
185//@{
186 /**
187 * @brief A representation for colors for use as a widget layout property.
188 *
189 * This marshals to and from integers.
190 */
191 class KDEUI_EXPORT ColorMode //krazy:exclude=dpointer (lightweight helper)
192 {
193 public:
194 /**
195 KStyle understands two kinds of colors:
196 * -# Palette entries. This means the item must be painted with a specific
197 * color role from the palette.
198 * -# Auto-selected black or white, dependent on the brightness of a certain
199 * color role from the palette.
200 */
201 enum Mode
202 {
203 PaletteEntryMode,
204 BWAutoContrastMode = 0x8000000
205 };
206 private:
207 Mode mode;
208 QPalette::ColorRole role;
209 public:
210
211 /// Constructor, using a the given palette role @p _role
212 /// and a default mode.
213 ColorMode(QPalette::ColorRole _role);
214
215 /// Constructor with explicit color mode and palette roles.
216 ColorMode(Mode _mode, QPalette::ColorRole _role);
217
218 /// Represent as an int to store as a property
219 operator int() const;
220
221 /// Decode from an int.
222 ColorMode(int encoded);
223
224 /// Return the color corresponding to our role from the palette,
225 /// automatically compensating for the contrast mode.
226 QColor color(const QPalette& palette);
227 };
228
229
230 /**
231 Base for our own option classes.
232 The idea here is that Option is the main base, and all the
233 public bases inherit off it indirectly using OptionBase,
234 which helps implement the default handling
235
236 When implementing the actual types, just implement the default ctor,
237 filling in defaults, and you're set.
238 */
239 struct KDEUI_EXPORT Option
240 {
241 virtual ~Option() {} //So dynamic_cast works, and g++ shuts up
242 };
243
244 /**
245 Intermediatary base that helps implement subtypes of Option
246 that properly handle defaults
247
248 EventualSubtype --- the type of option which will be implemented
249 by inheritting of this class
250
251 BaseType --- the type of option from which this should inherit
252 */
253 template<typename EventualSubtype, typename BaseType>
254 struct KDEUI_EXPORT OptionBase: public BaseType
255 {
256 /** Default value for this option. Uses the default constructor
257 of EventualSubtype to create the option.
258 */
259 static EventualSubtype* defaultOption()
260 {
261 static EventualSubtype* theDefault = 0; //### function static, not very nice,
262 //but avoids need for explicit instantiation.
263
264 if (!theDefault)
265 theDefault = new EventualSubtype;
266
267 return theDefault;
268 }
269 };
270
271 /**
272 The extractOption method casts the passed in option object, and returns
273 it, if available, or the defaults for the given type. When implementing
274 drawing of things with associated options, just use this to extract
275 the parameter.
276 */
277 template<typename T>
278 static T extractOption(Option* option);
279
280 /**
281 Option representing the color of the thing to draw. Used for arrows, and for text
282 (the latter actually uses TextOption)
283 */
284 struct KDEUI_EXPORT ColorOption: public OptionBase<ColorOption, Option>
285 {
286 /** Color to use for the drawing. Public, modifiable. */
287 ColorMode color;
288
289 ColorOption(): color(QPalette::ButtonText)
290 {}
291 };
292
293 /**
294 Option for drawing icons: represents whether the icon should be active or not.
295 The implementation is responsible for all other flags
296 */
297 struct KDEUI_EXPORT IconOption: public OptionBase<IconOption, Option>
298 {
299 bool active; ///< Is the icon active?
300 QIcon icon; ///< Icon drawn by this option
301 QSize size;
302
303 IconOption(): active(false)
304 {}
305 };
306
307 /**
308 * Option for drawing double scrollbar buttons, indicating whether
309 * a button should be drawn active or not.
310 * @sa ScrollBar::Primitive
311 */
312 struct KDEUI_EXPORT DoubleButtonOption: public OptionBase<DoubleButtonOption, Option>
313 {
314 /**
315 * List of active button possibilities.
316 */
317 enum ActiveButton
318 {
319 None, ///< No button is active
320 Top, ///< Vertical scrollbar: The upper button is active
321 Left, ///< Horizontal scrollbar: The left button is active
322 Right, ///< Horizontal scrollbar: The right button is active
323 Bottom ///< Vertical scrollbar: The lower button is active
324 };
325
326 /**
327 Whether any of the two buttons is active; and if yes, which
328 one.
329 */
330 ActiveButton activeButton;
331
332 DoubleButtonOption(): activeButton(None)
333 {}
334
335 /**
336 * Convenience constructor.
337 *
338 * @param ab initializes the active button property
339 */
340 DoubleButtonOption(ActiveButton ab): activeButton(ab)
341 {}
342 };
343
344 /**
345 * Option for drawing WT_Window titlebar buttons, indicating whether
346 * the button is pressed, and containing the window icon
347 * @sa Window
348 */
349 struct KDEUI_EXPORT TitleButtonOption: public OptionBase<TitleButtonOption, Option>
350 {
351 bool active; ///< whether the button is pressed
352 QIcon icon; ///< window Icon
353// /// whether the button is hovered, this doesn't work at the moment (not even in any Qt style)...
354// bool hover;
355
356 TitleButtonOption(): active(false)/*, hover(false)*/
357 {}
358
359 /**
360 * Convenience constructor.
361 *
362 * @param act initializes the active button property
363 */
364 TitleButtonOption(bool act): active(act)
365 {}
366 };
367
368 ///Option representing text drawing info. For Generic::Text.
369 struct KDEUI_EXPORT TextOption: public OptionBase<TextOption, ColorOption>
370 {
371 Qt::Alignment hAlign; ///< The horizontal alignment, default is Qt::AlignLeft
372 QString text; ///< The text to draw
373
374 TextOption();
375
376 /**
377 * Convenience constructor.
378 *
379 * @param _text initializes the text string property
380 */
381 TextOption(const QString& _text);
382
383 /**
384 * Called by the constructor to set the default value of @c hAlign
385 */
386 void init();
387 };
388//@}
389
390/**
391 * \defgroup WidgetGroup KStyle widget representation
392 * Things related to the representation of widgets.
393 */
394//@{
395 /**
396 This enum is used to represent KStyle's concept of
397 a widget, and to associate drawing requests and metrics
398 with it. The generic value is used for primitives and metrics
399 that are common between many widgets
400 */
401 enum WidgetType
402 {
403 WT_Generic, ///< @sa Generic
404 WT_PushButton, ///< @sa PushButton
405 WT_Splitter, ///< @sa Splitter
406 WT_CheckBox, ///< @sa CheckBox
407 WT_RadioButton, ///< @sa RadioButton
408 WT_DockWidget, ///< @sa DockWidget
409 WT_ProgressBar, ///< @sa ProgressBar
410 WT_MenuBar, ///< @sa MenuBar
411 WT_MenuBarItem, ///< @sa MenuBarItem
412 WT_Menu, ///< @sa Menu
413 WT_MenuItem, ///< @sa MenuItem
414 WT_ScrollBar, ///< @sa ScrollBar
415 WT_TabBar, ///< @sa TabBar
416 WT_TabWidget, ///< @sa TabWidget
417 WT_Slider, ///< @sa Slider
418 WT_Tree, ///< @sa Tree
419 WT_SpinBox, ///< @sa SpinBox
420 WT_ComboBox, ///< @sa ComboBox
421 WT_Header, ///< @sa Header
422 WT_LineEdit, ///< @sa LineEdit
423 WT_GroupBox, ///< @sa GroupBox
424 WT_StatusBar, ///< @sa StatusBar
425 WT_ToolBar, ///< @sa ToolBar
426 WT_ToolButton, ///< @sa ToolButton
427 WT_ToolBoxTab, ///< @sa ToolBoxTab
428 WT_Window, ///< @sa Window
429 WT_Limit = 0xFFFF ///< For enum extensibility
430 };
431
432
433 /**
434 These constants describe how to access various fields of a margin property.
435 For example, to set an additional top margin of 2 pixels, use
436 * \code
437 * setWidgetLayoutProp(WT_SomeWidget, SomeWidget::Margin + Top, 2);
438 * \endcode
439 */
440 enum MarginOffsets
441 {
442 MainMargin, /**< The main margin is applied equally on each side.
443 * In the example above, 'SomeWidget::Margin+MainMargin' is
444 * the same as 'SomeWidget::Margin'. */
445 Top, ///< Apply an additional top margin.
446 Bot, ///< Apply an additional bottom margin.
447 Left, ///< Apply an additional left margin.
448 Right, ///< Apply an additional right margin.
449 MarginInc /**< Used to reserve space in an enum for the Top, Bot,
450 * Left, Right margins. */
451 };
452
453
454 /**
455 * Basic primitive drawing operations. Are intended to be used in every
456 * WidgetType combination.
457 */
458 struct Generic
459 {
460 /**
461 * Layout properties. These can be set with setWidgetLayoutProp()
462 * Generic LayoutProps contain a few properties which are not
463 * directly related to a specific widget type.
464 */
465 enum LayoutProp
466 {
467 DefaultFrameWidth, ///< The FrameWidth used by LineEdit, etc..., default is \b 2 [sets QStyle::PM_DefaultFrameWidth]
468 DefaultLayoutSpacing, ///< The spacing used by layouts, unless the style implements layoutSpacingImplementation(), default is \b 6 [sets QStyle::PM_DefaultLayoutSpacing]
469 DefaultLayoutMargin ///< The margin used by layouts, default is \b 9 [sets QStyle::PM_DefaultChildMargin and QStyle::PM_DefaultTopLevelMargin]
470 };
471
472 /**
473 * Primitive drawing operations.
474 * @note The arrows are centering primitives, which means they draw in
475 * the center of the specified rectangle.
476 */
477 enum Primitive
478 {
479 Text = 0xFFFF, ///< Passes in TextOption
480 Icon, ///< Passes in IconOption
481 FocusIndicator, ///< Indication that this widget has focus
482 Frame, /**< Frame around widget
483 * @note QFrame derived widgets are painted using
484 * WT_Generic widget type and this Generic::Frame primitive. */
485 ArrowUp, ///< Up arrow (pointing up)
486 ArrowDown, ///< Down arrow
487 ArrowRight, ///< Right arrow
488 ArrowLeft ///< Left arrow
489 };
490 };
491
492 /**
493 * @brief Describes widgets like QPushButton.
494 *
495 * @sa WT_PushButton
496 */
497 struct PushButton
498 {
499 /**
500 * The layout of a PushButton is structured as follows:
501 * -# Between the very outside and the bevel is the default indicator
502 * area, controlled by the @c PushButton::DefaultIndicatorMargin .
503 * -# From the bevel, the content and focus rect margins are measured.
504 * Only the content margin is used to size the content area.
505 * -# Inside the content area, @c PushButton::MenuIndicatorSize is allocated to the down
506 * arrow if there is a popup menu.
507 * -# @c PushButton::TextToIconSpace is allocated between icon and text if both exist
508 *
509 * @sa setWidgetLayoutProp()
510 */
511 enum LayoutProp
512 {
513 ContentsMargin, ///< (\b 5) space between the bevel and the button contents
514 FocusMargin = ContentsMargin + MarginInc, ///< (\b 3) Used to calculate the area of the focus indicator. Measured from the bevel.
515 DefaultIndicatorMargin = FocusMargin + MarginInc, ///< (\b 0 ?) Default indicator between the very outside and the bevel. KStyle may reserve this for auto-default buttons, too, for consistency's sake. [the MainMargin sets QStyle::PM_ButtonDefaultIndicator]
516 PressedShiftHorizontal = DefaultIndicatorMargin + MarginInc, ///< (\b 2) horizontal contents shift for pressed buttons [sets QStyle::PM_ButtonShiftHorizontal]
517 PressedShiftVertical, ///< (\b 2) vertical contents shift for pressed buttons [sets QStyle::PM_ButtonShiftVertical]
518 MenuIndicatorSize, ///< (\b 8) Space inside the content area, which is allocated to the down arrow if there is a popup menu [sets QStyle::PM_MenuButtonIndicator, except for toolbuttons]
519 TextToIconSpace ///< (\b 6) space between the icon and the text if both exist
520 };
521
522 /**
523 * Relevant Generic elements:
524 * - @c Generic::Text the button's text
525 * - @c Generic::FocusIndicator indicating that the button has keyboard focus
526 * - @c Generic::ArrowDown indicating that the button has a popup menu associated to it
527 *
528 * [KStyle implements @c QStyle::CE_PushButtonBevel to compose the primitives]
529 *
530 * @sa drawKStylePrimitive()
531 */
532 enum Primitive
533 {
534 Panel, /**< the pushbutton panel
535 * [implements QStyle::PE_PanelButtonCommand] */
536 DefaultButtonFrame /**< frame indicating a default button, painted before
537 * the button Panel
538 * [implements QStyle::PE_FrameDefaultButton] */
539 };
540 };
541
542 /**
543 * @brief Describes widgets like QSplitter.
544 *
545 * @sa WT_Splitter
546 */
547 struct Splitter
548 {
549 /**
550 * @sa setWidgetLayoutProp()
551 */
552 enum LayoutProp
553 {
554 Width ///< (\b 6) size of the splitter handle [sets QStyle::PM_SplitterWidth]
555 };
556
557 /**
558 * [the Handles implement QStyle::CE_Splitter]
559 *
560 * @sa drawKStylePrimitive()
561 */
562 enum Primitive
563 {
564 HandleHor, /**< The splitter handle, horizontal. Flags: @c State_Enabled&&State_MouseOver for mouseOver */
565 HandleVert /**< The splitter handle, vertical. Flags: @c State_Enabled&&State_MouseOver for mouseOver */
566 };
567 };
568
569 /**
570 * @brief Describes widgets like QCheckBox.
571 *
572 * @sa WT_CheckBox
573 */
574 struct CheckBox
575 {
576 /**
577 * @sa setWidgetLayoutProp()
578 */
579 enum LayoutProp
580 {
581 Size, ///< (\b 16) size of the checkbox [sets PM_IndicatorWidth, PM_IndicatorHeight]
582 BoxTextSpace, ///< (\b 6) space to leave between checkbox and text (and icon between them in case there is one)
583 NoLabelFocusMargin, /**< (\b 1) rectangle to apply to the checkbox rectangle
584 * to get where to paint the focus rectangle in
585 * case of a labelless checkbox */
586 FocusMargin = NoLabelFocusMargin + MarginInc ///< (\b 0) margin around the checkbox contents reserved for the focus rect @todo have a look, it isn't as nice as plastique etc.
587 };
588
589 /**
590 * Relevant elements:
591 * - @c Generic::Text the CheckBox label alongside the CheckBox
592 * - @c Generic::FocusIndicator the focus indicator. Usually drawn around the
593 * text label. If no label exists, it is drawn around the CheckBox.
594 *
595 * [check primitives implement QStyle::PE_IndicatorCheckBox]
596 * [KStyle implements QStyle::CE_CheckBox to compose a CheckBox using
597 * the mentioned primitives]
598 *
599 * @sa drawKStylePrimitive()
600 */
601 enum Primitive
602 {
603 CheckOn, ///< checkbox which is checked
604 CheckOff, ///< checkbox which is not checked
605 CheckTriState ///< tristate checkbox (neither off nor on)
606 };
607 };
608
609 /**
610 * @brief Describes widgets like QRadioButton.
611 */
612 struct RadioButton
613 {
614 /**
615 * @sa setWidgetLayoutProp()
616 */
617 enum LayoutProp
618 {
619 Size, /**< [sets QStyle::PM_ExclusiveIndicatorWidth,
620 * QStyle::PM_ExclusiveIndicatorHeight]
621 * @sa CheckBox::Size */
622 BoxTextSpace, ///< @sa CheckBox::BoxTextSpace
623 FocusMargin ///< @sa CheckBox::FocusMargin
624 };
625
626 /**
627 * Relevant Generic elements:
628 * - @c Generic::Text the RadioButton label alongside the RadioButton
629 * - @c Generic::FocusIndicator the keyboard focus indicator
630 *
631 * [check primitives implement QStyle::PE_IndicatorRadioButton]
632 * [KStyle implements QStyle::CE_RadioButton to compose a RadioButton using
633 * the mentioned primitives]
634 *
635 * @sa drawKStylePrimitive()
636 */
637 enum Primitive
638 {
639 RadioOn, ///< radiobutton which is checked
640 RadioOff ///< radiobutton which is not checked
641 };
642 };
643
644
645 /**
646 * @brief Describes the title of a dock widget.
647 *
648 * @sa WT_DockWidget
649 */
650 struct DockWidget
651 {
652 /**
653 * @sa setWidgetLayoutProp()
654 */
655 enum LayoutProp
656 {
657 TitleTextColor, ///< (\b ColorMode(QPalette::HighlightedText)) color mode of the title text
658 TitleMargin, ///< (\b 2) Margin around title contents: Note that the symmetric margin (MainMargin) is used to size the title! Additional the Left and Right margins can be used to position the title text a little, though (to set Top and Bottom is not advisable). [the MainMargin sets QStyle::PM_DockWidgetTitleMargin]
659 FrameWidth = TitleMargin + MarginInc, ///< (\b 3) width of the frame around floating dockwidgets [sets QStyle::PM_DockWidgetFrameWidth]
660 SeparatorExtent ///< (\b 6) width of the area which separates the (docked) dock window from the window contents [sets QStyle::PM_DockWidgetSeparatorExtent]
661 };
662
663 /**
664 * Relevant Generic elements:
665 * - @c Generic::Text the title text
666 * - @c Generic::Frame the frame around floating dockwidgets
667 *
668 * [KStyle implements @c QStyle::CE_DockWidgetTitle to split it into KStyle primitives]
669 *
670 * @sa drawKStylePrimitive()
671 */
672 enum Primitive
673 {
674 TitlePanel, ///< the panel/background of the title bar
675 SeparatorHandle ///< the splitter between dockwidgets
676 };
677 };
678
679 /**
680 * @brief Describes widgets like QProgressBar.
681 *
682 * @todo support for Qt > 4.1 orientation, bottomToTop, invertedAppearance properties!
683 *
684 * @sa WT_ProgressBar
685 */
686 struct ProgressBar
687 {
688 /**
689 * @sa setWidgetLayoutProp()
690 */
691 enum LayoutProp
692 {
693 GrooveMargin, ///< (\b 2) Margin to allocate for the groove. Content area will be inside of it.
694 SideText = GrooveMargin + MarginInc, ///< (\b false) set this to true to have the text positionned to the side
695 SideTextSpace, ///< (\b 3) Extra space besides that needed for text to allocate to side indicator (on both sides).
696 Precision, ///< (\b 1) The indicator size will always be a multiple of this (modulo busy indicator size clamping). [sets QStyle::PM_ProgressBarChunkWidth]
697 BusyIndicatorSize, ///< (\b 10) The busy indicator size, in percent of area size.
698 MaxBusyIndicatorSize ///< (\b 10000) size limit on the busy indicator size
699 };
700
701 /**
702 * Relevant Generic elements:
703 * - @c Generic::Text the progress label
704 *
705 * @sa drawKStylePrimitive()
706 */
707 enum Primitive
708 {
709 Groove, /**< the progressbar groove, drawn before the progress
710 * Indicator [implements QStyle::CE_ProgressBarGroove] */
711 Indicator, ///< The actual bar indicating the progress...
712 BusyIndicator /**< Used to indicate business, for example when
713 * no progress is known (minimum and maximum values
714 * both set to 0) */
715 };
716 };
717
718
719 /**
720 * @brief Describes widgets like QMenuBar.
721 *
722 * @sa WT_MenuBar
723 */
724 struct MenuBar
725 {
726 /**
727 * @sa setWidgetLayoutProp()
728 */
729 enum LayoutProp
730 {
731 Margin, /**< (MainMargin \b 2, Left \b 4, Right \b 4)
732 * Margin rectangle for the contents. */
733 ItemSpacing = Margin + MarginInc ///< (\b 14) Space between items [sets QStyle::PM_MenuBarItemSpacing]
734 };
735
736 /**
737 * @sa drawKStylePrimitive()
738 */
739 enum Property
740 {
741 EmptyArea /**< Empty area of a menu bar, e.g. background
742 * color. Maybe the place to fake toolbar separators (?)
743 * [implements QStyle::CE_MenuBarEmptyArea] */
744 };
745 };
746
747
748 /**
749 * @brief Describes MenuBar items.
750 *
751 * Relevant elements:
752 * - @c Generic::Text text appearing as menubar entry
753 */
754 struct MenuBarItem
755 {
756 /**
757 * @sa setWidgetLayoutProp()
758 */
759 enum LayoutProp
760 {
761 Margin, /**< (\b 1) Margin rectangle to allocate for any
762 * bevel, etc. (Text will be drawn with
763 * the inside rect). */
764 Dummy = Margin + MarginInc //Paranoia about underlying type
765 };
766
767 /**
768 * @sa drawKStylePrimitive()
769 */
770 enum Primitive
771 {
772 Panel ///< The panel/background of a menubar item. Interesting flags: State_Selected && State_HasFocus for mouseOver, State_Sunken for pressed state.
773 };
774 };
775
776 /**
777 * @brief Describes a menu.
778 *
779 * @sa WT_Menu
780 */
781 struct Menu
782 {
783 /**
784 * @sa setWidgetLayoutProp()
785 */
786 enum LayoutProp
787 {
788 FrameWidth, ///< (\b 1) The width of the frame, note that this does not affect the layout.
789 Margin, ///< (\b 3) The margin of the menu. @todo have a look at comments at PM_MenuHMargin...
790 ScrollerHeight = Margin + MarginInc, ///< (\b 10) Height of a menu scroller. [sets QStyle::PM_MenuScrollerHeight]
791 TearOffHeight ///< (\b 10) Height of the TearOff area. [sets QStyle::PM_MenuTearoffHeight]
792 };
793
794 /**
795 * Relevant Generic elements:
796 * - @c Generic::Frame frame around the menu panel
797 *
798 * @sa drawKStylePrimitive()
799 */
800 enum Primitive
801 {
802 Background, ///< Menu and MenuItem background
803 TearOff, /**< paints the area where a menu can be teared off
804 * [implements QStyle::CE_MenuTearoff] */
805 Scroller /**< scrolling areas in a QMenu
806 * [implements QStyle::CE_MenuScroller] */
807 };
808 };
809
810 /**
811 * @brief Describes an item in a menu.
812 *
813 * MenuItems are layouted like this:
814 * -# There are two MenuItem modes, toggled by @c LP_MenuItem_CheckAlongsideIcon.
815 * Horizontal layout inside the items is as follow:
816 * - @c LP_MenuItem_CheckAlongsideIcon disabled:
817 * |icon/checkmark|IconSpace|text|AccelSpace|accel|ArrowSpace|ArrowWidth|
818 * - @c LP_MenuItem_CheckAlongsideIcon enabled:
819 * |checkmark|CheckSpace|icon|IconSpace|text|AccelSpace|accel|ArrowSpace|ArrowWidth|
820 * -# The icon/checkmark column is at least @c LP_MenuItem_CheckWidth wide in all cases.
821 * -# Then Margin is applied outside that.
822 *
823 * @note For the subprimitives the passed rect is their own.
824 * @note Background is erased with WT_Menu/Menu::Background.
825 *
826 * @sa WT_MenuItem
827 */
828 struct MenuItem
829 {
830 /**
831 * @sa setWidgetLayoutProp()
832 */
833 enum LayoutProp
834 {
835 Margin, ///< (\b 2) margin for each entry
836 CheckAlongsideIcon = Margin + MarginInc,
837 /**< (\b 0) Set to non-zero to have checkmarks painted
838 * separate from icons. */
839 CheckWidth, /**< (\b 12) size of the checkmark column
840 * (CheckAlongsideButton enabled). */
841 CheckSpace, /**< (\b 3) Space between the checkmark column and the icon
842 * column (CheckAlongsideButton enabled).*/
843 IconWidth, ///< (\b 12) minimum size of the icon column
844 IconSpace, ///< (\b 3) space between the icon column and text column
845 AccelSpace, ///< (\b 0 ?) space between text and keyboard accelerator label
846 ArrowSpace, ///< (\b 3) space between the text column and arrow column (indicating sub menus)
847 ArrowWidth, ///< (\b 11) space to reserve for the menu arrow column
848 SeparatorHeight,///< (\b 0) heigh of separator
849 MinHeight, ///< (\b 16) limit on the size of item content
850 ActiveTextColor,///< (\b ColorMode(QPalette::HighlightedText)) color for active text and arrow
851 TextColor, ///< (\b ColorMode(QPalette::Text)) color for inactive text and arrow
852 DisabledTextColor, ///< (\b ColorMode(QPalette::Text)) color for inactive + disabled text and arrow
853 ActiveDisabledTextColor ///< (\b ColorMode(QPalette::Text)) color for active + disabled text and arrow
854 };
855
856 /**
857 * Relevant Generic elements:
858 * - @c Generic::Text the text of the menu item
859 * - @c Generic::ArrowLeft @c Generic::ArrowRight arrows indicating a sub-menu
860 *
861 * @sa drawKStylePrimitive()
862 */
863 enum Primitive
864 {
865 CheckColumn, ///< Background of the checkmark/icon column
866 CheckOn, ///< The checkmark - checked
867 CheckOff, ///< The checkmark - not checked
868 RadioOn, ///< The checkmark of exclusive actions - selected
869 RadioOff, ///< The checkmark of exclusive actions - not selected
870 CheckIcon, ///< When @c CheckAlongsideIcon is disabled and item is checked: checkmark Indicator painted below the icon
871 Separator, //A separator item.
872 ItemIndicator //Shows the active item
873 };
874 };
875
876
877 /**
878 * @brief Describes widgets like QScrollBar.
879 *
880 * @sa WT_ScrollBar
881 */
882 struct ScrollBar
883 {
884 /**
885 * @note Dimensions of LayoutProperties are generally specified with respect
886 * to the vertical scrollbar. Of course, for horizontal ones they're flipped.
887 *
888 * @sa setWidgetLayoutProp()
889 */
890 enum LayoutProp
891 {
892 DoubleTopButton, ///< (\b 0) set to non-zero to have two buttons on top
893 DoubleBotButton, ///< (\b 1) set to non-zero to have two buttons on bottom
894 SingleButtonHeight, ///< (\b 16) height of a single button
895 DoubleButtonHeight, ///< (\b 32) height of a double button
896 BarWidth, ///< (\b 16) width of a scrollbar [sets QStyle::PM_ScrollBarExtent]
897 MinimumSliderHeight,/**< (\b 0 ?) the minimum slider height
898 * @note If the scrollbar is too small to accommodate
899 * this, this will not be enforced. */
900 ArrowColor, /**< (\b ColorMode(ColorMode::BWAutoContrastMode, QPalette::Button)) color mode of a button arrow
901 * @sa ColorMode */
902 ActiveArrowColor /**< (\b ColorMode(ColorMode::BWAutoContrastMode, QPalette::ButtonText)) color mode of a pressed button arrow (?) */
903 };
904
905 /**
906 * Relevant Generic elements:
907 * - The @c Generic arrows
908 *
909 * [Groove Areas implement QStyle::CE_ScrollBarAddPage and QStyle::CE_ScrollBarSubPage]
910 * [Sliders implement QStyle::CE_ScrollBarSlider]
911 *
912 * @sa drawKStylePrimitive()
913 */
914 enum Primitive
915 {
916 SingleButtonVert, ///< used to draw a 1-button bevel, vertical
917 SingleButtonHor, ///< used to draw a 1-button bevel, horizontal
918 DoubleButtonVert, /**< Used to draw a 2-button bevel, vertical.
919 * A DoubleButtonOption is passed to say which
920 * button is pressed. */
921 DoubleButtonHor, /** @see DoubleButtonVert */
922 GrooveAreaVertBottom, ///< scrollbar groove area, vertical. An interesting flag is @c State_Sunken for pressed state
923 GrooveAreaHorRight, ///< scrollbar groove area, horizontal. Flags: @c State_Sunken for pressed state
924 GrooveAreaVertTop, ///< scrollbar groove area, vertical. An interesting flag is @c State_Sunken for pressed state
925 GrooveAreaHorLeft, ///< scrollbar groove area, horizontal. Flags: @c State_Sunken for pressed state
926 SliderVert, ///< scrollbar slider, vertical. Flags: @c State_On&&State_Sunken for pressed state
927 SliderHor ///< scrollbar slider, horizontal. Flags: @c State_On&&State_Sunken for pressed state
928 };
929 };
930
931 /**
932 * @brief Describes a tab bar.
933 *
934 * @sa WT_TabBar
935 */
936 struct TabBar
937 {
938 /**
939 * Each tab is basically built hiearchically out of the following areas:
940 * -# Content area, one of the following layouts:
941 * - Icon <- TextToIconSpace -> Text
942 * - Icon
943 * - Text
944 * -# Bevel: @c LP_TabBar_TabContentsMargin outside of the content area
945 * -# Focus indicator is placed @c LP_TabBar_TabFocusMargin inside the bevel
946 *
947 * @note The side tabs just have those rotated, bottom tabs have the margins reversed.
948 *
949 * @sa setWidgetLayoutProp()
950 */
951 enum LayoutProp
952 {
953 TabContentsMargin, ///< (\b 6) margin around the tab contents, used to size the tab
954 TabFocusMargin = TabContentsMargin + MarginInc,
955 /**< (\b 3) where the tab focus rect is placed, measured from the
956 * tab sides (?) */
957 TabTextToIconSpace = TabFocusMargin + MarginInc,
958 /**< (\b 0 ?) space between icon and text if the tab contains both */
959 TabOverlap, /**< (\b 0) Amount of pixels tabs should overlap. The
960 * paint rectangle will be extended to the left for
961 * all tabs which are not at the beginning (accordingly
962 * extended to the right in RightToLeft mode; extended
963 * to the top for East/West tabs). */
964 BaseHeight, ///< (\b 2) the height of the tabBar's base, usually the frame width [sets QStyle::PM_TabBarBaseHeight] @todo is this used for things like I intended TabWidget::ContentsMargin for?
965 BaseOverlap, ///< (\b 2) the number of pixels the tabs overlap with the base (i.e. tabWidget frame) [sets QStyle::PM_TabBarBaseOverlap]
966 ScrollButtonWidth ///< (\b 10) buttons which are shown when there's not enough space for tabs (A ToolButton is used for this) [sets QStyle::PM_TabBarScrollButtonWidth]
967 };
968
969 /**
970 * Relevant elements:
971 * - @c Generic::Text for the TabBar labels
972 * - @c Generic::FocusIndicator for focused tabs
973 * - @c Generic::Icon for icons associated to tabs
974 * - @c ToolButton::Panel paints the scroll button (when the tabs don't fit the tab bar)
975 */
976 enum Primitive
977 {
978 EastText, /**< Special rotated text for east tabs. */
979 WestText, ///< @see EastText
980 NorthTab, ///< @todo say something about triangular shape etc.
981 EastTab,
982 WestTab,
983 SouthTab,
984 BaseFrame, ///< [implements QStyle::PE_FrameTabBarBase]
985 IndicatorTear /**< painted in the left edge of a tabbar when the left
986 * tab is scrolled out
987 * [implements PE_IndicatorTabTear]
988 * @todo KStyle default implementation...? */
989 };
990 };
991
992 /**
993 * @brief Describes a tab widget (frame).
994 *
995 * Relevant elements:
996 * - @c Generic::Frame for the frame/panel of the TabWidget
997 *
998 * @sa WT_TabWidget
999 */
1000 struct TabWidget
1001 {
1002 /**
1003 * @sa setWidgetLayoutProp()
1004 */
1005 enum LayoutProp
1006 {
1007 ContentsMargin, /**< (\b 2) Width of the frame around a tab widget.
1008 * Margins for a tabwidget with tab position 'North' are
1009 * specified as expected. For other positions, the
1010 * sides are rotated accordingly, e.g. the left margin
1011 * of a 'West' tabwidget is the same as top for a 'North'
1012 * tabwidget.
1013 * [sets QStyle::SE_TabWidgetTabContents] */
1014 DummyProp = ContentsMargin+MarginInc
1015 };
1016 };
1017
1018 /**
1019 * @brief Describes a slider, like QSlider.
1020 *
1021 * @sa WT_Slider
1022 */
1023 struct Slider
1024 {
1025
1026 /**
1027 * @note The description applies to horizontal sliders.
1028 *
1029 * @sa setWidgetLayoutProp()
1030 */
1031 enum LayoutProp
1032 {
1033 HandleThickness, ///< (\b 20) The height of a slider handle
1034 HandleLength ///< (\b 16) The width of a slider handle [sets QStyle::PM_SliderLength]
1035 };
1036
1037 /**
1038 * Relevant Generic elements:
1039 * - @c Generic::FocusIndicator indicating keyboard focus
1040 *
1041 * @sa drawKStylePrimitive()
1042 */
1043 enum Primitive
1044 {
1045 HandleVert, ///< A vertical slider handle
1046 HandleHor, ///< A horizontal slider handle
1047 GrooveVert, ///< A vertical slider groove
1048 GrooveHor ///< A horizontal slider groove
1049 };
1050 };
1051
1052
1053 /**
1054 * @brief Describes an expandable tree, e.g. in a QListView.
1055 */
1056 struct Tree
1057 {
1058 /**
1059 * For trees, all the control we provide here is to provide a cap on the size
1060 * of the expander widget, which is always square. There are 4 primitives to
1061 * implement: open and closed expander, and horizontal and vertical lines.
1062 * If you're using dots, it's suggested you use global brush alignment to
1063 * keep it all nicely aligned.
1064 *
1065 * @sa setWidgetLayoutProp()
1066 */
1067 enum LayoutProp
1068 {
1069 MaxExpanderSize /**< (\b 9) @note If you set MaxExpanderSize to a value less
1070 * than 9, designer will look funny. The value should also
1071 * be odd, or value - 1 will be used.
1072 */
1073 };
1074
1075 /**
1076 * @sa drawKStylePrimitive()
1077 */
1078 enum Primitive
1079 {
1080 ExpanderClosed, ///< A closed tree expander, usually drawn as '+'. KStyle has a default implementation (Windows-like look).
1081 ExpanderOpen, ///< An opened tree expander, usually drawn as '-' KStyle has a default implementation.
1082 HorizontalBranch, /**< A horizontal tree line.
1083 * @note If you're using dots, it's suggested you
1084 * use global brush alignment to keep it all nicely
1085 * aligned. */
1086 VerticalBranch /**< @see HorizontalBranch */
1087 };
1088 };
1089
1090 /**
1091 * @brief Describes a widget like QSpinBox.
1092 */
1093 struct SpinBox
1094 {
1095 /**
1096 * @note The description applies to LTR (left to right) mode.
1097 *
1098 * -# @c FrameWidth and @c ButtonWidth are used to size
1099 * the contents area. To the EditField, @c FrameWidth
1100 * is added at the left, top, bottom while @c ButtonWidth is added
1101 * at the right.
1102 * -# The @c ButtonMargin is measured from the right side of the
1103 * EditField and the outside. Inside it, the up and down buttons are aligned with
1104 * spacing @c ButtonSpacing.
1105 * -# To make sure that both buttons are always of the same height, enable
1106 * @c SymmetricButtons.
1107 *
1108 * @sa setWidgetLayoutProp()
1109 */
1110 enum LayoutProp
1111 {
1112 FrameWidth, /**< (\b 1) Space reserved left, top, bottom of the SpinBox
1113 * [sets QStyle::PM_SpinBoxFrameWidth] */
1114 ButtonWidth, ///< (\b 16) Space reserved for the widget, right of the EditField
1115 ButtonMargin, /**< (MainMargin \b 0, Right Top Bot \b 1)
1116 * Where the up/down buttons are located, measured
1117 * from right of the edit field and the top/right/bottom
1118 * widget edges. */
1119 ButtonSpacing = ButtonMargin + MarginInc, ///< (\b 1) spacing between up/down buttons
1120 SymmetricButtons, /**< (\b 0) Set to non-zero to make sure both buttons are
1121 * always of the same height. To achieve this, the
1122 * spacing of the buttons will be reduced by 1 if
1123 * necessary to avoid rounding problems. Needs to be
1124 * handled in your drawing code. */
1125 SupportFrameless, /**< (\b 0) Set to non-zero to indicate that you are able to
1126 * handle frame-less SpinBoxes. For a SpinBox with no
1127 * frame, FrameWidth and Top/Bottom/Right ButtonMargin
1128 * is ignored. */
1129 ContentsMargin
1130 /**< (\b 5) space between the bevel and the spinbox contents
1131 */
1132 };
1133
1134 /**
1135 * Relevant Generic elements:
1136 * - @c Generic::Frame for the area around text input field and buttons
1137 * - @c Generic::ArrowUp @c Generic::ArrowDown drawn on the buttons
1138 */
1139 enum Primitive
1140 {
1141 EditField, /**< the text contents area, painted after Generic::Frame
1142 * @note This is respected only if the combobox is not
1143 * editable. */
1144 UpButton, /**< Panel of the spinbox button which increases the value */
1145 DownButton, /**< Panel of the spinbox button which decreases the value */
1146 ButtonArea, /**< Can be used in addition or instead of
1147 * @c KPE_SpinBox_UpButton and @c KPE_SpinBox_DownButton.
1148 * The button area is painted before them. */
1149 PlusSymbol, /**< Plus symbol painted on top of the up button,
1150 * centering primitive */
1151 MinusSymbol /**< Minus symbol painted on top of the down button,
1152 * centering primitive */
1153 };
1154 };
1155
1156 /**
1157 * @brief Describes a widget like QComboBox.
1158 */
1159 struct ComboBox
1160 {
1161 /**
1162 * @note The description applies to LTR (left to right) mode.
1163 *
1164 * -# @c FrameWidth and @c ButtonWidth are used to size
1165 * the contents area. To the EditField, @c FrameWidth
1166 * is added at the left, top, bottom while @c ButtonWidth is added
1167 * at the right.
1168 * -# The @c ButtonMargin is measured from the right side of the
1169 * EditField and the outside. Inside it, the button is aligned.
1170 * -# The @c FocusMargin is measured from the EditField rect.
1171 */
1172 enum LayoutProp
1173 {
1174 FrameWidth, /**< (\b 1) @see SpinBox::FrameWidth */
1175 ButtonWidth, /**< (\b 16) @see SpinBox::ButtonWidth */
1176 ButtonMargin, /**< (MainMargin \b 0, Right Top Bot \b 1)
1177 * @see SpinBox::ButtonMargin */
1178 FocusMargin = ButtonMargin + MarginInc,
1179 /**< (\b 1) Focus margin for ComboBoxes that aren't
1180 * editable, measured from the EditField rect */
1181 SupportFrameless = FocusMargin + MarginInc,
1182 /**< (\b 0) @see LP_SpinBox_SupportFrameless same description
1183 * applies here */
1184 ContentsMargin
1185 /**< (\b 5) space between the bevel and the combobox contents
1186 */
1187 };
1188
1189 /**
1190 * Relevant Generic elements:
1191 * - @c Generic::Frame for the area around text input field and button
1192 * - @c Generic::ArrowDown drawn on the button
1193 * - @c Generic::FocusIndicator to indicate keyboard focus
1194 *
1195 * @sa drawKStylePrimitive()
1196 */
1197 enum Primitive
1198 {
1199 EditField, /**< @see SpinBox::EditField */
1200 Button /**< The button panel of the combobox */
1201 };
1202 };
1203
1204 /**
1205 * @brief Describes a list header, like in QListView.
1206 *
1207 * @sa WT_Header
1208 */
1209 struct Header
1210 {
1211 /**
1212 * @sa setWidgetLayoutProp()
1213 */
1214 enum LayoutProp
1215 {
1216 ContentsMargin, /**< (\b 3) margin around contents used to size the header. */
1217 TextToIconSpace = ContentsMargin + MarginInc,
1218 /**< (\b 3) space that is allocated between icon and text
1219 * if both exist
1220 * [sets QStyle::PM_HeaderMargin] */
1221 MarkSize /**< (\b 9) size of the sort indicator in a header
1222 * [sets QStyle::PM_HeaderMarkSize] */
1223 };
1224
1225 /**
1226 * Relevant Generic elements:
1227 * - @c Generic::Text for the header text label
1228 * - @c Generic::ArrowUp @c Generic::ArrowDown to indicate the sorting of the column
1229 *
1230 * [the Sections implement QStyle::CE_HeaderSection]
1231 */
1232 enum Primitive
1233 {
1234 SectionHor, ///< header section, horizontal
1235 SectionVert ///< header section, vertical
1236 };
1237 };
1238
1239 /**
1240 * @brief Describes a text edit widget like QLineEdit.
1241 *
1242 * The frame width of lineedits is determined using Generic::DefaultFrameWidth
1243 */
1244 struct LineEdit
1245 {
1246 /**
1247 * Relevant Generic elements:
1248 * - @c Generic::Frame paints a lineedit frame only [implements QStyle::PE_FrameLineEdit]
1249 *
1250 * @sa drawKStylePrimitive()
1251 */
1252 enum Primitive
1253 {
1254 Panel ///< the panel for a QLineEdit (including frame...) [implements QStyle::PE_PanelLineEdit]
1255 };
1256 };
1257
1258 /**
1259 * @brief Describes something like QGroupBox.
1260 *
1261 * Relevant Generic elements:
1262 * - @c Generic::Frame frame around the group box
1263 *
1264 * [the Frames implement QStyle::PE_FrameGroupBox]
1265 *
1266 * @sa Generic::DefaultFrameWidth
1267 *
1268 * @sa WT_GroupBox
1269 */
1270 struct GroupBox
1271 {
1272 /**
1273 * @sa setWidgetLayoutProp()
1274 */
1275 enum LayoutProps
1276 {
1277 FrameWidth, /**< (\b 2) width of a groupbox frame */
1278 TextAlignTop, /**< (\b 0) set to non-zero, the title will be aligned
1279 * above the groupbox frame, not vertically centered
1280 * [sets QStyle::SH_GroupBox_TextLabelVerticalAlignment] */
1281 TitleTextColor ///< (\b ColorMode(QPalette::Text)) color of the title text label
1282 };
1283 /**
1284 * @sa drawKStylePrimitive()
1285 */
1286 enum Primitive
1287 {
1288 FlatFrame /**< For groupboxes which are set to be 'flat' (usually
1289 * a divider line from top left to top right). KStyle
1290 * has a basic default implementation */
1291 };
1292 };
1293
1294 /**
1295 * @brief Describes a status bar section.
1296 *
1297 * Relevant Generic elements:
1298 * - @c Generic::Frame paints the status bar section [implements QStyle::PE_FrameStatusBar]
1299 *
1300 * No LayoutProps for now.
1301 *
1302 * @sa WT_StatusBar
1303 */
1304 struct StatusBar
1305 {
1306 /**
1307 No LayoutProps for now.
1308 */
1309 };
1310
1311 /**
1312 * @brief Describes a tool bar.
1313 *
1314 * @sa WT_ToolBar
1315 */
1316 struct ToolBar
1317 {
1318 /**
1319 * @sa setWidgetLayoutProp()
1320 */
1321 enum LayoutProps
1322 {
1323 HandleExtent, ///< (\b 6) the width(hor)/height(vert) of a ToolBar handle [sets QStyle::PM_ToolBarHandleExtent]
1324 SeparatorExtent, ///< (\b 6) the width/height of a ToolBar separator [sets QStyle::PM_ToolBarSeparatorExtent]
1325 ExtensionExtent, ///< (\b 10) the width/height of a ToolBar extender, when there is not enough room for toolbar buttons [sets PM_ToolBarExtensionExtent]
1326 FrameWidth, /**< (\b 2) width of the frame around toolbars
1327 * [sets QStyle::PM_ToolBarFrameWidth] */
1328 ItemMargin, ///< (\b 1) [sets QStyle::PM_ToolBarItemMargin]
1329 ItemSpacing ///< (\b 3) [sets QStyle::PM_ToolBarItemSpacing]
1330 };
1331
1332 /**
1333 * [the Handles implement QStyle::PE_IndicatorToolBarHandle]
1334 * [the Panels implement QStyle::CE_ToolBar]
1335 *
1336 * @sa drawKStylePrimitive()
1337 */
1338 enum Primitive
1339 {
1340 HandleHor, ///< handle of a toolbar, horizontal
1341 HandleVert, ///< handle of a toolbar, vertical
1342 Separator, ///< [implements QStyle::PE_IndicatorToolBarSeparator]
1343 PanelHor, ///< the actual toolbar, horizontal
1344 PanelVert ///< the actual toolbar, vertical
1345 };
1346 };
1347
1348
1349 /**
1350 * @brief Describes a tab for a tool box, like QToolBox.
1351 *
1352 * @sa WT_ToolBoxTab
1353 */
1354 struct ToolBoxTab
1355 {
1356 /**
1357 * @sa setWidgetLayoutProp()
1358 */
1359 enum LayoutProps
1360 {
1361 Margin /**< (\b 0) used to specify the
1362 * position of the tab contents, doesn't influence the tab size
1363 * [sets QStyle::SE_ToolBoxTabContents] */
1364 };
1365
1366 /**
1367 * @sa drawKStylePrimitive()
1368 */
1369 enum Primitive
1370 {
1371 Panel /**< the panel of a toolbox tab, KStyles default implementation
1372 * paints WT_ToolButton/ToolButton::Panel
1373 * [implements CE_ToolBoxTab] */
1374 };
1375 };
1376
1377
1378 /**
1379 * @brief Describes widgets like QToolButton (usually inside a QToolBar).
1380 * The drawing of ToolButton's is much like that of PushButtons; however, in some cases the widget is configured
1381 * to not have a separate arrow area, but to incorporate the area inside the button itself. To handle this mode,
1382 * set InlineMenuIndicatorSize to the size of the arrow,
1383 * and the InlineMenuIndicatorXOff, and InlineMenuIndicatorYOff to offset from the bottom-right corner to place that
1384 * rectangle. If InlineMenuIndicatorSize isn't set, the arrow won't be drawn.
1385 *
1386 * @sa WT_ToolButton
1387 */
1388 struct ToolButton
1389 {
1390 /**
1391 * @sa setWidgetLayoutProp()
1392 */
1393 enum LayoutProps
1394 {
1395 ContentsMargin, /**< (\b 5) Margin reserved around the contents size of
1396 * a toolbutton. Used to size the contents. */
1397 FocusMargin = ContentsMargin + MarginInc,
1398 /**< (\b 3) Where the focus rect will be drawn, measured
1399 * from the widget sides */
1400 MenuIndicatorSize, /**< (\b 11) Size for the separate menu arrows on tool buttons
1401 * [sets QStyle::PM_MenuButtonIndicator wheen a toolbutton option is passed in] */
1402 InlineMenuIndicatorSize = FocusMargin + MarginInc, /**< (\b 0) Size of arrow when it's incorporated into
1403 * the button directly. If it's 0, it will not be drawn
1404 * @since 4.1 */
1405 InlineMenuIndicatorXOff, /**< Horizontal offset off the bottom-right corner to place the arrow
1406 * if it's incorporated directly, and not in a separate area
1407 * @since 4.1 */
1408 InlineMenuIndicatorYOff /**< Vertical offset off the bottom-right corner to place the arrow
1409 * if it's incorporated directly, and not in a separate area
1410 * @since 4.1 */
1411 };
1412
1413 /**
1414 * Relevant Generic elements:
1415 * - @c Generic::ArrowDown indicating an associated sub-menu
1416 *
1417 * @todo Implement CE_ToolButtonLabel to have own Generic::Text, Generic::Icon,
1418 * and LayoutProps PressedShiftHorizontal, PressedShiftVertical,
1419 * TextToIconSpace, MenuIndicatorSize...
1420 *
1421 * @sa drawKStylePrimitive()
1422 */
1423 enum Primitive
1424 {
1425 Panel /**< the toolbutton panel
1426 * [implements QStyle::PE_PanelButtonTool] */
1427 };
1428 };
1429
1430
1431 /**
1432 * @brief Describes windows, like in QWorkspace.
1433 *
1434 * @todo SP_TitleBar* pixmaps
1435 *
1436 * @sa WT_Window
1437 */
1438 struct Window
1439 {
1440 /**
1441 * @sa setWidgetLayoutProp()
1442 */
1443 enum LayoutProps
1444 {
1445 TitleTextColor, ///< (\b ColorMode(QPalette::HighlightedText)) color mode of the titlebar text
1446 TitleHeight, ///< (\b 20) height of the titlebar [sets QStyle::PM_TitleBarHeight]
1447 NoTitleFrame, /**< (\b 0) if set to non-zero, the frame primitive is not
1448 * expected to paint around the titlebar area
1449 * [sets QStyle::SH_TitleBar_NoBorder] */
1450 TitleMargin, /**< (\b 2) margin around titlebar contents (buttons,
1451 * text label), used to position them and determine the
1452 * height of titlebar buttons, doesn't influence size */
1453 ButtonWidth = TitleMargin + MarginInc, ///< (\b 16) width of a titlebar button
1454 ButtonSpace, ///< (\b 2) space between titlebar buttons
1455 ButtonToTextSpace ///< (\b 3) space between buttons and the title text
1456 };
1457
1458 /**
1459 * Relevant Generic elements:
1460 * - @c Generic::Text paints the titlebar text label
1461 * - @c Generic::Frame indicating an associated sub-menu
1462 *
1463 * [titlebar elements implement CC_TitleBar]
1464 *
1465 * @sa drawKStylePrimitive()
1466 */
1467 enum Primitive
1468 {
1469 TitlePanel, ///< whole titlebar panel/background, by KStyle default it's filled with plain highlight color
1470 ButtonMenu, ///< system menu button, passes TitleButtonOption
1471 ButtonMin, ///< minimize button, passes TitleButtonOption
1472 ButtonMax, ///< maximize button, passes TitleButtonOption
1473 ButtonRestore, ///< restore button, passes TitleButtonOption @todo split min/max restore?
1474 ButtonClose, ///< close button, passes TitleButtonOption
1475 ButtonShade, ///< shade button, passes TitleButtonOption
1476 ButtonUnshade, ///< button to remove the shade state, passes TitleButtonOption
1477 ButtonHelp ///< context help button, passes TitleButtonOption
1478 };
1479 };
1480//@}
1481
1482 ///Interface for the style to configure various metrics that KStyle has customizable.
1483 void setWidgetLayoutProp(WidgetType widget, int metric, int value);
1484
1485 /**
1486 * @brief Used to obtain information about KStyle layout properties and metrics.
1487 *
1488 * The default implementation returns values which are set
1489 * using setWidgetLayoutProp(), so normally it's not necessary to implement
1490 * it yourself.
1491 *
1492 * @note This method is not meant to be accessible from outside KStyle.
1493 *
1494 * @param widgetType the widget type context where the @p metric property belongs to
1495 * @param metric the value of this property is requested
1496 * @param opt Qt option parameters
1497 * @param w the actual widget this call is related to
1498 */
1499 virtual int widgetLayoutProp(WidgetType widgetType, int metric,
1500 const QStyleOption* opt = 0, const QWidget* w = 0) const;
1501
1502 /**
1503 * @brief Draws primitives which are used inside KStyle.
1504 *
1505 * KStyle implements various elements of QStyle::ComplexControl
1506 * and QStyle::ControlElement for convenience. Usually complex drawing is
1507 * split into smaller pieces, which can be text, icons, or other KStyle primitives.
1508 * These are painted by this method.
1509 *
1510 * Common Qt option parameters are unpacked for convenience, and information
1511 * from KStyle are passed as a KStyleOption.
1512 *
1513 * @note This method is not meant to be accessible from outside KStyle.
1514 * @note You should make sure to use the @p r parameter for the rectangle,
1515 * since the QStyleOption is generally unaltered from the original request,
1516 * even if layout indicates a different painting rectangle.
1517 *
1518 * @param widgetType the widget context in which this call is happening in
1519 * @param primitive the primitive which should be called. Primitives from the Generic
1520 * struct are not directly coupled to the @p widgetType , other primitives are usually
1521 * defined in the struct corresponding to the widget type.
1522 * @param opt Qt option parameters
1523 * @param r parameter for the rectangle
1524 * @param pal the palette extracted from @p opt for convenience
1525 * @param flags state flags extracted from @p opt for convenience
1526 * @param p used to draw the primitive
1527 * @param widget the widget which is painted on
1528 * @param kOpt information passed from KStyle
1529 */
1530 virtual void drawKStylePrimitive(WidgetType widgetType, int primitive,
1531 const QStyleOption* opt,
1532 const QRect &r, const QPalette &pal,
1533 State flags, QPainter* p,
1534 const QWidget* widget = 0,
1535 Option* kOpt = 0) const;
1536private:
1537 ///Should we use a side text here?
1538 bool useSideText(const QStyleOptionProgressBar* opt) const;
1539 int sideTextWidth(const QStyleOptionProgressBar* pbOpt) const;
1540
1541 ///Returns true if the tab is vertical
1542 bool isVerticalTab (const QStyleOptionTab* tbOpt) const;
1543
1544 ///Returns true if the tab has reflected layout
1545 bool isReflectedTab(const QStyleOptionTab* tbOpt) const;
1546
1547 enum Side
1548 {
1549 North,
1550 East,
1551 West,
1552 South
1553 };
1554
1555 Side tabSide(const QStyleOptionTab* tbOpt) const;
1556
1557 ///Returns the tab rectangle adjusted for the tab direction
1558 QRect marginAdjustedTab(const QStyleOptionTab* tbOpt, int property) const;
1559
1560 ///Wrapper around visualRect for easier use
1561 QRect handleRTL(const QStyleOption* opt, const QRect& subRect) const;
1562 QPoint handleRTL(const QStyleOption* opt, const QPoint& pos) const;
1563
1564 ///Storage for metrics/flags
1565 QVector<QVector<int> > metrics;
1566
1567 ///Expands out the dimension to make sure it incorporates the margins
1568 QSize expandDim(const QSize& orig, WidgetType widget, int baseMarginMetric, const QStyleOption* opt, const QWidget* w, bool rotated = false) const;
1569
1570 ///Calculates the contents rectangle by subtracting out the appropriate margins
1571 ///from the outside
1572 QRect insideMargin(const QRect &orig, WidgetType widget, int baseMarginMetric, const QStyleOption* opt, const QWidget* w) const;
1573
1574 ///Internal subrect calculations, for e.g. scrollbar arrows,
1575 ///where we fake our output to get Qt to do what we want
1576 QRect internalSubControlRect (ComplexControl control, const QStyleOptionComplex* opt,
1577 SubControl subControl, const QWidget* w) const;
1578
1579 // fitt's law label support: QLabel focusing its buddy widget
1580 const QObject *clickedLabel;
1581
1582 template<typename T>
1583 static T extractOptionHelper(T*);
1584
1585public:
1586/** @name QStyle Methods
1587 * These are methods reimplemented from QStyle. Usually it's not necessary to
1588 * reimplement them yourself.
1589 *
1590 * Some of them are there for binary compatibility reasons only; all they do is to call
1591 * the implementation from QCommonStyle.
1592 */
1593//@{
1594 void drawControl (ControlElement elem, const QStyleOption* opt, QPainter* p, const QWidget* w) const;
1595 void drawPrimitive (PrimitiveElement elem, const QStyleOption* opt, QPainter* p, const QWidget* w) const;
1596 int pixelMetric (PixelMetric metric, const QStyleOption* opt = 0, const QWidget* w = 0) const;
1597 QRect subElementRect (SubElement subRect, const QStyleOption* opt, const QWidget* w) const;
1598 QSize sizeFromContents(ContentsType type, const QStyleOption* opt,
1599 const QSize& contentsSize, const QWidget* w) const;
1600 int styleHint (StyleHint hint, const QStyleOption* opt, const QWidget* w,
1601 QStyleHintReturn* returnData) const;
1602 QRect subControlRect (ComplexControl control, const QStyleOptionComplex* opt,
1603 SubControl subControl, const QWidget* w) const;
1604 SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex* opt,
1605 const QPoint& pt, const QWidget* w) const;
1606 void drawComplexControl (ComplexControl cc, const QStyleOptionComplex* opt,
1607 QPainter *p, const QWidget* w) const;
1608
1609 void polish(QWidget *);
1610 void unpolish(QWidget *);
1611 void polish(QApplication *);
1612 void unpolish(QApplication *);
1613 void polish(QPalette &);
1614 QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
1615 int flags, bool enabled,
1616 const QString &text) const;
1617 QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
1618 void drawItemText(QPainter *painter, const QRect &rect,
1619 int flags, const QPalette &pal, bool enabled,
1620 const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
1621 void drawItemPixmap(QPainter *painter, const QRect &rect,
1622 int alignment, const QPixmap &pixmap) const;
1623 QPalette standardPalette() const;
1624 QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
1625 const QWidget *widget = 0) const; //### kde5 remove
1626 QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
1627 const QStyleOption *opt) const;
1628 bool eventFilter(QObject *, QEvent *);
1629
1630protected Q_SLOTS:
1631 int layoutSpacingImplementation(QSizePolicy::ControlType control1,
1632 QSizePolicy::ControlType control2, Qt::Orientation orientation,
1633 const QStyleOption *option, const QWidget *widget) const;
1634
1635 QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option = 0,
1636 const QWidget *widget = 0) const;
1637//@}
1638private:
1639 KStylePrivate * const d;
1640};
1641
1642template<typename T>
1643const char* kstyleName()
1644{ return "default"; }
1645
1646/**
1647 * Template class which helps implementing the widget style plugin interface.
1648 *
1649 * You don't need to use this class directly. Use the following
1650 * macro (defined in kstyle.h) and you are done:
1651 * \code
1652 * K_EXPORT_STYLE("StyleName", StyleClassName)
1653 * \endcode
1654 */
1655template<typename T>
1656class KStyleFactory: public QStylePlugin
1657{
1658 QStringList keys() const
1659 {
1660 QStringList l;
1661 l << kstyleName<T>();
1662 return l;
1663 }
1664
1665 QStyle* create(const QString& id)
1666 {
1667 QStringList names = keys();
1668 //check whether included in the keys
1669 if (names.contains(id, Qt::CaseInsensitive))
1670 return new T();
1671
1672 return 0;
1673 }
1674};
1675
1676// get the pointed-to type from a pointer
1677template<typename T>
1678T KStyle::extractOptionHelper(T*)
1679{
1680 return T();
1681}
1682
1683template<typename T>
1684T KStyle::extractOption(Option* option)
1685{
1686 if (option) {
1687 if (dynamic_cast<T>(option))
1688 return static_cast<T>(option);
1689 // Ugly hacks for when RTLD_GLOBAL is not used (quite common with plugins, really)
1690 // and dynamic_cast fails.
1691 // This is still partially broken as it doesn't take into account subclasses.
1692 // ### KDE5 do this somehow differently
1693 if ( qstrcmp(typeid(*option).name(), typeid(extractOptionHelper(static_cast<T>(0))).name()) == 0 )
1694 return static_cast<T>(option);
1695 }
1696
1697 //### warn if cast failed?
1698
1699 //since T is a pointer type, need this to get to the static.
1700 return static_cast<T>(0)->defaultOption();
1701}
1702
1703#define K_EXPORT_STYLE(name,type) template<> const char* kstyleName<type>() { return name; } \
1704 Q_EXPORT_PLUGIN(KStyleFactory<type>)
1705
1706#endif
1707// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
1708