akmenu-next/arm9/source/ui/windowmanager.cpp
2024-10-13 02:11:14 -07:00

169 lines
5.3 KiB
C++

/*
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