1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: Hualet Wang <mr.asianwang@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DMENUBASE_H
#define DMENUBASE_H
// this event type was added in libxcb 1.10,
// but we support also older version
#ifndef XCB_GE_GENERIC
#define XCB_GE_GENERIC 35
#endif
#include <QWidget>
#include <QSharedPointer>
#include <QGraphicsDropShadowEffect>
#include <xcb/xcb.h>
#include <X11/extensions/XI2proto.h>
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"
// New and old version of this struct share the following fields:
typedef struct qt_xcb_ge_event_t {
uint8_t response_type;
uint8_t extension;
uint16_t sequence;
uint32_t length;
uint16_t event_type;
} qt_xcb_ge_event_t;
class QColor;
class QTimer;
class QMargins;
class QJsonArray;
class QByteArray;
class DMenuContent;
class DMenuBase : public QWidget
{
Q_OBJECT
public:
explicit DMenuBase(QWidget *parent = 0);
struct ItemStyle {
QColor itemBackgroundColor;
QColor itemTextColor;
QColor itemShortcutColor;
QString checkmarkIcon;
QString subMenuIndicatorIcon;
};
Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
Q_PROPERTY(QMargins shadowMargins READ shadowMargins WRITE setShadowMargins NOTIFY shadowMarginsChanged)
Q_PROPERTY(QMargins menuContentMargins READ menuContentMargins WRITE setMenuContentMargins NOTIFY menuContentMarginsChanged)
Q_PROPERTY(int itemLeftSpacing READ itemLeftSpacing WRITE setItemLeftSpacing NOTIFY itemLeftSpacingChanged)
Q_PROPERTY(int itemCenterSpacing READ itemCenterSpacing WRITE setItemCenterSpacing NOTIFY itemCenterSpacingChanged)
Q_PROPERTY(int itemRightSpacing READ itemRightSpacing WRITE setItemRightSpacing NOTIFY itemRightSpacingChanged)
int radius();
void setRadius(int);
QMargins shadowMargins();
void setShadowMargins(QMargins);
QMargins menuContentMargins();
void setMenuContentMargins(QMargins);
int itemLeftSpacing();
void setItemLeftSpacing(int);
int itemCenterSpacing();
void setItemCenterSpacing(int);
int itemRightSpacing();
void setItemRightSpacing(int);
QSharedPointer<DMenuContent> menuContent();
void setMenuContent(QSharedPointer<DMenuContent> content);
DMenuBase *subMenu();
void setContent(QJsonArray items);
void destroyAll();
void grabFocus();
void releaseFocus();
DMenuBase *menuUnderPoint(QPoint);
DMenuBase *getRootMenu();
void setItemActivity(const QString &itemId, bool isActive);
void setItemChecked(const QString &itemId, bool checked);
void setItemText(const QString &itemId, const QString &text);
const ItemStyle normalStyle();
const ItemStyle hoverStyle();
const ItemStyle inactiveStyle();
virtual void setPosition(int, int) = 0;
virtual void showSubMenu(int, int, QJsonObject) = 0;
signals:
void radiusChanged(int radius);
void shadowMarginsChanged(QMargins shadowWidth);
void menuContentMarginsChanged(QMargins menuContentMargins);
void itemBackgroundColorChanged(QColor itemBackgroundColor);
void itemTextColorChanged(QColor itemTextColor);
void itemShortcutColorChanged(QColor itemShortcutColor);
void itemLeftSpacingChanged(int itemLeftSpacing);
void itemCenterSpacingChanged(int itemCenterSpacing);
void itemRightSpacingChanged(int itemRightSpacing);
void itemClicked(QString id, bool checked);
protected:
DMenuBase *_subMenu;
ItemStyle _normalStyle;
ItemStyle _hoverStyle;
ItemStyle _inactiveStyle;
virtual bool nativeEvent(const QByteArray &, void *, long *);
private slots:
void grabFocusSlot();
private:
int xiErrorBase;
int xiEventBase;
int xiOpCode;
int _radius;
QMargins _shadowMargins;
QMargins _menuContentMargins;
int _itemLeftSpacing;
int _itemCenterSpacing;
int _itemRightSpacing;
QSharedPointer<DMenuContent> _menuContent;
QGraphicsDropShadowEffect *_dropShadow;
QTimer *_grabFocusTimer;
void queryXIExtension();
bool isXIEvent(xcb_generic_event_t *event, int opCode);
bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type);
qreal fixed1616ToReal(FP1616 val);
bool grabFocusInternal(int);
void updateAll();
};
#endif // DMENUBASE_H
|