diff options
Diffstat (limited to 'indra/newview/llviewerwindow.cpp')
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 1135 |
1 files changed, 677 insertions, 458 deletions
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 72e40e3030..3508f92a2f 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -31,6 +31,11 @@ */ #include "llviewerprecompiledheaders.h" +#include "llviewerwindow.h" + +#if LL_WINDOWS +#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally +#endif // system library includes #include <stdio.h> @@ -38,14 +43,17 @@ #include <fstream> #include <algorithm> +#include "llagent.h" +#include "llagentcamera.h" #include "llfloaterreg.h" +#include "llmeshrepository.h" #include "llpanellogin.h" #include "llviewerkeyboard.h" #include "llviewermenu.h" -#include "llviewerwindow.h" #include "llviewquery.h" #include "llxmltree.h" +#include "llslurl.h" //#include "llviewercamera.h" #include "llrender.h" @@ -75,10 +83,12 @@ #include "timing.h" #include "llviewermenu.h" #include "lltooltip.h" +#include "llmediaentry.h" +#include "llurldispatcher.h" +#include "llurlsimstring.h" // newview includes #include "llagent.h" -#include "llalertdialog.h" #include "llbox.h" #include "llconsole.h" #include "llviewercontrol.h" @@ -97,8 +107,6 @@ #include "llfloaterbuildoptions.h" #include "llfloaterbuyland.h" #include "llfloatercamera.h" -#include "llfloaterchat.h" -#include "llfloaterchatterbox.h" #include "llfloatercustomize.h" #include "llfloaterland.h" #include "llfloaterinspect.h" @@ -117,6 +125,7 @@ #include "llhudview.h" #include "llimagebmp.h" #include "llimagej2c.h" +#include "llimageworker.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -124,8 +133,7 @@ #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" -#include "llnotify.h" -#include "lloverlaybar.h" +#include "llpopupview.h" #include "llpreviewtexture.h" #include "llprogressview.h" #include "llresmgr.h" @@ -138,14 +146,12 @@ #include "llstatview.h" #include "llsurface.h" #include "llsurfacepatch.h" -#include "llimview.h" #include "lltexlayer.h" #include "lltextbox.h" #include "lltexturecache.h" #include "lltexturefetch.h" #include "lltextureview.h" #include "lltool.h" -#include "lltoolbar.h" #include "lltoolcomp.h" #include "lltooldraganddrop.h" #include "lltoolface.h" @@ -157,7 +163,6 @@ #include "lltoolselectland.h" #include "lltrans.h" #include "lluictrlfactory.h" -#include "lluploaddialog.h" #include "llurldispatcher.h" // SLURL from other app instance #include "llvieweraudio.h" #include "llviewercamera.h" @@ -180,7 +185,6 @@ #include "llworldmapview.h" #include "pipeline.h" #include "llappviewer.h" -#include "llurlsimstring.h" #include "llviewerdisplay.h" #include "llspatialpartition.h" #include "llviewerjoystick.h" @@ -189,12 +193,16 @@ #include "llbottomtray.h" #include "llnearbychatbar.h" #include "llagentui.h" +#include "llwearablelist.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" #include "llnotificationmanager.h" #include "llfloaternotificationsconsole.h" #include "llnearbychat.h" +#include "llviewerwindowlistener.h" #if LL_WINDOWS #include <tchar.h> // For Unicode conversion methods @@ -228,6 +236,7 @@ S32 gDebugRaycastFaceHit; BOOL gDisplayWindInfo = FALSE; BOOL gDisplayCameraPos = FALSE; BOOL gDisplayFOV = FALSE; +BOOL gDisplayBadge = FALSE; S32 CHAT_BAR_HEIGHT = 28; S32 OVERLAY_BAR_HEIGHT = 20; @@ -252,19 +261,21 @@ public: virtual void recordMessage(LLError::ELevel level, const std::string& message) { - // only log warnings to chat console - if (level == LLError::LEVEL_WARN) - { - LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat"); - if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat")) - { - LLChat chat; - chat.mText = message; - chat.mSourceType = CHAT_SOURCE_SYSTEM; + //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread - chat_floater->addChat(chat, FALSE, FALSE); - } - } + // only log warnings to chat console + //if (level == LLError::LEVEL_WARN) + //{ + //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat"); + //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat")) + //{ + // LLChat chat; + // chat.mText = message; + // chat.mSourceType = CHAT_SOURCE_SYSTEM; + + // chat_floater->addChat(chat, FALSE, FALSE); + //} + //} } }; @@ -310,7 +321,7 @@ public: mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f ); // Draw stuff growing up from right lower corner of screen - U32 xpos = mWindow->getWindowWidth() - 350; + U32 xpos = mWindow->getWorldViewWidthScaled() - 350; U32 ypos = 64; const U32 y_inc = 20; @@ -326,7 +337,9 @@ public: S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); - addText(xpos, ypos, llformat(" Debug %d: %d:%02d:%02d", idx, hours,mins,secs)); ypos += y_inc2; + std::string label = gDebugTimerLabel[idx]; + if (label.empty()) label = llformat("Debug: %d", idx); + addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2; } F32 time = gFrameTimeSeconds; @@ -352,9 +365,9 @@ public: agent_center_text = llformat("AgentCenter %f %f %f", (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - if (gAgent.getAvatarObject()) + if (isAgentAvatarValid()) { - tvector = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mRoot.getWorldPosition()); + tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition()); agent_root_center_text = llformat("AgentRootCenter %f %f %f", (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); } @@ -372,7 +385,7 @@ public: agent_left_text = llformat("AgentLeftAxis %f %f %f", (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - tvector = gAgent.getCameraPositionGlobal(); + tvector = gAgentCamera.getCameraPositionGlobal(); camera_center_text = llformat("CameraCenter %f %f %f", (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); @@ -413,6 +426,11 @@ public: addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); ypos += y_inc; } + if (gDisplayBadge) + { + addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); + ypos += y_inc * 2; + } /*if (LLViewerJoystick::getInstance()->getOverrideCamera()) { @@ -471,6 +489,10 @@ public: } ypos += y_inc; + addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); + LLRender::sUICalls = LLRender::sUIVerts = 0; + ypos += y_inc; + addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount)); ypos += y_inc; @@ -564,6 +586,50 @@ public: ypos += y_inc; } } + + + if (gSavedSettings.getBOOL("DebugShowUploadCost")) + { + addText(xpos, ypos, llformat(" Meshes: L$%d", gPipeline.mDebugMeshUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, llformat(" Sculpties: L$%d", gPipeline.mDebugSculptUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, llformat(" Textures: L$%d", gPipeline.mDebugTextureUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, "Upload Cost: "); + + ypos += y_inc; + } + + //temporary hack to give feedback on mesh upload progress + if (!gMeshRepo.mUploads.empty()) + { + for (std::vector<LLMeshUploadThread*>::iterator iter = gMeshRepo.mUploads.begin(); + iter != gMeshRepo.mUploads.end(); ++iter) + { + LLMeshUploadThread* thread = *iter; + + addText(xpos, ypos, llformat("Mesh Upload -- price quote: %d:%d | upload: %d:%d | create: %d", + thread->mPendingConfirmations, thread->mUploadQ.size()+thread->mTextureQ.size(), + thread->mPendingUploads, thread->mConfirmedQ.size()+thread->mConfirmedTextureQ.size(), + thread->mInstanceQ.size())); + ypos += y_inc; + } + } + + S32 pending = (S32) gMeshRepo.mPendingRequests.size(); + S32 header = (S32) gMeshRepo.mThread->mHeaderReqQ.size(); + S32 lod = (S32) gMeshRepo.mThread->mLODReqQ.size(); + + if (pending + header + lod + LLMeshRepoThread::sActiveHeaderRequests + LLMeshRepoThread::sActiveLODRequests != 0) + { + addText(xpos, ypos, llformat ("Mesh Queue - %d pending (%d:%d header | %d:%d LOD)", + pending, + LLMeshRepoThread::sActiveHeaderRequests, header, + LLMeshRepoThread::sActiveLODRequests, lod)); + + ypos += y_inc; + } } void draw() @@ -593,9 +659,8 @@ void LLViewerWindow::updateDebugText() BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) { - std::string buttonname; - std::string buttonstatestr; - BOOL handled = FALSE; + const char* buttonname = ""; + const char* buttonstatestr = ""; S32 x = pos.mX; S32 y = pos.mY; x = llround((F32)x / mDisplayScale.mV[VX]); @@ -672,27 +737,23 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK } // Topmost view gets a chance before the hierarchy - LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - if (top_ctrl) - { - S32 local_x, local_y; - top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); - if (down) - { - if (top_ctrl->pointInView(local_x, local_y)) - { - return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ; - } - else - { - gFocusMgr.setTopCtrl(NULL); - } - } - else - { - handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask); - } - } + //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + //if (top_ctrl) + //{ + // S32 local_x, local_y; + // top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); + // if (top_ctrl->pointInView(local_x, local_y)) + // { + // return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ; + // } + // else + // { + // if (down) + // { + // gFocusMgr.setTopCtrl(NULL); + // } + // } + //} // Give the UI views a chance to process the click if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ) @@ -708,34 +769,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl; } - if (down) + // Do not allow tool manager to handle mouseclicks if we have disconnected + if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) { - if (gDisconnected) - { - return FALSE; - } - - if(LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) - { - return TRUE; - } + return TRUE; } - else - { - if( !handled ) - { - handled = mRootView->handleAnyMouseClick(x, y, mask, clicktype, down); - } - if( !handled ) - { - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - if (tool) - { - handled = tool->handleAnyMouseClick(x, y, mask, clicktype, down); - } - } - } // If we got this far on a down-click, it wasn't handled. // Up-clicks, though, are always handled as far as the OS is concerned. @@ -783,7 +822,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK // *HACK: this should be rolled into the composite tool logic, not // hardcoded at the top level. - if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()) + if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()) { // If the current tool didn't process the click, we should show // the pie menu. This can be done by passing the event to the pie @@ -810,6 +849,154 @@ BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MAS // Always handled as far as the OS is concerned. return TRUE; } + +LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data) +{ + LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE; + + const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop"); + const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop"); + + if ( prim_media_dnd_enabled || slurl_dnd_enabled ) + { + switch(action) + { + // Much of the handling for these two cases is the same. + case LLWindowCallbacks::DNDA_TRACK: + case LLWindowCallbacks::DNDA_DROPPED: + case LLWindowCallbacks::DNDA_START_TRACKING: + { + bool drop = (LLWindowCallbacks::DNDA_DROPPED == action); + + if (slurl_dnd_enabled) + { + + // special case SLURLs + // isValidSLURL() call was added here to make sure that dragged SLURL is valid (EXT-4964) + if ( LLSLURL::isSLURL( data ) && LLSLURL::isValidSLURL( data ) ) + { + if (drop) + { + LLURLDispatcher::dispatch( data, NULL, true ); + LLURLSimString::setStringRaw( LLSLURL::stripProtocol( data ) ); + LLPanelLogin::refreshLocation( true ); + LLPanelLogin::updateLocationUI(); + } + return LLWindowCallbacks::DND_MOVE; + }; + } + + if (prim_media_dnd_enabled) + { + LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ ); + + LLUUID object_id = pick_info.getObjectID(); + S32 object_face = pick_info.mObjectFace; + std::string url = data; + + lldebugs << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << llendl; + + LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject())); + + if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty()) + { + LLTextureEntry *te = obj->getTE(object_face); + if (te) + { + if (drop) + { + // object does NOT have media already + if ( ! te->hasMedia() ) + { + // we are allowed to modify the object + if ( obj->permModify() ) + { + // Create new media entry + LLSD media_data; + // XXX Should we really do Home URL too? + media_data[LLMediaEntry::HOME_URL_KEY] = url; + media_data[LLMediaEntry::CURRENT_URL_KEY] = url; + media_data[LLMediaEntry::AUTO_PLAY_KEY] = true; + obj->syncMediaData(object_face, media_data, true, true); + // XXX This shouldn't be necessary, should it ?!? + if (obj->getMediaImpl(object_face)) + obj->getMediaImpl(object_face)->navigateReload(); + obj->sendMediaDataUpdate(); + + result = LLWindowCallbacks::DND_COPY; + } + } + else + // object HAS media already + { + // URL passes the whitelist + if (te->getMediaData()->checkCandidateUrl( url ) ) + { + // we are allowed to modify the object or we have navigate permissions + // NOTE: Design states you you can change the URL if you have media + // navigate permissions even if you do not have prim modify rights + if ( obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT ) ) + { + // just navigate to the URL + if (obj->getMediaImpl(object_face)) + { + obj->getMediaImpl(object_face)->navigateTo(url); + } + else + { + // This is very strange. Navigation should + // happen via the Impl, but we don't have one. + // This sends it to the server, which /should/ + // trigger us getting it. Hopefully. + LLSD media_data; + media_data[LLMediaEntry::CURRENT_URL_KEY] = url; + obj->syncMediaData(object_face, media_data, true, true); + obj->sendMediaDataUpdate(); + } + result = LLWindowCallbacks::DND_LINK; + } + } + } + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = NULL; + + } + else + { + // Check the whitelist, if there's media (otherwise just show it) + if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url)) + { + if ( obj != mDragHoveredObject) + { + // Highlight the dragged object + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = obj; + LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject); + } + result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK; + } + } + } + } + } + } + break; + + case LLWindowCallbacks::DNDA_STOP_TRACKING: + // The cleanup case below will make sure things are unhilighted if necessary. + break; + } + + if (prim_media_dnd_enabled && + result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull()) + { + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = NULL; + } + } + + return result; +} BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { @@ -856,6 +1043,7 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window) // Note: we won't get this if we have captured the mouse. llassert( gFocusMgr.getMouseCapture() == NULL ); mMouseInWindow = FALSE; + LLToolTipMgr::instance().blockToolTips(); } BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) @@ -982,7 +1170,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) { // if we're in world, show a progress bar to hide reloading of textures llinfos << "Restoring GL during activate" << llendl; - restoreGL("Restoring..."); + restoreGL(LLTrans::getString("ProgressRestoring")); } else { @@ -1002,13 +1190,17 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) else { mActive = FALSE; - if (gSavedSettings.getBOOL("AllowIdleAFK")) + + if (gSavedSettings.getS32("AFKTimeout")) { gAgent.setAFK(); } // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues - gAgent.changeCameraToDefault(); + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + gAgentCamera.changeCameraToDefault(); + } send_agent_pause(); @@ -1025,7 +1217,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating) { - //if (!activating) gAgent.changeCameraToDefault(); + //if (!activating) gAgentCamera.changeCameraToDefault(); LLViewerJoystick::getInstance()->setNeedsReset(true); return FALSE; @@ -1189,9 +1381,9 @@ LLViewerWindow::LLViewerWindow( mActive(TRUE), mWantFullscreen(fullscreen), mShowFullscreenProgress(FALSE), - mWindowRect(0, height, width, 0), - mVirtualWindowRect(0, height, width, 0), - mWorldViewRect(0, height, width, 0), + mWindowRectRaw(0, height, width, 0), + mWindowRectScaled(0, height, width, 0), + mWorldViewRectRaw(0, height, width, 0), mLeftMouseDown(FALSE), mMiddleMouseDown(FALSE), mRightMouseDown(FALSE), @@ -1204,7 +1396,9 @@ LLViewerWindow::LLViewerWindow( mResDirty(false), mStatesDirty(false), mIsFullscreenChecked(false), - mCurrResolutionIndex(0) + mCurrResolutionIndex(0), + mViewerWindowListener(new LLViewerWindowListener(this)), + mProgressView(NULL) { LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")); LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); @@ -1227,7 +1421,7 @@ LLViewerWindow::LLViewerWindow( gSavedSettings.getBOOL("DisableVerticalSync"), !gNoRender, ignore_pixel_depth, - gSavedSettings.getU32("RenderFSAASamples")); + 0); //gSavedSettings.getU32("RenderFSAASamples")); if (!LLAppViewer::instance()->restoreErrorTrap()) { @@ -1237,7 +1431,7 @@ LLViewerWindow::LLViewerWindow( if (NULL == mWindow) { - LLSplashScreen::update("Shutting down..."); + LLSplashScreen::update(LLTrans::getString("ShuttingDown")); #if LL_LINUX || LL_SOLARIS llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt or README-solaris.txt for further information." << llendl; @@ -1259,8 +1453,8 @@ LLViewerWindow::LLViewerWindow( { LLCoordWindow size; mWindow->getSize(&size); - mWindowRect.set(0, size.mY, size.mX, 0); - mVirtualWindowRect.set(0, llround((F32)size.mY / mDisplayScale.mV[VY]), llround((F32)size.mX / mDisplayScale.mV[VX]), 0); + mWindowRectRaw.set(0, size.mY, size.mX, 0); + mWindowRectScaled.set(0, llround((F32)size.mY / mDisplayScale.mV[VY]), llround((F32)size.mX / mDisplayScale.mV[VX]), 0); } LLFontManager::initClass(); @@ -1299,6 +1493,7 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. + LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ; gTextureList.init(); LLViewerTextureManager::init() ; gBumpImageList.init(); @@ -1315,15 +1510,15 @@ LLViewerWindow::LLViewerWindow( // Create container for all sub-views LLView::Params rvp; rvp.name("root"); - rvp.rect(mVirtualWindowRect); + rvp.rect(mWindowRectScaled); rvp.mouse_opaque(false); rvp.follows.flags(FOLLOWS_NONE); mRootView = LLUICtrlFactory::create<LLRootView>(rvp); LLUI::setRootView(mRootView); // Make avatar head look forward at start - mCurrentMousePoint.mX = getWindowWidth() / 2; - mCurrentMousePoint.mY = getWindowHeight() / 2; + mCurrentMousePoint.mX = getWindowWidthScaled() / 2; + mCurrentMousePoint.mY = getWindowHeightScaled() / 2; gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle"); mOverlayTitle = gSavedSettings.getString("OverlayTitle"); @@ -1335,6 +1530,7 @@ LLViewerWindow::LLViewerWindow( mDebugText = new LLDebugText(this); + mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); } void LLViewerWindow::initGLDefaults() @@ -1368,10 +1564,14 @@ void LLViewerWindow::initGLDefaults() gCylinder.prerender(); } +struct MainPanel : public LLPanel +{ +}; + void LLViewerWindow::initBase() { - S32 height = getWindowHeight(); - S32 width = getWindowWidth(); + S32 height = getWindowHeightScaled(); + S32 width = getWindowWidthScaled(); LLRect full_window(0, height, width, 0); @@ -1391,29 +1591,21 @@ void LLViewerWindow::initBase() // Create the floater view at the start so that other views can add children to it. // (But wait to add it as a child of the root view so that it will be in front of the // other views.) + MainPanel* main_view = new MainPanel(); + LLUICtrlFactory::instance().buildPanel(main_view, "main_view.xml"); + main_view->setShape(full_window); + getRootView()->addChild(main_view); + + // placeholder widget that controls where "world" is rendered + mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); + mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle(); + mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle(); + mPopupView = main_view->getChild<LLPopupView>("popup_holder"); // Constrain floaters to inside the menu and status bar regions. - LLRect floater_view_rect = full_window; - // make space for menu bar - floater_view_rect.mTop -= MENU_BAR_HEIGHT; - - LLFloaterView::Params fvparams; - fvparams.name("Floater View"); - fvparams.rect(floater_view_rect); - fvparams.mouse_opaque(false); - fvparams.follows.flags(FOLLOWS_ALL); - fvparams.tab_stop(false); - gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams); - - LLSnapshotFloaterView::Params snapParams; - snapParams.name("Snapshot Floater View"); - snapParams.rect(full_window); - snapParams.enabled(false); - gSnapshotFloaterView = LLUICtrlFactory::create<LLSnapshotFloaterView> (snapParams); + gFloaterView = main_view->getChild<LLFloaterView>("Floater View"); + gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View"); - // Snapshot floater must start invisible otherwise it eats all - // the tooltips. JC - gSnapshotFloaterView->setVisible(FALSE); // Console llassert( !gConsole ); @@ -1438,43 +1630,19 @@ void LLViewerWindow::initBase() } #endif - // Debug view over the console - LLDebugView::Params debug_p; - debug_p.name("DebugView"); - debug_p.rect(full_window); - debug_p.follows.flags(FOLLOWS_ALL); - debug_p.visible(true); - gDebugView = LLUICtrlFactory::create<LLDebugView>(debug_p); - getRootView()->addChild(gDebugView); - - // Add floater view at the end so it will be on top, and give it tab priority over others - getRootView()->addChild(gFloaterView, -1); - getRootView()->addChild(gSnapshotFloaterView); - - // notify above floaters! - LLRect notify_rect = floater_view_rect; - LLNotifyBoxView::Params p; - p.name("notify_container"); - p.rect(notify_rect); - p.mouse_opaque(false); - p.follows.flags(FOLLOWS_ALL); - gNotifyBoxView = LLUICtrlFactory::create<LLNotifyBoxView> (p); - getRootView()->addChild(gNotifyBoxView, -2); - - // View for tooltips - LLToolTipView::Params hvp; - hvp.name("tooltip view"); - hvp.rect(full_window); - hvp.follows.flags(FOLLOWS_ALL); - gToolTipView = LLUICtrlFactory::create<LLToolTipView>(hvp); - gToolTipView->setFollowsAll(); - getRootView()->addChild(gToolTipView); + gDebugView = getRootView()->getChild<LLDebugView>("DebugView"); + gDebugView->init(); + gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view"); // Add the progress bar view (startup view), which overrides everything - mProgressView = new LLProgressView(full_window); - getRootView()->addChild(mProgressView); + mProgressView = getRootView()->getChild<LLProgressView>("progress_view"); setShowProgress(FALSE); setProgressCancelButtonVisible(FALSE); + + gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder"); + + LLMenuGL::sMenuContainer = gMenuHolder; + } void LLViewerWindow::initWorldUI() @@ -1483,24 +1651,19 @@ void LLViewerWindow::initWorldUI() S32 width = mRootView->getRect().getWidth(); LLRect full_window(0, height, width, 0); - gIMMgr = LLIMMgr::getInstance(); - // side tray - getRootView()->addChild(LLSideTray::getInstance()); + gIMMgr = LLIMMgr::getInstance(); - getRootView()->sendChildToFront(gFloaterView); - getRootView()->sendChildToFront(gSnapshotFloaterView); + //getRootView()->sendChildToFront(gFloaterView); + //getRootView()->sendChildToFront(gSnapshotFloaterView); // new bottom panel - LLRect rc = LLBottomTray::getInstance()->getRect(); - rc.mLeft = 0; - rc.mRight = mRootView->getRect().getWidth(); - LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE); - LLBottomTray::getInstance()->setRect(rc); - - // Pre initialize instance communicate instance; - // currently needs to happen before initializing chat or IM - LLFloaterReg::getInstance("communicate"); + LLPanel* bottom_tray_container = getRootView()->getChild<LLPanel>("bottom_tray_container"); + LLBottomTray* bottom_tray = LLBottomTray::getInstance(); + bottom_tray->setShape(bottom_tray_container->getLocalRect()); + bottom_tray->setFollowsAll(); + bottom_tray_container->addChild(bottom_tray); + bottom_tray_container->setVisible(TRUE); LLRect morph_view_rect = full_window; morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); @@ -1512,16 +1675,6 @@ void LLViewerWindow::initWorldUI() gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp); getRootView()->addChild(gMorphView); - // Make space for nav bar. - LLRect floater_view_rect = gFloaterView->getRect(); - LLRect notify_view_rect = gNotifyBoxView->getRect(); - floater_view_rect.mTop -= NAVIGATION_BAR_HEIGHT; - floater_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight(); - notify_view_rect.mTop -= NAVIGATION_BAR_HEIGHT; - notify_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight(); - gFloaterView->setRect(floater_view_rect); - gNotifyBoxView->setRect(notify_view_rect); - LLWorldMapView::initClass(); // Force gFloaterWorldMap to initialize @@ -1532,23 +1685,23 @@ void LLViewerWindow::initWorldUI() LLFloaterReg::hideInstance("build"); // Status bar - S32 menu_bar_height = gMenuBarView->getRect().getHeight(); - LLRect root_rect = getRootView()->getRect(); - LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height); - gStatusBar = new LLStatusBar(status_rect); - gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP); - - gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE); - gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight()); + LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container"); + gStatusBar = new LLStatusBar(status_bar_container->getLocalRect()); + gStatusBar->setFollowsAll(); + gStatusBar->setShape(status_bar_container->getLocalRect()); // sync bg color with menu bar gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); + status_bar_container->addChild(gStatusBar); + status_bar_container->setVisible(TRUE); // Navigation bar + LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container"); LLNavigationBar* navbar = LLNavigationBar::getInstance(); - navbar->reshape(root_rect.getWidth(), navbar->getRect().getHeight(), TRUE); // *TODO: redundant? - navbar->translate(0, root_rect.getHeight() - menu_bar_height - navbar->getRect().getHeight()); // FIXME + navbar->setShape(nav_bar_container->getLocalRect()); navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get()); + nav_bar_container->addChild(navbar); + nav_bar_container->setVisible(TRUE); if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) { @@ -1580,19 +1733,6 @@ void LLViewerWindow::initWorldUI() LLBottomTray::getInstance()->showGestureButton(FALSE); } - getRootView()->addChild(gStatusBar); - getRootView()->addChild(navbar); - - - //sidetray - //then notify area - //then menu - //getRootView()->sendChildToFront(LLSideTray::getInstance()); - - getRootView()->sendChildToFront(gNotifyBoxView); - // menu holder appears on top to get first pass at all mouse events - getRootView()->sendChildToFront(gMenuHolder); - if ( gHUDView == NULL ) { LLRect hud_rect = full_window; @@ -1606,11 +1746,26 @@ void LLViewerWindow::initWorldUI() getRootView()->addChildInBack(gHUDView); } - // this allows not to see UI elements created while UI initializing after Alt+Tab was pressed during login. EXT-744. - moveProgressViewToFront(); + LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container"); + LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); + panel_ssf_container->addChild(panel_stand_stop_flying); + panel_ssf_container->setVisible(TRUE); - // tooltips are always on top - getRootView()->sendChildToFront(gToolTipView); + // put sidetray in container + LLPanel* side_tray_container = getRootView()->getChild<LLPanel>("side_tray_container"); + LLSideTray* sidetrayp = LLSideTray::getInstance(); + sidetrayp->setShape(side_tray_container->getLocalRect()); + // don't follow right edge to avoid spurious resizes, since we are using a fixed width layout + sidetrayp->setFollows(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_BOTTOM); + side_tray_container->addChild(sidetrayp); + side_tray_container->setVisible(FALSE); + + // put sidetray buttons in their own panel + LLPanel* buttons_panel = sidetrayp->getButtonsPanel(); + LLPanel* buttons_panel_container = getRootView()->getChild<LLPanel>("side_bar_tabs"); + buttons_panel->setShape(buttons_panel_container->getLocalRect()); + buttons_panel->setFollowsAll(); + buttons_panel_container->addChild(buttons_panel); } // Destroy the UI @@ -1627,7 +1782,19 @@ void LLViewerWindow::shutdownViews() { gMorphView->setVisible(FALSE); } + + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open + // will crump with LL_ERRS. + LLModalDialog::shutdownModals(); + // destroy the nav bar, not currently part of gViewerWindow + // *TODO: Make LLNavigationBar part of gViewerWindow + delete LLNavigationBar::getInstance(); + + // destroy menus after instantiating navbar above, as it needs + // access to gMenuHolder + cleanup_menus(); + // Delete all child views. delete mRootView; mRootView = NULL; @@ -1641,8 +1808,6 @@ void LLViewerWindow::shutdownViews() gMorphView = NULL; gHUDView = NULL; - - gNotifyBoxView = NULL; } void LLViewerWindow::shutdownGL() @@ -1657,6 +1822,8 @@ void LLViewerWindow::shutdownGL() gSky.cleanup(); stop_glerror(); + LLWearableList::instance().cleanup() ; + gTextureList.shutdown(); stop_glerror(); @@ -1670,7 +1837,10 @@ void LLViewerWindow::shutdownGL() stop_glerror(); LLViewerTextureManager::cleanup() ; - + LLImageGL::cleanupClass() ; + + llinfos << "All textures and llimagegl images are destroyed!" << llendl ; + llinfos << "Cleaning up select manager" << llendl; LLSelectMgr::getInstance()->cleanup(); @@ -1691,6 +1861,9 @@ LLViewerWindow::~LLViewerWindow() { llinfos << "Destroying Window" << llendl; destroyWindow(); + + delete mDebugText; + mDebugText = NULL; } @@ -1725,8 +1898,8 @@ void LLViewerWindow::sendShapeToSim() msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); msg->nextBlockFast(_PREHASH_HeightWidthBlock); msg->addU32Fast(_PREHASH_GenCounter, 0); - U16 height16 = (U16) mWorldViewRect.getHeight(); - U16 width16 = (U16) mWorldViewRect.getWidth(); + U16 height16 = (U16) mWorldViewRectRaw.getHeight(); + U16 width16 = (U16) mWorldViewRectRaw.getWidth(); msg->addU16Fast(_PREHASH_Height, height16); msg->addU16Fast(_PREHASH_Width, width16); gAgent.sendReliableMessage(); @@ -1748,14 +1921,14 @@ void LLViewerWindow::reshape(S32 width, S32 height) } // update our window rectangle - mWindowRect.mRight = mWindowRect.mLeft + width; - mWindowRect.mTop = mWindowRect.mBottom + height; + mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width; + mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height; //glViewport(0, 0, width, height ); if (height > 0) { - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRect.getHeight() ); + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); } @@ -1765,8 +1938,8 @@ void LLViewerWindow::reshape(S32 width, S32 height) LLUI::setScaleFactor(mDisplayScale); // update our window rectangle - mVirtualWindowRect.mRight = mVirtualWindowRect.mLeft + llround((F32)width / mDisplayScale.mV[VX]); - mVirtualWindowRect.mTop = mVirtualWindowRect.mBottom + llround((F32)height / mDisplayScale.mV[VY]); + mWindowRectScaled.mRight = mWindowRectScaled.mLeft + llround((F32)width / mDisplayScale.mV[VX]); + mWindowRectScaled.mTop = mWindowRectScaled.mBottom + llround((F32)height / mDisplayScale.mV[VY]); setup2DViewport(); @@ -1879,21 +2052,24 @@ void LLViewerWindow::drawDebugText() { gGL.color4f(1,1,1,1); gGL.pushMatrix(); + gGL.pushUIMatrix(); { // scale view by UI global scale factor and aspect ratio correction factor - glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); + gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); mDebugText->draw(); } + gGL.popUIMatrix(); gGL.popMatrix(); + gGL.flush(); } void LLViewerWindow::draw() { -#if LL_DEBUG +//#if LL_DEBUG LLView::sIsDrawing = TRUE; -#endif +//#endif stop_glerror(); LLUI::setLineWidth(1.f); @@ -1908,7 +2084,7 @@ void LLViewerWindow::draw() if (!gSavedSettings.getBOOL("RenderUIBuffer")) { - LLUI::sDirtyRect = this->getWindowRect(); + LLUI::sDirtyRect = getWindowRectScaled(); } // HACK for timecode debugging @@ -1922,8 +2098,8 @@ void LLViewerWindow::draw() microsecondsToTimecodeString(gFrameTime,text); const LLFontGL* font = LLFontGL::getFontSansSerif(); font->renderUTF8(text, 0, - llround((getWindowWidth()/2)-100.f), - llround((getWindowHeight()-60.f)), + llround((getWindowWidthScaled()/2)-100.f), + llround((getWindowHeightScaled()-60.f)), LLColor4( 1.f, 1.f, 1.f, 1.f ), LLFontGL::LEFT, LLFontGL::TOP); } @@ -1932,9 +2108,11 @@ void LLViewerWindow::draw() // No translation needed, this view is glued to 0,0 gGL.pushMatrix(); + LLUI::pushMatrix(); { + // scale view by UI global scale factor and aspect ratio correction factor - glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); + gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); LLVector2 old_scale_factor = LLUI::sGLScaleFactor; // apply camera zoom transform (for high res screenshots) @@ -1946,8 +2124,8 @@ void LLViewerWindow::draw() int pos_y = sub_region / llceil(zoom_factor); int pos_x = sub_region - (pos_y*llceil(zoom_factor)); // offset for this tile - glTranslatef((F32)getWindowWidth() * -(F32)pos_x, - (F32)getWindowHeight() * -(F32)pos_y, + glTranslatef((F32)getWindowWidthScaled() * -(F32)pos_x, + (F32)getWindowHeightScaled() * -(F32)pos_y, 0.f); glScalef(zoom_factor, zoom_factor, 1.f); LLUI::sGLScaleFactor *= zoom_factor; @@ -1956,7 +2134,7 @@ void LLViewerWindow::draw() // Draw tool specific overlay on world LLToolMgr::getInstance()->getCurrentTool()->draw(); - if( gAgent.cameraMouselook() ) + if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() ) { drawMouselookInstructions(); stop_glerror(); @@ -1992,22 +2170,20 @@ void LLViewerWindow::draw() const S32 DIST_FROM_TOP = 20; LLFontGL::getFontSansSerifBig()->renderUTF8( mOverlayTitle, 0, - llround( getWindowWidth() * 0.5f), - getWindowHeight() - DIST_FROM_TOP, + llround( getWindowWidthScaled() * 0.5f), + getWindowHeightScaled() - DIST_FROM_TOP, LLColor4(1, 1, 1, 0.4f), LLFontGL::HCENTER, LLFontGL::TOP); } LLUI::sGLScaleFactor = old_scale_factor; } + LLUI::popMatrix(); gGL.popMatrix(); -#if LL_DEBUG +//#if LL_DEBUG LLView::sIsDrawing = FALSE; -#endif - - // UI post-draw Updates - gNotifyBoxView->updateNotifyBoxView(); +//#endif } // Takes a single keydown event, usually when UI is visible @@ -2100,31 +2276,30 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // arrow keys move avatar while chatting hack if (chat_editor && chat_editor->hasFocus()) { - if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar")) + // If text field is empty, there's no point in trying to move + // cursor with arrow keys, so allow movement + if (chat_editor->getText().empty() + || gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) { - switch(key) + // let Control-Up and Control-Down through for chat line history, + if (!(key == KEY_UP && mask == MASK_CONTROL) + && !(key == KEY_DOWN && mask == MASK_CONTROL)) { - case KEY_LEFT: - case KEY_RIGHT: - case KEY_UP: - // let CTRL UP through for chat line history - if( MASK_CONTROL == mask ) - { - break; - } - case KEY_DOWN: - // let CTRL DOWN through for chat line history - if( MASK_CONTROL == mask ) + switch(key) { + case KEY_LEFT: + case KEY_RIGHT: + case KEY_UP: + case KEY_DOWN: + case KEY_PAGE_UP: + case KEY_PAGE_DOWN: + case KEY_HOME: + // when chatbar is empty or ArrowKeysAlwaysMove set, + // pass arrow keys on to avatar... + return FALSE; + default: break; } - case KEY_PAGE_UP: - case KEY_PAGE_DOWN: - case KEY_HOME: - // when chatbar is empty or ArrowKeysMoveAvatar set, pass arrow keys on to avatar... - return FALSE; - default: - break; } } } @@ -2141,7 +2316,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // Try for a new-format gesture - if (LLGestureManager::instance().triggerGesture(key, mask)) + if (LLGestureMgr::instance().triggerGesture(key, mask)) { return TRUE; } @@ -2294,61 +2469,65 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) // Zoom the camera in and out behavior - if(top_ctrl == 0 && mWorldViewRect.pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) ) - gAgent.handleScrollWheel(clicks); + if(top_ctrl == 0 && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) ) + gAgentCamera.handleScrollWheel(clicks); return; } -void LLViewerWindow::moveCursorToCenter() +void LLViewerWindow::addPopup(LLView* popup) { - S32 x = mWorldViewRect.getWidth() / 2; - S32 y = mWorldViewRect.getHeight() / 2; - - //on a forced move, all deltas get zeroed out to prevent jumping - mCurrentMousePoint.set(x,y); - mLastMousePoint.set(x,y); - mCurrentMouseDelta.set(0,0); + if (mPopupView) + { + mPopupView->addPopup(popup); + } +} - LLUI::setMousePositionScreen(x, y); +void LLViewerWindow::removePopup(LLView* popup) +{ + if (mPopupView) + { + mPopupView->removePopup(popup); + } } -void LLViewerWindow::updateBottomTrayRect() +void LLViewerWindow::clearPopups() { - if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated()) + if (mPopupView) { - S32 side_tray_width = 0; - if(LLSideTray::getInstance()->getVisible()) - { - side_tray_width = LLSideTray::getInstance()->getTrayWidth(); - } + mPopupView->clearPopups(); + } +} - LLBottomTray* bottom_tray = LLBottomTray::getInstance(); - S32 right = llround((F32)mWindowRect.mRight / mDisplayScale.mV[VX]) - side_tray_width; +void LLViewerWindow::moveCursorToCenter() +{ + if (! gSavedSettings.getBOOL("DisableMouseWarp")) + { + S32 x = getWorldViewWidthScaled() / 2; + S32 y = getWorldViewHeightScaled() / 2; + + //on a forced move, all deltas get zeroed out to prevent jumping + mCurrentMousePoint.set(x,y); + mLastMousePoint.set(x,y); + mCurrentMouseDelta.set(0,0); - LLRect rc = bottom_tray->getRect(); - if (right != rc.mRight) - { - rc.mRight = right; - bottom_tray->reshape(rc.getWidth(), rc.getHeight(), FALSE); - bottom_tray->setRect(rc); - mOnBottomTrayWidthChanged(); - } + LLUI::setMousePositionScreen(x, y); } } + ////////////////////////////////////////////////////////////////////// // // Hover handlers // -void append_xui_tooltip(LLView* viewp, std::string& tool_tip_msg) +void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params) { if (viewp) { - if (!tool_tip_msg.empty()) + if (!params.styled_message().empty()) { - tool_tip_msg.append("\n---------\n"); + params.styled_message.add().text("\n---------\n"); } LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView(); // NOTE: we skip "root" since it is assumed @@ -2358,15 +2537,16 @@ void append_xui_tooltip(LLView* viewp, std::string& tool_tip_msg) { LLView* viewp = *tooltip_it; - tool_tip_msg.append(viewp->getName()); + params.styled_message.add().text(viewp->getName()); + LLPanel* panelp = dynamic_cast<LLPanel*>(viewp); if (panelp && !panelp->getXMLFilename().empty()) { - tool_tip_msg.append("("); - tool_tip_msg.append(panelp->getXMLFilename()); - tool_tip_msg.append(")"); + params.styled_message.add() + .text("(" + panelp->getXMLFilename() + ")") + .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f)); } - tool_tip_msg.append("/"); + params.styled_message.add().text("/"); } } } @@ -2375,11 +2555,17 @@ void append_xui_tooltip(LLView* viewp, std::string& tool_tip_msg) // event processing. void LLViewerWindow::updateUI() { + static LLFastTimer::DeclareTimer ftm("Update UI"); + LLFastTimer t(ftm); + static std::string last_handle_msg; - updateWorldViewRect(); + LLConsole::updateClass(); + + // animate layout stacks so we have up to date rect for world view + LLLayoutStack::updateClass(); - updateBottomTrayRect(); + updateWorldViewRect(); LLView::sMouseHandlerMessage.clear(); @@ -2411,20 +2597,63 @@ void LLViewerWindow::updateUI() BOOL handled_by_top_ctrl = FALSE; LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); + LLView* captor_view = dynamic_cast<LLView*>(mouse_captor); + + //FIXME: only include captor and captor's ancestors if mouse is truly over them --RN //build set of views containing mouse cursor by traversing UI hierarchy and testing //screen rect against mouse cursor view_handle_set_t mouse_hover_set; - // start at current mouse captor (if is a view) or UI root - LLView* root_view = NULL; - root_view = dynamic_cast<LLView*>(mouse_captor); + // constraint mouse enter events to children of mouse captor + LLView* root_view = captor_view; + + // if mouse captor doesn't exist or isn't a LLView + // then allow mouse enter events on entire UI hierarchy if (!root_view) { root_view = mRootView; } + // include all ancestors of captor_view as automatically having mouse + if (captor_view) + { + LLView* captor_parent_view = captor_view->getParent(); + while(captor_parent_view) + { + mouse_hover_set.insert(captor_parent_view->getHandle()); + captor_parent_view = captor_parent_view->getParent(); + } + } + // aggregate visible views that contain mouse cursor in display order + LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups(); + + for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it) + { + LLView* popup = popup_it->get(); + if (popup && popup->calcScreenBoundingRect().pointInRect(x, y)) + { + // iterator over contents of top_ctrl, and throw into mouse_hover_set + for (LLView::tree_iterator_t it = popup->beginTreeDFS(); + it != popup->endTreeDFS(); + ++it) + { + LLView* viewp = *it; + if (viewp->getVisible() + && viewp->calcScreenBoundingRect().pointInRect(x, y)) + { + // we have a view that contains the mouse, add it to the set + mouse_hover_set.insert(viewp->getHandle()); + } + else + { + // skip this view and all of its children + it.skipDescendants(); + } + } + } + } // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y)) @@ -2590,6 +2819,8 @@ void LLViewerWindow::updateUI() if (gSavedSettings.getBOOL("DebugShowXUINames")) { + LLToolTip::Params params; + LLView* tooltip_view = mRootView; LLView::tree_iterator_t end_it = mRootView->endTreeDFS(); for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it) @@ -2607,7 +2838,6 @@ void LLViewerWindow::updateUI() else if (dynamic_cast<LLUICtrl*>(viewp) && viewp != gMenuHolder && viewp != gFloaterView - && viewp != gNotifyBoxView && viewp != gConsole) { if (dynamic_cast<LLFloater*>(viewp)) @@ -2622,20 +2852,20 @@ void LLViewerWindow::updateUI() // NOTE: this emulates visiting only the leaf nodes that meet our criteria if (!viewp->hasAncestor(tooltip_view)) { - append_xui_tooltip(tooltip_view, tool_tip_msg); + append_xui_tooltip(tooltip_view, params); screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); } tooltip_view = viewp; } } - append_xui_tooltip(tooltip_view, tool_tip_msg); + append_xui_tooltip(tooltip_view, params); screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(tool_tip_msg) - .sticky_rect(screen_sticky_rect) - .max_width(400)); + params.sticky_rect = screen_sticky_rect; + params.max_width = 400; + + LLToolTipMgr::instance().show(params); } // if there is a mouse captor, nothing else gets a tooltip else if (mouse_captor) @@ -2747,8 +2977,8 @@ void LLViewerWindow::updateMouseDelta() mWindow->getCursorPosition(&mouse_pos); if (mouse_pos.mX < 0 || mouse_pos.mY < 0 || - mouse_pos.mX > mWindowRect.getWidth() || - mouse_pos.mY > mWindowRect.getHeight()) + mouse_pos.mX > mWindowRectRaw.getWidth() || + mouse_pos.mY > mWindowRectRaw.getHeight()) { mMouseInWindow = FALSE; } @@ -2863,43 +3093,39 @@ void LLViewerWindow::updateKeyboardFocus() LLSideTray::getInstance()->highlightFocused(); } +static LLFastTimer::DeclareTimer FTM_UPDATE_WORLD_VIEW("Update World View"); void LLViewerWindow::updateWorldViewRect(bool use_full_window) { - if (!LLSideTray::instanceCreated()) return; + LLFastTimer ft(FTM_UPDATE_WORLD_VIEW); // start off using whole window to render world - LLRect new_world_rect = mWindowRect; + LLRect new_world_rect = mWindowRectRaw; - if (use_full_window == false) + if (use_full_window == false && mWorldViewPlaceholder.get()) { - // pull in right side of world view based on sidetray - LLSideTray* sidetray = LLSideTray::getInstance(); - if (sidetray->getVisible()) - { - new_world_rect.mRight -= llround((F32)sidetray->getTrayWidth() * mDisplayScale.mV[VX]); - } + new_world_rect = mWorldViewPlaceholder.get()->calcScreenRect(); + // clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers + new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1); + new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1); - // push top of world view below nav bar - if (LLNavigationBar::getInstance()->getVisible()) - { - LLNavigationBar* barp = LLNavigationBar::getInstance(); - LLRect nav_bar_rect; - if(barp->localRectToOtherView(barp->getLocalRect(), &nav_bar_rect, mRootView)) - { - new_world_rect.mTop = llround((F32)LLNavigationBar::getInstance()->getRect().mBottom * mDisplayScale.mV[VY]); - } - } + new_world_rect.mLeft = llround((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]); + new_world_rect.mRight = llround((F32)new_world_rect.mRight * mDisplayScale.mV[VX]); + new_world_rect.mBottom = llround((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]); + new_world_rect.mTop = llround((F32)new_world_rect.mTop * mDisplayScale.mV[VY]); } - if (mWorldViewRect != new_world_rect) + if (mWorldViewRectRaw != new_world_rect) { - // sending a signal with a new WorldView rect - mOnWorldViewRectUpdated(mWorldViewRect, new_world_rect); - - mWorldViewRect = new_world_rect; + mWorldViewRectRaw = new_world_rect; gResizeScreenTexture = TRUE; - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRect.getHeight() ); + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + + LLRect old_world_rect_scaled = mWorldViewRectScaled; + mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); + + // sending a signal with a new WorldView rect + mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled); } } @@ -2911,9 +3137,9 @@ void LLViewerWindow::saveLastMouse(const LLCoordGL &point) { mCurrentMousePoint.mX = 0; } - else if (point.mX > getWindowWidth()) + else if (point.mX > getWindowWidthScaled()) { - mCurrentMousePoint.mX = getWindowWidth(); + mCurrentMousePoint.mX = getWindowWidthScaled(); } else { @@ -2924,9 +3150,9 @@ void LLViewerWindow::saveLastMouse(const LLCoordGL &point) { mCurrentMousePoint.mY = 0; } - else if (point.mY > getWindowHeight() ) + else if (point.mY > getWindowHeightScaled() ) { - mCurrentMousePoint.mY = getWindowHeight(); + mCurrentMousePoint.mY = getWindowHeightScaled(); } else { @@ -2939,7 +3165,6 @@ void LLViewerWindow::saveLastMouse(const LLCoordGL &point) // Must be called after displayObjects is called, which sets the mGLName parameter // NOTE: This function gets called 3 times: // render_ui_3d: FALSE, FALSE, TRUE -// renderObjectsForSelect: TRUE, pick_parcel_wall, FALSE // render_hud_elements: FALSE, FALSE, FALSE void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud ) { @@ -2969,7 +3194,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, // setup HUD render if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { - LLBBox hud_bbox = gAgent.getAvatarObject()->getHUDBBox(); + LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); // set up transform to encompass bounding box of HUD glMatrixMode(GL_PROJECTION); @@ -2996,7 +3221,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, glPushMatrix(); if (selection->getSelectType() == SELECT_TYPE_HUD) { - F32 zoom = gAgent.mHUDCurZoom; + F32 zoom = gAgentCamera.mHUDCurZoom; glScalef(zoom, zoom, zoom); } @@ -3115,7 +3340,7 @@ LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLView // world at the location of the mouse click LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot ); - LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgent.getCameraPositionGlobal(); + LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); // make mouse vector as long as object vector, so it touchs a point near // where the user clicked on the object @@ -3124,7 +3349,7 @@ LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLView LLVector3d new_pos; new_pos.setVec(mouse_direction_global); // transform mouse vector back to world coords - new_pos += gAgent.getCameraPositionGlobal(); + new_pos += gAgentCamera.getCameraPositionGlobal(); return new_pos; } @@ -3155,7 +3380,6 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback return; } - // push back pick info object BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha) { @@ -3164,27 +3388,8 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback pick_transparent = TRUE; } - // center initial pick frame buffer region under mouse cursor - // since that area is guaranteed to be onscreen and hence a valid - // part of the framebuffer - if (mPicks.empty()) - { - mPickScreenRegion.setCenterAndSize(x, y_from_bot, PICK_DIAMETER, PICK_DIAMETER); - - if (mPickScreenRegion.mLeft < mWorldViewRect.mLeft) mPickScreenRegion.translate(mWorldViewRect.mLeft - mPickScreenRegion.mLeft, 0); - if (mPickScreenRegion.mBottom < mWorldViewRect.mBottom) mPickScreenRegion.translate(0, mWorldViewRect.mBottom - mPickScreenRegion.mBottom); - if (mPickScreenRegion.mRight > mWorldViewRect.mRight ) mPickScreenRegion.translate(mWorldViewRect.mRight - mPickScreenRegion.mRight, 0); - if (mPickScreenRegion.mTop > mWorldViewRect.mTop ) mPickScreenRegion.translate(0, mWorldViewRect.mTop - mPickScreenRegion.mTop); - } - - // set frame buffer region for picking results - // stack multiple picks left to right - LLRect screen_region = mPickScreenRegion; - screen_region.translate(mPicks.size() * PICK_DIAMETER, 0); - - LLPickInfo pick(LLCoordGL(x, y_from_bot), screen_region, mask, pick_transparent, TRUE, callback); - - schedulePick(pick); + LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, TRUE, callback); + schedulePick(pick_info); } void LLViewerWindow::schedulePick(LLPickInfo& pick_info) @@ -3199,10 +3404,11 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info) return; } - llassert_always(pick_info.mScreenRegion.notEmpty()); mPicks.push_back(pick_info); // delay further event processing until we receive results of pick + // only do this for async picks so that handleMouseUp won't be called + // until the pick triggered in handleMouseDown has been processed, for example mWindow->delayInputProcessing(); } @@ -3250,21 +3456,18 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans return LLPickInfo(); } - pickAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent); - // assume that pickAsync put the results in the back of the mPicks list - if(mPicks.size() != 0) - { - mLastPick = mPicks.back(); - mLastPick.fetchResults(); - mPicks.pop_back(); - } - else + BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); + if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha) { - llwarns << "List of last picks is empty" << llendl; - llwarns << "Using stub pick" << llendl; - mLastPick = LLPickInfo(); + // build mode allows interaction with all transparent objects + // "Show Debug Alpha" means no object actually transparent + pick_transparent = TRUE; } + // shortcut queueing in mPicks and just update mLastPick in place + mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), gKeyboard->currentMask(TRUE), pick_transparent, TRUE, NULL); + mLastPick.fetchResults(); + return mLastPick; } @@ -3380,11 +3583,11 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const F32 fov = LLViewerCamera::getInstance()->getView(); // find world view center in scaled ui coordinates - F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; - F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); // calculate pixel distance to screen - F32 distance = ((F32)getWorldViewHeight() / (mDisplayScale.mV[VY] * 2.f)) / (tan(fov / 2.f)); + F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f)); // calculate click point relative to middle of screen F32 click_x = x - center_x; @@ -3403,17 +3606,17 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const { // find screen resolution - S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]); + S32 height = getWorldViewHeightScaled(); // find world view center - F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; - F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5 F32 hud_x = -((F32)x - center_x) / height; F32 hud_y = ((F32)y - center_y) / height; - return LLVector3(0.f, hud_x/gAgent.mHUDCurZoom, hud_y/gAgent.mHUDCurZoom); + return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom); } // Returns unit vector relative to camera in camera space @@ -3425,12 +3628,12 @@ LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect(); // find screen resolution - S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]); - S32 width = llround((F32)getWorldViewWidth() / mDisplayScale.mV[VX]); + S32 height = getWorldViewHeightScaled(); + S32 width = getWorldViewWidthScaled(); // find world view center - F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; - F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); // calculate click point relative to middle of screen F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f; @@ -3460,7 +3663,7 @@ BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, con LLVector3d plane_normal_global_d; plane_normal_global_d.setVec(plane_normal_global); F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d); - LLVector3d plane_origin_camera_rel = plane_point_global - gAgent.getCameraPositionGlobal(); + LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal(); F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel) / plane_mouse_dot; if (llabs(plane_mouse_dot) < 0.00001) @@ -3474,7 +3677,7 @@ BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, con mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d); } - point = gAgent.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d; + point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d; return mouse_look_at_scale > 0.0; } @@ -3492,12 +3695,12 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d const F32 SECOND_PASS_STEP = 0.1f; // meters LLVector3d camera_pos_global; - camera_pos_global = gAgent.getCameraPositionGlobal(); + camera_pos_global = gAgentCamera.getCameraPositionGlobal(); LLVector3d probe_point_global; LLVector3 probe_point_region; // walk forwards to find the point - for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgent.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP) + for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgentCamera.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP) { LLVector3d mouse_direction_global_d; mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); @@ -3670,8 +3873,8 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) ||(size.mY != new_height + BORDERHEIGHT)) { // use actual display dimensions, not virtual UI dimensions - S32 x = gViewerWindow->getWindowDisplayWidth(); - S32 y = gViewerWindow->getWindowDisplayHeight(); + S32 x = gViewerWindow->getWindowWidthRaw(); + S32 y = gViewerWindow->getWindowHeightRaw(); BORDERWIDTH = size.mX - x; BORDERHEIGHT = size.mY- y; LLCoordScreen new_size(new_width + BORDERWIDTH, @@ -3770,12 +3973,12 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // Copy screen to a buffer // crop sides or top and bottom, if taking a snapshot of different aspect ratio // from window - S32 snapshot_width = mWindowRect.getWidth(); - S32 snapshot_height = mWindowRect.getHeight(); + S32 snapshot_width = mWindowRectRaw.getWidth(); + S32 snapshot_height = mWindowRectRaw.getHeight(); // SNAPSHOT - S32 window_width = mWindowRect.getWidth(); - S32 window_height = mWindowRect.getHeight(); - LLRect window_rect = mWindowRect; + S32 window_width = mWindowRectRaw.getWidth(); + S32 window_height = mWindowRectRaw.getHeight(); + LLRect window_rect = mWindowRectRaw; BOOL use_fbo = FALSE; LLRenderTarget target; @@ -3806,7 +4009,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei window_width = snapshot_width; window_height = snapshot_height; scale_factor = 1.f; - mWindowRect.set(0, snapshot_height, snapshot_width, 0); + mWindowRectRaw.set(0, snapshot_height, snapshot_width, 0); target.bindTarget(); } } @@ -3839,7 +4042,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei return FALSE ; } - BOOL high_res = scale_factor > 1.f; + BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher if (high_res) { send_agent_pause(); @@ -3874,7 +4077,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLViewerCamera::getInstance()->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor))); setup3DRender(); - gObjectList.renderPickList(gViewerWindow->getVirtualWindowRect(), FALSE, FALSE); + gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE); } else { @@ -3953,7 +4156,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if (use_fbo) { - mWindowRect = window_rect; + mWindowRectRaw = window_rect; target.flush(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -4027,30 +4230,20 @@ void LLViewerWindow::drawMouselookInstructions() { // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) const std::string instructions = LLTrans::getString("LeaveMouselook"); - const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Huge", LLFontGL::BOLD)); + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD)); //to be on top of Bottom bar when it is opened const S32 INSTRUCTIONS_PAD = 50; font->renderUTF8( instructions, 0, - getVirtualWorldViewRect().getCenterX(), - getVirtualWorldViewRect().mBottom + INSTRUCTIONS_PAD, + getWorldViewRectScaled().getCenterX(), + getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD, LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ), LLFontGL::HCENTER, LLFontGL::TOP, LLFontGL::NORMAL,LLFontGL::DROP_SHADOW); } -S32 LLViewerWindow::getWindowHeight() const -{ - return mVirtualWindowRect.getHeight(); -} - -S32 LLViewerWindow::getWindowWidth() const -{ - return mVirtualWindowRect.getWidth(); -} - void* LLViewerWindow::getPlatformWindow() const { return mWindow->getPlatformWindow(); @@ -4071,49 +4264,65 @@ LLRootView* LLViewerWindow::getRootView() const return mRootView; } -LLRect LLViewerWindow::getVirtualWorldViewRect() const +LLRect LLViewerWindow::getWorldViewRectScaled() const { - LLRect world_view_rect = mWorldViewRect; - world_view_rect.mLeft = llround((F32)world_view_rect.mLeft / mDisplayScale.mV[VX]); - world_view_rect.mRight = llround((F32)world_view_rect.mRight / mDisplayScale.mV[VX]); - world_view_rect.mBottom = llround((F32)world_view_rect.mBottom / mDisplayScale.mV[VY]); - world_view_rect.mTop = llround((F32)world_view_rect.mTop / mDisplayScale.mV[VY]); - return world_view_rect; + return mWorldViewRectScaled; } -S32 LLViewerWindow::getWorldViewHeight() const +S32 LLViewerWindow::getWorldViewHeightScaled() const { - return mWorldViewRect.getHeight(); + return mWorldViewRectScaled.getHeight(); } -S32 LLViewerWindow::getWorldViewWidth() const +S32 LLViewerWindow::getWorldViewWidthScaled() const { - return mWorldViewRect.getWidth(); + return mWorldViewRectScaled.getWidth(); } -S32 LLViewerWindow::getWindowDisplayHeight() const + +S32 LLViewerWindow::getWorldViewHeightRaw() const +{ + return mWorldViewRectRaw.getHeight(); +} + +S32 LLViewerWindow::getWorldViewWidthRaw() const +{ + return mWorldViewRectRaw.getWidth(); +} + +S32 LLViewerWindow::getWindowHeightScaled() const { - return mWindowRect.getHeight(); + return mWindowRectScaled.getHeight(); } -S32 LLViewerWindow::getWindowDisplayWidth() const +S32 LLViewerWindow::getWindowWidthScaled() const { - return mWindowRect.getWidth(); + return mWindowRectScaled.getWidth(); +} + +S32 LLViewerWindow::getWindowHeightRaw() const +{ + return mWindowRectRaw.getHeight(); +} + +S32 LLViewerWindow::getWindowWidthRaw() const +{ + return mWindowRectRaw.getWidth(); } void LLViewerWindow::setup2DRender() { // setup ortho camera - gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight()); + gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight()); setup2DViewport(); } void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset) { - gGLViewport[0] = mWindowRect.mLeft + x_offset; - gGLViewport[1] = mWindowRect.mBottom + y_offset; - gGLViewport[2] = mWindowRect.getWidth(); - gGLViewport[3] = mWindowRect.getHeight(); + gGLViewport[0] = mWindowRectRaw.mLeft + x_offset; + gGLViewport[1] = mWindowRectRaw.mBottom + y_offset; + gGLViewport[2] = mWindowRectRaw.getWidth(); + gGLViewport[3] = mWindowRectRaw.getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } @@ -4121,7 +4330,7 @@ void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset) void LLViewerWindow::setup3DRender() { // setup perspective camera - LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRect.mLeft, mWorldViewRect.mBottom, mWorldViewRect.getWidth(), mWorldViewRect.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f); + LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f); setup3DViewport(); } @@ -4129,17 +4338,17 @@ void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset) { if (LLRenderTarget::getCurrentBoundTarget() != NULL) { - // don't use translation component of mWorldViewRect, as we are already in a properly sized render target + // don't use translation component of mWorldViewRectRaw, as we are already in a properly sized render target gGLViewport[0] = x_offset; gGLViewport[1] = y_offset; } else { - gGLViewport[0] = mWorldViewRect.mLeft + x_offset; - gGLViewport[1] = mWorldViewRect.mBottom + y_offset; + gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset; + gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset; } - gGLViewport[2] = mWorldViewRect.getWidth(); - gGLViewport[3] = mWorldViewRect.getHeight(); + gGLViewport[2] = mWorldViewRectRaw.getWidth(); + gGLViewport[3] = mWorldViewRectRaw.getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } @@ -4350,8 +4559,8 @@ void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height) if (mWindow && mWindow->getFullscreen() == mWantFullscreen) { - width = getWindowDisplayWidth(); - height = getWindowDisplayHeight(); + width = getWindowWidthRaw(); + height = getWindowHeightRaw(); } else if (mWantFullscreen) { @@ -4398,7 +4607,7 @@ BOOL LLViewerWindow::checkSettings() getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio")); } - reshape(getWindowDisplayWidth(), getWindowDisplayHeight()); + reshape(getWindowWidthRaw(), getWindowHeightRaw()); // force aspect ratio if (mIsFullscreenChecked) @@ -4461,7 +4670,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) stopGL(); if (show_progress_bar) { - restoreGL("Changing Resolution..."); + restoreGL(LLTrans::getString("ProgressChangingResolution")); } else { @@ -4486,8 +4695,9 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, return TRUE; } - U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); - U32 old_fsaa = mWindow->getFSAASamples(); + //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); + //U32 old_fsaa = mWindow->getFSAASamples(); + // going from windowed to windowed if (!old_fullscreen && !fullscreen) { @@ -4497,7 +4707,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mWindow->setSize(size); } - if (fsaa == old_fsaa) + //if (fsaa == old_fsaa) { return TRUE; } @@ -4526,13 +4736,13 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, gSavedSettings.setS32("WindowY", old_pos.mY); } - mWindow->setFSAASamples(fsaa); + //mWindow->setFSAASamples(fsaa); result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync); if (!result_first_try) { // try to switch back - mWindow->setFSAASamples(old_fsaa); + //mWindow->setFSAASamples(old_fsaa); result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync); if (!result_second_try) @@ -4548,7 +4758,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, llinfos << "Restoring GL during resolution change" << llendl; if (show_progress_bar) { - restoreGL("Changing Resolution..."); + restoreGL(LLTrans::getString("ProgressChangingResolution")); } else { @@ -4560,7 +4770,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, LLSD args; args["RESX"] = llformat("%d",size.mX); args["RESY"] = llformat("%d",size.mY); - LLNotifications::instance().add("ResolutionSwitchFail", args); + LLNotificationsUtil::add("ResolutionSwitchFail", args); size = old_size; // for reshape below } @@ -4624,15 +4834,14 @@ F32 LLViewerWindow::getDisplayAspectRatio() const F32 LLViewerWindow::getWorldViewAspectRatio() const { - F32 world_aspect = (F32)mWorldViewRect.getWidth() / (F32)mWorldViewRect.getHeight(); - //F32 window_aspect = (F32)mWindowRect.getWidth() / (F32)mWindowRect.getHeight(); + F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight(); + //F32 window_aspect = (F32)mWindowRectRaw.getWidth() / (F32)mWindowRectRaw.getHeight(); if (mWindow->getFullscreen()) { return world_aspect * mWindow->getPixelAspectRatio(); } else { - llinfos << "World aspect ratio: " << world_aspect << llendl; return world_aspect; } } @@ -4642,7 +4851,7 @@ void LLViewerWindow::calcDisplayScale() F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); LLVector2 display_scale; display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); - F32 height_normalization = gSavedSettings.getBOOL("UIAutoScale") ? ((F32)mWindowRect.getHeight() / display_scale.mV[VY]) / 768.f : 1.f; + F32 height_normalization = gSavedSettings.getBOOL("UIAutoScale") ? ((F32)mWindowRectRaw.getHeight() / display_scale.mV[VY]) / 768.f : 1.f; if(mWindow->getFullscreen()) { display_scale *= (ui_scale_factor * height_normalization); @@ -4660,8 +4869,8 @@ void LLViewerWindow::calcDisplayScale() if (mWindow->getFullscreen()) { - display_scale.mV[0] = llround(display_scale.mV[0], 2.0f/(F32) mWindowRect.getWidth()); - display_scale.mV[1] = llround(display_scale.mV[1], 2.0f/(F32) mWindowRect.getHeight()); + display_scale.mV[0] = llround(display_scale.mV[0], 2.0f/(F32) mWindowRectRaw.getWidth()); + display_scale.mV[1] = llround(display_scale.mV[1], 2.0f/(F32) mWindowRectRaw.getHeight()); } if (display_scale != mDisplayScale) @@ -4674,6 +4883,18 @@ void LLViewerWindow::calcDisplayScale() } } +//static +LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale) +{ + LLRect res = rect; + res.mLeft = llround((F32)res.mLeft / display_scale.mV[VX]); + res.mRight = llround((F32)res.mRight / display_scale.mV[VX]); + res.mBottom = llround((F32)res.mBottom / display_scale.mV[VY]); + res.mTop = llround((F32)res.mTop / display_scale.mV[VY]); + + return res; +} + S32 LLViewerWindow::getChatConsoleBottomPad() { S32 offset = 0; @@ -4686,7 +4907,7 @@ S32 LLViewerWindow::getChatConsoleBottomPad() LLRect LLViewerWindow::getChatConsoleRect() { - LLRect full_window(0, getWindowHeight(), getWindowWidth(), 0); + LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0); LLRect console_rect = full_window; const S32 CONSOLE_PADDING_TOP = 24; @@ -4708,7 +4929,7 @@ LLRect LLViewerWindow::getChatConsoleRect() { // Make console rect somewhat narrow so having inventory open is // less of a problem. - console_rect.mRight = console_rect.mLeft + 2 * getWindowWidth() / 3; + console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3; } return console_rect; @@ -4731,9 +4952,9 @@ bool LLViewerWindow::onAlert(const LLSD& notify) // If we're in mouselook, the mouse is hidden and so the user can't click // the dialog buttons. In that case, change to First Person instead. - if( gAgent.cameraMouselook() ) + if( gAgentCamera.cameraMouselook() ) { - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); } return false; } @@ -4760,13 +4981,11 @@ LLPickInfo::LLPickInfo() } LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, - const LLRect& screen_region, - MASK keyboard_mask, - BOOL pick_transparent, - BOOL pick_uv_coords, - void (*pick_callback)(const LLPickInfo& pick_info)) + MASK keyboard_mask, + BOOL pick_transparent, + BOOL pick_uv_coords, + void (*pick_callback)(const LLPickInfo& pick_info)) : mMousePt(mouse_pos), - mScreenRegion(screen_region), mKeyMask(keyboard_mask), mPickCallback(pick_callback), mPickType(PICK_INVALID), @@ -4847,7 +5066,7 @@ void LLPickInfo::fetchResults() { mPickType = PICK_OBJECT; } - mObjectOffset = gAgent.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); + mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); mObjectID = objectp->mID; mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; |