android gestures

This commit is contained in:
Zira project 2020-11-16 23:32:33 +05:00
parent 43ebcbbb3c
commit 3a29e620f0
14 changed files with 317 additions and 13 deletions

View file

@ -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);

View file

@ -18,6 +18,9 @@ public:
SettingsDialog(Settings * settings, QWidget * parent);
~SettingsDialog() override;
std::unordered_map<std::string, std::string> 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();

View file

@ -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

View file

@ -32,6 +32,8 @@
#include <QInputDialog>
#include <QAction>
#include <QScreen>
#include <QScroller>
#include <QScrollerProperties>
#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);
}

View file

@ -13,6 +13,7 @@
#include <QKeyEvent>
#include <QFileDialog>
#include <QShortcut>
#include <QScroller>
#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);
}

View file

@ -6,6 +6,8 @@
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QScroller>
#include <QScrollerProperties>
FileDialog::FileDialog(QWidget *parent) : QFileDialog(parent)
{
@ -32,9 +34,24 @@ FileDialog::FileDialog(QWidget *parent) : QFileDialog(parent)
if (newFolderButton != nullptr) newFolderButton->hide();
QTreeView * treeView = findChild<QTreeView *>("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<QListView *>("listView");
if (listView != nullptr) listView->setDragEnabled(false);
if (listView != nullptr) {
listView->setDragEnabled(false);
}
QDialogButtonBox * buttonBox = findChild<QDialogButtonBox *>("buttonBox");
if (buttonBox != nullptr && layout() != nullptr) {

View file

@ -3,6 +3,7 @@
#include <QMenu>
#include <QShortcut>
#include <QKeyEvent>
#include <QScroller>
#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"));

View file

@ -8,6 +8,7 @@
#include "ui_helpdialog.h"
#include <QFile>
#include <QTextStream>
#include <QScroller>
#include "helper.h"
const QString TPL_QT_VERSION = "<div><center>Qt %1</center></div>";
@ -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
}

View file

@ -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);

View file

@ -5,6 +5,7 @@
*******************************************/
#include <QKeyEvent>
#include <QScroller>
#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()

View file

@ -11,6 +11,7 @@
#include <QTimer>
#include <QScrollBar>
#include <QFontDatabase>
#include <QScroller>
#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 {

View file

@ -12,6 +12,8 @@
#include <QDirIterator>
#include <QStyledItemDelegate>
#include <QAbstractItemView>
#include <QScroller>
#include <QTimer>
#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;
}

View file

@ -1,8 +1,13 @@
#include "welcome.h"
#include <QTimer>
#include <QScroller>
#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
}

View file

@ -148,6 +148,12 @@
</property>
<item>
<widget class="QCheckBox" name="spellCheckerCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable spell checker (plugin required)</string>
</property>
@ -168,6 +174,12 @@
</property>
<item>
<widget class="QCheckBox" name="experimentalModeCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable experimental mode</string>
</property>
@ -1209,6 +1221,18 @@
</property>
<item>
<widget class="QCheckBox" name="phplintCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Enable php lint by default (syntax check)</string>
</property>
@ -1229,6 +1253,18 @@
</property>
<item>
<widget class="QCheckBox" name="phpcsCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Enable php code sniffer by default</string>
</property>
@ -1521,6 +1557,12 @@
</property>
<item>
<widget class="QLabel" name="snippetsLabel">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Format: [{mode:@name}] = [[text \n\t {$cursor} \n text]]</string>
</property>
@ -1541,6 +1583,12 @@
</property>
<item>
<widget class="QLabel" name="snippetsLabel2">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>[mode: php,js,css,html; name: [a-zA-Z0-9]{2,}; \n -new line; \t - indent]</string>
</property>
@ -1555,6 +1603,12 @@
</property>
<item>
<widget class="QLabel" name="snippetsLabel3">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>{$cursor} - cursor position;</string>
</property>
@ -1569,6 +1623,12 @@
</property>
<item>
<widget class="QLabel" name="snippetsLabel4">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>{$selectStart} ... {$selectEnd} - selection;</string>
</property>
@ -1583,6 +1643,12 @@
</property>
<item>
<widget class="QLabel" name="snippetsLabel5">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>{$multiSelectStart} ... {$multiSelectEnd} - multi-selection;</string>
</property>
@ -1858,6 +1924,18 @@
</property>
<item>
<widget class="QCheckBox" name="gitCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Allow git commands execution</string>
</property>
@ -1878,6 +1956,18 @@
</property>
<item>
<widget class="QCheckBox" name="serversCheckbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Allow service commands execution (servers)</string>
</property>