|
|
/* This file is part of the KDE libraries Copyright (C) 1999 Daniel M. DuleyThis 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 #include #include #include #include #include #include #include #define WIDGETS 54 /** * This class adds simple time management to KPixmap for use in flushing * KThemeCache. * * @author Daniel M. Duley */ 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 * */ 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 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 */ 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: dfaure on kde.faure.org on Thu Jan 17 22:16:05 2002, using kdoc 2.0a53. |