fix touchend and slide processing to make it consistent.
This commit is contained in:
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Source:
|
||||
* https://github.com/opentx/libopenui
|
||||
*
|
||||
* This file is a part of libopenui library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "keyboard_base.h"
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
#include "touch.h"
|
||||
#endif
|
||||
|
||||
MainWindow * MainWindow::_instance = nullptr;
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
TouchState touchState;
|
||||
Keyboard * Keyboard::activeKeyboard = nullptr;
|
||||
#endif
|
||||
|
||||
void MainWindow::emptyTrash()
|
||||
{
|
||||
for (auto window: trash) {
|
||||
delete window;
|
||||
}
|
||||
trash.clear();
|
||||
}
|
||||
|
||||
void MainWindow::checkEvents()
|
||||
{
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
if (touchPanelEventOccured()) {
|
||||
touchPanelRead();
|
||||
}
|
||||
|
||||
if (touchState.event == TE_DOWN) {
|
||||
onTouchStart(touchState.x + scrollPositionX, touchState.y + scrollPositionY);
|
||||
slidingWindow = nullptr;
|
||||
}
|
||||
else if (touchState.event == TE_UP) {
|
||||
touchState.event = TE_NONE;
|
||||
onTouchEnd(touchState.startX + scrollPositionX, touchState.startY + scrollPositionY);
|
||||
}
|
||||
else if (touchState.event == TE_SLIDE) {
|
||||
if (touchState.deltaX || touchState.deltaY) {
|
||||
onTouchSlide(touchState.x, touchState.y, touchState.startX, touchState.startY, touchState.deltaX, touchState.deltaY);
|
||||
touchState.lastDeltaX = touchState.deltaX;
|
||||
touchState.lastDeltaY = touchState.deltaY;
|
||||
touchState.deltaX = 0;
|
||||
touchState.deltaY = 0;
|
||||
}
|
||||
}
|
||||
else if (touchState.event == TE_SLIDE_END && slidingWindow) {
|
||||
if (touchState.lastDeltaX > SLIDE_SPEED_REDUCTION)
|
||||
touchState.lastDeltaX -= SLIDE_SPEED_REDUCTION;
|
||||
else if (touchState.lastDeltaX < -SLIDE_SPEED_REDUCTION)
|
||||
touchState.lastDeltaX += SLIDE_SPEED_REDUCTION;
|
||||
else
|
||||
touchState.lastDeltaX = 0;
|
||||
if (touchState.lastDeltaY > SLIDE_SPEED_REDUCTION)
|
||||
touchState.lastDeltaY -= SLIDE_SPEED_REDUCTION;
|
||||
else if (touchState.lastDeltaY < -SLIDE_SPEED_REDUCTION)
|
||||
touchState.lastDeltaY += SLIDE_SPEED_REDUCTION;
|
||||
else
|
||||
touchState.lastDeltaY = 0;
|
||||
|
||||
onTouchSlide(touchState.x, touchState.y, touchState.startX, touchState.startY, touchState.lastDeltaX, touchState.lastDeltaY);
|
||||
slidingWindow = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
Window::checkEvents();
|
||||
}
|
||||
|
||||
void MainWindow::invalidate(const rect_t & rect)
|
||||
{
|
||||
if (invalidatedRect.w) {
|
||||
auto left = limit<coord_t>(0, rect.left(), invalidatedRect.left());
|
||||
auto right = limit<coord_t>(invalidatedRect.right(), rect.right(), LCD_W);
|
||||
auto top = limit<coord_t>(0, rect.top(), invalidatedRect.top());
|
||||
auto bottom = limit<coord_t>(rect.bottom(), invalidatedRect.bottom(), LCD_H);
|
||||
invalidatedRect = {left, top, right - left, bottom - top};
|
||||
}
|
||||
else {
|
||||
invalidatedRect = rect;
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::refresh()
|
||||
{
|
||||
if (invalidatedRect.w) {
|
||||
if (invalidatedRect.x > 0 || invalidatedRect.y > 0 || invalidatedRect.w < LCD_W || invalidatedRect.h < LCD_H) {
|
||||
TRACE_WINDOWS("Refresh rect: left=%d top=%d width=%d height=%d", invalidatedRect.left(), invalidatedRect.top(), invalidatedRect.w, invalidatedRect.h);
|
||||
lcdCopy(lcd->getData(), lcdFront->getData());
|
||||
}
|
||||
else {
|
||||
TRACE_WINDOWS("Refresh full screen");
|
||||
}
|
||||
lcd->setOffset(0, 0);
|
||||
lcd->setClippingRect(invalidatedRect.left(), invalidatedRect.right(), invalidatedRect.top(), invalidatedRect.bottom());
|
||||
fullPaint(lcd);
|
||||
invalidatedRect.w = 0;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::run(bool trash)
|
||||
{
|
||||
auto start = ticksNow();
|
||||
|
||||
checkEvents();
|
||||
|
||||
if (trash) {
|
||||
emptyTrash();
|
||||
}
|
||||
|
||||
if (refresh()) {
|
||||
lcdRefresh();
|
||||
}
|
||||
|
||||
auto delta = ticksNow() - start;
|
||||
if (delta > 10 * SYSTEM_TICKS_1MS) {
|
||||
TRACE_WINDOWS("MainWindow::run took %dms", (ticksNow() - start) / SYSTEM_TICKS_1MS);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user