diff --git a/QOpenHD.pro b/QOpenHD.pro index d7b0289ee..3d0ef89d6 100755 --- a/QOpenHD.pro +++ b/QOpenHD.pro @@ -102,6 +102,7 @@ LinuxBuild { SOURCES += \ app/logging/hudlogmessagesmodel.cpp \ app/logging/logmessagesmodel.cpp \ + app/util/mousehelper.cpp \ app/util/qopenhd.cpp \ app/util/WorkaroundMessageBox.cpp \ app/util/qrenderstats.cpp \ @@ -116,6 +117,7 @@ HEADERS += \ app/logging/hudlogmessagesmodel.h \ app/logging/loghelper.h \ app/logging/logmessagesmodel.h \ + app/util/mousehelper.h \ app/util/qopenhd.h \ app/util/WorkaroundMessageBox.h \ app/util/qrenderstats.h \ diff --git a/app/main.cpp b/app/main.cpp index a9bb3e342..19ab95b9e 100755 --- a/app/main.cpp +++ b/app/main.cpp @@ -61,6 +61,7 @@ const QVector permissions({"android.permission.INTERNET", #include "logging/logmessagesmodel.h" #include "logging/hudlogmessagesmodel.h" #include "util/qopenhd.h" +#include "util/mousehelper.h" #include "util/WorkaroundMessageBox.h" #include "util/restartqopenhdmessagebox.h" @@ -243,8 +244,6 @@ int main(int argc, char *argv[]) { } QApplication app(argc, argv); - // Customize cursor if needed - QOpenHD::instance().customize_cursor_from_settings(); { // This includes dpi adjustment QScreen* screen=app.primaryScreen(); if(screen){ @@ -280,6 +279,7 @@ int main(int argc, char *argv[]) { // Needs to be registered first, otherwise we can have threading issue(s) engine.rootContext()->setContextProperty("_messageBoxInstance", &WorkaroundMessageBox::instance()); engine.rootContext()->setContextProperty("_restartqopenhdmessagebox", &RestartQOpenHDMessageBox::instance()); + engine.rootContext()->setContextProperty("_mouseHelper", &MouseHelper::instance()); engine.rootContext()->setContextProperty("_qrenderstats", &QRenderStats::instance()); diff --git a/app/util/mousehelper.cpp b/app/util/mousehelper.cpp new file mode 100644 index 000000000..8faa2610c --- /dev/null +++ b/app/util/mousehelper.cpp @@ -0,0 +1,125 @@ +#include "mousehelper.h" +#include "qdebug.h" +#include "qpixmap.h" + +#include + +static QCursor create_custom_cursor(const int cursor_type,const int cursor_scale){ + assert(cursor_type!=0); + QPixmap pixmap; + if(cursor_type==1){ + pixmap=QPixmap("://resources/cursors/arrow_512_transparent.png"); + }else if(cursor_type==2){ + pixmap=QPixmap("://resources/cursors/arrow_512_white.png"); + }else if(cursor_type==3){ + pixmap=QPixmap("://resources/cursors/arrow_512_green.png"); + }else{ + pixmap=QPixmap("://resources/cursors/hand_white.png"); + } + int size_px= 16; + if(cursor_scale==0){ + size_px =16; + }else if(cursor_scale==1){ + size_px = 32; + }else if(cursor_scale==2){ + size_px=64; + }else if(cursor_scale==3){ + size_px= 128; + } + pixmap = pixmap.scaled(size_px,size_px); + // position is a bit of a mess + QCursor cursor; + // arrow - roughly + if(cursor_type==1 || cursor_type==2 || cursor_type==3){ + cursor=QCursor(pixmap,pixmap.width()/16,pixmap.height()/16); + }else{ + // The hand is a bit different + cursor=QCursor(pixmap,pixmap.width()/3,pixmap.height()/4); + } + return cursor; +} + + +MouseHelper &MouseHelper::instance() +{ + static MouseHelper i; + return i; +} + +MouseHelper::MouseHelper() +{ + m_timer.setSingleShot(true); + m_timer.callOnTimeout([this]() {on_timeout();}); + init_from_settings(); +} + +void MouseHelper::init_from_settings() +{ + QSettings settings; + const int custom_cursor_type=settings.value("custom_cursor_type",0).toInt(); + const int custom_cursor_scale=settings.value("custom_cursor_scale",1).toInt(); + const bool enable_cursor_auto_hide=settings.value("enable_cursor_auto_hide",false).toBool(); + set_active_cursor_type_and_scale(custom_cursor_type,custom_cursor_scale); + set_hide_cursor_inactive_enable(enable_cursor_auto_hide); +} + +void MouseHelper::set_active_cursor_type_and_scale(const int cursor_type, const int cursor_scale) +{ + m_cursor_type=cursor_type; + m_cursor_scale=cursor_scale; + update_cursor_state(); +} + +void MouseHelper::set_hide_cursor_inactive_enable(bool enable) +{ + if(enable){ + QCoreApplication::instance()->installEventFilter(this); + m_enable_hide_cursor_when_inactive=true; + }else{ + QCoreApplication::instance()->removeEventFilter(this); + m_enable_hide_cursor_when_inactive=false; + m_timer.stop(); + m_cursor_state_active=true; + update_cursor_state(); + } +} + +bool MouseHelper::eventFilter(QObject *pWatched, QEvent *pEvent){ + if (pEvent->type() == QEvent::MouseMove){ + on_mouse_event(); + } + return QObject::eventFilter(pWatched, pEvent); +} + +void MouseHelper::on_timeout(){ + if(m_cursor_state_active){ + m_cursor_state_active= false; + update_cursor_state(); + } +} + +void MouseHelper::on_mouse_event(){ + if(!m_cursor_state_active){ + m_cursor_state_active= true; + update_cursor_state(); + } + // restarts the timer if already running + m_timer.start(m_inactivity_duration_msec); +} + +void MouseHelper::update_cursor_state(){ + if(m_cursor_state_active){ + if(m_cursor_type==0){ + // Default application cursor + QApplication::restoreOverrideCursor(); + }else{ + // Install the custom cursor + QApplication::restoreOverrideCursor(); + auto custom_cursor=create_custom_cursor(m_cursor_type,m_cursor_scale); + QApplication::setOverrideCursor(custom_cursor); + } + }else{ + QApplication::restoreOverrideCursor(); + QApplication::setOverrideCursor(Qt::BlankCursor); + } +} diff --git a/app/util/mousehelper.h b/app/util/mousehelper.h new file mode 100644 index 000000000..f65a8d44e --- /dev/null +++ b/app/util/mousehelper.h @@ -0,0 +1,41 @@ +#ifndef QMOUSEHIDER_H +#define QMOUSEHIDER_H + +#include + +#include +#include +#include + +// adds 2 features +// 1) high visibility cursor for people in the field +// 2) cursor auto hide +class MouseHelper : public QObject +{ + Q_OBJECT +public: + static MouseHelper& instance(); + explicit MouseHelper(); + + void init_from_settings(); + // update when settings change + Q_INVOKABLE void set_active_cursor_type_and_scale(const int cursor_type,const int cursor_scale); + // Enable / disable auto hide + Q_INVOKABLE void set_hide_cursor_inactive_enable(bool enable); +private: + const int m_inactivity_duration_msec=3000; + QTimer m_timer; + int m_cursor_type=0; + int m_cursor_scale=1; + bool m_enable_hide_cursor_when_inactive=false; + bool m_cursor_state_active= true; // active by default + + bool eventFilter(QObject *pWatched, QEvent *pEvent) override; + void on_mouse_event(); + void on_timeout(); + void update_cursor_state(); + +}; + + +#endif // QMOUSEHIDER_H diff --git a/app/util/qopenhd.cpp b/app/util/qopenhd.cpp index 8c0056144..1e8ee17d2 100644 --- a/app/util/qopenhd.cpp +++ b/app/util/qopenhd.cpp @@ -26,6 +26,7 @@ #include #endif +#include "mousehelper.h" QOpenHD &QOpenHD::instance() { @@ -231,56 +232,6 @@ QString QOpenHD::show_local_ip() } -void QOpenHD::customize_cursor(const int cursor_type,const int cursor_scale) -{ - QApplication::restoreOverrideCursor(); - // Default 0 - do not change - if(cursor_type==0)return; - qDebug()<<"Custom cursor type:"< 260 ? 260 : parent.width height: main_item.height anchors.centerIn: parent diff --git a/qml/ui/elements/AppSettings.qml b/qml/ui/elements/AppSettings.qml index f40ca06ce..da4324369 100644 --- a/qml/ui/elements/AppSettings.qml +++ b/qml/ui/elements/AppSettings.qml @@ -389,6 +389,7 @@ Settings { property int custom_cursor_type: 0 property int custom_cursor_scale: 1 // arbitrary scale values - higher == bigger, + property bool enable_cursor_auto_hide: false // experimental - mavlink via TCP property bool dev_mavlink_via_tcp: false