/* windowmanager.cpp Copyright (C) 2007 Acekard, www.acekard.com Copyright (C) 2007-2009 somebody Copyright (C) 2009 yellow wood goblin SPDX-License-Identifier: GPL-3.0-or-later */ #include "windowmanager.h" #include "ui.h" namespace akui { cWindowManager::cWindowManager() : _currentWindow(NULL, NULL), _focusedWindow(NULL), _windowBelowPen(NULL), _capturedWindow(NULL) {} cWindowManager::~cWindowManager() {} void cWindowManager::setFocusedWindow(cWindow* aWindow) { if (aWindow != focusedWindow() && (!aWindow || aWindow->isFocusable())) { if (focusedWindow()) focusedWindow()->disableFocused(); _focusedWindow = aWindow; if (aWindow) aWindow->enableFocused(); } } cWindowManager& cWindowManager::addWindow(cWindow* aWindow) { if (_currentWindow()) { _currentWindow._focused = focusedWindow(); _backgroundWindows.push_back(_currentWindow); } _currentWindow = cWindowRec(aWindow); setFocusedWindow(aWindow); updateBackground(); return *this; } cWindowManager& cWindowManager::removeWindow(cWindow* aWindow) { if (aWindow == _currentWindow()) { if (_backgroundWindows.empty()) { _currentWindow = cWindowRec(NULL, NULL); } else { _currentWindow = _backgroundWindows.back(); _backgroundWindows.pop_back(); setFocusedWindow(_currentWindow._focused); } } else { for (cWindows::iterator it = _backgroundWindows.begin(); it != _backgroundWindows.end(); ++it) { if ((*it)() == aWindow) { _backgroundWindows.erase(it); break; } } } if (focusedWindow() && aWindow->doesHierarchyContain(focusedWindow())) { _focusedWindow = _currentWindow(); } updateBackground(); return *this; } const cWindowManager& cWindowManager::update(void) { #if 0 for(cWindows::iterator it=_backgroundWindows.begin();it!=_backgroundWindows.end();++it) { dbg_printf("background (%s)\n",(*it)()->text().c_str()); } dbg_printf("currentWindow (%s)\n",_currentWindow()?_currentWindow()->text().c_str():"NULL"); #endif if (_currentWindow()) { _currentWindow()->update(); _currentWindow()->render(); } return *this; } const cWindowManager& cWindowManager::updateBackground(void) { gdi().setMainEngineLayer(MEL_DOWN); for (cWindows::iterator it = _backgroundWindows.begin(); it != _backgroundWindows.end(); ++it) { (*it)()->update(); } for (cWindows::iterator it = _backgroundWindows.begin(); it != _backgroundWindows.end(); ++it) { (*it)()->render(); } gdi().setMainEngineLayer(MEL_UP); update(); gdi().present(); return *this; } bool cWindowManager::process(cMessage& message) const { return _currentWindow()->process(message); } cWindowManager& cWindowManager::checkForWindowBelowPen(const cPoint& touchPoint) { _windowBelowPen = NULL; if (_currentWindow()->isVisible()) { cWindow* wbp = _currentWindow()->windowBelow(touchPoint); if (wbp) _windowBelowPen = wbp; } return *this; } void cWindowManager::updateFocusIfNecessary(const cPoint& touchPoint) { cWindow* wbp = windowBelowPen(); if (wbp != focusedWindow()) setFocusedWindow(wbp); if (wbp && !wbp->isFocusable()) _capturedWindow = wbp; } bool cWindowManager::processTouchMessage(cTouchMessage& message) { bool isHandled = false; if (windowBelowPen()) { isHandled = windowBelowPen()->process(message); // dbg_printf("windowBelowPen() %s process touch\n",windowBelowPen()->text().c_str()); } else { isHandled = process(message); // dbg_printf("default process touch\n"); } return isHandled; } bool cWindowManager::onKeyDown(unsigned char keyCode, unsigned char shift) { cKeyMessage msg(cMessage::keyDown, keyCode, shift); return process(msg); } bool cWindowManager::onKeyUp(unsigned char keyCode, unsigned char shift) { cKeyMessage msg(cMessage::keyUp, keyCode, shift); return process(msg); } bool cWindowManager::onTouchDown(int x, int y) { _capturedWindow = NULL; checkForWindowBelowPen(cPoint(x, y)); cTouchMessage msg(cMessage::touchDown, cPoint(x, y)); bool isHandled = processTouchMessage(msg); updateFocusIfNecessary(cPoint(x, y)); return isHandled; } bool cWindowManager::onTouchUp(int x, int y) { checkForWindowBelowPen(cPoint(x, y)); cTouchMessage msg(cMessage::touchUp, cPoint(x, y)); dbg_printf("window below pen (%s)\n", _windowBelowPen ? _windowBelowPen->text().c_str() : "NULL"); dbg_printf("focusedWindow (%s)\n", focusedWindow() ? focusedWindow()->text().c_str() : "NULL"); if (_capturedWindow) { bool result = _capturedWindow->process(msg); _capturedWindow = NULL; return result; } if (focusedWindow() && windowBelowPen() != focusedWindow()) return focusedWindow()->process(msg); return processTouchMessage(msg); } bool cWindowManager::onTouchMove(int x, int y) { const INPUT& input = getInput(); cTouchMessage msg(cMessage::touchMove, cPoint(x, y)); checkForWindowBelowPen(cPoint(input.touchPt.px, input.touchPt.py)); dbg_printf("touch move %d %d\n", x, y); return processTouchMessage(msg); } } // namespace akui