File indexing completed on 2024-04-21 14:55:48

0001 /**
0002  * KStyle for KDE4
0003  * Copyright (C) 2004-2005 Maksim Orlovich <maksim@kde.org>
0004  * Copyright (C) 2005,2006 Sandro Giessl <giessl@kde.org>
0005  *
0006  * Based in part on the following software:
0007  *  KStyle for KDE3
0008  *      Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
0009  *      Portions  (C) 1998-2000 TrollTech AS
0010  *  Keramik for KDE3,
0011  *      Copyright (C) 2002      Malte Starostik   <malte@kde.org>
0012  *                (C) 2002-2003 Maksim Orlovich  <maksim@kde.org>
0013  *      Portions  (C) 2001-2002 Karol Szwed     <gallium@kde.org>
0014  *                (C) 2001-2002 Fredrik Höglund <fredrik@kde.org>
0015  *                (C) 2000 Daniel M. Duley       <mosfet@kde.org>
0016  *                (C) 2000 Dirk Mueller         <mueller@kde.org>
0017  *                (C) 2001 Martijn Klingens    <klingens@kde.org>
0018  *                (C) 2003 Sandro Giessl      <sandro@giessl.com>
0019  *  This library is free software; you can redistribute it and/or
0020  *  modify it under the terms of the GNU Library General Public
0021  *  License as published by the Free Software Foundation; either
0022  *  version 2 of the License, or (at your option) any later version.
0023  *
0024  *  This library is distributed in the hope that it will be useful,
0025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0027  *  Library General Public License for more details.
0028  *
0029  * You should have received a copy of the GNU Library General Public License
0030  * along with this library; see the file COPYING.LIB.  If not, write to
0031  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0032  * Boston, MA 02110-1301, USA.
0033  */
0034 
0035 #ifndef KDE_K4STYLE_H
0036 #define KDE_K4STYLE_H
0037 
0038 #include <kdelibs4support_export.h>
0039 
0040 #include <QCommonStyle>
0041 #include <QPalette>
0042 #include <QStylePlugin>
0043 #include <typeinfo>
0044 
0045 class QStyleOptionProgressBar;
0046 class QStyleOptionTab;
0047 
0048 class K4StylePrivate;
0049 /**
0050  * Makes style coding more convenient.
0051  *
0052  * @todo and allows to style KDE specific widgets.
0053  *
0054  * K4Style strives to ease style development by implementing various QStyle
0055  * methods. These implementations are based on
0056  * -# the concept of Layout Properties. These properties can be set using
0057  *    setWidgetLayoutProp(). K4Style uses this information to respect various
0058  *    metrics (like space between primitives or margins around widget contents)
0059  *    or turn specific features on or off.
0060  * -# the concept of K4Style Primitives. These can be implemented by overriding
0061  *    drawKStylePrimitive() and providing drawing methods for specific
0062  *    primitives. Often, the drawing of more complex widgets consists of
0063  *    several primitives.
0064  *
0065  * In the following modules, information about related members is collected:
0066  * - \ref OptionGroup
0067  * - \ref WidgetGroup
0068  *
0069  * @author Maksim Orlovich (maksim\@kde.org)
0070  * @author Sandro Giessl (giessl\@kde.org)
0071  *
0072  * @see KStyleFactory for how to implement the style plugin interface.
0073  */
0074 // TODO: From 'Qt4 Themes' discussion on kde-devel
0075 // - Remi Villatel: extend QStyle enums for KColorButton, KColorCombo, KKeyButton, split PE_HeaderSection into KPopupTitle, PopupMenuTitle, TaskContainer)
0076 // - RV: KLineEdit "plays with its colors" - related to K4Style?
0077 // - RV: KMulitTabBarTab ... does it need support from K4Style (instead of manual button rotation etc.)? Or is it dumped already?
0078 // - RV: KTabCtl draws itself mimicking QDrawShadeThingies
0079 // - 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
0080 // - LM: User interface guidelines... related to K4Style?
0081 // - e.g. drawFancyPE() in kdeui for KDE widgets: check "qobject_cast<K4Style*>(style())", or fallback drawing...
0082 // TODO: implement standardIcon().. and what about standardPalette()?
0083 // TODO: maybe the arrow in CE_PushButtonLabel should be painted in CE_PushButtonBevel like QCommonStyle
0084 
0085 class KDELIBS4SUPPORT_DEPRECATED_EXPORT K4Style: public QCommonStyle
0086 {
0087     Q_OBJECT
0088 
0089 public:
0090     K4Style();
0091     ~K4Style() override;
0092 
0093     /**
0094      * Returns the default widget style.
0095      */
0096     static QString defaultStyle();
0097     /**
0098      * Runtime element extension
0099      * This is just convenience and does /not/ require the using widgets style to inherit K4Style
0100      * (i.e. calling this while using cleanlooks won't segfault or so but just return 0)
0101      * Returns a unique id for an element string (e.g. "CE_CapacityBar")
0102      *
0103      * For simplicity, only StyleHints, ControlElements and their SubElements are supported
0104      * If you don't need extended SubElement functionality, just drop it
0105      *
0106      * @param element The style element, represented as string.
0107      * Naming convention: "appname.(2-char-element-type)_element"
0108      * where the 2-char-element-type is of {SH, CE, SE}
0109      * (widgets in kdelibs don't have to pass the appname)
0110      * examples: "CE_CapacityBar", "amarok.CE_Analyzer"
0111      * @param widget Your widget ("this") passing this is mandatory, passing NULL will just return 0
0112      * @returns a unique id for the @p element string or 0, if the element is not supported by the
0113      * widgets current style
0114      *
0115      * Important notes:
0116      * 1) If your string lacks the matching "SH_", "CE_" or "SE_" token the element
0117      * request will be ignored (return is 0)
0118      * 2) Try to avoid custom elements and use default ones (if possible) to get better style support
0119      * and keep UI coherency
0120      * 3) If you cache this value (good idea, this requires a map lookup) don't (!) forget to catch
0121      * style changes in QWidget::changeEvent()
0122      */
0123     static StyleHint customStyleHint(const QString &element, const QWidget *widget);
0124     static ControlElement customControlElement(const QString &element, const QWidget *widget);
0125     static SubElement customSubElement(const QString &element, const QWidget *widget);
0126 
0127 protected:
0128 
0129     /**
0130     * Runtime element extension, allows inheriting styles to add support custom elements
0131     * merges supporting inherit chains
0132     * Supposed to be called e.g. in your constructor.
0133     *
0134     * NOTICE: in order to have this work, your style must provide
0135     * an "X-KDE-CustomElements" classinfo, i.e.
0136     * class MyStyle : public K4Style
0137     * {
0138     *       Q_OBJECT
0139     *       Q_CLASSINFO ("X-KDE-CustomElements", "true")
0140     *
0141     *   public:
0142     *       .....
0143     * }
0144     *
0145     * @param element The style element, represented as string.
0146     * Suggested naming convention: appname.(2-char-element-type)_element
0147     * where the 2-char-element-type is of {SH, CE, SE}
0148     * widgets in kdelibs don't have to pass the appname
0149     * examples: "CE_CapacityBar", "amarok.CE_Analyzer"
0150     *
0151     * Important notes:
0152     * 1) If your string lacks the matching "SH_", "CE_" or "SE_" token the element
0153     * request will be ignored (return is 0)
0154     * 2) To keep UI coherency, don't support any nonsense in your style, but convince app developers
0155     * to use standard elements - if available
0156     */
0157     StyleHint newStyleHint(const QString &element);
0158     ControlElement newControlElement(const QString &element);
0159     SubElement newSubElement(const QString &element);
0160 
0161     /** @name Helper Methods
0162     * These are methods helping with QRect handling, for example.
0163     */
0164 //@{
0165     /**
0166      Draws inside the rectangle using a thinkness 0 pen. This is what drawRect in Qt3 used to do.
0167     */
0168     void drawInsideRect(QPainter *p, const QRect &r) const;
0169 
0170     /**
0171      Returns a w x h QRect center inside the 'in' rectangle
0172     */
0173     QRect centerRect(const QRect &in, int w, int h) const;
0174 
0175     /**
0176      Return a size-dimension QRect centered inside the 'in' rectangle
0177     */
0178     QRect centerRect(const QRect &in, const QSize &size) const;
0179 //@}
0180 
0181     /**
0182      * \defgroup OptionGroup K4Style option representation
0183      * Things related to the representation of options passed when drawing things.
0184      */
0185 //@{
0186     /**
0187      * @brief A representation for colors for use as a widget layout property.
0188      *
0189      * This marshals to and from integers.
0190     */
0191     class KDELIBS4SUPPORT_DEPRECATED_EXPORT ColorMode //krazy:exclude=dpointer (lightweight helper)
0192     {
0193     public:
0194         /**
0195          K4Style understands two kinds of colors:
0196          * -# Palette entries. This means the item must be painted with a specific
0197          *    color role from the palette.
0198          * -# Auto-selected black or white, dependent on the brightness of a certain
0199          *    color role from the palette.
0200         */
0201         enum Mode {
0202             PaletteEntryMode,
0203             BWAutoContrastMode = 0x8000000
0204         };
0205     private:
0206         Mode                mode;
0207         QPalette::ColorRole role;
0208     public:
0209 
0210         /// Constructor, using a the given palette role @p _role
0211         /// and a default mode.
0212         ColorMode(QPalette::ColorRole _role);
0213 
0214         /// Constructor with explicit color mode and palette roles.
0215         ColorMode(Mode _mode, QPalette::ColorRole _role);
0216 
0217         /// Represent as an int to store as a property
0218         operator int() const;
0219 
0220         /// Decode from an int.
0221         ColorMode(int encoded);
0222 
0223         /// Return the color corresponding to our role from the palette,
0224         /// automatically compensating for the contrast mode.
0225         QColor color(const QPalette &palette);
0226     };
0227 
0228     /**
0229      Base for our own option classes.
0230      The idea here is that Option is the main base, and all the
0231      public bases inherit off it indirectly using OptionBase,
0232      which helps implement the default handling
0233 
0234      When implementing the actual types, just implement the default ctor,
0235      filling in defaults, and you're set.
0236     */
0237     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT Option {
0238         virtual ~Option() {} //So dynamic_cast works, and g++ shuts up
0239     };
0240 
0241     /**
0242      Intermediatary base that helps implement subtypes of Option
0243      that properly handle defaults
0244 
0245      EventualSubtype --- the type of option which will be implemented
0246      by inheritting of this class
0247 
0248      BaseType        --- the type of option from which this should inherit
0249      */
0250     template<typename EventualSubtype, typename BaseType>
0251     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT OptionBase: public BaseType {
0252         /** Default value for this option. Uses the default constructor
0253             of EventualSubtype to create the option.
0254         */
0255         static EventualSubtype *defaultOption()
0256         {
0257             static EventualSubtype *theDefault = nullptr; //### function static, not very nice,
0258             //but avoids need for explicit instantiation.
0259 
0260             if (!theDefault) {
0261                 theDefault = new EventualSubtype;
0262             }
0263 
0264             return theDefault;
0265         }
0266     };
0267 
0268     /**
0269      The extractOption method casts the passed in option object, and returns
0270      it, if available, or the defaults for the given type. When implementing
0271      drawing of things with associated options, just use this to extract
0272      the parameter.
0273     */
0274     template<typename T>
0275     static T extractOption(Option *option);
0276 
0277     /**
0278      Option representing the color of the thing to draw. Used for arrows, and for text
0279      (the latter actually uses TextOption)
0280     */
0281     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT ColorOption: public OptionBase<ColorOption, Option> {
0282         /** Color to use for the drawing. Public, modifiable. */
0283         ColorMode color;
0284 
0285         ColorOption(): color(QPalette::ButtonText)
0286         {}
0287     };
0288 
0289     /**
0290      Option for drawing icons: represents whether the icon should be active or not.
0291      The implementation is responsible for all other flags
0292     */
0293     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT IconOption: public OptionBase<IconOption, Option> {
0294         bool  active; ///< Is the icon active?
0295         QIcon icon;   ///< Icon drawn by this option
0296         QSize size;
0297 
0298         IconOption(): active(false)
0299         {}
0300     };
0301 
0302     /**
0303      * Option for drawing double scrollbar buttons, indicating whether
0304      * a button should be drawn active or not.
0305      * @sa ScrollBar::Primitive
0306      */
0307     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT DoubleButtonOption: public OptionBase<DoubleButtonOption, Option> {
0308         /**
0309          * List of active button possibilities.
0310          */
0311         enum ActiveButton {
0312             None,   ///< No button is active
0313             Top,    ///< Vertical scrollbar: The upper button is active
0314             Left,   ///< Horizontal scrollbar: The left button is active
0315             Right,  ///< Horizontal scrollbar: The right button is active
0316             Bottom  ///< Vertical scrollbar: The lower button is active
0317         };
0318 
0319         /**
0320               Whether any of the two buttons is active; and if yes, which
0321               one.
0322         */
0323         ActiveButton activeButton;
0324 
0325         DoubleButtonOption(): activeButton(None)
0326         {}
0327 
0328         /**
0329          * Convenience constructor.
0330          *
0331          * @param ab initializes the active button property
0332          */
0333         DoubleButtonOption(ActiveButton ab): activeButton(ab)
0334         {}
0335     };
0336 
0337     /**
0338      * Option for drawing WT_Window titlebar buttons, indicating whether
0339      * the button is pressed, and containing the window icon
0340      * @sa Window
0341      */
0342     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT TitleButtonOption: public OptionBase<TitleButtonOption, Option> {
0343         bool active;  ///< whether the button is pressed
0344         QIcon icon;   ///< window Icon
0345 //         /// whether the button is hovered, this doesn't work at the moment (not even in any Qt style)...
0346 //         bool hover;
0347 
0348         TitleButtonOption(): active(false)/*, hover(false)*/
0349         {}
0350 
0351         /**
0352          * Convenience constructor.
0353          *
0354          * @param act initializes the active button property
0355          */
0356         TitleButtonOption(bool act): active(act)
0357         {}
0358     };
0359 
0360     ///Option representing text drawing info. For Generic::Text.
0361     struct KDELIBS4SUPPORT_DEPRECATED_EXPORT TextOption: public OptionBase<TextOption, ColorOption> {
0362         Qt::Alignment        hAlign; ///< The horizontal alignment, default is Qt::AlignLeft
0363         QString              text;   ///< The text to draw
0364 
0365         TextOption();
0366 
0367         /**
0368          * Convenience constructor.
0369          *
0370          * @param _text initializes the text string property
0371          */
0372         TextOption(const QString &_text);
0373 
0374         /**
0375          * Called by the constructor to set the default value of @c hAlign
0376          */
0377         void init();
0378     };
0379 //@}
0380 
0381     /**
0382      * \defgroup WidgetGroup K4Style widget representation
0383      * Things related to the representation of widgets.
0384      */
0385 //@{
0386     /**
0387      This enum is used to represent K4Style's concept of
0388      a widget, and to associate drawing requests and metrics
0389      with it. The generic value is used for primitives and metrics
0390      that are common between many widgets
0391     */
0392     enum WidgetType {
0393         WT_Generic,         ///< @sa Generic
0394         WT_PushButton,      ///< @sa PushButton
0395         WT_Splitter,        ///< @sa Splitter
0396         WT_CheckBox,        ///< @sa CheckBox
0397         WT_RadioButton,     ///< @sa RadioButton
0398         WT_DockWidget,      ///< @sa DockWidget
0399         WT_ProgressBar,     ///< @sa ProgressBar
0400         WT_MenuBar,         ///< @sa MenuBar
0401         WT_MenuBarItem,     ///< @sa MenuBarItem
0402         WT_Menu,            ///< @sa Menu
0403         WT_MenuItem,        ///< @sa MenuItem
0404         WT_ScrollBar,       ///< @sa ScrollBar
0405         WT_TabBar,          ///< @sa TabBar
0406         WT_TabWidget,       ///< @sa TabWidget
0407         WT_Slider,          ///< @sa Slider
0408         WT_Tree,            ///< @sa Tree
0409         WT_SpinBox,         ///< @sa SpinBox
0410         WT_ComboBox,        ///< @sa ComboBox
0411         WT_Header,          ///< @sa Header
0412         WT_LineEdit,        ///< @sa LineEdit
0413         WT_GroupBox,        ///< @sa GroupBox
0414         WT_StatusBar,       ///< @sa StatusBar
0415         WT_ToolBar,         ///< @sa ToolBar
0416         WT_ToolButton,      ///< @sa ToolButton
0417         WT_ToolBoxTab,      ///< @sa ToolBoxTab
0418         WT_Window,          ///< @sa Window
0419         WT_Limit = 0xFFFF ///< For enum extensibility
0420     };
0421 
0422     /**
0423      These constants describe how to access various fields of a margin property.
0424      For example, to set an additional top margin of 2 pixels, use
0425      * \code
0426      * setWidgetLayoutProp(WT_SomeWidget, SomeWidget::Margin + Top, 2);
0427      * \endcode
0428      */
0429     enum MarginOffsets {
0430         MainMargin, /**< The main margin is applied equally on each side.
0431                      * In the example above, 'SomeWidget::Margin+MainMargin' is
0432                      * the same as 'SomeWidget::Margin'. */
0433         Top,        ///< Apply an additional top margin.
0434         Bot,        ///< Apply an additional bottom margin.
0435         Left,       ///< Apply an additional left margin.
0436         Right,      ///< Apply an additional right margin.
0437         MarginInc   /**< Used to reserve space in an enum for the Top, Bot,
0438                      * Left, Right margins. */
0439     };
0440 
0441     /**
0442      * Basic primitive drawing operations. Are intended to be used in every
0443      * WidgetType combination.
0444      */
0445     struct Generic {
0446         /**
0447          * Layout properties. These can be set with setWidgetLayoutProp()
0448          * Generic LayoutProps contain a few properties which are not
0449          * directly related to a specific widget type.
0450          */
0451         enum LayoutProp {
0452             DefaultFrameWidth,    ///< The FrameWidth used by LineEdit, etc..., default is \b 2 [sets QStyle::PM_DefaultFrameWidth]
0453             DefaultLayoutSpacing, ///< The spacing used by layouts, unless the style implements layoutSpacingImplementation(), default is \b 6 [sets QStyle::PM_DefaultLayoutSpacing]
0454             DefaultLayoutMargin   ///< The margin used by layouts, default is \b 9 [sets QStyle::PM_DefaultChildMargin and QStyle::PM_DefaultTopLevelMargin]
0455         };
0456 
0457         /**
0458          * Primitive drawing operations.
0459          * @note The arrows are centering primitives, which means they draw in
0460          * the center of the specified rectangle.
0461          */
0462         enum Primitive {
0463             Text = 0xFFFF,  ///< Passes in TextOption
0464             Icon,           ///< Passes in IconOption
0465             FocusIndicator, ///< Indication that this widget has focus
0466             Frame,          /**< Frame around widget
0467                              * @note QFrame derived widgets are painted using
0468                              * WT_Generic widget type and this Generic::Frame primitive. */
0469             ArrowUp,        ///< Up arrow (pointing up)
0470             ArrowDown,      ///< Down arrow
0471             ArrowRight,     ///< Right arrow
0472             ArrowLeft       ///< Left arrow
0473         };
0474     };
0475 
0476     /**
0477      * @brief Describes widgets like QPushButton.
0478      *
0479      * @sa WT_PushButton
0480      */
0481     struct PushButton {
0482         /**
0483          * The layout of a PushButton is structured as follows:
0484          * -# Between the very outside and the bevel is the default indicator
0485          *    area, controlled by the @c PushButton::DefaultIndicatorMargin .
0486          * -# From the bevel, the content and focus rect margins are measured.
0487          *    Only the content margin is used to size the content area.
0488          * -# Inside the content area, @c PushButton::MenuIndicatorSize is allocated to the down
0489          *    arrow if there is a popup menu.
0490          * -# @c PushButton::TextToIconSpace is allocated between icon and text if both exist
0491          *
0492          * @sa setWidgetLayoutProp()
0493          */
0494         enum LayoutProp {
0495             ContentsMargin, ///< (\b 5) space between the bevel and the button contents
0496             FocusMargin            = ContentsMargin + MarginInc, ///< (\b 3) Used to calculate the area of the focus indicator. Measured from the bevel.
0497             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]
0498             PressedShiftHorizontal = DefaultIndicatorMargin + MarginInc, ///< (\b 2) horizontal contents shift for pressed buttons [sets QStyle::PM_ButtonShiftHorizontal]
0499             PressedShiftVertical, ///< (\b 2) vertical contents shift for pressed buttons [sets QStyle::PM_ButtonShiftVertical]
0500             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]
0501             TextToIconSpace ///< (\b 6) space between the icon and the text if both exist
0502         };
0503 
0504         /**
0505          * Relevant Generic elements:
0506          * - @c Generic::Text the button's text
0507          * - @c Generic::FocusIndicator indicating that the button has keyboard focus
0508          * - @c Generic::ArrowDown indicating that the button has a popup menu associated to it
0509          *
0510          * [K4Style implements @c QStyle::CE_PushButtonBevel to compose the primitives]
0511          *
0512          * @sa drawKStylePrimitive()
0513          */
0514         enum Primitive {
0515             Panel,              /**< the pushbutton panel
0516                                  * [implements QStyle::PE_PanelButtonCommand] */
0517             DefaultButtonFrame  /**< frame indicating a default button, painted before
0518                                  * the button Panel
0519                                  * [implements QStyle::PE_FrameDefaultButton] */
0520         };
0521     };
0522 
0523     /**
0524      * @brief Describes widgets like QSplitter.
0525      *
0526      * @sa WT_Splitter
0527      */
0528     struct Splitter {
0529         /**
0530          * @sa setWidgetLayoutProp()
0531          */
0532         enum LayoutProp {
0533             Width ///< (\b 6) size of the splitter handle [sets QStyle::PM_SplitterWidth]
0534         };
0535 
0536         /**
0537          * [the Handles implement QStyle::CE_Splitter]
0538          *
0539          * @sa drawKStylePrimitive()
0540          */
0541         enum Primitive {
0542             HandleHor,      /**< The splitter handle, horizontal. Flags: @c State_Enabled&&State_MouseOver for mouseOver */
0543             HandleVert      /**< The splitter handle, vertical. Flags: @c State_Enabled&&State_MouseOver for mouseOver */
0544         };
0545     };
0546 
0547     /**
0548      * @brief Describes widgets like QCheckBox.
0549      *
0550      * @sa WT_CheckBox
0551      */
0552     struct CheckBox {
0553         /**
0554          * @sa setWidgetLayoutProp()
0555          */
0556         enum LayoutProp {
0557             Size,               ///< (\b 16) size of the checkbox [sets PM_IndicatorWidth, PM_IndicatorHeight]
0558             BoxTextSpace,       ///< (\b 6) space to leave between checkbox and text (and icon between them in case there is one)
0559             NoLabelFocusMargin, /**< (\b 1) rectangle to apply to the checkbox rectangle
0560                                  * to get where to paint the focus rectangle in
0561                                  * case of a labelless checkbox */
0562             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.
0563         };
0564 
0565         /**
0566          * Relevant elements:
0567          * - @c Generic::Text the CheckBox label alongside the CheckBox
0568          * - @c Generic::FocusIndicator the focus indicator. Usually drawn around the
0569          *      text label. If no label exists, it is drawn around the CheckBox.
0570          *
0571          * [check primitives implement QStyle::PE_IndicatorCheckBox]
0572          * [K4Style implements QStyle::CE_CheckBox to compose a CheckBox using
0573          *  the mentioned primitives]
0574          *
0575          * @sa drawKStylePrimitive()
0576          */
0577         enum Primitive {
0578             CheckOn,        ///< checkbox which is checked
0579             CheckOff,       ///< checkbox which is not checked
0580             CheckTriState   ///< tristate checkbox (neither off nor on)
0581         };
0582     };
0583 
0584     /**
0585      * @brief Describes widgets like QRadioButton.
0586      */
0587     struct RadioButton {
0588         /**
0589          * @sa setWidgetLayoutProp()
0590          */
0591         enum LayoutProp {
0592             Size, /**< [sets QStyle::PM_ExclusiveIndicatorWidth,
0593                    *    QStyle::PM_ExclusiveIndicatorHeight]
0594                    * @sa CheckBox::Size */
0595             BoxTextSpace, ///< @sa CheckBox::BoxTextSpace
0596             FocusMargin   ///< @sa CheckBox::FocusMargin
0597         };
0598 
0599         /**
0600          * Relevant Generic elements:
0601          * - @c Generic::Text the RadioButton label alongside the RadioButton
0602          * - @c Generic::FocusIndicator the keyboard focus indicator
0603          *
0604          * [check primitives implement QStyle::PE_IndicatorRadioButton]
0605          * [K4Style implements QStyle::CE_RadioButton to compose a RadioButton using
0606          *  the mentioned primitives]
0607          *
0608          * @sa drawKStylePrimitive()
0609          */
0610         enum Primitive {
0611             RadioOn,        ///< radiobutton which is checked
0612             RadioOff        ///< radiobutton which is not checked
0613         };
0614     };
0615 
0616     /**
0617      * @brief Describes the title of a dock widget.
0618      *
0619      * @sa WT_DockWidget
0620      */
0621     struct DockWidget {
0622         /**
0623          * @sa setWidgetLayoutProp()
0624          */
0625         enum LayoutProp {
0626             TitleTextColor, ///< (\b ColorMode(QPalette::HighlightedText)) color mode of the title text
0627             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]
0628             FrameWidth = TitleMargin + MarginInc,  ///< (\b 3) width of the frame around floating dockwidgets [sets QStyle::PM_DockWidgetFrameWidth]
0629             SeparatorExtent ///< (\b 6) width of the area which separates the (docked) dock window from the window contents [sets QStyle::PM_DockWidgetSeparatorExtent]
0630         };
0631 
0632         /**
0633          * Relevant Generic elements:
0634          * - @c Generic::Text the title text
0635          * - @c Generic::Frame the frame around floating dockwidgets
0636          *
0637          * [K4Style implements @c QStyle::CE_DockWidgetTitle to split it into K4Style primitives]
0638          *
0639          * @sa drawKStylePrimitive()
0640          */
0641         enum Primitive {
0642             TitlePanel, ///< the panel/background of the title bar
0643             SeparatorHandle ///< the splitter between dockwidgets
0644         };
0645     };
0646 
0647     /**
0648      * @brief Describes widgets like QProgressBar.
0649      *
0650      * @todo support for Qt > 4.1 orientation, bottomToTop, invertedAppearance properties!
0651      *
0652      * @sa WT_ProgressBar
0653      */
0654     struct ProgressBar {
0655         /**
0656          * @sa setWidgetLayoutProp()
0657          */
0658         enum LayoutProp {
0659             GrooveMargin,        ///< (\b 2) Margin to allocate for the groove. Content area will be inside of it.
0660             SideText = GrooveMargin + MarginInc, ///< (\b false) set this to true to have the text positionned to the side
0661             SideTextSpace,       ///< (\b 3) Extra space besides that needed for text to allocate to side indicator (on both sides).
0662             Precision,           ///< (\b 1) The indicator size will always be a multiple of this (modulo busy indicator size clamping). [sets QStyle::PM_ProgressBarChunkWidth]
0663             BusyIndicatorSize,   ///< (\b 10) The busy indicator size, in percent of area size.
0664             MaxBusyIndicatorSize ///< (\b 10000) size limit on the busy indicator size
0665         };
0666 
0667         /**
0668          * Relevant Generic elements:
0669          * - @c Generic::Text the progress label
0670          *
0671          * @sa drawKStylePrimitive()
0672          */
0673         enum Primitive {
0674             Groove,         /**< the progressbar groove, drawn before the progress
0675                              * Indicator [implements QStyle::CE_ProgressBarGroove] */
0676             Indicator,      ///< The actual bar indicating the progress...
0677             BusyIndicator   /**< Used to indicate business, for example when
0678                              * no progress is known (minimum and maximum values
0679                              * both set to 0) */
0680         };
0681     };
0682 
0683     /**
0684      * @brief Describes widgets like QMenuBar.
0685      *
0686      * @sa WT_MenuBar
0687      */
0688     struct MenuBar {
0689         /**
0690          * @sa setWidgetLayoutProp()
0691          */
0692         enum LayoutProp {
0693             Margin,           /**< (MainMargin \b 2, Left \b 4, Right \b 4)
0694                                * Margin rectangle for the contents. */
0695             ItemSpacing = Margin + MarginInc ///< (\b 14) Space between items [sets QStyle::PM_MenuBarItemSpacing]
0696         };
0697 
0698         /**
0699          * @sa drawKStylePrimitive()
0700          */
0701         enum Property {
0702             EmptyArea /**< Empty area of a menu bar, e.g. background
0703                        * color. Maybe the place to fake toolbar separators (?)
0704                        * [implements QStyle::CE_MenuBarEmptyArea] */
0705         };
0706     };
0707 
0708     /**
0709      * @brief Describes MenuBar items.
0710      *
0711      * Relevant elements:
0712      * - @c Generic::Text text appearing as menubar entry
0713      */
0714     struct MenuBarItem {
0715         /**
0716          * @sa setWidgetLayoutProp()
0717          */
0718         enum LayoutProp {
0719             Margin,                    /**< (\b 1) Margin rectangle to allocate for any
0720                                         * bevel, etc. (Text will be drawn with
0721                                         * the inside rect). */
0722             Dummy = Margin + MarginInc //Paranoia about underlying type
0723         };
0724 
0725         /**
0726          * @sa drawKStylePrimitive()
0727          */
0728         enum Primitive {
0729             Panel       ///< The panel/background of a menubar item. Interesting flags: State_Selected && State_HasFocus for mouseOver, State_Sunken for pressed state.
0730         };
0731     };
0732 
0733     /**
0734      * @brief Describes a menu.
0735      *
0736      * @sa WT_Menu
0737      */
0738     struct Menu {
0739         /**
0740          * @sa setWidgetLayoutProp()
0741          */
0742         enum LayoutProp {
0743             FrameWidth, ///< (\b 1) The width of the frame, note that this does not affect the layout.
0744             Margin,     ///< (\b 3) The margin of the menu. @todo have a look at comments at PM_MenuHMargin...
0745             ScrollerHeight = Margin + MarginInc, ///< (\b 10) Height of a menu scroller. [sets QStyle::PM_MenuScrollerHeight]
0746             TearOffHeight ///< (\b 10) Height of the TearOff area. [sets QStyle::PM_MenuTearoffHeight]
0747         };
0748 
0749         /**
0750          * Relevant Generic elements:
0751          * - @c Generic::Frame frame around the menu panel
0752          *
0753          * @sa drawKStylePrimitive()
0754          */
0755         enum Primitive {
0756             Background, ///< Menu and MenuItem background
0757             TearOff,    /**< paints the area where a menu can be teared off
0758                          * [implements QStyle::CE_MenuTearoff] */
0759             Scroller    /**< scrolling areas in a QMenu
0760                          * [implements QStyle::CE_MenuScroller] */
0761         };
0762     };
0763 
0764     /**
0765      * @brief Describes an item in a menu.
0766      *
0767      * MenuItems are layouted like this:
0768      * -# There are two MenuItem modes, toggled by @c LP_MenuItem_CheckAlongsideIcon.
0769      *    Horizontal layout inside the items is as follow:
0770      *     - @c LP_MenuItem_CheckAlongsideIcon disabled:
0771      *          |icon/checkmark|IconSpace|text|AccelSpace|accel|ArrowSpace|ArrowWidth|
0772      *     - @c LP_MenuItem_CheckAlongsideIcon enabled:
0773      *          |checkmark|CheckSpace|icon|IconSpace|text|AccelSpace|accel|ArrowSpace|ArrowWidth|
0774      * -# The icon/checkmark column is at least @c LP_MenuItem_CheckWidth wide in all cases.
0775      * -# Then Margin is applied outside that.
0776      *
0777      * @note For the subprimitives the passed rect is their own.
0778      * @note Background is erased with WT_Menu/Menu::Background.
0779      *
0780      * @sa WT_MenuItem
0781      */
0782     struct MenuItem {
0783         /**
0784          * @sa setWidgetLayoutProp()
0785          */
0786         enum LayoutProp {
0787             Margin,         ///< (\b 2) margin for each entry
0788             CheckAlongsideIcon = Margin + MarginInc,
0789             /**< (\b 0) Set to non-zero to have checkmarks painted
0790              * separate from icons. */
0791             CheckWidth,     /**< (\b 12) size of the checkmark column
0792                              * (CheckAlongsideButton enabled). */
0793             CheckSpace,     /**< (\b 3) Space between the checkmark column and the icon
0794                              * column (CheckAlongsideButton enabled).*/
0795             IconWidth,      ///< (\b 12) minimum size of the icon column
0796             IconSpace,      ///< (\b 3) space between the icon column and text column
0797             AccelSpace,     ///< (\b 0 ?) space between text and keyboard accelerator label
0798             ArrowSpace,     ///< (\b 3) space between the text column and arrow column (indicating sub menus)
0799             ArrowWidth,     ///< (\b 11) space to reserve for the menu arrow column
0800             SeparatorHeight,///< (\b 0) heigh of separator
0801             MinHeight,      ///< (\b 16) limit on the size of item content
0802             ActiveTextColor,///< (\b ColorMode(QPalette::HighlightedText)) color for active text and arrow
0803             TextColor,      ///< (\b ColorMode(QPalette::Text)) color for inactive text and arrow
0804             DisabledTextColor, ///< (\b ColorMode(QPalette::Text)) color for inactive + disabled text and arrow
0805             ActiveDisabledTextColor ///< (\b ColorMode(QPalette::Text)) color for active + disabled text and arrow
0806         };
0807 
0808         /**
0809          * Relevant Generic elements:
0810          * - @c Generic::Text the text of the menu item
0811          * - @c Generic::ArrowLeft @c Generic::ArrowRight arrows indicating a sub-menu
0812          *
0813          * @sa drawKStylePrimitive()
0814          */
0815         enum Primitive {
0816             CheckColumn, ///< Background of the checkmark/icon column
0817             CheckOn,     ///< The checkmark - checked
0818             CheckOff,    ///< The checkmark - not checked
0819             RadioOn,     ///< The checkmark of exclusive actions - selected
0820             RadioOff,    ///< The checkmark of exclusive actions - not selected
0821             CheckIcon,   ///< When @c CheckAlongsideIcon is disabled and item is checked: checkmark Indicator painted below the icon
0822             Separator,   //A separator item.
0823             ItemIndicator //Shows the active item
0824         };
0825     };
0826 
0827     /**
0828      * @brief Describes widgets like QScrollBar.
0829      *
0830      * @sa WT_ScrollBar
0831      */
0832     struct ScrollBar {
0833         /**
0834          * @note Dimensions of LayoutProperties are generally specified with respect
0835          *       to the vertical scrollbar. Of course, for horizontal ones they're flipped.
0836          *
0837          * @sa setWidgetLayoutProp()
0838          */
0839         enum LayoutProp {
0840             DoubleTopButton,    ///< (\b 0) set to non-zero to have two buttons on top
0841             DoubleBotButton,    ///< (\b 1) set to non-zero to have two buttons on bottom
0842             SingleButtonHeight, ///< (\b 16) height of a single button
0843             DoubleButtonHeight, ///< (\b 32) height of a double button
0844             BarWidth,           ///< (\b 16) width of a scrollbar [sets QStyle::PM_ScrollBarExtent]
0845             MinimumSliderHeight,/**< (\b 0 ?) the minimum slider height
0846                                  * @note If the scrollbar is too small to accommodate
0847                                  *       this, this will not be enforced. */
0848             ArrowColor,         /**< (\b ColorMode(ColorMode::BWAutoContrastMode, QPalette::Button)) color mode of a button arrow
0849                                  * @sa ColorMode */
0850             ActiveArrowColor    /**< (\b ColorMode(ColorMode::BWAutoContrastMode, QPalette::ButtonText)) color mode of a pressed button arrow (?) */
0851         };
0852 
0853         /**
0854          * Relevant Generic elements:
0855          * - The @c Generic arrows
0856          *
0857          * [Groove Areas implement QStyle::CE_ScrollBarAddPage and QStyle::CE_ScrollBarSubPage]
0858          * [Sliders implement QStyle::CE_ScrollBarSlider]
0859          *
0860          * @sa drawKStylePrimitive()
0861          */
0862         enum Primitive {
0863             SingleButtonVert,   ///< used to draw a 1-button bevel, vertical
0864             SingleButtonHor,    ///< used to draw a 1-button bevel, horizontal
0865             DoubleButtonVert,           /**< Used to draw a 2-button bevel, vertical.
0866                                          * A DoubleButtonOption is passed to say which
0867                                          * button is pressed. */
0868             DoubleButtonHor,            /** @see DoubleButtonVert */
0869             GrooveAreaVertBottom,   ///< scrollbar groove area, vertical. An interesting flag is @c State_Sunken for pressed state
0870             GrooveAreaHorRight,    ///< scrollbar groove area, horizontal. Flags: @c State_Sunken for pressed state
0871             GrooveAreaVertTop,   ///< scrollbar groove area, vertical. An interesting flag is @c State_Sunken for pressed state
0872             GrooveAreaHorLeft,    ///< scrollbar groove area, horizontal. Flags: @c State_Sunken for pressed state
0873             SliderVert,       ///< scrollbar slider, vertical. Flags: @c State_On&&State_Sunken for pressed state
0874             SliderHor         ///< scrollbar slider, horizontal. Flags: @c State_On&&State_Sunken for pressed state
0875         };
0876     };
0877 
0878     /**
0879      * @brief Describes a tab bar.
0880      *
0881      * @sa WT_TabBar
0882      */
0883     struct TabBar {
0884         /**
0885          * Each tab is basically built hiearchically out of the following areas:
0886          * -# Content area, one of the following layouts:
0887          *     - Icon <- TextToIconSpace -> Text
0888          *     - Icon
0889          *     - Text
0890          * -# Bevel: @c LP_TabBar_TabContentsMargin outside of the content area
0891          * -# Focus indicator is placed @c LP_TabBar_TabFocusMargin inside the bevel
0892          *
0893          * @note The side tabs just have those rotated, bottom tabs have the margins reversed.
0894          *
0895          * @sa setWidgetLayoutProp()
0896          */
0897         enum LayoutProp {
0898             TabContentsMargin,  ///< (\b 6) margin around the tab contents, used to size the tab
0899             TabFocusMargin     = TabContentsMargin + MarginInc,
0900             /**< (\b 3) where the tab focus rect is placed, measured from the
0901              * tab sides (?) */
0902             TabTextToIconSpace = TabFocusMargin    + MarginInc,
0903             /**< (\b 0 ?) space between icon and text if the tab contains both */
0904             TabOverlap,         /**< (\b 0) Amount of pixels tabs should overlap. The
0905                                  * paint rectangle will be extended to the left for
0906                                  * all tabs which are not at the beginning (accordingly
0907                                  * extended to the right in RightToLeft mode; extended
0908                                  * to the top for East/West tabs). */
0909             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?
0910             BaseOverlap,       ///< (\b 2) the number of pixels the tabs overlap with the base (i.e. tabWidget frame) [sets QStyle::PM_TabBarBaseOverlap]
0911             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]
0912         };
0913 
0914         /**
0915          * Relevant elements:
0916          * - @c Generic::Text for the TabBar labels
0917          * - @c Generic::FocusIndicator for focused tabs
0918          * - @c Generic::Icon for icons associated to tabs
0919          * - @c ToolButton::Panel paints the scroll button (when the tabs don't fit the tab bar)
0920          */
0921         enum Primitive {
0922             EastText,       /**< Special rotated text for east tabs. */
0923             WestText,       ///< @see EastText
0924             NorthTab,       ///< @todo say something about triangular shape etc.
0925             EastTab,
0926             WestTab,
0927             SouthTab,
0928             BaseFrame,      ///< [implements QStyle::PE_FrameTabBarBase]
0929             IndicatorTear   /**< painted in the left edge of a tabbar when the left
0930                              * tab is scrolled out
0931                              * [implements PE_IndicatorTabTear]
0932                              * @todo K4Style default implementation...? */
0933         };
0934     };
0935 
0936     /**
0937      * @brief Describes a tab widget (frame).
0938      *
0939      * Relevant elements:
0940      * - @c Generic::Frame for the frame/panel of the TabWidget
0941      *
0942      * @sa WT_TabWidget
0943      */
0944     struct TabWidget {
0945         /**
0946          * @sa setWidgetLayoutProp()
0947          */
0948         enum LayoutProp {
0949             ContentsMargin,      /**< (\b 2) Width of the frame around a tab widget.
0950                                * Margins for a tabwidget with tab position 'North' are
0951                                * specified as expected. For other positions, the
0952                                * sides are rotated accordingly, e.g. the left margin
0953                                * of a 'West' tabwidget is the same as top for a 'North'
0954                                * tabwidget.
0955                                * [sets QStyle::SE_TabWidgetTabContents] */
0956             DummyProp = ContentsMargin + MarginInc
0957         };
0958     };
0959 
0960     /**
0961      * @brief Describes a slider, like QSlider.
0962      *
0963      * @sa WT_Slider
0964      */
0965     struct Slider {
0966 
0967         /**
0968          * @note The description applies to horizontal sliders.
0969          *
0970          * @sa setWidgetLayoutProp()
0971          */
0972         enum LayoutProp {
0973             HandleThickness, ///< (\b 20) The height of a slider handle
0974             HandleLength     ///< (\b 16) The width of a slider handle [sets QStyle::PM_SliderLength]
0975         };
0976 
0977         /**
0978          * Relevant Generic elements:
0979          * - @c Generic::FocusIndicator indicating keyboard focus
0980          *
0981          * @sa drawKStylePrimitive()
0982          */
0983         enum Primitive {
0984             HandleVert,   ///< A vertical slider handle
0985             HandleHor,    ///< A horizontal slider handle
0986             GrooveVert,   ///< A vertical slider groove
0987             GrooveHor     ///< A horizontal slider groove
0988         };
0989     };
0990 
0991     /**
0992      * @brief Describes an expandable tree, e.g. in a QListView.
0993      */
0994     struct Tree {
0995         /**
0996          * For trees, all the control we provide here is to provide a cap on the size
0997          * of the expander widget, which is always square. There are 4 primitives to
0998          * implement: open and closed expander, and horizontal and vertical lines.
0999          * If you're using dots, it's suggested you use global brush alignment to
1000          * keep it all nicely aligned.
1001          *
1002          * @sa setWidgetLayoutProp()
1003          */
1004         enum LayoutProp {
1005             MaxExpanderSize      /**< (\b 9) @note If you set MaxExpanderSize to a value less
1006                                   * than 9, designer will look funny. The value should also
1007                                   * be odd, or value - 1 will be used.
1008                                   */
1009         };
1010 
1011         /**
1012          * @sa drawKStylePrimitive()
1013          */
1014         enum Primitive {
1015             ExpanderClosed, ///< A closed tree expander, usually drawn as '+'. K4Style has a default implementation (Windows-like look).
1016             ExpanderOpen,   ///< An opened tree expander, usually drawn as '-' K4Style has a default implementation.
1017             HorizontalBranch, /**< A horizontal tree line.
1018                                * @note If you're using dots, it's suggested you
1019                                * use global brush alignment to keep it all nicely
1020                                * aligned. */
1021             VerticalBranch    /**< @see HorizontalBranch */
1022         };
1023     };
1024 
1025     /**
1026      * @brief Describes a widget like QSpinBox.
1027      */
1028     struct SpinBox {
1029         /**
1030          * @note The description applies to LTR (left to right) mode.
1031          *
1032          * -# @c FrameWidth and @c ButtonWidth are used to size
1033          * the contents area. To the EditField, @c FrameWidth
1034          * is added at the left, top, bottom while @c ButtonWidth is added
1035          * at the right.
1036          * -# The @c ButtonMargin is measured from the right side of the
1037          * EditField and the outside. Inside it, the up and down buttons are aligned with
1038          * spacing @c ButtonSpacing.
1039          * -# To make sure that both buttons are always of the same height, enable
1040          * @c SymmetricButtons.
1041          *
1042          * @sa setWidgetLayoutProp()
1043          */
1044         enum LayoutProp {
1045             FrameWidth,        /**< (\b 1) Space reserved left, top, bottom of the SpinBox
1046                                 * [sets QStyle::PM_SpinBoxFrameWidth] */
1047             ButtonWidth,       ///< (\b 16) Space reserved for the widget, right of the EditField
1048             ButtonMargin,      /**< (MainMargin \b 0, Right Top Bot \b 1)
1049                                 * Where the up/down buttons are located, measured
1050                                 * from right of the edit field and the top/right/bottom
1051                                 * widget edges. */
1052             ButtonSpacing = ButtonMargin + MarginInc, ///< (\b 1) spacing between up/down buttons
1053             SymmetricButtons,  /**< (\b 0) Set to non-zero to make sure both buttons are
1054                                 * always of the same height. To achieve this, the
1055                                 * spacing of the buttons will be reduced by 1 if
1056                                 * necessary to avoid rounding problems. Needs to be
1057                                 * handled in your drawing code. */
1058             SupportFrameless,   /**< (\b 0) Set to non-zero to indicate that you are able to
1059                                 * handle frame-less SpinBoxes. For a SpinBox with no
1060                                 * frame, FrameWidth and Top/Bottom/Right ButtonMargin
1061                                 * is ignored. */
1062             ContentsMargin
1063             /**< (\b 5) space between the bevel and the spinbox contents
1064                 */
1065         };
1066 
1067         /**
1068          * Relevant Generic elements:
1069          * - @c Generic::Frame for the area around text input field and buttons
1070          * - @c Generic::ArrowUp @c Generic::ArrowDown drawn on the buttons
1071          */
1072         enum Primitive {
1073             EditField,          /**< the text contents area, painted after Generic::Frame
1074                                  * @note This is respected only if the combobox is not
1075                                  * editable. */
1076             UpButton,           /**< Panel of the spinbox button which increases the value */
1077             DownButton,         /**< Panel of the spinbox button which decreases the value */
1078             ButtonArea,         /**< Can be used in addition or instead of
1079                                  * @c KPE_SpinBox_UpButton and @c KPE_SpinBox_DownButton.
1080                                  * The button area is painted before them. */
1081             PlusSymbol,         /**< Plus symbol painted on top of the up button,
1082                                  * centering primitive */
1083             MinusSymbol         /**< Minus symbol painted on top of the down button,
1084                                  * centering primitive */
1085         };
1086     };
1087 
1088     /**
1089      * @brief Describes a widget like QComboBox.
1090      */
1091     struct ComboBox {
1092         /**
1093          * @note The description applies to LTR (left to right) mode.
1094          *
1095          * -# @c FrameWidth and @c ButtonWidth are used to size
1096          * the contents area. To the EditField, @c FrameWidth
1097          * is added at the left, top, bottom while @c ButtonWidth is added
1098          * at the right.
1099          * -# The @c ButtonMargin is measured from the right side of the
1100          * EditField and the outside. Inside it, the button is aligned.
1101          * -# The @c FocusMargin is measured from the EditField rect.
1102          */
1103         enum LayoutProp {
1104             FrameWidth,         /**< (\b 1) @see SpinBox::FrameWidth */
1105             ButtonWidth,        /**< (\b 16) @see SpinBox::ButtonWidth */
1106             ButtonMargin,       /**< (MainMargin \b 0, Right Top Bot \b 1)
1107                                  * @see SpinBox::ButtonMargin */
1108             FocusMargin = ButtonMargin + MarginInc,
1109             /**< (\b 1) Focus margin for ComboBoxes that aren't
1110              * editable, measured from the EditField rect */
1111             SupportFrameless = FocusMargin + MarginInc,
1112             /**< (\b 0) @see LP_SpinBox_SupportFrameless same description
1113              * applies here */
1114             ContentsMargin
1115             /**< (\b 5) space between the bevel and the combobox contents
1116                 */
1117         };
1118 
1119         /**
1120         * Relevant Generic elements:
1121          * - @c Generic::Frame for the area around text input field and button
1122          * - @c Generic::ArrowDown drawn on the button
1123          * - @c Generic::FocusIndicator to indicate keyboard focus
1124          *
1125          * @sa drawKStylePrimitive()
1126          */
1127         enum Primitive {
1128             EditField,          /**< @see SpinBox::EditField */
1129             Button              /**< The button panel of the combobox */
1130         };
1131     };
1132 
1133     /**
1134      * @brief Describes a list header, like in QListView.
1135      *
1136      * @sa WT_Header
1137      */
1138     struct Header {
1139         /**
1140          * @sa setWidgetLayoutProp()
1141          */
1142         enum LayoutProp {
1143             ContentsMargin,      /**< (\b 3) margin around contents used to size the header. */
1144             TextToIconSpace = ContentsMargin + MarginInc,
1145             /**< (\b 3) space that is allocated between icon and text
1146              * if both exist
1147              * [sets QStyle::PM_HeaderMargin] */
1148             MarkSize             /**< (\b 9) size of the sort indicator in a header
1149                                   * [sets QStyle::PM_HeaderMarkSize] */
1150         };
1151 
1152         /**
1153          * Relevant Generic elements:
1154          * - @c Generic::Text for the header text label
1155          * - @c Generic::ArrowUp @c Generic::ArrowDown to indicate the sorting of the column
1156          *
1157          * [the Sections implement QStyle::CE_HeaderSection]
1158          */
1159         enum Primitive {
1160             SectionHor, ///< header section, horizontal
1161             SectionVert ///< header section, vertical
1162         };
1163     };
1164 
1165     /**
1166      * @brief Describes a text edit widget like QLineEdit.
1167      *
1168      * The frame width of lineedits is determined using Generic::DefaultFrameWidth
1169      */
1170     struct LineEdit {
1171         /**
1172          * Relevant Generic elements:
1173          * - @c Generic::Frame paints a lineedit frame only [implements QStyle::PE_FrameLineEdit]
1174          *
1175          * @sa drawKStylePrimitive()
1176          */
1177         enum Primitive {
1178             Panel     ///< the panel for a QLineEdit (including frame...) [implements QStyle::PE_PanelLineEdit]
1179         };
1180     };
1181 
1182     /**
1183      * @brief Describes something like QGroupBox.
1184      *
1185      * Relevant Generic elements:
1186      * - @c Generic::Frame frame around the group box
1187      *
1188      * [the Frames implement QStyle::PE_FrameGroupBox]
1189      *
1190      * @sa Generic::DefaultFrameWidth
1191      *
1192      * @sa WT_GroupBox
1193      */
1194     struct GroupBox {
1195         /**
1196          * @sa setWidgetLayoutProp()
1197          */
1198         enum LayoutProps {
1199             FrameWidth, /**< (\b 2) width of a groupbox frame */
1200             TextAlignTop, /**< (\b 0) set to non-zero, the title will be aligned
1201                           * above the groupbox frame, not vertically centered
1202                           * [sets QStyle::SH_GroupBox_TextLabelVerticalAlignment] */
1203             TitleTextColor ///< (\b ColorMode(QPalette::Text)) color of the title text label
1204         };
1205         /**
1206          * @sa drawKStylePrimitive()
1207          */
1208         enum Primitive {
1209             FlatFrame  /**< For groupboxes which are set to be 'flat' (usually
1210                         * a divider line from top left to top right). K4Style
1211                         * has a basic default implementation */
1212         };
1213     };
1214 
1215     /**
1216      * @brief Describes a status bar section.
1217      *
1218      * Relevant Generic elements:
1219      * - @c Generic::Frame paints the status bar section [implements QStyle::PE_FrameStatusBar]
1220      *
1221      * No LayoutProps for now.
1222      *
1223      * @sa WT_StatusBar
1224      */
1225     struct StatusBar {
1226         /**
1227         No LayoutProps for now.
1228          */
1229     };
1230 
1231     /**
1232      * @brief Describes a tool bar.
1233      *
1234      * @sa WT_ToolBar
1235      */
1236     struct ToolBar {
1237         /**
1238          * @sa setWidgetLayoutProp()
1239          */
1240         enum LayoutProps {
1241             HandleExtent,       ///< (\b 6) the width(hor)/height(vert) of a ToolBar handle [sets QStyle::PM_ToolBarHandleExtent]
1242             SeparatorExtent,    ///< (\b 6) the width/height of a ToolBar separator [sets QStyle::PM_ToolBarSeparatorExtent]
1243             ExtensionExtent,    ///< (\b 10) the width/height of a ToolBar extender, when there is not enough room for toolbar buttons [sets PM_ToolBarExtensionExtent]
1244             FrameWidth,    /**< (\b 2) width of the frame around toolbars
1245                             * [sets QStyle::PM_ToolBarFrameWidth] */
1246             ItemMargin,         ///< (\b 1) [sets QStyle::PM_ToolBarItemMargin]
1247             ItemSpacing         ///< (\b 3) [sets QStyle::PM_ToolBarItemSpacing]
1248         };
1249 
1250         /**
1251          * [the Handles implement QStyle::PE_IndicatorToolBarHandle]
1252          * [the Panels implement QStyle::CE_ToolBar]
1253          *
1254          * @sa drawKStylePrimitive()
1255          */
1256         enum Primitive {
1257             HandleHor, ///< handle of a toolbar, horizontal
1258             HandleVert, ///< handle of a toolbar, vertical
1259             Separator, ///< [implements QStyle::PE_IndicatorToolBarSeparator]
1260             PanelHor,  ///< the actual toolbar, horizontal
1261             PanelVert  ///< the actual toolbar, vertical
1262         };
1263     };
1264 
1265     /**
1266      * @brief Describes a tab for a tool box, like QToolBox.
1267      *
1268      * @sa WT_ToolBoxTab
1269      */
1270     struct ToolBoxTab {
1271         /**
1272          * @sa setWidgetLayoutProp()
1273          */
1274         enum LayoutProps {
1275             Margin  /**< (\b 0) used to specify the
1276                      * position of the tab contents, doesn't influence the tab size
1277                      * [sets QStyle::SE_ToolBoxTabContents] */
1278         };
1279 
1280         /**
1281          * @sa drawKStylePrimitive()
1282          */
1283         enum Primitive {
1284             Panel   /**< the panel of a toolbox tab, K4Style default implementation
1285                      * paints WT_ToolButton/ToolButton::Panel
1286                      * [implements CE_ToolBoxTab] */
1287         };
1288     };
1289 
1290     /**
1291      * @brief Describes widgets like QToolButton (usually inside a QToolBar).
1292      * The drawing of ToolButton's is much like that of PushButtons; however, in some cases the widget is configured
1293      * to not have a separate arrow area, but to incorporate the area inside the button itself. To handle this mode,
1294      * set InlineMenuIndicatorSize to the size of the arrow,
1295      * and the InlineMenuIndicatorXOff, and InlineMenuIndicatorYOff to offset from the bottom-right corner to place that
1296      * rectangle. If InlineMenuIndicatorSize isn't set, the arrow won't be drawn.
1297      *
1298      * @sa WT_ToolButton
1299      */
1300     struct ToolButton {
1301         /**
1302          * @sa setWidgetLayoutProp()
1303          */
1304         enum LayoutProps {
1305             ContentsMargin,  /**< (\b 5) Margin reserved around the contents size of
1306                               * a toolbutton. Used to size the contents. */
1307             FocusMargin            = ContentsMargin + MarginInc,
1308             /**< (\b 3) Where the focus rect will be drawn, measured
1309              * from the widget sides */
1310             MenuIndicatorSize, /**< (\b 11) Size for the separate menu arrows on tool buttons
1311                                  * [sets QStyle::PM_MenuButtonIndicator wheen a toolbutton option is passed in] */
1312             InlineMenuIndicatorSize = FocusMargin + MarginInc, /**< (\b 0) Size of arrow when it's incorporated into
1313                                                                 * the button directly. If it's 0, it will not be drawn
1314                                                                 * @since 4.1 */
1315             InlineMenuIndicatorXOff,  /**< Horizontal offset off the bottom-right corner to place the arrow
1316                                        * if it's incorporated directly, and not in a separate area
1317                                        * @since 4.1 */
1318             InlineMenuIndicatorYOff   /**< Vertical offset off the bottom-right corner to place the arrow
1319                                        * if it's incorporated directly, and not in a separate area
1320                                        * @since 4.1 */
1321         };
1322 
1323         /**
1324          * Relevant Generic elements:
1325          * - @c Generic::ArrowDown indicating an associated sub-menu
1326          *
1327          * @todo Implement CE_ToolButtonLabel to have own Generic::Text, Generic::Icon,
1328          *       and LayoutProps PressedShiftHorizontal, PressedShiftVertical,
1329          *       TextToIconSpace, MenuIndicatorSize...
1330          *
1331          * @sa drawKStylePrimitive()
1332          */
1333         enum Primitive {
1334             Panel           /**< the toolbutton panel
1335                              * [implements QStyle::PE_PanelButtonTool] */
1336         };
1337     };
1338 
1339     /**
1340      * @brief Describes windows, like in QWorkspace.
1341      *
1342      * @todo SP_TitleBar* pixmaps
1343      *
1344      * @sa WT_Window
1345      */
1346     struct Window {
1347         /**
1348          * @sa setWidgetLayoutProp()
1349          */
1350         enum LayoutProps {
1351             TitleTextColor, ///< (\b ColorMode(QPalette::HighlightedText)) color mode of the titlebar text
1352             TitleHeight, ///< (\b 20) height of the titlebar [sets QStyle::PM_TitleBarHeight]
1353             NoTitleFrame, /**< (\b 0) if set to non-zero, the frame primitive is not
1354                            * expected to paint around the titlebar area
1355                            * [sets QStyle::SH_TitleBar_NoBorder] */
1356             TitleMargin,  /**< (\b 2) margin around titlebar contents (buttons,
1357                            * text label), used to position them and determine the
1358                            * height of titlebar buttons, doesn't influence size */
1359             ButtonWidth = TitleMargin + MarginInc, ///< (\b 16) width of a titlebar button
1360             ButtonSpace,      ///< (\b 2) space between titlebar buttons
1361             ButtonToTextSpace ///< (\b 3) space between buttons and the title text
1362         };
1363 
1364         /**
1365          * Relevant Generic elements:
1366          * - @c Generic::Text paints the titlebar text label
1367          * - @c Generic::Frame indicating an associated sub-menu
1368          *
1369          * [titlebar elements implement CC_TitleBar]
1370          *
1371          * @sa drawKStylePrimitive()
1372          */
1373         enum Primitive {
1374             TitlePanel,  ///< whole titlebar panel/background, by K4Style default it's filled with plain highlight color
1375             ButtonMenu,     ///< system menu button, passes TitleButtonOption
1376             ButtonMin,      ///< minimize button, passes TitleButtonOption
1377             ButtonMax,      ///< maximize button, passes TitleButtonOption
1378             ButtonRestore,  ///< restore button, passes TitleButtonOption @todo split min/max restore?
1379             ButtonClose,    ///< close button, passes TitleButtonOption
1380             ButtonShade,    ///< shade button, passes TitleButtonOption
1381             ButtonUnshade,  ///< button to remove the shade state, passes TitleButtonOption
1382             ButtonHelp      ///< context help button, passes TitleButtonOption
1383         };
1384     };
1385 //@}
1386 
1387     ///Interface for the style to configure various metrics that K4Style has customizable.
1388     void setWidgetLayoutProp(WidgetType widget, int metric, int value);
1389 
1390     /**
1391      * @brief Used to obtain information about K4Style layout properties and metrics.
1392      *
1393      * The default implementation returns values which are set
1394      * using setWidgetLayoutProp(), so normally it's not necessary to implement
1395      * it yourself.
1396      *
1397      * @note This method is not meant to be accessible from outside K4Style.
1398      *
1399      * @param widgetType the widget type context where the @p metric property belongs to
1400      * @param metric the value of this property is requested
1401      * @param opt Qt option parameters
1402      * @param w the actual widget this call is related to
1403      */
1404     virtual int widgetLayoutProp(WidgetType widgetType, int metric,
1405                                  const QStyleOption *opt = nullptr, const QWidget *w = nullptr) const;
1406 
1407     /**
1408      * @brief Draws primitives which are used inside K4Style.
1409      *
1410      * K4Style implements various elements of QStyle::ComplexControl
1411      * and QStyle::ControlElement for convenience. Usually complex drawing is
1412      * split into smaller pieces, which can be text, icons, or other K4Style primitives.
1413      * These are painted by this method.
1414      *
1415      * Common Qt option parameters are unpacked for convenience, and information
1416      * from K4Style are passed as a KStyleOption.
1417      *
1418      * @note This method is not meant to be accessible from outside K4Style.
1419      * @note You should make sure to use the @p r parameter for the rectangle,
1420      * since the QStyleOption is generally unaltered from the original request,
1421      * even if layout indicates a different painting rectangle.
1422      *
1423      * @param widgetType the widget context in which this call is happening in
1424      * @param primitive the primitive which should be called. Primitives from the Generic
1425      * struct are not directly coupled to the @p widgetType , other primitives are usually
1426      * defined in the struct corresponding to the widget type.
1427      * @param opt Qt option parameters
1428      * @param r parameter for the rectangle
1429      * @param pal the palette extracted from @p opt for convenience
1430      * @param flags state flags extracted from @p opt for convenience
1431      * @param p used to draw the primitive
1432      * @param widget the widget which is painted on
1433      * @param kOpt information passed from K4Style
1434      */
1435     virtual void drawKStylePrimitive(WidgetType widgetType, int primitive,
1436                                      const QStyleOption *opt,
1437                                      const QRect &r, const QPalette &pal,
1438                                      State flags, QPainter *p,
1439                                      const QWidget *widget = nullptr,
1440                                      Option *kOpt    = nullptr) const;
1441 private:
1442     ///Should we use a side text here?
1443     bool useSideText(const QStyleOptionProgressBar *opt)     const;
1444     int  sideTextWidth(const QStyleOptionProgressBar *pbOpt) const;
1445 
1446     ///Returns true if the tab is vertical
1447     bool isVerticalTab(const QStyleOptionTab *tbOpt) const;
1448 
1449     ///Returns true if the tab has reflected layout
1450     bool isReflectedTab(const QStyleOptionTab *tbOpt) const;
1451 
1452     enum Side {
1453         North,
1454         East,
1455         West,
1456         South
1457     };
1458 
1459     Side tabSide(const QStyleOptionTab *tbOpt) const;
1460 
1461     ///Returns the tab rectangle adjusted for the tab direction
1462     QRect marginAdjustedTab(const QStyleOptionTab *tbOpt, int property) const;
1463 
1464     ///Wrapper around visualRect for easier use
1465     QRect  handleRTL(const QStyleOption *opt, const QRect &subRect) const;
1466     QPoint handleRTL(const QStyleOption *opt, const QPoint &pos)    const;
1467 
1468     ///Storage for metrics/flags
1469     QVector<QVector<int> > metrics;
1470 
1471     ///Expands out the dimension to make sure it incorporates the margins
1472     QSize expandDim(const QSize &orig, WidgetType widget, int baseMarginMetric, const QStyleOption *opt, const QWidget *w, bool rotated = false) const;
1473 
1474     ///Calculates the contents rectangle by subtracting out the appropriate margins
1475     ///from the outside
1476     QRect insideMargin(const QRect &orig, WidgetType widget, int baseMarginMetric, const QStyleOption *opt, const QWidget *w) const;
1477 
1478     ///Internal subrect calculations, for e.g. scrollbar arrows,
1479     ///where we fake our output to get Qt to do what we want
1480     QRect internalSubControlRect(ComplexControl control, const QStyleOptionComplex *opt,
1481                                  SubControl subControl, const QWidget *w) const;
1482 
1483     // fitt's law label support: QLabel focusing its buddy widget
1484     const QObject *clickedLabel;
1485 
1486 public:
1487     /** @name QStyle Methods
1488      * These are methods reimplemented from QStyle. Usually it's not necessary to
1489      * reimplement them yourself.
1490      *
1491      * Some of them are there for binary compatibility reasons only; all they do is to call
1492      * the implementation from QCommonStyle.
1493      */
1494 //@{
1495     void drawControl(ControlElement   elem, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
1496     void drawPrimitive(PrimitiveElement elem, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
1497     int  pixelMetric(PixelMetric    metric, const QStyleOption *opt = nullptr, const QWidget *w = nullptr) const override;
1498     QRect subElementRect(SubElement    subRect, const QStyleOption *opt, const QWidget *w) const override;
1499     QSize sizeFromContents(ContentsType     type, const QStyleOption *opt,
1500                            const QSize &contentsSize, const QWidget *w) const override;
1501     int   styleHint(StyleHint        hint, const QStyleOption *opt, const QWidget *w,
1502                     QStyleHintReturn *returnData) const override;
1503     QRect subControlRect(ComplexControl control, const QStyleOptionComplex *opt,
1504                          SubControl subControl, const QWidget *w) const override;
1505     SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
1506                                      const QPoint &pt, const QWidget *w) const override;
1507     void       drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
1508                                   QPainter *p,      const QWidget *w) const override;
1509 
1510     void polish(QWidget *) override;
1511     void unpolish(QWidget *) override;
1512     void polish(QApplication *) override;
1513     void unpolish(QApplication *) override;
1514     void polish(QPalette &) override;
1515     QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
1516                        int flags, bool enabled,
1517                        const QString &text) const override;
1518     QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const override;
1519     void drawItemText(QPainter *painter, const QRect &rect,
1520                       int flags, const QPalette &pal, bool enabled,
1521                       const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const override;
1522     void drawItemPixmap(QPainter *painter, const QRect &rect,
1523                         int alignment, const QPixmap &pixmap) const override;
1524     QPalette standardPalette() const override;
1525     QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
1526                            const QWidget *widget = nullptr) const override; //### kde5 remove
1527     QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
1528                                 const QStyleOption *opt) const override;
1529     bool eventFilter(QObject *, QEvent *) override;
1530 
1531     int layoutSpacing(QSizePolicy::ControlType control1,
1532                       QSizePolicy::ControlType control2, Qt::Orientation orientation,
1533                       const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override;
1534 
1535     QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
1536                        const QWidget *widget = nullptr) const override;
1537 //@}
1538 private:
1539     K4StylePrivate *const d;
1540 };
1541 
1542 template<typename T>
1543 const char *kstyleName()
1544 {
1545     return "default";
1546 }
1547 
1548 /**
1549  * Template class which helps implementing the widget style plugin interface.
1550  *
1551  * You don't need to use this class directly. Use the following
1552  * macro (defined in kstyle.h) and you are done:
1553  * \code
1554  * K_EXPORT_STYLE("StyleName", StyleClassName)
1555  * \endcode
1556  */
1557 template<typename T>
1558 class K4StyleFactory: public QStylePlugin
1559 {
1560     QStringList keys() const
1561     {
1562         QStringList l;
1563         l << kstyleName<T>();
1564         return l;
1565     }
1566 
1567     QStyle *create(const QString &id) override
1568     {
1569         QStringList names = keys();
1570         //check whether included in the keys
1571         if (names.contains(id, Qt::CaseInsensitive)) {
1572             return new T();
1573         }
1574 
1575         return nullptr;
1576     }
1577 };
1578 
1579 template<typename T>
1580 T K4Style::extractOption(Option *option)
1581 {
1582     if (option) {
1583         if (dynamic_cast<T>(option)) {
1584             return static_cast<T>(option);
1585         }
1586         // Ugly hacks for when RTLD_GLOBAL is not used (quite common with plugins, really)
1587         // and dynamic_cast fails.
1588         // This is still partially broken as it doesn't take into account subclasses.
1589         // ### KDE5 do this somehow differently
1590         if (qstrcmp(typeid(*option).name(), typeid(typename std::remove_pointer<T>::type).name()) == 0) {
1591             return static_cast<T>(option);
1592         }
1593     }
1594 
1595     //### warn if cast failed?
1596 
1597     //since T is a pointer type, need this to get to the static.
1598     return static_cast<T>(nullptr)->defaultOption();
1599 }
1600 
1601 #define K_EXPORT_K4STYLE(name,type) template<> const char* kstyleName<type>() { return name; } \
1602     Q_EXPORT_PLUGIN(K4StyleFactory<type>)
1603 
1604 #endif