1 /* This file is part of the KDE project 2 Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 3 Copyright (C) 2011-2013 Jarosław Staniek <staniek@kde.org> 4 5 Based on qmenu_p.h from Qt 4.7 6 7 based on oxygenhelper.h 8 9 Copyright 2009-2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org> 10 Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com> 11 Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net> 12 Copyright 2007 C. Boemann <cbo@boemann.dk> 13 Copyright 2007 Fredrik Höglund <fredrik@kde.org> 14 15 This library is free software; you can redistribute it and/or 16 modify it under the terms of the GNU Library General Public 17 License as published by the Free Software Foundation; either 18 version 2 of the License, or (at your option) any later version. 19 20 This library is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 Library General Public License for more details. 24 25 You should have received a copy of the GNU Library General Public License 26 along with this library; see the file COPYING.LIB. If not, write to 27 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 28 * Boston, MA 02110-1301, USA. 29 */ 30 31 #ifndef KEXIMENUWIDGET_P_H 32 #define KEXIMENUWIDGET_P_H 33 34 #include "KexiMenuWidget.h" 35 36 #include <KSharedConfig> 37 38 #include <QStyleOption> 39 #include <QCache> 40 #include <QMap> 41 #include <QHash> 42 #include <QBasicTimer> 43 #include <QPointer> 44 #include <QAbstractButton> 45 46 class QEventLoop; 47 48 //! Used to define transparent clickable logo area 49 class ClickableLogoArea : public QAbstractButton 50 { 51 Q_OBJECT 52 public: 53 explicit ClickableLogoArea(QWidget *parent = 0); 54 protected Q_SLOTS: 55 void slotClicked(); 56 protected: 57 virtual void paintEvent(QPaintEvent*); 58 }; 59 60 //used to walk up the popup list 61 struct KexiMenuWidgetCaused { 62 QPointer<QWidget> widget; 63 QPointer<QAction> action; 64 }; 65 66 class OxygenHelper 67 { 68 public: 69 OxygenHelper(); 70 virtual ~OxygenHelper(); 71 bool lowThreshold(const QColor &color); 72 bool highThreshold(const QColor &color); 73 virtual const QColor& backgroundTopColor(const QColor &color); 74 virtual const QColor& backgroundBottomColor(const QColor &color); 75 virtual const QColor& backgroundRadialColor(const QColor &color); 76 virtual QPixmap verticalGradient(const QColor &color, int height, int offset = 0); 77 virtual QPixmap radialGradient(const QColor &color, int width, int height = 64); 78 void renderOxygenWindowBackground(QPainter *p, const QRect &clipRect, 79 const QWidget *widget, const QWidget* window, 80 const QColor& color, int y_shift=-23, 81 int gradientHeight = 64); 82 83 //!@name window background gradients 84 //@{ 85 /*! 86 \par y_shift: shift the background gradient upwards, to fit with the windec 87 \par gradientHeight: the height of the generated gradient. 88 for different heights, the gradient is translated so that it is always at the same position from the bottom 89 */ 90 void renderWindowBackground(QPainter *p, const QRect &clipRect, 91 const QWidget *widget, const QPalette & pal, 92 int y_shift=-23, int gradientHeight = 64); 93 94 void renderMenuBackground(QPainter* p, const QRect& clipRect, const QWidget* widget, 95 const QPalette& pal); 96 void renderMenuBackground(QPainter*, const QRect&, const QWidget*, const QColor&); 97 98 //! draw frame that mimics some sort of shadows around a panel 99 /*! it is used for menus, detached dock panels and toolbar, 100 as well as window decoration when compositing is disabled */ 101 // virtual void drawFloatFrame( 102 // QPainter *p, const QRect r, const QColor &color, 103 // bool drawUglyShadow=true, bool isActive=false, 104 // const QColor &frameColor=QColor(), 105 // TileSet::Tiles tiles = TileSet::Ring 106 // ); 107 108 typedef QCache<quint64, QPixmap> PixmapCache; 109 typedef QCache<quint64, QColor> ColorCache; 110 typedef QMap<quint32, bool> ColorMap; 111 112 PixmapCache m_backgroundCache; 113 ColorCache m_backgroundTopColorCache; 114 ColorCache m_backgroundBottomColorCache; 115 ColorCache m_backgroundRadialColorCache; 116 ColorMap m_lowThreshold; 117 ColorMap m_highThreshold; 118 119 KSharedConfigPtr _config; 120 qreal _contrast; 121 qreal _bgcontrast; 122 }; 123 124 class KexiMenuWidgetPrivate // : public QWidgetPrivate 125 { 126 public: KexiMenuWidgetPrivate(KexiMenuWidget * menu)127 explicit KexiMenuWidgetPrivate(KexiMenuWidget *menu) : q(menu), itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), 128 collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0), 129 currentAction(0), 130 scroll(0), eventLoop(0), /*tearoff(0),*/ /*tornoff(0),*/ /*tearoffHighlighted(0),*/ 131 hasCheckableItems(0), sloppyAction(0), /* doChildEffects(false)*/ 132 hasFrame(true), clickableLogoArea(0) 133 { 134 } ~KexiMenuWidgetPrivate()135 virtual ~KexiMenuWidgetPrivate() 136 { 137 delete scroll; 138 //! @todo KEXI3 port OxygenHelper 139 #if 0 140 delete oxygenHelper; 141 #endif 142 } 143 void init(); 144 145 //static KexiMenuWidgetPrivate *get(KexiMenuWidgetPrivate *m) { return m->d_func(); } 146 int scrollerHeight() const; 147 148 KexiMenuWidget *q; 149 150 //item calculations 151 mutable int itemsDirty; 152 mutable int maxIconWidth, tabWidth; 153 QRect actionRect(QAction *) const; 154 155 mutable QVector<QRect> actionRects; 156 mutable QHash<QAction *, QWidget *> widgetItems; 157 void updateActionRects() const; 158 QRect popupGeometry(const QWidget *widget) const; 159 QRect popupGeometry(int screen = -1) const; 160 mutable int ncols : 4; //4 bits is probably plenty 161 bool collapsibleSeparators; 162 163 bool activationRecursionGuard; 164 165 //selection 166 static KexiMenuWidget *mouseDown; 167 QPoint mousePopupPos; 168 int hasHadMouse; 169 int aboutToHide; 170 int motions; 171 QAction *currentAction; 172 QBasicTimer menuDelayTimer; 173 QWidget *topCausedWidget() const; 174 QAction *actionAt(QPoint p) const; 175 void setFirstActionActive(); 176 void setCurrentAction(QAction *, int popup = -1, KexiMenuWidget::SelectionReason reason = KexiMenuWidget::SelectedFromElsewhere, bool activateFirst = false); 177 //void popupAction(QAction *, int, bool); 178 void setSyncAction(); 179 180 //scrolling support 181 struct QMenuScroller { 182 enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter }; 183 enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; 184 uint scrollFlags : 2, scrollDirection : 2; 185 int scrollOffset; 186 QBasicTimer scrollTimer; 187 QMenuScrollerQMenuScroller188 QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } ~QMenuScrollerQMenuScroller189 ~QMenuScroller() { } 190 } *scroll; 191 void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); 192 void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); 193 void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false); 194 195 //synchronous operation (ie exec()) 196 QEventLoop *eventLoop; 197 QPointer<QAction> syncAction; 198 199 //search buffer 200 QString searchBuffer; 201 QBasicTimer searchBufferTimer; 202 203 //passing of mouse events up the parent hierarchy 204 QPointer<KexiMenuWidget> activeMenu; 205 bool mouseEventTaken(QMouseEvent *); 206 207 virtual QList<QPointer<QWidget> > calcCausedStack() const; 208 KexiMenuWidgetCaused causedPopup; 209 void hideUpToMenuBar(); 210 void hideMenu(KexiMenuWidget *menu, bool justRegister = false); 211 212 //index mappings actionAt(int i)213 inline QAction *actionAt(int i) const { return q->actions().at(i); } indexOf(QAction * act)214 inline int indexOf(QAction *act) const { return q->actions().indexOf(act); } 215 216 //tear off support 217 // uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1; 218 // QPointer<QTornOffMenu> tornPopup; 219 220 mutable bool hasCheckableItems; 221 222 //sloppy selection 223 static int sloppyDelayTimer; 224 mutable QAction *sloppyAction; 225 QRegion sloppyRegion; 226 227 //default action 228 QPointer<QAction> defaultAction; 229 230 QAction *menuAction; 231 QAction *defaultMenuAction; 232 233 void setOverrideMenuAction(QAction *); 234 void overrideMenuActionDestroyed(); 235 236 //firing of events 237 void activateAction(QAction *, QAction::ActionEvent, bool self=true); 238 void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); 239 240 void actionTriggered(); 241 void actionHovered(); 242 243 bool hasMouseMoved(const QPoint &globalPos); 244 245 void setLayoutDirection_helper(Qt::LayoutDirection direction); 246 247 void updateLayoutDirection(); 248 249 void setLayoutDirection_helper(QWidget* w, Qt::LayoutDirection direction); 250 251 int frameWidth(const QStyleOption* opt = 0) const; 252 253 bool actionPersistentlySelected(const QAction* action) const; 254 255 void setActionPersistentlySelected(QAction* action, bool set); 256 257 void toggleActionPersistentlySelected(QAction* action); 258 259 //menu fading/scrolling effects 260 //bool doChildEffects; 261 262 QPointer<QAction> actionAboutToTrigger; 263 QPointer<QWidget> noReplayFor; 264 //! Frame visibility 265 bool hasFrame; 266 267 QPointer<KexiMenuWidgetAction> previousPersistentlySelectedAction; 268 269 //! True if persistent selections are enabled. False by default. 270 //bool persistentSelectionsEnabled; 271 272 //! @todo KEXI3 port OxygenHelper 273 #if 0 274 OxygenHelper *oxygenHelper; 275 #endif 276 bool bespin; 277 bool qtcurve; 278 279 //! @return y coordinate of bottom margin of last menu item 280 int bottomOfLastItem() const; 281 int logoBottomMargin() const; 282 void updateLogo(); 283 void updateLogoPixmap(); 284 QPixmap calligraLogoPixmap; 285 ClickableLogoArea *clickableLogoArea; 286 QWidget *socialWidget; 287 QFont smallTextFont; 288 }; 289 290 #endif // KEXIMENUWIDGET_P_H 291