put files in wrong place
This commit is contained in:
-141
@@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-564
@@ -1,564 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "window.h"
|
|
||||||
#include "touch.h"
|
|
||||||
|
|
||||||
Window * Window::focusWindow = nullptr;
|
|
||||||
Window * Window::slidingWindow = nullptr;
|
|
||||||
Window * Window::touchedWindow = nullptr;
|
|
||||||
std::list<Window *> Window::trash;
|
|
||||||
|
|
||||||
Window::Window(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags):
|
|
||||||
parent(parent),
|
|
||||||
rect(rect),
|
|
||||||
innerWidth(rect.w),
|
|
||||||
innerHeight(rect.h),
|
|
||||||
windowFlags(windowFlags),
|
|
||||||
textFlags(textFlags)
|
|
||||||
{
|
|
||||||
if (parent) {
|
|
||||||
parent->addChild(this, windowFlags & PUSH_FRONT);
|
|
||||||
if (!(windowFlags & TRANSPARENT)) {
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::~Window()
|
|
||||||
{
|
|
||||||
TRACE_WINDOWS("Destroy %p %s", this, getWindowDebugString().c_str());
|
|
||||||
|
|
||||||
if (focusWindow == this) {
|
|
||||||
focusWindow = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::attach(Window * newParent)
|
|
||||||
{
|
|
||||||
if (parent) detach();
|
|
||||||
parent = newParent;
|
|
||||||
if (newParent) newParent->addChild(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::detach()
|
|
||||||
{
|
|
||||||
if (parent) {
|
|
||||||
parent->removeChild(this);
|
|
||||||
parent = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::deleteLater(bool detach, bool trash)
|
|
||||||
{
|
|
||||||
if (_deleted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TRACE_WINDOWS("Delete %p %s", this, getWindowDebugString().c_str());
|
|
||||||
|
|
||||||
_deleted = true;
|
|
||||||
|
|
||||||
if (static_cast<Window *>(focusWindow) == static_cast<Window *>(this)) {
|
|
||||||
focusWindow = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detach)
|
|
||||||
this->detach();
|
|
||||||
else
|
|
||||||
parent = nullptr;
|
|
||||||
|
|
||||||
deleteChildren();
|
|
||||||
|
|
||||||
if (closeHandler) {
|
|
||||||
closeHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trash) {
|
|
||||||
Window::trash.push_back(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::clear()
|
|
||||||
{
|
|
||||||
scrollPositionX = 0;
|
|
||||||
scrollPositionY = 0;
|
|
||||||
innerWidth = rect.w;
|
|
||||||
innerHeight = rect.h;
|
|
||||||
deleteChildren();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::deleteChildren()
|
|
||||||
{
|
|
||||||
for (auto window: children) {
|
|
||||||
window->deleteLater(false);
|
|
||||||
}
|
|
||||||
children.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::clearFocus()
|
|
||||||
{
|
|
||||||
if (focusWindow) {
|
|
||||||
focusWindow->onFocusLost();
|
|
||||||
focusWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setFocus(uint8_t flag, Window * from)
|
|
||||||
{
|
|
||||||
if (deleted())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TRACE_WINDOWS("%s setFocus()", getWindowDebugString().c_str());
|
|
||||||
|
|
||||||
if (focusWindow != this) {
|
|
||||||
// scroll before calling focusHandler so that the window can adjust the scroll position if needed
|
|
||||||
Window * parent = this->parent;
|
|
||||||
while (parent && parent->getWindowFlags() & FORWARD_SCROLL) {
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
if (parent) {
|
|
||||||
parent->scrollTo(this);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearFocus();
|
|
||||||
focusWindow = this;
|
|
||||||
if (focusHandler) {
|
|
||||||
focusHandler(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setScrollPositionX(coord_t value)
|
|
||||||
{
|
|
||||||
auto newScrollPosition = max<coord_t>(0, min<coord_t>(innerWidth - width(), value));
|
|
||||||
if (newScrollPosition != scrollPositionX) {
|
|
||||||
scrollPositionX = newScrollPosition;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setScrollPositionY(coord_t value)
|
|
||||||
{
|
|
||||||
auto newScrollPosition = min<coord_t>(innerHeight - height(), value);
|
|
||||||
|
|
||||||
if (newScrollPosition < 0 && innerHeight != INFINITE_HEIGHT) {
|
|
||||||
newScrollPosition = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newScrollPosition != scrollPositionY) {
|
|
||||||
scrollPositionY = newScrollPosition;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::scrollTo(Window * child)
|
|
||||||
{
|
|
||||||
coord_t offsetX = 0;
|
|
||||||
coord_t offsetY = 0;
|
|
||||||
|
|
||||||
Window * parentWindow = child->getParent();
|
|
||||||
while (parentWindow && parentWindow != this) {
|
|
||||||
offsetX += parentWindow->left();
|
|
||||||
offsetY += parentWindow->top();
|
|
||||||
parentWindow = parentWindow->getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
const rect_t scrollRect = {
|
|
||||||
offsetX + child->left(),
|
|
||||||
offsetY + child->top(),
|
|
||||||
min(child->width(), width()),
|
|
||||||
min(child->height(), height())
|
|
||||||
};
|
|
||||||
|
|
||||||
scrollTo(scrollRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::scrollTo(const rect_t & rect)
|
|
||||||
{
|
|
||||||
if (rect.top() < scrollPositionY) {
|
|
||||||
setScrollPositionY(pageHeight ? rect.top() - (rect.top() % pageHeight) : rect.top() - 5);
|
|
||||||
}
|
|
||||||
else if (rect.bottom() > scrollPositionY + height() - 5) {
|
|
||||||
setScrollPositionY(pageHeight ? rect.top() - (rect.top() % pageHeight) : rect.bottom() - height() + 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rect.left() < scrollPositionX) {
|
|
||||||
setScrollPositionX(pageWidth ? rect.left() - (rect.left() % pageWidth) : rect.left() - 5);
|
|
||||||
}
|
|
||||||
else if (rect.right() > scrollPositionX + width() - 5) {
|
|
||||||
setScrollPositionX(pageWidth ? rect.left() - (rect.left() % pageWidth) : rect.right() - width() + 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::hasOpaqueRect(const rect_t & testRect) const
|
|
||||||
{
|
|
||||||
if (!rect.contains(testRect))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (windowFlags & OPAQUE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect_t relativeRect = {testRect.x - rect.x, testRect.y - rect.y, testRect.w, testRect.h};
|
|
||||||
for (auto child: children) {
|
|
||||||
if (child->hasOpaqueRect(relativeRect))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::fullPaint(BitmapBuffer * dc)
|
|
||||||
{
|
|
||||||
bool paintNeeded = true;
|
|
||||||
std::list<Window *>::iterator firstChild;
|
|
||||||
|
|
||||||
coord_t xmin, xmax, ymin, ymax;
|
|
||||||
dc->getClippingRect(xmin, xmax, ymin, ymax);
|
|
||||||
coord_t x = dc->getOffsetX();
|
|
||||||
coord_t y = dc->getOffsetY();
|
|
||||||
|
|
||||||
if (windowFlags & PAINT_CHILDREN_FIRST) {
|
|
||||||
paintChildren(dc, children.begin());
|
|
||||||
dc->setOffset(x, y);
|
|
||||||
dc->setClippingRect(xmin, xmax, ymin, ymax);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
firstChild = children.end();
|
|
||||||
rect_t relativeRect = {xmin - x, ymin - y, xmax - xmin, ymax - ymin};
|
|
||||||
while (firstChild != children.begin()) {
|
|
||||||
auto child = *(--firstChild);
|
|
||||||
if (child->hasOpaqueRect(relativeRect)) {
|
|
||||||
paintNeeded = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paintNeeded) {
|
|
||||||
TRACE_WINDOWS_INDENT("%s%s", getWindowDebugString().c_str(), hasFocus() ? " (*)" : "");
|
|
||||||
paint(dc);
|
|
||||||
#if defined(WINDOWS_INSPECT_BORDER_COLOR)
|
|
||||||
dc->drawSolidRect(0, 0, width(), height(), 1, WINDOWS_INSPECT_BORDER_COLOR);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TRACE_WINDOWS_INDENT("%s (skipped)", getWindowDebugString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(windowFlags & NO_SCROLLBAR)) {
|
|
||||||
drawVerticalScrollbar(dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(windowFlags & PAINT_CHILDREN_FIRST)) {
|
|
||||||
paintChildren(dc, firstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::isChildFullSize(const Window * child) const
|
|
||||||
{
|
|
||||||
return child->top() == 0 && child->height() == height() && child->left() == 0 && child->width() == width();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::isChildVisible(const Window * window) const
|
|
||||||
{
|
|
||||||
for (auto rit = children.rbegin(); rit != children.rend(); rit++) {
|
|
||||||
auto child = *rit;
|
|
||||||
if (child == window) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((child->getWindowFlags() & OPAQUE) & isChildFullSize(child)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setInsideParentScrollingArea()
|
|
||||||
{
|
|
||||||
Window * parent = getParent();
|
|
||||||
while (parent && parent->getWindowFlags() & FORWARD_SCROLL) {
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
if (parent) {
|
|
||||||
parent->scrollTo(this);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::paintChildren(BitmapBuffer * dc, std::list<Window *>::iterator it)
|
|
||||||
{
|
|
||||||
coord_t x = dc->getOffsetX();
|
|
||||||
coord_t y = dc->getOffsetY();
|
|
||||||
coord_t xmin, xmax, ymin, ymax;
|
|
||||||
dc->getClippingRect(xmin, xmax, ymin, ymax);
|
|
||||||
|
|
||||||
for (; it != children.end(); it++) {
|
|
||||||
auto child = *it;
|
|
||||||
|
|
||||||
coord_t child_xmin = x + child->rect.x;
|
|
||||||
if (child_xmin >= xmax)
|
|
||||||
continue;
|
|
||||||
coord_t child_ymin = y + child->rect.y;
|
|
||||||
if (child_ymin >= ymax)
|
|
||||||
continue;
|
|
||||||
coord_t child_xmax = child_xmin + child->rect.w;
|
|
||||||
if (child_xmax <= xmin)
|
|
||||||
continue;
|
|
||||||
coord_t child_ymax = child_ymin + child->rect.h;
|
|
||||||
if (child_ymax <= ymin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dc->setOffset(x + child->rect.x - child->scrollPositionX, y + child->rect.y - child->scrollPositionY);
|
|
||||||
dc->setClippingRect(max(xmin, x + child->rect.left()),
|
|
||||||
min(xmax, x + child->rect.right()),
|
|
||||||
max(ymin, y + child->rect.top()),
|
|
||||||
min(ymax, y + child->rect.bottom()));
|
|
||||||
child->fullPaint(dc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HARDWARE_TOUCH)
|
|
||||||
coord_t Window::getSnapStep(coord_t relativeScrollPosition, coord_t pageSize)
|
|
||||||
{
|
|
||||||
coord_t result = 0;
|
|
||||||
if (relativeScrollPosition > pageSize / 2) {
|
|
||||||
// closer to next page
|
|
||||||
result = (pageSize - relativeScrollPosition);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// closer to previous page
|
|
||||||
result = (0 - relativeScrollPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not get too slow
|
|
||||||
if (abs(result) > 32)
|
|
||||||
result /= 2;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Window::checkEvents()
|
|
||||||
{
|
|
||||||
auto copy = children;
|
|
||||||
for (auto child: copy) {
|
|
||||||
if (!child->deleted()) {
|
|
||||||
child->checkEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this == Window::focusWindow) {
|
|
||||||
event_t event = getWindowEvent();
|
|
||||||
if (event) {
|
|
||||||
this->onEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (windowFlags & REFRESH_ALWAYS) {
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HARDWARE_TOUCH)
|
|
||||||
if (touchState.event != TE_SLIDE && touchState.lastDeltaX == 0 && touchState.lastDeltaY == 0) {
|
|
||||||
if (pageWidth) {
|
|
||||||
coord_t relativeScrollPosition = getScrollPositionX() % pageWidth;
|
|
||||||
if (relativeScrollPosition) {
|
|
||||||
setScrollPositionX(getScrollPositionX() + getSnapStep(relativeScrollPosition, pageWidth));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pageHeight) {
|
|
||||||
coord_t relativeScrollPosition = getScrollPositionY() % pageHeight;
|
|
||||||
if (relativeScrollPosition) {
|
|
||||||
setScrollPositionY(getScrollPositionY() + getSnapStep(relativeScrollPosition, pageHeight));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::onEvent(event_t event)
|
|
||||||
{
|
|
||||||
TRACE_WINDOWS("%s received event 0x%X", Window::getWindowDebugString("Window").c_str(), event);
|
|
||||||
if (parent) {
|
|
||||||
parent->onEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HARDWARE_TOUCH)
|
|
||||||
bool Window::onTouchStart(coord_t x, coord_t y)
|
|
||||||
{
|
|
||||||
for (auto it = children.rbegin(); it != children.rend(); ++it) {
|
|
||||||
auto child = *it;
|
|
||||||
if (child->rect.contains(x, y)) {
|
|
||||||
if (child->onTouchStart(x - child->rect.x + child->scrollPositionX, y - child->rect.y + child->scrollPositionY)) {
|
|
||||||
// remember the first window that processed the touch start event. We will give that window
|
|
||||||
// the opportunity to process the touchend first, and also after a slide end so the touched window
|
|
||||||
// always gets a touchEnd if it processed the touch start.
|
|
||||||
if (touchedWindow == nullptr) {
|
|
||||||
touchedWindow = child;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::forwardTouchEnd(coord_t x, coord_t y)
|
|
||||||
{
|
|
||||||
// give the touched window the opportunity to process the touch first before it is
|
|
||||||
// forwarded: See on touchstart
|
|
||||||
if (touchedWindow != nullptr) {
|
|
||||||
auto savedTouchWindow = touchedWindow;
|
|
||||||
touchedWindow = nullptr;
|
|
||||||
// transalte x and y through the parent hierarchy
|
|
||||||
auto myParent = savedTouchWindow->parent;
|
|
||||||
while(myParent != nullptr) {
|
|
||||||
x = x - myParent->rect.x + myParent->scrollPositionX;
|
|
||||||
y = y - myParent->rect.y + myParent->scrollPositionY;
|
|
||||||
myParent = myParent->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savedTouchWindow->onTouchEnd(
|
|
||||||
x - savedTouchWindow->rect.x + savedTouchWindow->scrollPositionX,
|
|
||||||
y - savedTouchWindow->rect.y + savedTouchWindow->scrollPositionY)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = children.rbegin(); it != children.rend(); ++it) {
|
|
||||||
auto child = *it;
|
|
||||||
if (child->rect.contains(x, y)) {
|
|
||||||
if (child->onTouchEnd(x - child->rect.x + child->scrollPositionX, y - child->rect.y + child->scrollPositionY)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::onTouchEnd(coord_t x, coord_t y)
|
|
||||||
{
|
|
||||||
return forwardTouchEnd(x, y) ? true : (windowFlags & OPAQUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Window::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY)
|
|
||||||
{
|
|
||||||
startX += getScrollPositionX();
|
|
||||||
startY += getScrollPositionY();
|
|
||||||
|
|
||||||
for (auto it = children.rbegin(); it != children.rend(); ++it) {
|
|
||||||
auto child = *it;
|
|
||||||
if (child->rect.contains(startX, startY)) {
|
|
||||||
if (child->onTouchSlide(x - child->rect.x, y - child->rect.y, startX - child->rect.x, startY - child->rect.y, slideX, slideY)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slidingWindow && slidingWindow != this) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slideY && innerHeight > rect.h) {
|
|
||||||
setScrollPositionY(scrollPositionY - slideY);
|
|
||||||
slidingWindow = this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slideX && innerWidth > rect.w) {
|
|
||||||
setScrollPositionX(scrollPositionX - slideX);
|
|
||||||
slidingWindow = this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Window::adjustInnerHeight()
|
|
||||||
{
|
|
||||||
coord_t bottomMax = 0;
|
|
||||||
for (auto child: children) {
|
|
||||||
bottomMax = max(bottomMax, child->rect.y + child->rect.h);
|
|
||||||
}
|
|
||||||
setInnerHeight(bottomMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t Window::adjustHeight()
|
|
||||||
{
|
|
||||||
coord_t old = rect.h;
|
|
||||||
adjustInnerHeight();
|
|
||||||
rect.h = innerHeight;
|
|
||||||
return rect.h - old;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::moveWindowsTop(coord_t y, coord_t delta)
|
|
||||||
{
|
|
||||||
if (getWindowFlags() & FORWARD_SCROLL) {
|
|
||||||
parent->moveWindowsTop(bottom(), delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto child: children) {
|
|
||||||
if (child->rect.y >= y) {
|
|
||||||
child->rect.y += delta;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::invalidate(const rect_t & rect)
|
|
||||||
{
|
|
||||||
if (isVisible()) {
|
|
||||||
parent->invalidate({this->rect.x + rect.x - parent->scrollPositionX, this->rect.y + rect.y - parent->scrollPositionY, rect.w, rect.h});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::drawVerticalScrollbar(BitmapBuffer * dc)
|
|
||||||
{
|
|
||||||
if (innerHeight > rect.h) {
|
|
||||||
coord_t yofs = divRoundClosest(rect.h * scrollPositionY, innerHeight);
|
|
||||||
coord_t yhgt = divRoundClosest(rect.h * rect.h, innerHeight);
|
|
||||||
if (yhgt < 15)
|
|
||||||
yhgt = 15;
|
|
||||||
if (yhgt + yofs > rect.h)
|
|
||||||
yhgt = rect.h - yofs;
|
|
||||||
dc->drawSolidFilledRect(rect.w - SCROLLBAR_WIDTH, scrollPositionY + yofs, SCROLLBAR_WIDTH, yhgt, COLOR_THEME_PRIMARY3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::drawHorizontalScrollbar(BitmapBuffer * dc)
|
|
||||||
{
|
|
||||||
if (innerWidth > rect.w) {
|
|
||||||
coord_t xofs = divRoundClosest(rect.w * scrollPositionX, innerWidth);
|
|
||||||
coord_t xwdth = divRoundClosest(rect.w * rect.w, innerWidth);
|
|
||||||
if (xwdth < 15)
|
|
||||||
xwdth = 15;
|
|
||||||
if (xwdth + xofs > rect.w)
|
|
||||||
xwdth = rect.w - xofs;
|
|
||||||
dc->drawSolidFilledRect(scrollPositionX + xofs, rect.h - SCROLLBAR_WIDTH, xwdth, SCROLLBAR_WIDTH, COLOR_THEME_PRIMARY3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-451
@@ -1,451 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <list>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <functional>
|
|
||||||
#include "bitmapbuffer.h"
|
|
||||||
#include "libopenui_defines.h"
|
|
||||||
#include "libopenui_helpers.h"
|
|
||||||
#include "libopenui_config.h"
|
|
||||||
|
|
||||||
typedef uint32_t WindowFlags;
|
|
||||||
|
|
||||||
#if !defined(_GNUC_)
|
|
||||||
#undef OPAQUE
|
|
||||||
#undef TRANSPARENT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
constexpr int INFINITE_HEIGHT = INT32_MAX;
|
|
||||||
|
|
||||||
constexpr WindowFlags OPAQUE = 1u << 0u;
|
|
||||||
constexpr WindowFlags TRANSPARENT = 1u << 1u;
|
|
||||||
constexpr WindowFlags NO_SCROLLBAR = 1u << 2u;
|
|
||||||
constexpr WindowFlags NO_FOCUS = 1u << 3u;
|
|
||||||
constexpr WindowFlags FORWARD_SCROLL = 1u << 4u;
|
|
||||||
constexpr WindowFlags REFRESH_ALWAYS = 1u << 5u;
|
|
||||||
constexpr WindowFlags PAINT_CHILDREN_FIRST = 1u << 6u;
|
|
||||||
constexpr WindowFlags PUSH_FRONT = 1u << 7u;
|
|
||||||
constexpr WindowFlags WINDOW_FLAGS_LAST = PUSH_FRONT;
|
|
||||||
|
|
||||||
enum SetFocusFlag
|
|
||||||
{
|
|
||||||
SET_FOCUS_DEFAULT,
|
|
||||||
SET_FOCUS_FORWARD,
|
|
||||||
SET_FOCUS_BACKWARD,
|
|
||||||
SET_FOCUS_FIRST
|
|
||||||
};
|
|
||||||
|
|
||||||
class Window
|
|
||||||
{
|
|
||||||
friend class GridLayout;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Window(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0);
|
|
||||||
|
|
||||||
virtual ~Window();
|
|
||||||
|
|
||||||
#if defined(DEBUG_WINDOWS)
|
|
||||||
virtual std::string getName() const
|
|
||||||
{
|
|
||||||
return "Window";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getRectString() const
|
|
||||||
{
|
|
||||||
char result[32];
|
|
||||||
sprintf(result, "[%d, %d, %d, %d]", left(), top(), width(), height());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getIndentString() const
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
auto tmp = parent;
|
|
||||||
while (tmp) {
|
|
||||||
result += " ";
|
|
||||||
tmp = tmp->getParent();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getWindowDebugString(const char * name = nullptr) const
|
|
||||||
{
|
|
||||||
return getName() + (name ? std::string(" [") + name + "] " : " ") + getRectString();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Window * getParent() const
|
|
||||||
{
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isChild(Window * window) const
|
|
||||||
{
|
|
||||||
return window == this || (parent && parent->isChild(window));
|
|
||||||
}
|
|
||||||
|
|
||||||
Window *getFullScreenWindow()
|
|
||||||
{
|
|
||||||
if (width() == LCD_W && height() == LCD_H) return this;
|
|
||||||
if (parent) return parent->getFullScreenWindow();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowFlags getWindowFlags() const
|
|
||||||
{
|
|
||||||
return windowFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWindowFlags(WindowFlags flags)
|
|
||||||
{
|
|
||||||
windowFlags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
LcdFlags getTextFlags() const
|
|
||||||
{
|
|
||||||
return textFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTextFlags(LcdFlags flags)
|
|
||||||
{
|
|
||||||
textFlags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCloseHandler(std::function<void()> handler)
|
|
||||||
{
|
|
||||||
closeHandler = std::move(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFocusHandler(std::function<void(bool)> handler)
|
|
||||||
{
|
|
||||||
focusHandler = std::move(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::list<Window *> getChildren()
|
|
||||||
{
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void deleteLater(bool detach = true, bool trash = true);
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
void deleteChildren();
|
|
||||||
|
|
||||||
bool hasFocus() const
|
|
||||||
{
|
|
||||||
return focusWindow == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Window * getFocus()
|
|
||||||
{
|
|
||||||
return focusWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
void scrollTo(const rect_t & rect);
|
|
||||||
|
|
||||||
void scrollTo(Window * child);
|
|
||||||
|
|
||||||
static void clearFocus();
|
|
||||||
|
|
||||||
virtual void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr);
|
|
||||||
|
|
||||||
void setRect(rect_t value)
|
|
||||||
{
|
|
||||||
rect = value;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWidth(coord_t value)
|
|
||||||
{
|
|
||||||
rect.w = value;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWindowCentered()
|
|
||||||
{
|
|
||||||
rect.x = (parent->width() - width()) / 2;
|
|
||||||
rect.y = (parent->height() - height()) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHeight(coord_t value)
|
|
||||||
{
|
|
||||||
rect.h = value;
|
|
||||||
if (windowFlags & FORWARD_SCROLL)
|
|
||||||
innerHeight = value;
|
|
||||||
else if (innerHeight <= value) {
|
|
||||||
setScrollPositionY(0);
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLeft(coord_t x)
|
|
||||||
{
|
|
||||||
rect.x = x;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTop(coord_t y)
|
|
||||||
{
|
|
||||||
rect.y = y;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t left() const
|
|
||||||
{
|
|
||||||
return rect.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t right() const
|
|
||||||
{
|
|
||||||
return rect.x + rect.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t top() const
|
|
||||||
{
|
|
||||||
return rect.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t bottom() const
|
|
||||||
{
|
|
||||||
return rect.y + rect.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t width() const
|
|
||||||
{
|
|
||||||
return rect.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t height() const
|
|
||||||
{
|
|
||||||
return rect.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect_t getRect() const
|
|
||||||
{
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t getInnerWidth() const
|
|
||||||
{
|
|
||||||
return innerWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInnerWidth(coord_t w)
|
|
||||||
{
|
|
||||||
innerWidth = w;
|
|
||||||
if (width() >= w) {
|
|
||||||
scrollPositionX = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPageWidth(coord_t w)
|
|
||||||
{
|
|
||||||
pageWidth = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPageHeight(coord_t h)
|
|
||||||
{
|
|
||||||
pageHeight = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t getPageCount() const
|
|
||||||
{
|
|
||||||
if (pageWidth)
|
|
||||||
return innerWidth / pageWidth;
|
|
||||||
else if (pageHeight)
|
|
||||||
return innerHeight / pageHeight;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t getPageIndex() const
|
|
||||||
{
|
|
||||||
if (pageWidth)
|
|
||||||
return (getScrollPositionX() + (pageWidth / 2)) / pageWidth;
|
|
||||||
else if (pageHeight)
|
|
||||||
return (getScrollPositionY() + (pageHeight / 2)) / pageHeight;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t getInnerHeight() const
|
|
||||||
{
|
|
||||||
return innerHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInnerHeight(coord_t h)
|
|
||||||
{
|
|
||||||
innerHeight = h;
|
|
||||||
if (windowFlags & FORWARD_SCROLL) {
|
|
||||||
rect.h = innerHeight;
|
|
||||||
parent->adjustInnerHeight();
|
|
||||||
}
|
|
||||||
else if (height() >= h) {
|
|
||||||
setScrollPositionY(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
coord_t maxScrollPosition = h - height();
|
|
||||||
if (scrollPositionY > maxScrollPosition) {
|
|
||||||
setScrollPositionY(maxScrollPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t getScrollPositionX() const
|
|
||||||
{
|
|
||||||
return scrollPositionX;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_t getScrollPositionY() const
|
|
||||||
{
|
|
||||||
return scrollPositionY;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setScrollPositionX(coord_t value);
|
|
||||||
|
|
||||||
virtual void setScrollPositionY(coord_t value);
|
|
||||||
|
|
||||||
bool isChildVisible(const Window * window) const;
|
|
||||||
|
|
||||||
bool isChildFullSize(const Window * window) const;
|
|
||||||
|
|
||||||
bool isVisible() const
|
|
||||||
{
|
|
||||||
return parent && parent->isChildVisible(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInsideParentScrollingArea() const
|
|
||||||
{
|
|
||||||
return parent && right() >= parent->getScrollPositionX() && left() <= parent->getScrollPositionX() + parent->width();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInsideParentScrollingArea();
|
|
||||||
|
|
||||||
void drawVerticalScrollbar(BitmapBuffer * dc);
|
|
||||||
|
|
||||||
void drawHorizontalScrollbar(BitmapBuffer * dc);
|
|
||||||
|
|
||||||
virtual void onEvent(event_t event);
|
|
||||||
|
|
||||||
void adjustInnerHeight();
|
|
||||||
|
|
||||||
coord_t adjustHeight();
|
|
||||||
|
|
||||||
void moveWindowsTop(coord_t y, coord_t delta);
|
|
||||||
|
|
||||||
void invalidate()
|
|
||||||
{
|
|
||||||
invalidate({0, 0, rect.w, rect.h});
|
|
||||||
}
|
|
||||||
|
|
||||||
void bringToTop()
|
|
||||||
{
|
|
||||||
attach(parent); // does a detach + attach
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void checkEvents();
|
|
||||||
|
|
||||||
void attach(Window * window);
|
|
||||||
|
|
||||||
void detach();
|
|
||||||
|
|
||||||
bool deleted() const
|
|
||||||
{
|
|
||||||
return _deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Window * parent;
|
|
||||||
std::list<Window *> children;
|
|
||||||
rect_t rect;
|
|
||||||
coord_t innerWidth;
|
|
||||||
coord_t innerHeight;
|
|
||||||
coord_t pageWidth = 0;
|
|
||||||
coord_t pageHeight = 0;
|
|
||||||
coord_t scrollPositionX = 0;
|
|
||||||
coord_t scrollPositionY = 0;
|
|
||||||
WindowFlags windowFlags;
|
|
||||||
LcdFlags textFlags;
|
|
||||||
bool _deleted = false;
|
|
||||||
|
|
||||||
static Window * focusWindow;
|
|
||||||
static Window * slidingWindow;
|
|
||||||
static Window * touchedWindow;
|
|
||||||
static std::list<Window *> trash;
|
|
||||||
|
|
||||||
std::function<void()> closeHandler;
|
|
||||||
std::function<void(bool)> focusHandler;
|
|
||||||
|
|
||||||
void addChild(Window * window, bool front = false)
|
|
||||||
{
|
|
||||||
if (front)
|
|
||||||
children.push_front(window);
|
|
||||||
else
|
|
||||||
children.push_back(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeChild(Window * window)
|
|
||||||
{
|
|
||||||
children.remove(window);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void invalidate(const rect_t & rect);
|
|
||||||
|
|
||||||
void paintChildren(BitmapBuffer * dc, std::list<Window *>::iterator it);
|
|
||||||
|
|
||||||
void fullPaint(BitmapBuffer * dc);
|
|
||||||
|
|
||||||
virtual void paint(BitmapBuffer *)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onFocusLost()
|
|
||||||
{
|
|
||||||
TRACE_WINDOWS("%s onFocusLost()", getWindowDebugString().c_str());
|
|
||||||
if (focusHandler) {
|
|
||||||
focusHandler(false);
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HARDWARE_TOUCH)
|
|
||||||
static coord_t getSnapStep(coord_t relativeScrollPosition, coord_t pageSize);
|
|
||||||
|
|
||||||
virtual bool onTouchStart(coord_t x, coord_t y);
|
|
||||||
|
|
||||||
virtual bool onTouchEnd(coord_t x, coord_t y);
|
|
||||||
|
|
||||||
virtual bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool forwardTouchEnd(coord_t x, coord_t y);
|
|
||||||
|
|
||||||
bool hasOpaqueRect(const rect_t & testRect) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user