# Source: kthemebase.h |
Annotated List
Files
Globals
Hierarchy
Index

    /* This file is part of the KDE libraries
       Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>

       This library is free software; you can redistribute it and/or
       modify it under the terms of the GNU Library General Public
       License version 2 as published by the Free Software Foundation.

       This library is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       Library General Public License for more details.

       You should have received a copy of the GNU Library General Public License
       along with this library; see the file COPYING.LIB.  If not, write to
       the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       Boston, MA 02111-1307, USA.
    */
    #ifndef __KTHEMEBASE_H
    #define __KTHEMEBASE_H

    #include <qdatetime.h>
    #include <qtimer.h>
    #include <kstyle.h>
    #include <kpixmap.h>
    #include <kconfig.h>
    #include <qimage.h>
    #include <qintcache.h>
    #include <qstring.h>

    #define WIDGETS 54

    /**
     * This class adds simple time management to KPixmap for use in flushing
     * KThemeCache.
     *
     * @author Daniel M. Duley <mosfet@kde.org>
     */
    class KThemePixmap : public KPixmap
    {
    public:
        enum BorderType{Top=0, Bottom, Left, Right, TopLeft, TopRight, BottomLeft,
        BottomRight};

        KThemePixmap(bool timer = true);
        KThemePixmap(const KThemePixmap &p);
        ~KThemePixmap();
        QPixmap* border(BorderType type);
        void setBorder(BorderType type, const QPixmap &p);
        void updateAccessed();
        bool isOld();
    protected:
        QTime *t;
        QPixmap *b[8];

    private:
        class KThemePixmapPrivate;
        KThemePixmapPrivate *d;
    };

    inline QPixmap* KThemePixmap::border(BorderType type)
    {
        return(b[type]);
    }

    inline void KThemePixmap::setBorder(BorderType type, const QPixmap &p)
    {
        if(b[type]){
            qWarning("KThemePixmap: Overwriting existing border!");
            delete(b[type]);
        }
        b[type] = new QPixmap(p);
    }

    inline void KThemePixmap::updateAccessed()
    {
        if (t)
            t->start();
    }

    inline bool KThemePixmap::isOld()
    {
        return(t ? t->elapsed() >= 300000 : false);
    }

    /**
     * A very simple pixmap cache for theme plugins. QPixmapCache is not used
     * since it uses QString keys which are not needed. All the information we
     * need can be encoded in a numeric key. Using QIntCache instead allows us to
     * skip the string operations.
     *
     * This class is mostly just inline methods that do bit operations on a key
     * composed of the widget ID, width and/or height, and then calls
     * QIntCache::find().
     *
     * One other thing to note is that full, horizontal, and vertically scaled
     * pixmaps are not used interchangeably. For example, if you insert a fully
     * scaled pixmap that is 32x32 then request a horizontally scaled pixmap with
     * a width of 32, they will not match. This is because a pixmap that has been
     * inserted into the cache has already been scaled at some point and it is
     * very likely the vertical height was not originally 32. Thus the pixmap
     * will be wrong when drawn, even though the horizontal width matches.
     *
     * @author Daniel M. Duley <mosfet@kde.org>
     *
     */
    class KThemeCache : public QObject
    {
        Q_OBJECT
    public:
        /**
         * The scale hints supported by the cache. Note that Tiled is not here
         * since tiled pixmaps are kept only once in KThemeBase.
         */
        enum ScaleHint{FullScale, HorizontalScale, VerticalScale};
        /**
         * The constructor.
         *
         * @param maxSize The maximum size of the cache in kilobytes.
         */
        KThemeCache(int maxSize, QObject *parent=0, const char *name=0);
        /**
         * Inserts a new pixmap into the cache.
         *
         * @param pixmap The pixmap to insert.
         * @param scale The scaling type of the pixmap.
         * @param widgetID The widget ID of the pixmap, usually from KThemeBase's
         * WidgetType enum.
         *
         * @return True if the insert was successful, false otherwise.
         */
        bool insert(KThemePixmap *pixmap, ScaleHint scale, int widgetID,
                   bool border=false, bool mask=false);
        /**
         * Returns a fully scaled pixmap.
         *
         * @param w The pixmap width to search for.
         * @param h The pixmap height to search for.
         * @param widgetID The widget ID to search for.
         *
         * @return True if a pixmap matching the width, height, and widget ID of
         * the pixmap exists, NULL otherwise.
         */
        KThemePixmap* pixmap(int w, int h, int widgetID, bool border=false,
                             bool mask=false);
        /**
         * Returns a horizontally scaled pixmap.
         *
         * @param w The pixmap width to search for.
         * @param widgetID The widget ID to search for.
         *
         * @return True if a pixmap matching the width and widget ID of
         * the pixmap exists, NULL otherwise.
         */
        KThemePixmap* horizontalPixmap(int w, int widgetID);
        /**
         * Returns a vertically scaled pixmap.
         *
         * @param h The pixmap height to search for.
         * @param widgetID The widget ID to search for.
         *
         * @return True if a pixmap matching the height and widget ID of
         * the pixmap exists, NULL otherwise.
         */
        KThemePixmap* verticalPixmap(int h, int widgetID);
    protected slots:
        void flushTimeout();
    protected:
        QIntCache<KThemePixmap> cache;
        QTimer flushTimer;

    private:
        class KThemeCachePrivate;
        KThemeCachePrivate *d;
    };

    /**
     * This is a base class for KDE themed styles. It implements a cache,
     * configuration file parsing, pixmap scaling, gradients, and a lot
     * of inline methods for accessing user specified parameters.
     *
     * Note that this class *does not* actually implement any themes. It just
     * provides the groundwork for doing so. The only reason to use this class
     * directly is if you plan to reimplement all of the widgets. Otherwise,
     * refer to KThemeStyle for a fully themed style you can derive from.
     *
     * @author Daniel M. Duley <mosfet@kde.org>
     */
    class KThemeBase: public KStyle
    {
        Q_OBJECT
    public:
        /**
         * Constructs a new KThemeBase object.
         */
        KThemeBase(const QString &configFile);
        ~KThemeBase();
        /**
         * Describes if a pixmap should be scaled fully, horizontally, vertically,
         * or not at all and tiled.
         */
        enum ScaleHint{FullScale, HorizontalScale, VerticalScale, TileScale};
        /**
         * The default arrow types.
         */
        enum ArrowStyle{MotifArrow, LargeArrow, SmallArrow};
        /**
         * The default frame shading styles.
         */
        enum ShadeStyle{Motif, Windows, Next, KDE};
        /**
         * The default scrollbar button layout. BottomLeft is like what Next
         * uses, BottomRight is like Platinum, and Opposite it like Windows and
         * Motif.
         */
         enum SButton{SBBottomLeft, SBBottomRight, SBOpposite};
        /**
         * The gradient types. Horizontal is left to right, Vertical is top to
         * bottom, and diagonal is upper-left to bottom-right.
         */
         enum Gradient{GrNone, GrHorizontal, GrVertical, GrDiagonal, GrPyramid,
         GrRectangle, GrElliptic, GrReverseBevel};
        /**
         * This provides a list of widget types that KThemeBase recognizes.
         */
        /* Internal note: The order here is important. Some widgets inherit
         * properties. This is usually for when you have two settings for the
         * same widget, ie: on(sunken), and off. The on settings will inherit
         * the properties of the off one when nothing is specified in the config.
         *
         * In order to be able to handle this while still having everything in
         * one group that is easy to loop from we have the following order:
         * unsunked(off) items, sunken(on)items, and then the ones that don't
         * matter. INHERIT_ITEMS define the number of widgets that have inheritence
         * so if 0 == PushButtonOff then INHERIT_ITEMS should == PushButtonOn
         * and so on. WIDGETS define the total number of widgets.
         */
         enum WidgetType{
             // Off (unsunken widgets)
             PushButton=0, ComboBox, HScrollBarSlider, VScrollBarSlider, Bevel,
             ToolButton, ScrollButton, HScrollDeco, VScrollDeco,
             ComboDeco, MenuItem, InactiveTab, ArrowUp, ArrowDown, ArrowLeft,
             ArrowRight,
             // On (sunken widgets)
             PushButtonDown, ComboBoxDown, HScrollBarSliderDown,
             VScrollBarSliderDown, BevelDown, ToolButtonDown, ScrollButtonDown,
             HScrollDecoDown, VScrollDecoDown, ComboDecoDown, MenuItemDown,
             ActiveTab, SunkenArrowUp, SunkenArrowDown, SunkenArrowLeft,
             SunkenArrowRight,
             // Everything else (indicators must have separate settings)
             HScrollGroove, VScrollGroove, Slider, SliderGroove, IndicatorOn,
             IndicatorOff, ExIndicatorOn, ExIndicatorOff, HBarHandle, VBarHandle,
             ToolBar, Splitter, CheckMark, MenuBar, DisArrowUp, DisArrowDown,
             DisArrowLeft, DisArrowRight, ProgressBar, ProgressBg, MenuBarItem,
             Background};

        /**
         * The scaling type specified by the KConfig file.
         *
         * @param widget A Widgets enum value.
         *
         * @return A ScaleHint enum value.
         */
        ScaleHint scaleHint(WidgetType widget) const;
        /**
         * The gradient type specified by the KConfig file.
         *
         * @param widget A Widgets enum value.
         *
         * @return A Gradient enum value.
         */
        Gradient gradientHint(WidgetType widget) const;
        /**
         * The color group specified for a given widget.
         * If a color group is set in the theme configuration
         * that is used, otherwise defaultColor is returned.
         *
         * @param defaultColor The colorGroup to set if one is available.
         *
         * @param widget The widget whose color group to retrieve.
         *
         */
        const QColorGroup* colorGroup(const QColorGroup &defaultGroup,
                                WidgetType widget) const;

        QBrush pixmapBrush(const QColorGroup &group, QColorGroup::ColorRole role,
                           int w, int h, WidgetType widget);
        /**
         * True if the widget has a pixmap or gradient specified.
         */
        bool isPixmap(WidgetType widget) const;
        /**
         * True if the widget has a color group specified.
         */
        bool isColor(WidgetType widget) const;
        /**
         * True if the user specified a 3D focus rectangle
         */
        bool is3DFocus() const;
        /**
         * If the user specified a 3D focus rectangle, they may also specify an
         * offset from the default rectangle to use when drawing it. This returns
         * the specified offset.
         */
        int focusOffset() const;
        /**
         * The border width of the specified widget.
         */
        int borderWidth(WidgetType widget) const;
        /**
         * Pixmap border width of the specified widget.
         */
        int pixBorderWidth(WidgetType widget) const;
        /**
         * Returns the border pixmap if enabled for the specified widget. This
         * will contain the originial pixmap, plus the edges separated in
         * KThemePixmap::border() if valid. If invalid it will return NULL.
         */
        KThemePixmap* borderPixmap(WidgetType widget);
        /**
         * The highlight width of the specified widget.
         */
        int highlightWidth(WidgetType widget) const;
        /**
         * The border plus highlight width of the widget.
         */
        int decoWidth(WidgetType widget) const;
        /**
         * The extent (width for vertical, height for horizontal) requested
         * for the scrollbars.
         */
        int getSBExtent() const;
        /**
         * The scrollbar button layout.
         */
        SButton scrollBarLayout() const;
        /**
         * The arrow type.
         */
        ArrowStyle arrowType() const;
        /**
         * The shading type.
         */
        ShadeStyle shade() const;
        /**
         * The frame width.
         */
        int frameWidth() const;
        /**
         * The splitter width.
         */
        int splitWidth() const;
        /**
         * The contrast for some bevel effects such as reverse gradient.
         */
        int bevelContrast(WidgetType widget) const;
        /**
         * The button text X shift.
         */
        int buttonXShift() const;
        /**
         * The button text Y shift.
         */
        int buttonYShift() const;
        /**
         * Returns either the slider length of the slider pixmap if available,
         * otherwise the length specified in the config file.
         */
        int sliderButtonLength() const;
        /**
         * True if rounded buttons are requested.
         */
        bool roundButton() const;
        /**
         * True if rounded comboboxes are requested.
         */
        bool roundComboBox() const;
        /**
         * True if rounded slider grooves are requested.
         */
        bool roundSlider() const;
        /**
         * True if a line should be drawn on the bottom of active tabs.
         */
        bool activeTabLine() const;
        /**
         * True if a line should be drawn on the bottom of inactive tabs.
         */
        bool inactiveTabLine() const;
        /**
         * Returns the current uncached pixmap for the given widget. This will
         * usually be either the last scaled or gradient pixmap if those have
         * been specified in the config file, the original pixmap if not, or NULL
         * if no pixmap has been specified.
         */
        KThemePixmap* uncached(WidgetType widget) const;
        /**
         * Returns the pixmap for the given widget at the specified width and
         * height. This will return NULL if no pixmap or gradient is specified.
         * It may also return a different sized pixmap if the scaling
         * is set to Tiled. When using this method, you should call it using
         * the needed width and height then use QPainter::drawTiledPixmap to
         * paint it. Doing this, if the pixmap is scaled it will be the proper
         * size, otherwise it will be tiled.
         *
         * @param w Requested width.
         * @param h Requested height.
         * @param widget Widget type.
         * @return The pixmap or NULL if one is not specified.
         */
        virtual KThemePixmap *scalePixmap(int w, int h, WidgetType widget);
        /**
         * This method reads a configuration file and applies it to the user's
         * kstylerc file. It does not signal applications to reload via the
         * KDEChangeGeneral atom, if you want to do this you must do so yourself.
         * See kcmdisplay's general.cpp for an example.
         *
         * @param file The configuration file to apply.
         */
        static void applyConfigFile(const QString &file);
    protected:
        /**
         * Returns a QImage for the given widget if the widget is scaled, NULL
         * otherwise. QImages of the original pixmap are stored for scaled
         * widgets in order to facilitate fast and accurate smooth-scaling. This
         * also saves us a conversion from a pixmap to an image then back again.
         */
        QImage* image(WidgetType widget) const;
        /**
         * Returns the gradient high color if one is specified, NULL otherwise.
         */
        QColor* gradientHigh(WidgetType widget) const;
        /**
         * Returns the gradient low color if one is specified, NULL otherwise.
         */
        QColor* gradientLow(WidgetType widget) const;
        /**
         * Reads in all the configuration file entries supported.
         *
         * @param colorStyle The style for the color groups. In KDE, colors were
         * calculated a little differently for Motif vs Windows styles. This
         * is obsolete.
         */
        void readConfig(Qt::GUIStyle colorStyle = Qt::WindowsStyle);
        void readWidgetConfig(int i, KConfig *config, QString *pixnames,
                              QString *brdnames, bool *loadArray);
        void copyWidgetConfig(int sourceID, int destID, QString *pixnames,
                             QString *brdnames);
        /**
         * Makes a full color group based on the given foreground and background
         * colors. This is the same code used by KDE (kapp.cpp) in previous
         * versions.
         */
        QColorGroup* makeColorGroup(QColor &fg, QColor &bg,
                                    Qt::GUIStyle style = Qt::WindowsStyle);
        KThemePixmap* scale(int w, int h, WidgetType widget);
        KThemePixmap* scaleBorder(int w, int h, WidgetType type);
        KThemePixmap* gradient(int w, int h, WidgetType widget);
        KThemePixmap* blend(WidgetType widget);
        void generateBorderPix(int i);
        void applyResourceGroup(KConfig *config, int i);
        void applyMiscResourceGroup(KConfig *config);
        void readResourceGroup(int i, QString *pixnames, QString *brdnames,
                              bool *loadArray);
        void readMiscResourceGroup();
        /**
         * Attempts to load a pixmap from the default KThemeBase locations.
         */
        KThemePixmap* loadPixmap(QString &name);
        /**
         * Attempts to load a image from the default KThemeBase locations.
         */
        QImage* loadImage(QString &name);
    private:
        SButton sbPlacement;
        ArrowStyle arrowStyle;
        ShadeStyle shading;
        int defaultFrame;
        int btnXShift, btnYShift;
        int sliderLen;
        int splitterWidth;
        int focus3DOffset;
        int sbExtent;
        bool smallGroove;
        bool roundedButton, roundedCombo, roundedSlider;
        bool aTabLine, iTabLine;
        bool focus3D;
        KThemeCache *cache;
        int cacheSize;
        QString configFileName;

        /**
         * The theme pixmaps. Many of these may be NULL if no pixmap is specified.
         * There may also be duplicate pixmap pointers if more than one widget
         * uses the same tiled pixmap. If a pixmap is tiled, it is kept here and
         * this acts as a cache. Otherwise this will hold whatever the last scaled
         * pixmap was.
         */
        KThemePixmap *pixmaps[WIDGETS];
        /**
         * The theme images. These are for scaled images and are kept in order
         * to maintain fast smoothscaling.
         */
        QImage *images[WIDGETS];
        /**
         * The border widths
         */
        unsigned char borders[WIDGETS];
        /**
         * The highlight widths
         */
        unsigned char highlights[WIDGETS];
        /**
         * The scale hints for pixmaps and gradients.
         */
        ScaleHint scaleHints[WIDGETS];
        /**
         * All the color groups.
         */
        QColorGroup *colors[WIDGETS];
        /**
         * Gradient low colors (or blend background).
         */
        QColor *grLowColors[WIDGETS];
        /**
         * Gradient high colors.
         */
        QColor *grHighColors[WIDGETS];
        /**
         * Gradient types.
         */
        Gradient gradients[WIDGETS];
        /**
         * Blend intensity factors
         */
        float blends[WIDGETS];
        /**
         * Bevel contrasts
         */
        unsigned char bContrasts[WIDGETS];
        /**
         * Duplicate pixmap entries (used during destruction).
         */
        bool duplicate[WIDGETS];
        /**
         * Pixmapped border widths
         */
        int pbWidth[WIDGETS];
        /**
         * Pixmapped borders
         */
        KThemePixmap *pbPixmaps[WIDGETS];
        /**
         * Duplicate border pixmapped border entries
         */
        bool pbDuplicate[WIDGETS];

    private:
        class KThemeBasePrivate;
        KThemeBasePrivate *d;

    };

    inline bool KThemeBase::isPixmap( WidgetType widget) const
    {
        return(pixmaps[widget] != NULL || gradients[widget] != GrNone);
    }

    inline bool KThemeBase::isColor(WidgetType widget) const
    {
        return(colors[widget] != NULL);
    }

    inline bool KThemeBase::is3DFocus() const
    {
        return(focus3D);
    }

    inline int KThemeBase::focusOffset() const
    {
        return(focus3DOffset);
    }

    inline int KThemeBase::bevelContrast(WidgetType widget) const
    {
        return(bContrasts[widget]);
    }

    inline KThemeBase::ScaleHint KThemeBase::scaleHint(WidgetType widget) const
    {
        return((widget < WIDGETS) ? scaleHints[widget] : TileScale);
    }

    inline KThemeBase::Gradient KThemeBase::gradientHint(WidgetType widget) const
    {
        return((widget < WIDGETS) ? gradients[widget] : GrNone);
    }

    inline KThemePixmap* KThemeBase::uncached(WidgetType widget) const
    {
        return(pixmaps[widget]);
    }

    inline QBrush KThemeBase::pixmapBrush(const QColorGroup &group,
                                          QColorGroup::ColorRole role,
                                          int w, int h, WidgetType widget)
    {
        if(pixmaps[widget] || images[widget])
            return(QBrush(group.color(role), *scalePixmap(w, h, widget)));
        else
            return(group.color(role));
    }

    inline const QColorGroup* KThemeBase::colorGroup(const QColorGroup &defaultGroup,
                                                     WidgetType widget) const
    {
        return((colors[widget]) ? colors[widget] : &defaultGroup);
    }

    inline int KThemeBase::borderWidth(WidgetType widget) const
    {
        return(pbWidth[widget] ? pbWidth[widget] : borders[widget]);
    }

    inline int KThemeBase::pixBorderWidth(WidgetType widget) const
    {
        return(pbWidth[widget]);
    }

    inline int KThemeBase::highlightWidth(WidgetType widget) const
    {
        return(pbWidth[widget] ? 0 : highlights[widget]);
    }

    inline int KThemeBase::decoWidth(WidgetType widget) const
    {
        return(pbWidth[widget] ? pbWidth[widget] : borders[widget]+highlights[widget]);
    }

    inline QColor* KThemeBase::gradientHigh(WidgetType widget) const
    {
        return(grHighColors[widget]);
    }

    inline QColor* KThemeBase::gradientLow(WidgetType widget) const
    {
        return(grLowColors[widget]);
    }

    inline QImage* KThemeBase::image(WidgetType widget) const
    {
        return(images[widget]);
    }

    inline KThemeBase::SButton KThemeBase::scrollBarLayout() const
    {
        return(sbPlacement);
    }

    inline KThemeBase::ArrowStyle KThemeBase::arrowType() const
    {
        return(arrowStyle);
    }

    inline KThemeBase::ShadeStyle KThemeBase::shade() const
    {
        return(shading);
    }

    inline int KThemeBase::frameWidth() const
    {
        return(defaultFrame);
    }

    inline int KThemeBase::buttonXShift() const
    {
        return(btnXShift);
    }

    inline int KThemeBase::splitWidth() const
    {
        return(splitterWidth);
    }

    inline int KThemeBase::buttonYShift() const
    {
        return(btnYShift);
    }

    inline int KThemeBase::sliderButtonLength() const
    {
        if(isPixmap(Slider))
            return(uncached(Slider)->width());
        else
            return(sliderLen);
    }

    inline bool KThemeBase::roundButton() const
    {
        return(roundedButton);
    }

    inline bool KThemeBase::roundComboBox() const
    {
        return(roundedCombo);
    }

    inline bool KThemeBase::roundSlider() const
    {
        return(roundedSlider);
    }

    inline bool KThemeBase::activeTabLine() const
    {
        return(aTabLine);
    }

    inline bool KThemeBase::inactiveTabLine() const
    {
        return(iTabLine);
    }

    inline int KThemeBase::getSBExtent() const
    {
        return(sbExtent);
    }

    inline KThemePixmap* KThemeBase::borderPixmap(WidgetType widget)
    {
        return(pbPixmaps[widget]);
    }

    #endif

Generated by: root@i386.ports.openbsd.org on Wed Apr 25 13:58:24 2001, using kdoc 2.0a53.