// Runs as we're exiting the menu void GameParamUserInterface::onEscape() { EditorUserInterface *ui = getUIManager()->getUI<EditorUserInterface>(); string newFilename = getMenuItem(1)->getValue(); bool filenameChanged = mLevelFilename != newFilename; if(filenameChanged) ui->setLevelFileName(newFilename); GameType *gameType = getUIManager()->getUI<EditorUserInterface>()->getLevel()->getGameType(); const Vector<string> *keys = gameType->getGameParameterMenuKeys(); for(S32 i = 0; i < keys->size(); i++) { MenuItemMap::iterator iter = mMenuItemMap.find(keys->get(i)); MenuItem *menuItem = iter->second.get(); gameType->saveMenuItem(menuItem, keys->get(i)); } if(anythingChanged() || filenameChanged) { EditorUserInterface *ui = getUIManager()->getUI<EditorUserInterface>(); // TODO -->Save undo state here!!! ui->validateLevel(); } // Now back to our previously scheduled program... (which will be the editor, of course) getUIManager()->reactivatePrevUI(); }
void AbstractMessageUserInterface::render() const { if(mRenderUnderlyingUi && getUIManager()->getPrevUI() != this) getUIManager()->renderPrevUI(this); renderMessageBox(mTitle, mInstr, mMessage, mMaxLines); }
void PlayerMenuUserInterface::playerSelected(U32 index) const { // When we created the menu, names were not sorted, and item indices were assigned in "natural order". Then // the menu items were sorted by name, and now the indices are now jumbled. This bit here tries to get the // new, actual list index of an item given its original index. for(S32 i = 0; i < getMenuItemCount(); i++) if(getMenuItem(i)->getIndex() == (S32)index) { index = i; break; } GameType *gt = getGame()->getGameType(); if(action == PlayerActionChangeTeam) { TeamMenuUserInterface *ui = getUIManager()->getUI<TeamMenuUserInterface>(); ui->mNameToChange = getMenuItem(index)->getPrompt(); getUIManager()->activate<TeamMenuUserInterface>(); // Show menu to let player select a new team } else if(gt) // action == Kick gt->c2sKickPlayer(getMenuItem(index)->getPrompt()); if(action != PlayerActionChangeTeam) // Unless we need to move on to the change team screen... getUIManager()->reactivateGameUI(); // ...it's back to the game! }
void ChatUserInterface::onLobbyChat() { // Escape chat only if the previous UI isn't UIQueryServers // This is to prevent spamming the chat window with joined/left messages if(getUIManager()->getPrevUI() == getUIManager()->getUI<QueryServersUserInterface>()) getUIManager()->reactivatePrevUI(); else onEscape(); }
void ChatUserInterface::onEscape() const { // Don't leave if UIQueryServers is a parent unless we're in-game... // Is UIQueryServers supposed to be a parent of UIGame?? if(!getUIManager()->cameFrom<QueryServersUserInterface>() || getUIManager()->cameFrom<GameUserInterface>()) leaveLobbyChat(); getUIManager()->reactivatePrevUI(); playBoop(); }
bool ErrorMessageUserInterface::usesEditorScreenMode() const { if(getUIManager()->getCurrentUI() == this) { TNLAssert(getUIManager()->getPrevUI() != this, "Why same UI twice?"); return getUIManager()->getPrevUI()->usesEditorScreenMode(); } else return getUIManager()->getCurrentUI()->usesEditorScreenMode(); }
// Run when UIChat is called in normal UI mode void ChatUserInterface::onActivate() { MasterServerConnection *masterConn = getGame()->getConnectionToMaster(); if(masterConn && masterConn->isEstablished()) masterConn->c2mJoinGlobalChat(); // Only clear the chat list if the previous UI was NOT UIQueryServers if(getUIManager()->getPrevUI() != getUIManager()->getUI<QueryServersUserInterface>()) mPlayersInLobbyChat.clear(); mRenderUnderlyingUI = true; mDisableShipKeyboardInput = true; // Prevent keystrokes from getting to game }
/** * @brief Filters message. * @param[in,out] msg message. * @return false to skip this message. true to dispatch this message. */ bool WinSkinWindow::FilterMessage(MSG* msg) { if (msg->hwnd != m_hWnd) return true; if (WM_KEYDOWN == msg->message || WM_SYSKEYDOWN == msg->message) { // マウスボタン、修飾キーは無視 switch (msg->wParam) { case VK_LBUTTON: case VK_RBUTTON: case VK_MBUTTON: case VK_SHIFT: case VK_CONTROL: case VK_MENU: return true; } UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { KeyEventParameter parameter; UInt32 modifiers = 0; modifiers |= ((::GetKeyState(VK_SHIFT) & 0x8000) ? KeyEventParameter::ModifierMask_Shift : 0); modifiers |= ((::GetKeyState(VK_CONTROL) & 0x8000) ? KeyEventParameter::ModifierMask_Ctrl : 0); modifiers |= ((::GetKeyState(VK_MENU) & 0x8000) ? KeyEventParameter::ModifierMask_Alt : 0); parameter.SetKeyCode(static_cast<DWORD>(msg->wParam)); parameter.SetModifiers(modifiers); return uiManager->KeyDown(parameter); } } return true; }
// --------------------------------------------------------------------- //! Called when user releases a mouse button. // --------------------------------------------------------------------- void BeSkinView::MouseUp( BPoint where //!< location of the cursor ) { if (0 == lastPressedMouseButton) { return; } UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { if (1 == lastPressedMouseButton) { uiManager->Button1Up(); } else if (2 == lastPressedMouseButton) { uiManager->Button2Up(); } } lastPressedMouseButton = 0; }
// --------------------------------------------------------------------- //! Cancels this task. // --------------------------------------------------------------------- void MouseHoverUITask::CancelTask() { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); uiManager->GetUIController()->EndTimer(UIController::TimerID_MouseHover); uiManager->EndTask(this); }
void PlaylistMenuUserInterface::processSelection(U32 index) { string playlistName = getMenuItem(index)->getPrompt(); if(playlistName == NO_PLAYLIST) playlistName = ""; setPlaylist(playlistName); // Different implementations when hosting vs. when playing getUIManager()->reactivatePrevUI(); // To hosting menu }
/** * @brief Starts task. */ void MouseHoverUITask::StartTask() { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); currentStep = 1; isBeingHot = true; updateAppearance(); uiManager->GetUIController()->BeginTimer(UIController::TimerID_MouseHover, HOVER_TIMER_ELAPSE); }
/** * @brief UM_REREAD_SKIN ハンドラ * @retval 0 処理したとき */ LRESULT WinSkinWindow::onRereadSkin( HWND /*hWnd*/, ///< ウィンドウハンドル UINT /*uMsg*/, ///< UM_REREAD_SKIN WPARAM /*wParam*/, ///< 利用しないパラメータ LPARAM /*lParam*/ ///< 利用しないパラメータ ) { getUIManager()->RereadSkin(); return 0; }
/** * @brief timer command handler. */ void BeSkinView::timerCommandReceived(uint32 timerCommand) { UIController::TimerID timerId = timerCommandToTimerId(timerCommand); UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { uiManager->TimerEvent(timerId); } }
void GameParamUserInterface::onActivate() { TNLAssert(getUIManager()->cameFrom<EditorUserInterface>(), "GameParamUserInterface should only be called from the editor!"); Level *level = getUIManager()->getUI<EditorUserInterface>()->getLevel(); const GameType *gameType = level->getGameType(); // Force rebuild of all params for current gameType; this will make sure we have the latest info if we've loaded a new level, // but will also preserve any values entered for gameTypes that are not current. clearCurrentGameTypeParams(gameType); // Load filename from editor only when we activate the menu mLevelFilename = stripExtension(getUIManager()->getUI<EditorUserInterface>()->getLevelFileName()); if(mLevelFilename == EditorUserInterface::UnnamedFile) mLevelFilename = ""; updateMenuItems(gameType); mOrigGameParams = level->toLevelCode(); // Save a copy of the params coming in for comparison when we leave to see what changed Cursor::disableCursor(); }
// --------------------------------------------------------------------- //! Called when window is activated or deactivated. // --------------------------------------------------------------------- void BeSkinView::WindowActivated( bool state //!< true if windows has become active, false if window no longer is the active. ) { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { uiManager->UIActivated(); } }
// --------------------------------------------------------------------- //! Called when user moves the mouse cursor. // --------------------------------------------------------------------- void BeSkinView::MouseMoved( BPoint where, //!< location of the cursor uint32 code, //!< enter or exit view, inside or outside view const BMessage *a_message //!< message if user is dragging ) { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { uiManager->MouseMove(); } }
// --------------------------------------------------------------------- LRESULT WinSkinWindow::onUMActivated( HWND /*hWnd*/, //!< ウィンドウハンドル UINT /*uMsg*/, //!< UM_ACTIVATED WPARAM /*wParam*/, //!< 利用しないパラメータ LPARAM /*lParam*/ //!< 利用しないパラメータ ) { UIManager* uiManager = getUIManager(); if (NULL != uiManager) { uiManager->UIActivated(); } return 0; }
// --------------------------------------------------------------------- //! Called when user presses a mouse button. // --------------------------------------------------------------------- void BeSkinView::MouseDown( BPoint where //!< location of the cursor ) { uint32 buttons = 0; BMessage* message = Window()->CurrentMessage(); if (NULL != message) { int32 value = 0; if (B_OK == message->FindInt32("buttons", &value)) { buttons = value; } } if (0 == (buttons & (B_PRIMARY_MOUSE_BUTTON | B_SECONDARY_MOUSE_BUTTON))) { return; } BWindow* window = Window(); if (!window->IsActive()) { window->Activate(); } // deactivate tool tip BMessage deactivateMessage(BeToolTipWindow::MSG_DEACTIVATE); toolTipMessenger->SendMessage(&deactivateMessage, static_cast<BHandler*>(NULL), 1000000); UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { if (buttons & B_PRIMARY_MOUSE_BUTTON) { uiManager->Button1Down(); lastPressedMouseButton = 1; } else if (buttons & B_SECONDARY_MOUSE_BUTTON) { uiManager->Button2Down(); lastPressedMouseButton = 2; } } }
void LevelMenuSelectUserInterface::processSelection(U32 index) { Parent::onActivate(); GameConnection *gc = getGame()->getConnectionToServer(); if((index & UPLOAD_LEVELS_BIT) && (index & (~UPLOAD_LEVELS_BIT)) < U32(mMenuDisplayItems.size())) { FolderManager *folderManager = mGameSettings->getFolderManager(); string filename = strictjoindir(folderManager->getLevelDir(), mMenuDisplayItems[index & (~UPLOAD_LEVELS_BIT)]); if(!gc->TransferLevelFile(filename.c_str())) getGame()->displayErrorMessage("!!! Can't upload level: unable to read file"); } else gc->c2sRequestLevelChange(index, false); // The selection index is the level to load getUIManager()->reactivateGameUI(); // Back to the game }
/** * @brief WM_TIMER ハンドラ * * UIManager にイベントを伝えます。 * @retval 0 処理したとき */ LRESULT WinSkinWindow::onTimer( HWND hWnd, ///< ウィンドウハンドル UINT uMsg, ///< WM_TIMER WPARAM wParam, ///< タイマID LPARAM lParam ///< コールバック関数 ) { base::wndProc(hWnd, uMsg, wParam, lParam); UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { uiManager->TimerEvent(winTimerIdToTimerId(static_cast<UINT_PTR>(wParam))); } return 0; }
/** * @brief Called when timer event occurred. * @param timerId ID of the timer. */ void MouseHoverUITask::TimerEvent(SInt32 timerId) { if (timerId != UIController::TimerID_MouseHover) { return; } UInt32 commandState = getUIManager()->GetCommandState(targetCommandID); if (commandState & UIManager::CommandState_Disabled & commandState) { CancelTask(); return; } if (!changeStatusAccordingToMouse()) { CancelTask(); return; } if (isBeingHot) { if (currentStep < stepCount) { currentStep++; updateAppearance(); } } else { if (currentStep > 0) { currentStep--; updateAppearance(); if (currentStep == 0) { CancelTask(); } } } }
/** * @brief Updates the appearance of the area. */ void MouseHoverUITask::updateAppearance() { if (targetSkinArea == ColorCodedSkin::Area_None) { return; } UIManager* uiManager = getUIManager(); ColorCodedSkin* skin = uiManager->GetSkin(); SInt32 normalImageIndex = normalActiveImageIndex; SInt32 hotImageIndex = hotActiveImageIndex; if (!uiManager->GetUIController()->IsUIActive()) { normalImageIndex = normalInactiveImageIndex; hotImageIndex = hotInactiveImageIndex; } skin->UpdatePartAppearanceWithBlend(targetSkinArea, hotImageIndex, normalImageIndex, currentStep * ColorCodedSkin::BlendRatio_Max / stepCount); uiManager->GetUIController()->UpdateUI(); }
// --------------------------------------------------------------------- //! Called when key is up. // --------------------------------------------------------------------- void BeSkinView::KeyUp( const char* bytes, //!< character which mapped to the key. int32 numBytes //!< length of parameter bytes. ) { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { BMessage* message = Window()->CurrentMessage(); int32 keyCode = 0; int32 modifiers = 0; message->FindInt32("key", &keyCode); message->FindInt32("modifiers", &modifiers); KeyEventParameter parameter; parameter.SetKeyCode(keyCode); parameter.SetModifiers(modifiers); uiManager->KeyUp(parameter); } }
/** * @brief Changes the status of this task according to mouse position. * @return false if this task shoule be canceled. */ bool MouseHoverUITask::changeStatusAccordingToMouse() { UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); Point32 mousePoint = uiManager->GetUIController()->GetMousePosition(); ColorCodedSkin* skin = uiManager->GetSkin(); SInt32 mouseSkinArea = skin->GetArea(mousePoint); bool isInArea = (mouseSkinArea == targetSkinArea); bool isHoverable; #if defined(BEOS) isHoverable = uiManager->GetUIController()->IsUIActive(); #else isHoverable = true; #endif if (isBeingHot && (!isInArea || !isHoverable)) { isBeingHot = false; if (currentStep > 0) { currentStep--; updateAppearance(); if (currentStep == 0) { return false; } } } else if (!isBeingHot && isInArea && isHoverable) { isBeingHot = true; if (currentStep < stepCount) { currentStep++; updateAppearance(); } } return true; }
// --------------------------------------------------------------------- LRESULT WinSkinWindow::onRButtonUp( HWND hWnd, //!< ウィンドウハンドル UINT uMsg, //!< WM_RBUTTONUP WPARAM wParam, //!< 様々な仮想キーが押されているかどうのフラグ LPARAM lParam //!< 下位ワードがマウスカーソルの X 座標、上位ワードが Y 座標 ) { base::wndProc(hWnd, uMsg, wParam, lParam); mousePosition.x = GET_X_LPARAM(lParam); mousePosition.y = GET_Y_LPARAM(lParam); mousePositionAvailable = true; UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { uiManager->Button2Up(); } return 0; }
// --------------------------------------------------------------------- LRESULT WinSkinWindow::onKeyUp( HWND hWnd, //!< ウィンドウハンドル UINT uMsg, //!< WM_KEYUP WPARAM wParam, //!< 仮想キーコード LPARAM lParam //!< フラグ ) { base::wndProc(hWnd, uMsg, wParam, lParam); // マウスボタンは無視 switch (wParam) { case VK_LBUTTON: case VK_RBUTTON: case VK_MBUTTON: case VK_SHIFT: case VK_CONTROL: case VK_MENU: return 0; } UIManager* uiManager = getUIManager(); ASSERT(NULL != uiManager); if (NULL != uiManager) { KeyEventParameter parameter; UInt32 modifiers = 0; modifiers |= ((::GetKeyState(VK_SHIFT) & 0x8000) ? KeyEventParameter::ModifierMask_Shift : 0); modifiers |= ((::GetKeyState(VK_CONTROL) & 0x8000) ? KeyEventParameter::ModifierMask_Ctrl : 0); modifiers |= ((::GetKeyState(VK_MENU) & 0x8000) ? KeyEventParameter::ModifierMask_Alt : 0); parameter.SetKeyCode(static_cast<DWORD>(wParam)); parameter.SetModifiers(modifiers); uiManager->KeyUp(parameter); } return 0; }
void ChatUserInterface::render() const { // If there is an underlying menu or other UI screen, render and dim it. // // We will skip rendering if the editor is a parent UI because of a couple // of difficult-to-solve issues: // 1. Fullscreen mode in editor usually has a different aspect ratio when // compared to the rest of the game (incl. the chat UI) // 2. The editor may have other sub-UIs opened (like QuickMenuUIs) that // may not handle the UIManager stack appropriately (likely a bug) and // will cause stack overflows if((mRenderUnderlyingUI && getUIManager()->hasPrevUI()) && !getUIManager()->cameFrom<EditorUserInterface>()) { getUIManager()->renderPrevUI(this); // ...render it... dimUnderlyingUI(); } // Render header renderHeader(); // And footer S32 vertFooterPos = DisplayManager::getScreenInfo()->getGameCanvasHeight() - vertMargin - VERT_FOOTER_SIZE; RenderUtils::drawCenteredString_fixed(vertFooterPos + VERT_FOOTER_SIZE - 2, VERT_FOOTER_SIZE - 2, Colors::green, "Type your message | ENTER to send | ESC exits"); renderChatters(horizMargin, vertFooterPos - CHAT_FONT_MARGIN * 2); // Render incoming chat msgs //mGL->glColor(Colors::white); U32 y = vertMargin + 60; static const S32 chatAreaHeight = DisplayManager::getScreenInfo()->getGameCanvasHeight() - 2 * vertMargin - // Screen area less margins VERT_FOOTER_SIZE - // Instructions at the bottom CHAT_NAMELIST_SIZE - CHAT_FONT_MARGIN * 2 - // Names of those in chatroom MENU_TITLE_SIZE - TITLE_SUBTITLE_GAP - MENU_SUBTITLE_SIZE - // Title/subtitle display CHAT_FONT_SIZE - CHAT_FONT_MARGIN - // Chat composition CHAT_FONT_SIZE; // Not sure... just need a little more space?? static const S32 MessageDisplayCount = chatAreaHeight / (CHAT_FONT_SIZE + CHAT_FONT_MARGIN); renderMessages(y, MessageDisplayCount); renderMessageComposition(vertFooterPos - 45 + CHAT_FONT_SIZE); // Give user notice that there is no connection to master, and thus chatting is ineffectual MasterServerConnection *masterConn = getGame()->getConnectionToMaster(); if(!(masterConn && masterConn->getConnectionState() == NetConnection::Connected)) { static const S32 fontsize = 20; static const S32 fontgap = 5; static const S32 margin = 20; static const char* line1 = "Not connected to Master Server"; static const char* line2 = "Your chat messages cannot be relayed"; static const S32 CORNER_INSET = 15; S32 yPos1 = 200; S32 yPos2 = yPos1 + (2 * (fontsize + fontgap + margin)); S32 width = RenderUtils::getStringWidth(fontsize, line2); S32 canvasWidth = DisplayManager::getScreenInfo()->getGameCanvasWidth(); S32 xPos1 = (canvasWidth - width) / 2 - margin; S32 xPos2 = xPos1 + width + (2 * margin); RenderUtils::drawFilledFancyBox(xPos1, yPos1, xPos2, yPos2, CORNER_INSET, Colors::red40, 1.0, Colors::red); yPos1 += margin + fontsize; RenderUtils::drawCenteredString_fixed(yPos1, fontsize, Colors::white, line1); RenderUtils::drawCenteredString_fixed(yPos1 + fontsize + fontgap, fontsize, Colors::white, line2); } }
void AbstractMessageUserInterface::quit() { getUIManager()->reactivatePrevUI(); }
/** * @brief Sets informations about initial state. * @param commandID target command id. * @param stepCount how many steps to become complete hot image. */ void MouseHoverUITask::SetInitialInformation(SInt32 commandID, SInt32 stepCount) { this->targetCommandID = commandID; this->targetSkinArea = getUIManager()->GetSkinAreaFromCommandId(commandID); this->stepCount = stepCount; }