Skip to content

Commit

Permalink
add hide mouse feature
Browse files Browse the repository at this point in the history
small UI improvements
  • Loading branch information
Consti10 committed Nov 17, 2023
1 parent ebaf36b commit 16a7a67
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 59 deletions.
2 changes: 2 additions & 0 deletions QOpenHD.pro
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down
4 changes: 2 additions & 2 deletions app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const QVector<QString> 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"

Expand Down Expand Up @@ -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){
Expand Down Expand Up @@ -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());

Expand Down
125 changes: 125 additions & 0 deletions app/util/mousehelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "mousehelper.h"
#include "qdebug.h"
#include "qpixmap.h"

#include <qsettings.h>

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);
}
}
41 changes: 41 additions & 0 deletions app/util/mousehelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef QMOUSEHIDER_H
#define QMOUSEHIDER_H

#include <atomic>

#include <QCoreApplication>
#include <QTimer>
#include <qapplication.h>

// 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
51 changes: 1 addition & 50 deletions app/util/qopenhd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QtAndroid>
#endif

#include "mousehelper.h"

QOpenHD &QOpenHD::instance()
{
Expand Down Expand Up @@ -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:"<<cursor_type<<" scale:"<<cursor_scale;
// QCursor cursor(Qt::PointingHandCursor);
// QApplication::setOverrideCursor(cursor);
// NOTE: the "OS" cursors cannot be scaled easily
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);
}
QApplication::setOverrideCursor(cursor);
}

void QOpenHD::customize_cursor_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();
customize_cursor(custom_cursor_type,custom_cursor_scale);
}

bool QOpenHD::is_linux()
{
// weird - linux might be defined on android ?!
Expand Down
3 changes: 0 additions & 3 deletions app/util/qopenhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ class QOpenHD : public QObject
Q_INVOKABLE bool reset_settings();
// only works on linux, dirty helper to get local IP address
Q_INVOKABLE QString show_local_ip();
// high visibility cursor for people in the field
Q_INVOKABLE void customize_cursor(const int cursor_type,const int cursor_scale);
Q_INVOKABLE void customize_cursor_from_settings();
// returns true if the platform qopenhd is running on is linux (embedded or x86)
// some settings an stuff depend on that, called from .qml
// NOTE: android is not linux in this definition !
Expand Down
24 changes: 22 additions & 2 deletions qml/ui/configpopup/qopenhd_settings/AppScreenSettingsView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ ScrollView {
value: settings.custom_cursor_type
onValueChanged: {
settings.custom_cursor_type = value
_qopenhd.customize_cursor(settings.custom_cursor_type,settings.custom_cursor_scale)
_mouseHelper.set_active_cursor_type_and_scale(settings.custom_cursor_type,settings.custom_cursor_scale)
}
}
}
Expand All @@ -234,7 +234,27 @@ ScrollView {
value: settings.custom_cursor_scale
onValueChanged: {
settings.custom_cursor_scale = value
_qopenhd.customize_cursor(settings.custom_cursor_type,settings.custom_cursor_scale)
_mouseHelper.set_active_cursor_type_and_scale(settings.custom_cursor_type,settings.custom_cursor_scale)
}
}
}
SettingBaseElement{
m_short_description: "Cursor AutoHide"
m_long_description: "Automatically hide cursor on inactivity"

Switch {
width: 32
height: elementHeight
anchors.rightMargin: Qt.inputMethod.visible ? 96 : 36

anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
checked: settings.enable_cursor_auto_hide
onCheckedChanged: {
if(settings.enable_cursor_auto_hide!=checked){
settings.enable_cursor_auto_hide=checked;
_mouseHelper.set_hide_cursor_inactive_enable(settings.enable_cursor_auto_hide);
}
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion qml/ui/configpopup/status/StatusCardBodyFC.qml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Column {
}

StatusCardRow{
m_left_text: qsTr("FW:") //Autopilot
m_left_text: qsTr("Firmware:") //Autopilot
m_right_text: _fcMavlinkSystem.autopilot_type_str
}

Expand All @@ -50,4 +50,9 @@ Column {
m_left_text: qsTr("SysID:")
m_right_text: _fcMavlinkSystem.for_osd_sys_id == -1 ? "na" : qsTr(""+_fcMavlinkSystem.for_osd_sys_id)
}
// Padding
Item{
Layout.fillWidth: true
Layout.fillHeight: true
}
}
2 changes: 1 addition & 1 deletion qml/ui/configpopup/status/StatusCardRow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Item {
}*/
// Actual item,centered
Item{
width: parent.width
width: parent.width > 260 ? 260 : parent.width
height: main_item.height
anchors.centerIn: parent

Expand Down
1 change: 1 addition & 0 deletions qml/ui/elements/AppSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 16a7a67

Please sign in to comment.