18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include "QtWidgets/qmenu.h"
21#include "QtWidgets/qmenubar.h"
23#include "QtWidgets/qstyleoption.h"
24#include "QtCore/qdatetime.h"
25#include "QtCore/qmap.h"
26#include "QtCore/qhash.h"
27#include "QtCore/qbasictimer.h"
28#include "private/qwidget_p.h"
30#include <qpa/qplatformmenu.h>
32#include <QtCore/qpointer.h>
97 , m_uni_directional(
false)
98 , m_select_other_actions(
false)
99 , m_use_reset_action(true)
128 m_time.
start(m_timeout, m_menu);
178 QSetValueOnDestroy<bool> setFirstMouse(m_first_mouse,
false);
179 QSetValueOnDestroy<QPointF> setPreviousPoint(m_previous_point, mousePos);
182 m_reset_action =
nullptr;
183 m_use_reset_action =
true;
184 }
else if (m_reset_action != resetAction) {
185 if (m_use_reset_action && resetAction) {
186 const QList<QAction *> actions = m_menu->
actions();
187 const int resetIdx = actions.indexOf(resetAction);
188 const int originIdx = actions.indexOf(m_origin_action);
189 if (resetIdx > -1 && originIdx > -1 &&
qAbs(resetIdx - originIdx) > 1)
190 m_use_reset_action =
false;
192 m_reset_action = resetAction;
195 if (m_action_rect.
contains(mousePos)) {
200 if (m_uni_directional && !m_first_mouse && resetAction != m_origin_action) {
204 left_to_right? sub_menu_rect.topLeft() : sub_menu_rect.topRight();
206 left_to_right? sub_menu_rect.bottomLeft() : sub_menu_rect.bottomRight();
207 qreal prev_slope_top =
slope(m_previous_point, sub_menu_top);
208 qreal prev_slope_bottom =
slope(m_previous_point, sub_menu_bottom);
210 qreal current_slope_top =
slope(mousePos, sub_menu_top);
211 qreal current_slope_bottom =
slope(mousePos, sub_menu_bottom);
213 bool slopeTop =
checkSlope(prev_slope_top, current_slope_top, sub_menu_top.y() < mousePos.
y());
214 bool slopeBottom =
checkSlope(prev_slope_bottom, current_slope_bottom, sub_menu_bottom.y() > mousePos.
y());
215 bool rightDirection =
false;
216 int mouseDir = int(m_previous_point.
y() - mousePos.
y());
218 rightDirection = rightDirection || slopeTop;
221 rightDirection = rightDirection || slopeBottom;
224 if (m_uni_dir_discarded_count >= m_uni_dir_fail_at_count && !rightDirection) {
225 m_uni_dir_discarded_count = 0;
230 m_uni_dir_discarded_count++;
232 m_uni_dir_discarded_count = 0;
248 QMenu *m_menu =
nullptr;
249 QAction *m_reset_action =
nullptr;
250 QAction *m_origin_action =
nullptr;
253 QPointer<QMenu> m_sub_menu;
256 short m_uni_dir_discarded_count = 0;
257 short m_uni_dir_fail_at_count = 0;
259 bool m_init_guard =
false;
260 bool m_first_mouse =
true;
263 bool m_uni_directional : 1;
264 bool m_select_other_actions : 1;
265 bool m_discard_state_when_entering_parent : 1;
266 bool m_dont_start_time_on_leave : 1;
267 bool m_use_reset_action : 1;
272 Q_DECLARE_PUBLIC(
QMenu)
332#ifdef QT_KEYPAD_NAVIGATION
333 QAction *selectAction =
nullptr;
334 QAction *cancelAction =
nullptr;
413 inline int indexOf(
QAction *act)
const {
return q_func()->actions().indexOf(act); }
452 QWidget *
parent =
nullptr, Qt::WindowFlags
f = Qt::WindowFlags());
The QAction class provides an abstraction for user commands that can be added to different user inter...
ActionEvent
This enum type is used when calling QAction::activate()
bool isSeparator() const
Returns true if this action is a separator action; otherwise it returns false.
void start(int msec, QObject *obj)
\obsolete Use chrono overload instead.
int timerId() const noexcept
Returns the timer's ID.
void stop()
Stops the timer.
bool isActive() const noexcept
Returns true if the timer is running and has not been stopped; otherwise returns false.
QObject * parent() const
Returns a pointer to the parent object.
The QPaintEvent class contains event parameters for paint events.
The QPainter class performs low-level painting on widgets and other paint devices.
\inmodule QtCore\reentrant
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
T * data() const noexcept
bool isNull() const noexcept
\inmodule QtCore\reentrant
bool contains(const QRectF &r) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore\reentrant
The QScreen class is used to query screen properties. \inmodule QtGui.
QSetValueOnDestroy(T &toSet, T value)
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
constexpr Policy verticalPolicy() const noexcept
Returns the vertical component of the size policy.
constexpr Policy horizontalPolicy() const noexcept
Returns the horizontal component of the size policy.
Policy
This enum describes the various per-dimension sizing types used when constructing a QSizePolicy.
\macro QT_RESTRICTED_CAST_FROM_ASCII
@ SH_Menu_SubMenuUniDirectionFailCount
@ SH_Menu_SubMenuUniDirection
@ SH_Menu_SubMenuResetWhenReenteringParent
@ SH_Menu_SubMenuSloppySelectOtherActions
@ SH_Menu_SubMenuDontStartSloppyOnLeave
@ SH_Menu_SubMenuSloppyCloseTimeout
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyIsNull(qfloat16 f) noexcept
constexpr T qAbs(const T &t)
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLbitfield GLuint64 timeout
[4]
#define QT_REQUIRE_CONFIG(feature)