/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "bagel/spacebar/baglib/pan_window.h" #include "bagel/spacebar/baglib/res.h" #include "bagel/spacebar/baglib/master_win.h" #include "bagel/spacebar/baglib/bagel.h" #include "bagel/spacebar/baglib/wield.h" #include "bagel/spacebar/boflib/gfx/sprite.h" #include "bagel/spacebar/baglib/button_object.h" #include "bagel/spacebar/baglib/character_object.h" #include "bagel/spacebar/baglib/text_object.h" #include "bagel/spacebar/boflib/std_keys.h" namespace Bagel { namespace SpaceBar { CBagPDA *CBagPanWindow::_pPDABmp; // Pointer to the PDA object int CBagPanWindow::_nCorrection; int CBagPanWindow::_nPanSpeed; CBagWield *CBagPanWindow::_pWieldBmp; // Pointer to the WIELD object void CBagPanWindow::initialize() { _pPDABmp = nullptr; _nCorrection = 4; _nPanSpeed = 1; _pWieldBmp = nullptr; } CBagPanWindow::CBagPanWindow() : CBagStorageDevWnd() { _xViewPortPos = CBofPoint(0, 20); _xMovementRect.setRectEmpty(); _nCorrection = CBagMasterWin::getCorrection(); _nPanSpeed = CBagMasterWin::getPanSpeed(); _pSlideBitmap = nullptr; _pPalette = nullptr; _bPaintToBackdrop = true; _bStretchToScreen = false; _bDraggingObject = false; _bDraggingStart = CBofPoint(0, 0); _pViewPortBitmap = nullptr; // Objects to be painted to the window _pFGObjectList = new CBofList(); // Declare this to be type game win, because it has a pda _xSDevType = SDEV_GAMEWIN; // Make sure the prefilter gets called. setPreFilterPan(true); CBagStorageDev::loadObjects(); } CBofRect CBagPanWindow::unSetSlideBitmap() { CBofRect viewRect; setLActiveObject(nullptr); if (_pSlideBitmap) { viewRect = _pSlideBitmap->getCurrView(); delete _pSlideBitmap; _pSlideBitmap = nullptr; } if (_pViewPortBitmap) { delete _pViewPortBitmap; _pViewPortBitmap = nullptr; } CBofSprite::closeLibrary(); // There is no palette right now CBofApp::getApp()->setPalette(nullptr); return viewRect; } CBofPalette *CBagPanWindow::setSlideBitmap(const CBofString &xSlideBmp, const CBofRect &xSlideRect) { if (!xSlideBmp.isEmpty()) { CBofRect viewRect = unSetSlideBitmap(); CBofRect cRect = getWindowRect(); if ((cRect.width() <= 0) || (cRect.width() > DEF_WIDTH)) cRect.setRect(cRect.left, cRect.top, cRect.left + DEF_WIDTH, cRect.bottom); cRect.bottom = cRect.top + 3 * cRect.width() / 4 - 1; if ((xSlideRect.width() <= 0) || (xSlideRect.width() > DEF_WIDTH)) viewRect.setRect(xSlideRect.left, xSlideRect.top, xSlideRect.left + DEF_WIDTH, DEF_HEIGHT); else viewRect = xSlideRect; // Open Pan bitmap _pSlideBitmap = new CBagPanBitmap(xSlideBmp, nullptr, viewRect); // Make sure the file was found if (!_pSlideBitmap->isValid()) { _pPalette = nullptr; reportError(ERR_FOPEN, "Unable to open file %s", xSlideBmp.getBuffer()); } else { // Set the bagel crap _pPalette = _pSlideBitmap->getPalette(); CBofApp::getApp()->setPalette(_pPalette); CBagel::getBagApp()->getMasterWnd()->selectPalette(_pPalette); CBofApp::getApp()->getMainWindow()->selectPalette(_pPalette); selectPalette(_pPalette); CBofSprite::openLibrary(_pPalette); _pSlideBitmap->setCorrWidth(_nCorrection); CBofBitmap *pBackDropBitmap = new CBofBitmap(DEF_WIDTH + 1, DEF_HEIGHT + 1, _pPalette); if (pBackDropBitmap->height() <= 0 || pBackDropBitmap->width() <= 0) { reportError(ERR_FOPEN, "Error opening bitmap"); } _pViewPortBitmap = new CBofBitmap(DEF_WIDTH + 1, _pSlideBitmap->height() + 1, _pPalette); if (!_pViewPortBitmap->height() || !_pViewPortBitmap->width()) { reportError(ERR_FOPEN, "Error opening bitmap"); } setBackdrop(pBackDropBitmap); move(cRect.left, cRect.top); } } return _pPalette; } CBagPanWindow::~CBagPanWindow() { CBagStorageDev::releaseObjects(); // Delete all master sprite objects if (_pSlideBitmap) { delete _pSlideBitmap; _pSlideBitmap = nullptr; } if (_pViewPortBitmap) { delete _pViewPortBitmap; _pViewPortBitmap = nullptr; } CBofSprite::closeLibrary(); // Free the off screen bitmap delete _pFGObjectList; } void CBagPanWindow::onClose() { CBagStorageDevWnd::onClose(); destroyWindow(); // Destruct the main window } ErrorCode CBagPanWindow::runModal(CBagObject *pObj) { if (_pSlideBitmap != nullptr) { _pSlideBitmap->updateView(); CBagStorageDevWnd::runModal(pObj); // Make sure we update the entire screen after this, // we're not really sure what got trashed, also, // the cursor background will contain bogus information, // so make sure that gets overwritten setPreFilterPan(true); } return _errCode; } ErrorCode CBagPanWindow::onRender(CBofBitmap *pBmp, CBofRect *pRect) { assert(isValidObject(this)); assert(pBmp != nullptr); if (_pSlideBitmap != nullptr) { _pSlideBitmap->updateView(); CBofRect dstRect(CBofPoint(0, 0), _pSlideBitmap->getViewSize()); CBofRect clientArea = getClientRect(); if (_pSlideBitmap->isPan()) { // Paint uncorrected view to backdrop CBofRect currViewRect = _pSlideBitmap->getCurrView(); // Hold current view CBofRect offsetRect; // Size of viewportbmp CBofRect srcRect = dstRect; // Src will be same as dst // If we've been given the go ahead to call prefilter, then // do so but don't do it again unless asked. if (preFilterPan()) { preFilter(pBmp, pRect, _pFGObjectList); setPreFilterPan(false); } _pSlideBitmap->paintUncorrected(_pViewPortBitmap, offsetRect); // Paint and return size srcRect.offsetRect(0, currViewRect.top - offsetRect.top); // less the offset from full // Paint the objects to the backdrop paintObjects(getObjectList(), _pViewPortBitmap, offsetRect, nullptr); dstRect.offsetRect(_xViewPortPos); // No correction ? if (_nCorrection == 0) { _pViewPortBitmap->paint(pBmp, &dstRect, &srcRect); } else { // Warp the backdrop to itself _pSlideBitmap->paintWarped(pBmp, dstRect, srcRect, 0, _pViewPortBitmap, offsetRect); } if (isFiltered()) { uint16 nFilterId = getFilterId(); (*_pBitmapFilter)(nFilterId, pBmp, pRect); } // Now paint it paintObjects(_pFGObjectList, pBmp, clientArea, nullptr, false); } else { // Close-Ups _pSlideBitmap->setCorrWidth(0, false); // If we've been given the go ahead to call prefilter, then // do so but don't do it again unless asked. if (preFilterPan()) { preFilter(pBmp, pRect, _pFGObjectList); setPreFilterPan(false); // Only paint the slide the first time around, if we paint // it in subsequent calls, then we will trash our PDA in this closeup, // and that will be a bad thing. dstRect.offsetRect(_xViewPortPos); ((CBofBitmap *)_pSlideBitmap)->paint(pBmp, _xViewPortPos.x, _xViewPortPos.y); } clientArea.offsetRect(-_xViewPortPos.x, -_xViewPortPos.y); paintObjects(getObjectList(), pBmp, clientArea, nullptr); if (isFiltered()) { uint16 nFilterId = getFilterId(); bool bFiltered = (*_pBitmapFilter)(nFilterId, pBmp, pRect); if (bFiltered) { setPreFilterPan(true); } } // This must be changed so that the foreground objects are actually // a list of child windows. The on paint message is then called with // the background bitmap paintObjects(_pFGObjectList, pBmp, clientArea, nullptr); _pSlideBitmap->setCorrWidth(_nCorrection, false); } } return _errCode; } ErrorCode CBagPanWindow::paintObjects(CBofList *list, CBofBitmap *pBmp, CBofRect &viewRect, CBofList *pUpdateArea, bool tempVar) { ErrorCode errorCode = ERR_NONE; // can't use a null pointer assert(pBmp != nullptr); int nCount = list->getCount(); if (nCount != 0) { int nW = _pSlideBitmap->width(); CBofPoint xCursorLocation = devPtToViewPort(*_xCursorLocation); int nMouseOverObj = -1; for (int i = 0; i < nCount; ++i) { CBagObject *pObj = list->getNodeItem(i); CBofRect xBmpRect = pObj->getRect(); // If it is a panorama we have to check for exceeded bounds if (!pObj->isForeGround() && (nW > 1024) && (viewRect.right > nW) && (xBmpRect.left < (nW / 2))) xBmpRect.offsetRect(nW, 0); CBofRect xIntrRect; if (xIntrRect.intersectRect(&viewRect, &xBmpRect) || pObj->isForeGround() || pObj->isModal()) { CBofPoint pt = xBmpRect.topLeft(); if (!pObj->isForeGround()) { pt = xBmpRect.topLeft() - viewRect.topLeft(); } xIntrRect = xBmpRect; xIntrRect.offsetRect(-xBmpRect.left, -xBmpRect.top); // Only update dirty objects... if (pObj->isDirty() || pObj->isAlwaysUpdate()) { if (!(pObj->getType() == TEXT_OBJ && ((CBagTextObject *)pObj)->isCaption() && pObj->isImmediateRun())) { pObj->update(pBmp, pt, &xIntrRect); // If we're in a closeup and we have a character animation // playing, then make sure we redraw CBagCharacterObject *pCharObj = (CBagCharacterObject *)pObj; // Only in closeups if (!_pSlideBitmap->isPan() && pObj->getType() == CHAR_OBJ) { // Handle non-modal movies also... if (pCharObj->getNumberOfLoops() == 1) { setPreFilterPan(true); } else if (pObj->isAttached() && // don't care if it's not running... (pCharObj->isStationary() == false) && (pCharObj->getNumberOfLoops() != 0) && // Plays multiple or infinite (fly == -1) ((pObj->getRect().width() != 480) && (pObj->getRect().height() != 360))) { // Redraw everything inside of the closeup... but not the PDA... // only want to redraw the closeup, not everything else. // // if our prefilter pan is already dirty, then don't mess with dirty // object list. bool b = preFilterPan(); setPreFilterPan(true); if (!b) { setDirtyAllObjects(false); } } } } } if (pUpdateArea) { xIntrRect.offsetRect(pt); pUpdateArea->addToTail(xIntrRect); } if (pObj->getRect().ptInRect(xCursorLocation)) { pObj->onMouseOver(0, xCursorLocation, this); nMouseOverObj = i; } } // if on screen } // While a valid object if ((nMouseOverObj < 0) && tempVar) noObjectsUnderMouse(); } return errorCode; } // Delete the foreground objects void CBagPanWindow::deleteFGObjects() { _pFGObjectList->removeAll(); } ErrorCode CBagPanWindow::insertFGObjects(CBagObject *pBmp) { // Can't use a nullptr pointer assert(pBmp != nullptr); _pFGObjectList->addToTail(pBmp); return _errCode; } CBagObject *CBagPanWindow::getFGObjects(const CBofString &sObjName) { int nListLen = _pFGObjectList->getCount(); for (int i = 0; i < nListLen; ++i) { CBagObject *pObj = (*_pFGObjectList)[i]; if ((pObj->getRefName().find(sObjName)) != -1) return pObj; } return nullptr; } void CBagPanWindow::activateView() { if (_pSlideBitmap) { _pSlideBitmap->activateScrolling(); _pSlideBitmap->setRotateRate(CBofPoint(32, 16)); } } void CBagPanWindow::deActivateView() { if (_pSlideBitmap) { _pSlideBitmap->deActivateScrolling(); } } void CBagPanWindow::enable() { activateView(); } void CBagPanWindow::disable() { flushAllMessages(); deActivateView(); } ErrorCode CBagPanWindow::onCursorUpdate(int nCurrObj) { assert(isValidObject(this)); if (nCurrObj >= 0) { CBagObject *pObj = getObjectByPos(nCurrObj); if (pObj != nullptr) CBagMasterWin::setActiveCursor(pObj->getOverCursor()); } else if (CBagWield::getWieldCursor() >= 0) { CBagMasterWin::setActiveCursor(CBagWield::getWieldCursor()); } return _errCode; } void CBagPanWindow::onKeyHit(uint32 lKey, uint32 lRepCount) { assert(isValidObject(this)); if (_pSlideBitmap != nullptr) { switch (lKey) { case BKEY_MINUS: if (_nCorrection == 0) { _nCorrection = 64; } _nCorrection >>= 1; _pSlideBitmap->setCorrWidth(_nCorrection); CBagMasterWin::setCorrection(_nCorrection); break; case BKEY_PLUS: if (_nCorrection == 0) { _nCorrection = 1; } else if ((_nCorrection <<= 1) > 32) { _nCorrection = 0; } _pSlideBitmap->setCorrWidth(_nCorrection); CBagMasterWin::setCorrection(_nCorrection); break; case BKEY_LEFT: _pSlideBitmap->setRotateRate(CBofPoint(16, 8)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirRIGHT); break; case BKEY_RIGHT: _pSlideBitmap->setRotateRate(CBofPoint(16, 8)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT); break; case BKEY_UP: _pSlideBitmap->setRotateRate(CBofPoint(16, 8)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirDOWN); break; case BKEY_DOWN: _pSlideBitmap->setRotateRate(CBofPoint(16, 8)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirUP); break; } } CBagStorageDevWnd::onKeyHit(lKey, lRepCount); } void CBagPanWindow::onMouseMove(uint32 nFlags, CBofPoint *p, void *) { assert(isValidObject(this)); assert(p != nullptr); CBofPoint xPoint = *p; CBagStorageDevWnd::onMouseMove(nFlags, &xPoint); if (!isCloseup()) { if (_pSlideBitmap != nullptr) { if (_cRightRect.ptInRect(xPoint)) { _pSlideBitmap->setRotateRate(CBofPoint(((xPoint.x - _xMovementRect.right) * (_nPanSpeed + 1)) / 2, 0)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT); CBagMasterWin::setActiveCursor(BOF_RT_CURSOR); } else if (_cLeftRect.ptInRect(xPoint)) { _pSlideBitmap->setRotateRate(CBofPoint(((_xMovementRect.left - xPoint.x) * (_nPanSpeed + 1)) / 2, 0)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirRIGHT); CBagMasterWin::setActiveCursor(BOF_LT_CURSOR); } else if (_cBottomRect.ptInRect(xPoint)) { _pSlideBitmap->setRotateRate(CBofPoint(0, (xPoint.y - _xMovementRect.bottom))); _pSlideBitmap->setDirection(CBagPanBitmap::kDirUP); CBagMasterWin::setActiveCursor(BOF_DN_CURSOR); } else if (_cTopRect.ptInRect(xPoint)) { _pSlideBitmap->setRotateRate(CBofPoint(0, (_xMovementRect.top - xPoint.y))); _pSlideBitmap->setDirection(CBagPanBitmap::kDirDOWN); CBagMasterWin::setActiveCursor(BOF_UP_CURSOR); } else { _pSlideBitmap->setDirection(CBagPanBitmap::kDirNONE); } if (getLActiveObject() && getLActivity()) { _pSlideBitmap->setDirection((CBagPanBitmap::Direction)(_pSlideBitmap->getDirection() | CBagPanBitmap::kDirVIEW)); } } } // Change cursor based on the Foreground object list // Run through background object list and find if the cursor is over an object CBofList *pList = _pFGObjectList; if (pList != nullptr) { CBagObject *pOverObj = nullptr; int nCount = pList->getCount(); for (int i = 0; i < nCount; ++i) { CBagObject *pObj = pList->getNodeItem(i); if (pObj->isInside(xPoint)) { pOverObj = pObj; } } // If we just happen to be over the pda then let our // PDA code decide... oh, and we're wielding... if (pOverObj != nullptr) { int nCursorID = -1; // the logz case is handled by onmousemove in zoompda if (pOverObj->getRefName().find("BPDA_WLD") != -1) { CBagPDA *pPda = (CBagPDA *)g_SDevManager->getStorageDevice(pOverObj->getRefName()); if (pPda != nullptr) { CBofRect cRect = pOverObj->getRect(); nCursorID = pPda->getProperCursor(xPoint, cRect); } } // Still no luck, if we're wielding, use that cursor. if (nCursorID == -1) { nCursorID = pOverObj->getOverCursor(); if (CBagWield::getWieldCursor() >= 0 && ((pOverObj->getRefName().find("BWIELD_WLD") != -1) || (pOverObj->getRefName().find("THUD_WLD") != -1))) { nCursorID = CBagWield::getWieldCursor(); } } CBagMasterWin::setActiveCursor(nCursorID); } } if (_bDraggingObject) { CBagObject *pObj = _pFGObjectList->getNodeItem(_pFGObjectList->getCount() - 1); pObj->setPosition(xPoint); } *_xCursorLocation = xPoint; } void CBagPanWindow::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *) { int nCount = _pFGObjectList->getCount(); if (nCount != 0) { for (int i = 0; i < nCount; ++i) { CBagObject *pObj = _pFGObjectList->getNodeItem(i); if (pObj->isInside(*xPoint)) { pObj->onLButtonDown(nFlags, xPoint, this); return; } } } CBagStorageDevWnd::onLButtonDown(nFlags, xPoint); MouseActivity nMA = getLActivity(); CBagObject *pActObj = getLActiveObject(); if (nMA && pActObj && pActObj->isMovable()) { _bDraggingObject = true; _bDraggingStart = pActObj->getPosition(); _pFGObjectList->addToTail(pActObj); } } void CBagPanWindow::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *) { MouseActivity nMA = getLActivity(); CBagObject *pActObj = getLActiveObject(); if ((pActObj != nullptr) && (nMA == kMouseDRAGGING) && (pActObj->getType() == BUTTON_OBJ) && (((CBagButtonObject *)pActObj)->getButtonType() == CBagButtonObject::BTN_SLIDER)) { pActObj->onLButtonUp(nFlags, xPoint, this); // We are not dragging a slider anymore setLActivity(kMouseNONE); setLActiveObject(nullptr); } else { bool bMoved = false; if (_bDraggingObject) { _bDraggingObject = false; pActObj = _pFGObjectList->removeTail(); int nCount = _pFGObjectList->getCount(); if (nCount != 0) { for (int i = 0; i < nCount; ++i) { CBagObject *pObj = _pFGObjectList->getNodeItem(i); CBofRect xBmpRect = pObj->getRect(); if (xBmpRect.ptInRect(*xPoint)) { pObj->onObjInteraction(pActObj, this); } } } if (pActObj->getPosition() != _bDraggingStart) { pActObj->setPosition(_bDraggingStart); bMoved = true; } } if (!bMoved) { // Parse backwards to get topmost obj 1st int nCount = _pFGObjectList->getCount(); if (nCount != 0) { for (int i = nCount - 1; i >= 0; --i) { CBagObject *pObj = _pFGObjectList->getNodeItem(i); if (pObj->isInside(*xPoint)) { pObj->onLButtonUp(nFlags, xPoint, this); return; } } } } CBagStorageDevWnd::onLButtonUp(nFlags, xPoint); } } void CBagPanWindow::onSize(uint32 nType, int cx, int cy) { // nRange defines the distance (in pixels) from a viewport edge // (toward the center of the viewport) that the viewport boundary // rectangles begin. The boundary rectangles surround the edges // of the viewport. When the mouse cursor enters a boundary rectangle, // it's time to pan the view. Larger positive values of nRange will // cause the boundary rectangle to extend farther from the viewport edge. // A value of zero will cause the boundary rectangles to be at the edge // of the viewport. If nRange has a negative value, the boundary // rectangle will start outside the viewport rectangle. // const int nRange = 16; CBofRect xMaxPanBmpRect; if (_pSlideBitmap) xMaxPanBmpRect = _pSlideBitmap->getMaxView(); else xMaxPanBmpRect.setRect(0, 0, DEF_WIDTH, DEF_HEIGHT); CBofPoint vp; CBofSize vs = CBofSize(cx, cy); // Check if the current view is greater than the max view if (vs.cx > xMaxPanBmpRect.width()) vs.cx = xMaxPanBmpRect.width(); if (_pSlideBitmap && _pSlideBitmap->width() > 480) vs.cy = 3 * vs.cx / 4; if (vs.cy > xMaxPanBmpRect.height()) vs.cy = xMaxPanBmpRect.height(); setViewPortSize(vs); vp.x = (cx - vs.cx) / 2; vp.y = 10; setViewPortPos(vp); vp.x += nRange; vp.y += nRange; vs.cx -= (2 * nRange); // Subtract 2*nRange from vs because there's vs.cy -= (2 * nRange); // a boundary rectangle on the left and right // *and* the top and bottom. CBofRect cRect(vp, vs); _cTopRect.setRect(cRect.left, 0, cRect.right, cRect.top); _cBottomRect.setRect(cRect.left, cRect.bottom, cRect.right, 480 - 1); _cLeftRect.setRect(0, cRect.top, cRect.left, cRect.bottom); _cRightRect.setRect(cRect.right, cRect.top, 640 - 1, cRect.bottom); setMovementRect(cRect); } void CBagPanWindow::OnWindowPosChanging(WindowPos *lpwndpos) { const int MENUNBORDER = 50; CBofRect xSlideBmpRect; xSlideBmpRect.setRect(0, 0, DEF_WIDTH, DEF_HEIGHT); if (lpwndpos->cx > xSlideBmpRect.width()) lpwndpos->cx = xSlideBmpRect.width(); if (lpwndpos->cy > xSlideBmpRect.height() + MENUNBORDER) lpwndpos->cy = xSlideBmpRect.height() + MENUNBORDER; } void CBagPanWindow::flushInputEvents() { g_system->getEventManager()->purgeKeyboardEvents(); g_system->getEventManager()->purgeMouseEvents(); } #define PAN_WIDTH 2048 #define PAN_HEIGHT 512 #define HALF_PAN_WIDTH (PAN_WIDTH/2) uint32 CBagPanWindow::rotateTo(CBofPoint &xPoint, int nRate) { assert(nRate > 0); if (_pSlideBitmap && (xPoint.x != -1) && (xPoint.y != -1)) { CBofRect r = _pSlideBitmap->getCurrView(); for (;;) { CBofPoint xCurrPos = r.topLeft(); int x = (xPoint.x - xCurrPos.x); int y = (xPoint.y - xCurrPos.y); if (abs(x) > HALF_PAN_WIDTH) { if (x > 0) { x -= PAN_WIDTH; } else { x += PAN_WIDTH; } } // Are we there yet? if (x == 0 && y == 0) break; int nRateX = MIN(x, nRate); if (x < 0) nRateX = MAX(x, -nRate); int nRateY = MIN(y, nRate); if (y < 0) nRateY = MAX(y, -nRate); r.offsetRect(nRateX, nRateY); _pSlideBitmap->setCurrView(r); paintScreen(); } } return 0; } uint32 CBagPanWindow::benchmark() { deActivateView(); _pSlideBitmap->activateScrolling(); _pSlideBitmap->setRotateRate(CBofPoint(8, 0)); _pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT); timerStart(); for (int i = 0; i < 50; i++) paintScreen(); uint32 dTime = timerStop(); activateView(); return dTime; } bool CBagPanWindow::deactivatePDA() { // If we have a PDA and the pda is active if (_pPDABmp && _pPDABmp->isActivated()) { // deactivate it _pPDABmp->deactivate(); // PDA successfully deactivated return true; } // PDA already deactivated return false; } bool CBagPanWindow::activatePDA() { // If we have a BMP and the pda is not active if (_pPDABmp && (!_pPDABmp->isActivated() || _pPDABmp->isActivating())) { _pPDABmp->activate(); // activate it // PDA successfully activated return true; } // PDA already activated return false; } const CBofPoint CBagPanWindow::devPtToViewPort(const CBofPoint &xPoint) { CBofRect r = _pSlideBitmap->getCurrView(); CBofPoint p; p.x = xPoint.x + r.left - _xViewPortPos.x; p.y = xPoint.y + r.top - _xViewPortPos.y; if (_pSlideBitmap->isPan()) { if (p.x >= _pSlideBitmap->width()) p.x -= _pSlideBitmap->width(); // If this view is being painted with a correction, we need // to correct the point to the warped view space. if (_nCorrection != 0) { p = _pSlideBitmap->warpedPoint(p); } } return p; } const CBofPoint CBagPanWindow::viewPortToDevPt(const CBofPoint &xPoint) { CBofRect r = _pSlideBitmap->getCurrView(); CBofPoint p(xPoint.x - r.left, xPoint.y - r.top); if (p.x < 0) p.x += _pSlideBitmap->width(); return p; } ErrorCode CBagPanWindow::attachActiveObjects() { CBagStorageDev::attachActiveObjects(); if (_pPDABmp != nullptr) { _pPDABmp->attachActiveObjects(); } return _errCode; } void CBagPanWindow::setViewPortSize(const CBofSize &xViewSize) { if (_pSlideBitmap) _pSlideBitmap->setViewSize(xViewSize); } const CBofRect CBagPanWindow::getViewPort() { CBofRect r; if (_pSlideBitmap) r = _pSlideBitmap->getCurrView(); return r; } const CBofSize CBagPanWindow::getViewPortSize() { CBofRect r; if (_pSlideBitmap) r = _pSlideBitmap->getCurrView(); return r.size(); } void CBagPanWindow::waitForPDA() { // Make sure we have a non-null pda while (_pPDABmp && _pPDABmp->isActivating()) { setPreFilterPan(true); _pPDABmp->setDirty(true); paintScreen(); } } } // namespace SpaceBar } // namespace Bagel