mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
190 lines
4.7 KiB
C++
190 lines
4.7 KiB
C++
#ifndef VCAPTAIN_H
|
|
#define VCAPTAIN_H
|
|
|
|
#include <functional>
|
|
|
|
#include <QWidget>
|
|
#include <QVector>
|
|
#include <QHash>
|
|
|
|
class QKeyEvent;
|
|
class VNavigationMode;
|
|
class QShortcut;
|
|
|
|
// bool func(void *p_target, void *p_data);
|
|
// Return true if the target needs to restore focus by the Captain.
|
|
typedef std::function<bool(void *, void *)> CaptainFunc;
|
|
|
|
|
|
// Will be passed to CaptainFunc as the data.
|
|
struct CaptainData
|
|
{
|
|
CaptainData(QWidget *p_focusWidgetBeforeCaptain)
|
|
: m_focusWidgetBeforeCaptain(p_focusWidgetBeforeCaptain)
|
|
{
|
|
}
|
|
|
|
QWidget *m_focusWidgetBeforeCaptain;
|
|
};
|
|
|
|
|
|
class VCaptain : public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit VCaptain(QWidget *p_parent);
|
|
|
|
// Register a target for Navigation mode.
|
|
void registerNavigationTarget(VNavigationMode *p_target);
|
|
|
|
// Register a target for Captain mode.
|
|
bool registerCaptainTarget(const QString &p_name,
|
|
const QString &p_key,
|
|
void *p_target,
|
|
CaptainFunc p_func);
|
|
|
|
void setCaptainModeEnabled(bool p_enabled);
|
|
|
|
void exitCaptainMode();
|
|
|
|
signals:
|
|
// Emit when mode changed.
|
|
void captainModeChanged(bool p_captainMode);
|
|
|
|
protected:
|
|
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
private slots:
|
|
// Exit Navigation mode if focus lost.
|
|
void handleFocusChanged(QWidget *p_old, QWidget *p_new);
|
|
|
|
private:
|
|
// A widget target for Navigation mode.
|
|
struct NaviModeTarget {
|
|
NaviModeTarget()
|
|
: m_target(nullptr), m_available(false)
|
|
{
|
|
}
|
|
|
|
NaviModeTarget(VNavigationMode *p_target, bool p_available)
|
|
: m_target(p_target), m_available(p_available)
|
|
{
|
|
}
|
|
|
|
VNavigationMode *m_target;
|
|
bool m_available;
|
|
};
|
|
|
|
// Modes.
|
|
enum class CaptainMode {
|
|
Normal = 0,
|
|
Pending,
|
|
Navigation
|
|
};
|
|
|
|
struct CaptainModeTarget {
|
|
CaptainModeTarget()
|
|
: m_target(nullptr), m_function(nullptr)
|
|
{
|
|
}
|
|
|
|
CaptainModeTarget(const QString &p_name,
|
|
const QString &p_key,
|
|
void *p_target,
|
|
CaptainFunc p_func)
|
|
: m_name(p_name),
|
|
m_key(p_key),
|
|
m_target(p_target),
|
|
m_function(p_func)
|
|
{
|
|
}
|
|
|
|
QString toString() const
|
|
{
|
|
return QString("Captain mode target %1 key[%2]").arg(m_name).arg(m_key);
|
|
}
|
|
|
|
// Name to display.
|
|
QString m_name;
|
|
|
|
// Key sequence to trigger this target.
|
|
// This is the sub-sequence after leader key.
|
|
QString m_key;
|
|
|
|
// Target.
|
|
void *m_target;
|
|
|
|
// Function to call when this target is trigger.
|
|
CaptainFunc m_function;
|
|
};
|
|
|
|
// Restore the focus to m_widgetBeforeCaptain.
|
|
void restoreFocus();
|
|
|
|
// Return true if finish handling the event; otherwise, let the base widget
|
|
// to handle it.
|
|
bool handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers);
|
|
|
|
// Handle key press event in Navigation mode.
|
|
bool handleKeyPressNavigationMode(int p_key,
|
|
Qt::KeyboardModifiers p_modifiers);
|
|
|
|
// Handle key press event in Captain mode.
|
|
bool handleKeyPressCaptainMode(int p_key,
|
|
Qt::KeyboardModifiers p_modifiers);
|
|
|
|
// Get next major key to use for Navigation mode.
|
|
QChar getNextMajorKey();
|
|
|
|
// Trigger navigation mode to ask all targets show themselves.
|
|
void triggerNavigationMode();
|
|
|
|
// Exit navigation mode to ask all targets hide themselves.
|
|
void exitNavigationMode();
|
|
|
|
// Called to trigger the action of a Captain target which has
|
|
// registered @p_key.
|
|
void triggerCaptainTarget(const QString &p_key);
|
|
|
|
void setMode(CaptainMode p_mode);
|
|
|
|
bool checkMode(CaptainMode p_mode) const;
|
|
|
|
void trigger();
|
|
|
|
void triggerCaptainMode();
|
|
|
|
static bool navigationModeByCaptain(void *p_target, void *p_data);
|
|
|
|
// Used to indicate current mode.
|
|
CaptainMode m_mode;
|
|
|
|
// The widget which has the focus before entering Captain mode.
|
|
QWidget *m_widgetBeforeCaptain;
|
|
|
|
// Targets for Navigation mode.
|
|
QVector<NaviModeTarget> m_naviTargets;
|
|
|
|
QChar m_nextMajorKey;
|
|
|
|
// Targets for Captain mode.
|
|
// Key(lower) -> CaptainModeTarget.
|
|
QHash<QString, CaptainModeTarget> m_captainTargets;
|
|
|
|
// Ignore focus change during handling Captain and Navigation target actions.
|
|
bool m_ignoreFocusChange;
|
|
|
|
QShortcut *m_captainModeShortcut;
|
|
};
|
|
|
|
inline void VCaptain::setMode(CaptainMode p_mode)
|
|
{
|
|
m_mode = p_mode;
|
|
}
|
|
|
|
inline bool VCaptain::checkMode(CaptainMode p_mode) const
|
|
{
|
|
return m_mode == p_mode;
|
|
}
|
|
#endif // VCAPTAIN_H
|