From 3a29e620f0fa9caff61f8c4223053eba5fb9db7f Mon Sep 17 00:00:00 2001 From: Zira project Date: Mon, 16 Nov 2020 23:32:33 +0500 Subject: [PATCH] android gestures --- include/editor.h | 1 + include/settingsdialog.h | 4 ++ include/welcome.h | 11 ++++- src/editor.cpp | 26 ++++++++++++ src/filebrowser.cpp | 4 ++ src/filedialog.cpp | 21 +++++++++- src/gitbrowser.cpp | 4 ++ src/helpdialog.cpp | 3 ++ src/mainwindow.cpp | 3 +- src/navigator.cpp | 6 +++ src/quickaccess.cpp | 7 ++++ src/settingsdialog.cpp | 88 ++++++++++++++++++++++++++++++++++++++- src/welcome.cpp | 62 +++++++++++++++++++++++---- ui/settings.ui | 90 ++++++++++++++++++++++++++++++++++++++++ 14 files changed, 317 insertions(+), 13 deletions(-) diff --git a/include/editor.h b/include/editor.h index 7e73b18..63bfd95 100644 --- a/include/editor.h +++ b/include/editor.h @@ -404,6 +404,7 @@ private: QTextCursor multiSelectCursor; int inputEventKey; // workaround for Android QTimer mousePressTimer; + bool ignoreMouseRelease; signals: void ready(int index); void statusBarText(int index, QString text); diff --git a/include/settingsdialog.h b/include/settingsdialog.h index 08f8f4c..80cbcc3 100644 --- a/include/settingsdialog.h +++ b/include/settingsdialog.h @@ -18,6 +18,9 @@ public: SettingsDialog(Settings * settings, QWidget * parent); ~SettingsDialog() override; std::unordered_map getData(); +protected: + void enableGestures(); + void disableGestures(); private: Ui::SettingsDialog * ui; Settings * settings; @@ -27,6 +30,7 @@ private: std::string tabsType; std::string newLineMode; int initScaleFactor; + bool isGesturesEnabled; private slots: void projectHomeButtonPressed(); void phpManualButtonPressed(); diff --git a/include/welcome.h b/include/welcome.h index 8188b28..f192e35 100644 --- a/include/welcome.h +++ b/include/welcome.h @@ -10,13 +10,20 @@ class Welcome : public QWidget public: explicit Welcome(bool light, QWidget *parent = nullptr); ~Welcome(); - void connectButtons(QWidget * mainWnd); void focus(); +protected: + void enableGestures(); + void disableGestures(); private: Ui::WelcomeScreen * ui; + bool isGesturesEnabled; signals: - + void openProject(); + void createProject(); public slots: +private slots: + void onOpenProjectPressed(); + void onCreateProjectPressed(); }; #endif // WELCOME_H diff --git a/src/editor.cpp b/src/editor.cpp index e993025..43262c2 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "math.h" #include "helper.h" #include "icon.h" @@ -432,6 +434,7 @@ Editor::Editor(SpellCheckerInterface * spellChecker, Settings * settings, Highli multiSelectInsertText = ""; multiSelectCursors.clear(); multiSelectCursor = QTextCursor(document()); + ignoreMouseRelease = false; connect(this, SIGNAL(undoAvailable(bool)), this, SLOT(onUndoAvailable(bool))); connect(this, SIGNAL(redoAvailable(bool)), this, SLOT(onRedoAvailable(bool))); @@ -495,6 +498,17 @@ Editor::Editor(SpellCheckerInterface * spellChecker, Settings * settings, Highli mousePressTimer.setInterval(1000); mousePressTimer.setSingleShot(true); connect(&mousePressTimer, SIGNAL(timeout()), this, SLOT(contextMenu())); + + #if defined(Q_OS_ANDROID) + // scrolling by gesture + QScroller::grabGesture(viewport(), QScroller::LeftMouseButtonGesture); + QScrollerProperties scrollProps; + scrollProps.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + scrollProps.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + scrollProps.setScrollMetric(QScrollerProperties::MinimumVelocity, 0); + scrollProps.setScrollMetric(QScrollerProperties::MaximumVelocity, 0); + QScroller::scroller(viewport())->setScrollerProperties(scrollProps); + #endif } Editor::~Editor() @@ -588,6 +602,7 @@ void Editor::reset() multiSelectString = ""; multiSelectInsertText = ""; multiSelectCursors.clear(); + ignoreMouseRelease = false; } void Editor::highlightProgressChanged(int percent) @@ -2427,6 +2442,7 @@ void Editor::inputMethodEvent(QInputMethodEvent *e) void Editor::contextMenu() { + ignoreMouseRelease = false; QContextMenuEvent * cEvent = new QContextMenuEvent(QContextMenuEvent::Keyboard, mapFromGlobal(QCursor::pos())); contextMenuEvent(cEvent); delete cEvent; @@ -2615,6 +2631,12 @@ void Editor::mousePressEvent(QMouseEvent *e) hideCompletePopup(); #if defined(Q_OS_ANDROID) mousePressTimer.start(); + // hide virtual keyboard if visible + if (QApplication::inputMethod()->isVisible()) { + QApplication::inputMethod()->hide(); + ignoreMouseRelease = true; + return; + } #endif QTextEdit::mousePressEvent(e); } @@ -2628,6 +2650,10 @@ void Editor::mouseReleaseEvent(QMouseEvent *e) } #if defined(Q_OS_ANDROID) if (mousePressTimer.isActive()) mousePressTimer.stop(); + if (ignoreMouseRelease) { + ignoreMouseRelease = false; + return; + } #endif QTextEdit::mouseReleaseEvent(e); } diff --git a/src/filebrowser.cpp b/src/filebrowser.cpp index c1575f8..05bf0ac 100644 --- a/src/filebrowser.cpp +++ b/src/filebrowser.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "helper.h" #include "createfiledialog.h" #include "createfolderdialog.h" @@ -79,6 +80,9 @@ void FileBrowser::initFileBrowser(QString homeDir) treeWidget->installEventFilter(this); #if defined(Q_OS_ANDROID) treeWidget->viewport()->installEventFilter(this); // for context menu + // scrolling by gesture + QScroller::grabGesture(treeWidget->viewport(), QScroller::LeftMouseButtonGesture); + treeWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); #endif pathLine->installEventFilter(this); } diff --git a/src/filedialog.cpp b/src/filedialog.cpp index 5065236..8cc1c2f 100644 --- a/src/filedialog.cpp +++ b/src/filedialog.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include FileDialog::FileDialog(QWidget *parent) : QFileDialog(parent) { @@ -32,9 +34,24 @@ FileDialog::FileDialog(QWidget *parent) : QFileDialog(parent) if (newFolderButton != nullptr) newFolderButton->hide(); QTreeView * treeView = findChild("treeView"); - if (treeView != nullptr) treeView->setDragEnabled(false); + if (treeView != nullptr) { + treeView->setDragEnabled(false); + #if defined(Q_OS_ANDROID) + // scrolling by gesture + QScroller::grabGesture(treeView->viewport(), QScroller::LeftMouseButtonGesture); + treeView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + QScrollerProperties scrollProps; + scrollProps.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + scrollProps.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + scrollProps.setScrollMetric(QScrollerProperties::MinimumVelocity, 0); + scrollProps.setScrollMetric(QScrollerProperties::MaximumVelocity, 0); + QScroller::scroller(treeView->viewport())->setScrollerProperties(scrollProps); + #endif + } QListView * listView = findChild("listView"); - if (listView != nullptr) listView->setDragEnabled(false); + if (listView != nullptr) { + listView->setDragEnabled(false); + } QDialogButtonBox * buttonBox = findChild("buttonBox"); if (buttonBox != nullptr && layout() != nullptr) { diff --git a/src/gitbrowser.cpp b/src/gitbrowser.cpp index 234850b..ced90dd 100644 --- a/src/gitbrowser.cpp +++ b/src/gitbrowser.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "icon.h" const QString GB_ACTION_NAME_ADD = "add"; @@ -23,6 +24,9 @@ GitBrowser::GitBrowser(QTreeWidget * widget, Settings * settings): treeWidget->installEventFilter(this); #if defined(Q_OS_ANDROID) treeWidget->viewport()->installEventFilter(this); // for context menu + // scrolling by gesture + QScroller::grabGesture(treeWidget->viewport(), QScroller::LeftMouseButtonGesture); + treeWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); #endif QString shortcutContextMenuStr = QString::fromStdString(settings->get("shortcut_context_menu")); diff --git a/src/helpdialog.cpp b/src/helpdialog.cpp index 186d811..4c945ec 100644 --- a/src/helpdialog.cpp +++ b/src/helpdialog.cpp @@ -8,6 +8,7 @@ #include "ui_helpdialog.h" #include #include +#include #include "helper.h" const QString TPL_QT_VERSION = "
Qt %1
"; @@ -31,6 +32,8 @@ HelpDialog::HelpDialog(QWidget *parent) : // maximize dialog in Android #if defined(Q_OS_ANDROID) setWindowState( windowState() | Qt::WindowMaximized); + // scrolling by gesture + QScroller::grabGesture(ui->helpScrollArea->viewport(), QScroller::LeftMouseButtonGesture); #endif } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 970df3e..5580e26 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -158,7 +158,8 @@ MainWindow::MainWindow(QWidget *parent) : // welcome screen welcomeScreen = new Welcome(schemeType == COLOR_SCHEME_LIGHT); ui->centralWidget->layout()->addWidget(welcomeScreen); - welcomeScreen->connectButtons(this); + connect(welcomeScreen, SIGNAL(openProject()), this, SLOT(on_actionOpenProject_triggered())); + connect(welcomeScreen, SIGNAL(createProject()), this, SLOT(on_actionNewProject_triggered())); // editor tabs editorTabs = new EditorTabs(spellChecker, ui->tabWidget, settings, highlightWords, completeWords, helpWords, spellWords, snippets); diff --git a/src/navigator.cpp b/src/navigator.cpp index 6d92f12..ac06378 100644 --- a/src/navigator.cpp +++ b/src/navigator.cpp @@ -5,6 +5,7 @@ *******************************************/ #include +#include #include "navigator.h" #include "helper.h" @@ -16,6 +17,11 @@ Navigator::Navigator(QTreeWidget * widget, Settings * /*settings*/) : treeWidget connect(treeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(navigatorExpanded(QTreeWidgetItem*))); connect(treeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(navigatorCollapsed(QTreeWidgetItem*))); treeWidget->installEventFilter(this); + #if defined(Q_OS_ANDROID) + // scrolling by gesture + QScroller::grabGesture(treeWidget->viewport(), QScroller::LeftMouseButtonGesture); + treeWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + #endif } void Navigator::clear() diff --git a/src/quickaccess.cpp b/src/quickaccess.cpp index 940da79..fa6a95e 100644 --- a/src/quickaccess.cpp +++ b/src/quickaccess.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "icon.h" #include "helper.h" @@ -98,6 +99,12 @@ QuickAccess::QuickAccess(Settings * settings, QWidget *parent) : QFrame(parent) } outputFont.setPointSize(std::stoi(fontSize)); resultsList->setFont(outputFont); + + #if defined(Q_OS_ANDROID) + // scrolling by gesture + QScroller::grabGesture(resultsList->viewport(), QScroller::LeftMouseButtonGesture); + resultsList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + #endif } QSize QuickAccess::sizeHint() const { diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 6ef80bc..9ce8769 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "helper.h" const std::string CHECKED_YES = "yes"; @@ -22,10 +24,13 @@ const std::string NEW_LINE_LF = "lf"; const std::string NEW_LINE_CR = "cr"; const std::string NEW_LINE_CRLF = "crlf"; +const int ANDROID_PUSH_BUTTON_DELAY = 100; + SettingsDialog::SettingsDialog(Settings * settings, QWidget * parent): QDialog(parent), ui(new Ui::SettingsDialog()), - settings(settings) + settings(settings), + isGesturesEnabled(false) { ui->setupUi(this); setModal(true); @@ -192,6 +197,8 @@ SettingsDialog::SettingsDialog(Settings * settings, QWidget * parent): // maximize dialog in Android #if defined(Q_OS_ANDROID) setWindowState( windowState() | Qt::WindowMaximized); + // scrolling by gesture + enableGestures(); #else ui->buttonBox->button(QDialogButtonBox::Help)->hide(); #endif @@ -504,49 +511,104 @@ void SettingsDialog::editorNewLineCRLFToggled(bool checked) void SettingsDialog::projectHomeButtonPressed() { + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTON_DELAY, this, SLOT(projectHomeButtonPressed())); + return; + } + #endif QString home = ui->projectsHomeLineEdit->text(); //QString dir = QFileDialog::getExistingDirectory(this, tr("Choose projects home directory"), home, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QString dir = Helper::getExistingDirectory(this, tr("Choose projects home directory"), home); if (dir.size() > 0) { ui->projectsHomeLineEdit->setText(dir); } + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif } void SettingsDialog::phpManualButtonPressed() { + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTON_DELAY, this, SLOT(phpManualButtonPressed())); + return; + } + #endif QString path = ui->phpmanualLineEdit->text(); QString dir = Helper::getExistingDirectory(this, tr("Select directory"), path); if (dir.size() > 0) { ui->phpmanualLineEdit->setText(dir); } + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif } void SettingsDialog::customThemesButtonPressed() { + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTON_DELAY, this, SLOT(customThemesButtonPressed())); + return; + } + #endif QString path = ui->customThemesFolderLineEdit->text(); QString dir = Helper::getExistingDirectory(this, tr("Select directory"), path); if (dir.size() > 0) { ui->customThemesFolderLineEdit->setText(dir); } + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif } void SettingsDialog::pluginsFolderButtonPressed() { + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTON_DELAY, this, SLOT(pluginsFolderButtonPressed())); + return; + } + #endif QString path = ui->pluginsFolderLineEdit->text(); QString dir = Helper::getExistingDirectory(this, tr("Select directory"), path); if (dir.size() > 0) { ui->pluginsFolderLineEdit->setText(dir); } + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif } void SettingsDialog::customSnippetsFileButtonPressed() { + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTON_DELAY, this, SLOT(customSnippetsFileButtonPressed())); + return; + } + #endif QString file = ui->customSnippetsFileLineEdit->text(); QFileInfo fInfo(file); QString fileName = Helper::getExistingFile(this, tr("Select file"), fInfo.absolutePath()); if (fileName.size() > 0) { ui->customSnippetsFileLineEdit->setText(fileName); } + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif } void SettingsDialog::resetButtonPressed() @@ -580,3 +642,27 @@ void SettingsDialog::contextMenuRequested() QContextMenuEvent * contextEvent = new QContextMenuEvent(QContextMenuEvent::Keyboard, widget->mapFromGlobal(QCursor::pos())); QCoreApplication::postEvent(widget, contextEvent); } + +void SettingsDialog::enableGestures() +{ + QScroller::grabGesture(ui->generalSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->editorSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->fileTypesSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->syntaxSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->snippetsSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->pathsSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->miscSettingsScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + isGesturesEnabled = true; +} + +void SettingsDialog::disableGestures() +{ + QScroller::ungrabGesture(ui->generalSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->editorSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->fileTypesSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->syntaxSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->snippetsSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->pathsSettingsScrollArea->viewport()); + QScroller::ungrabGesture(ui->miscSettingsScrollArea->viewport()); + isGesturesEnabled = false; +} diff --git a/src/welcome.cpp b/src/welcome.cpp index 811884d..d395c77 100644 --- a/src/welcome.cpp +++ b/src/welcome.cpp @@ -1,8 +1,13 @@ #include "welcome.h" +#include +#include #include "helper.h" +const int ANDROID_PUSH_BUTTONS_DELAY = 100; + Welcome::Welcome(bool light, QWidget *parent) : QWidget(parent), - ui(new Ui::WelcomeScreen()) + ui(new Ui::WelcomeScreen()), + isGesturesEnabled(false) { ui->setupUi(this); @@ -18,8 +23,13 @@ Welcome::Welcome(bool light, QWidget *parent) : QWidget(parent), #if defined(Q_OS_ANDROID) ui->welcomeLabelLayout->setContentsMargins(0, 0, 0, 10); + // scrolling by gesture + enableGestures(); #endif + connect(ui->welcomeOpenProjectButton, SIGNAL(pressed()), this, SLOT(onOpenProjectPressed())); + connect(ui->welcomeCreateProjectButton, SIGNAL(pressed()), this, SLOT(onCreateProjectPressed())); + hide(); } @@ -28,13 +38,51 @@ Welcome::~Welcome() delete ui; } -void Welcome::connectButtons(QWidget *mainWnd) -{ - connect(ui->welcomeOpenProjectButton, SIGNAL(pressed()), mainWnd, SLOT(on_actionOpenProject_triggered())); - connect(ui->welcomeCreateProjectButton, SIGNAL(pressed()), mainWnd, SLOT(on_actionNewProject_triggered())); -} - void Welcome::focus() { ui->welcomeOpenProjectButton->setFocus(); } + +void Welcome::enableGestures() +{ + QScroller::grabGesture(ui->welcomeScrollArea->viewport(), QScroller::LeftMouseButtonGesture); + isGesturesEnabled = true; +} + +void Welcome::disableGestures() +{ + QScroller::ungrabGesture(ui->welcomeScrollArea->viewport()); + isGesturesEnabled = false; +} + +void Welcome::onCreateProjectPressed() +{ + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTONS_DELAY, this, SLOT(onCreateProjectPressed())); + return; + } + #endif + emit createProject(); + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif +} + +void Welcome::onOpenProjectPressed() +{ + #if defined(Q_OS_ANDROID) + // temporarily disable gestures and call it again after delay + if (isGesturesEnabled) { + disableGestures(); + QTimer::singleShot(ANDROID_PUSH_BUTTONS_DELAY, this, SLOT(onOpenProjectPressed())); + return; + } + #endif + emit openProject(); + #if defined(Q_OS_ANDROID) + enableGestures(); + #endif +} diff --git a/ui/settings.ui b/ui/settings.ui index 8798969..5fff44f 100644 --- a/ui/settings.ui +++ b/ui/settings.ui @@ -148,6 +148,12 @@ + + + 0 + 0 + + Enable spell checker (plugin required) @@ -168,6 +174,12 @@ + + + 0 + 0 + + Enable experimental mode @@ -1209,6 +1221,18 @@ + + + 0 + 0 + + + + + 300 + 0 + + Enable php lint by default (syntax check) @@ -1229,6 +1253,18 @@ + + + 0 + 0 + + + + + 300 + 0 + + Enable php code sniffer by default @@ -1521,6 +1557,12 @@ + + + 400 + 0 + + Format: [{mode:@name}] = [[text \n\t {$cursor} \n text]] @@ -1541,6 +1583,12 @@ + + + 400 + 0 + + [mode: php,js,css,html; name: [a-zA-Z0-9]{2,}; \n -new line; \t - indent] @@ -1555,6 +1603,12 @@ + + + 400 + 0 + + {$cursor} - cursor position; @@ -1569,6 +1623,12 @@ + + + 400 + 0 + + {$selectStart} ... {$selectEnd} - selection; @@ -1583,6 +1643,12 @@ + + + 400 + 0 + + {$multiSelectStart} ... {$multiSelectEnd} - multi-selection; @@ -1858,6 +1924,18 @@ + + + 0 + 0 + + + + + 300 + 0 + + Allow git commands execution @@ -1878,6 +1956,18 @@ + + + 0 + 0 + + + + + 300 + 0 + + Allow service commands execution (servers)