void PopupMenu::mouseReleaseEvent(QMouseEvent *e) { DEBUG_PRST_ROUTES(stderr, "PopupMenu::mouseReleaseEvent this:%p\n", this); if(_contextMenu && _contextMenu->isVisible()) return; // Removed by Tim. Why not stay-open scrollable menus? // if(MusEGlobal::config.scrollableSubMenus) // { // QMenu::mouseReleaseEvent(e); // return; // } QAction* action = actionAt(e->pos()); if (!(action && action == activeAction() && !action->isSeparator() && action->isEnabled())) action=NULL; #ifdef POPUP_MENU_DISABLE_STAY_OPEN if (action && action->menu() != NULL && action->isCheckable()) action->activate(QAction::Trigger); QMenu::mouseReleaseEvent(e); if (action && action->menu() != NULL && action->isCheckable()) close(); return; #else // Check for Ctrl to stay open. const bool stay_open = _stayOpen && (MusEGlobal::config.popupsDefaultStayOpen || (e->modifiers() & Qt::ControlModifier)); // Stay open? Or does the action have a submenu, but also a checkbox of its own? if(action && (stay_open || (action->isEnabled() && action->menu() && action->isCheckable()))) { DEBUG_PRST_ROUTES(stderr, "PopupMenu::mouseReleaseEvent: stay open\n"); action->trigger(); // Trigger the action. e->accept(); if(!stay_open) closeUp(); return; // We handled it. } // Otherwise let ancestor QMenu handle it... e->ignore(); QMenu::mouseReleaseEvent(e); #endif // POPUP_MENU_DISABLE_STAY_OPEN }
bool PopupMenu::event(QEvent* event) { DEBUG_PRST_ROUTES(stderr, "PopupMenu::event:%p activePopupWidget:%p this:%p class:%s event type:%d\n", event, QApplication::activePopupWidget(), this, metaObject()->className(), event->type()); switch(event->type()) { #ifndef POPUP_MENU_DISABLE_STAY_OPEN case QEvent::MouseButtonDblClick: { if(_stayOpen) { QMouseEvent* e = static_cast<QMouseEvent*>(event); if(e->modifiers() == Qt::NoModifier) { event->accept(); // Convert into a return press, which selects the item and closes the menu. // Note that with double click, it's a press followed by release followed by double click. // That would toggle our item twice eg on->off->on, which is hopefully OK. QKeyEvent ke(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); //ke.ignore(); // Pass it on return QMenu::event(&ke); } } } break; case QEvent::KeyPress: { QKeyEvent* e = static_cast<QKeyEvent*>(event); switch(e->key()) { case Qt::Key_Space: if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this)) break; case Qt::Key_Select: case Qt::Key_Return: case Qt::Key_Enter: { if(QAction* act = activeAction()) { const bool stay_open = _stayOpen && (MusEGlobal::config.popupsDefaultStayOpen || (e->modifiers() & Qt::ControlModifier)); // Stay open? Or does the action have a submenu, but also a checkbox of its own? if(stay_open || (act->isEnabled() && act->menu() && act->isCheckable())) { act->trigger(); // Trigger the action. event->accept(); if(!stay_open) closeUp(); return true; // We handled it. } // Otherwise let ancestor QMenu handle it... } } break; default: break; } } break; #endif // POPUP_MENU_DISABLE_STAY_OPEN #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL case QEvent::MouseMove: { if(!MusEGlobal::config.scrollableSubMenus) { QMouseEvent* e = static_cast<QMouseEvent*>(event); QPoint globPos = e->globalPos(); int dw = QApplication::desktop()->width(); // We want the whole thing if multiple monitors. if(x() < 0 && globPos.x() <= 0) // If on the very first pixel (or beyond) { moveDelta = 32; if(!timer->isActive()) timer->start(); event->accept(); return true; } else if(x() + width() >= dw && globPos.x() >= (dw -1)) // If on the very last pixel (or beyond) { moveDelta = -32; if(!timer->isActive()) timer->start(); event->accept(); return true; } if(timer->isActive()) timer->stop(); } } break; #endif // POPUP_MENU_DISABLE_AUTO_SCROLL default: break; } event->ignore(); return QMenu::event(event); }
void TattooMap::showCloseUp(int closeUpNum) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; // Reset scroll position screen._currentScroll = Common::Point(0, 0); // Get the closeup images Common::String fname = Common::String::format("res%02d.vgs", closeUpNum + 1); ImageFile pic(fname); Point32 closeUp(_data[closeUpNum].x * 100, _data[closeUpNum].y * 100); Point32 delta((SHERLOCK_SCREEN_WIDTH / 2 - closeUp.x / 100) * 100 / CLOSEUP_STEPS, (SHERLOCK_SCREEN_HEIGHT / 2 - closeUp.y / 100) * 100 / CLOSEUP_STEPS); Common::Rect oldBounds(closeUp.x / 100, closeUp.y / 100, closeUp.x / 100 + 1, closeUp.y / 100 + 1); int size = 64; int n = 256; int deltaVal = 512; bool minimize = false; int scaleVal, newSize; do { scaleVal = n; newSize = pic[0].sDrawXSize(n); if (newSize > size) { if (minimize) deltaVal /= 2; n += deltaVal; } else { minimize = true; deltaVal /= 2; n -= deltaVal; if (n < 1) n = 1; } } while (deltaVal && size != newSize); int deltaScale = (SCALE_THRESHOLD - scaleVal) / CLOSEUP_STEPS; for (int step = 0; step < CLOSEUP_STEPS; ++step) { Common::Point picSize(pic[0].sDrawXSize(scaleVal), pic[0].sDrawYSize(scaleVal)); Common::Point pt(closeUp.x / 100 - picSize.x / 2, closeUp.y / 100 - picSize.y / 2); restoreArea(oldBounds); screen._backBuffer1.transBlitFrom(pic[0], pt, false, 0, scaleVal); screen.slamRect(oldBounds); screen.slamArea(pt.x, pt.y, picSize.x, picSize.y); oldBounds = Common::Rect(pt.x, pt.y, pt.x + picSize.x + 1, pt.y + picSize.y + 1); closeUp += delta; scaleVal += deltaScale; events.wait(1); } // Handle final drawing of closeup // TODO: Handle scrolling Common::Rect r(SHERLOCK_SCREEN_WIDTH / 2 - pic[0]._width / 2, SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2, SHERLOCK_SCREEN_WIDTH / 2 - pic[0]._width / 2 + pic[0]._width, SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2 + pic[0]._height); restoreArea(oldBounds); screen._backBuffer1.transBlitFrom(pic[0], Common::Point(r.left, r.top)); screen.slamRect(oldBounds); screen.slamRect(r); events.wait(2); }