summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerwindow.cpp')
-rw-r--r--indra/newview/llviewerwindow.cpp4961
1 files changed, 2292 insertions, 2669 deletions
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 900fd6fc8b..a0a3380441 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2,63 +2,68 @@
* @file llviewerwindow.cpp
* @brief Implementation of the LLViewerWindow class.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
-#include "llpanellogin.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>
#include <iostream>
#include <fstream>
+#include <algorithm>
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llfloaterreg.h"
+#include "llpanellogin.h"
+#include "llviewerkeyboard.h"
+#include "llviewermenu.h"
#include "llviewquery.h"
#include "llxmltree.h"
+#include "llslurl.h"
//#include "llviewercamera.h"
-#include "llglimmediate.h"
+#include "llrender.h"
#include "llvoiceclient.h" // for push-to-talk button handling
-#ifdef SABINRIG
-#include "cbw.h"
-#endif //SABINRIG
-
//
// TODO: Many of these includes are unnecessary. Remove them.
//
// linden library includes
-#include "audioengine.h" // mute on minimize
+#include "llaudioengine.h" // mute on minimize
#include "indra_constants.h"
#include "llassetstorage.h"
+#include "llerrorcontrol.h"
#include "llfontgl.h"
+#include "llmousehandler.h"
#include "llrect.h"
#include "llsky.h"
#include "llstring.h"
@@ -71,13 +76,13 @@
#include "lltimer.h"
#include "timing.h"
#include "llviewermenu.h"
+#include "lltooltip.h"
+#include "llmediaentry.h"
+#include "llurldispatcher.h"
// newview includes
#include "llagent.h"
-#include "llalertdialog.h"
#include "llbox.h"
-#include "llcameraview.h"
-#include "llchatbar.h"
#include "llconsole.h"
#include "llviewercontrol.h"
#include "llcylinder.h"
@@ -91,61 +96,56 @@
#include "llface.h"
#include "llfeaturemanager.h"
#include "llfilepicker.h"
+#include "llfirstuse.h"
#include "llfloater.h"
-#include "llfloateractivespeakers.h"
#include "llfloaterbuildoptions.h"
#include "llfloaterbuyland.h"
-#include "llfloaterchat.h"
-#include "llfloaterchatterbox.h"
-#include "llfloatercustomize.h"
-#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
+#include "llfloatercamera.h"
#include "llfloaterland.h"
#include "llfloaterinspect.h"
#include "llfloatermap.h"
-#include "llfloatermute.h"
#include "llfloaternamedesc.h"
#include "llfloaterpreference.h"
#include "llfloatersnapshot.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
#include "llfocusmgr.h"
-#include "llframestatview.h"
+#include "llfontfreetype.h"
#include "llgesturemgr.h"
#include "llglheaders.h"
-#include "llhippo.h"
-#include "llhoverview.h"
+#include "lltooltip.h"
#include "llhudmanager.h"
+#include "llhudobject.h"
#include "llhudview.h"
#include "llimagebmp.h"
#include "llimagej2c.h"
-#include "llinventoryview.h"
+#include "llimageworker.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
#include "llmodaldialog.h"
#include "llmorphview.h"
#include "llmoveview.h"
-#include "llnotify.h"
-#include "lloverlaybar.h"
+#include "llnavigationbar.h"
+#include "llpopupview.h"
#include "llpreviewtexture.h"
#include "llprogressview.h"
#include "llresmgr.h"
-#include "llrootview.h"
+#include "llsidetray.h"
#include "llselectmgr.h"
-#include "llsphere.h"
+#include "llrootview.h"
+#include "llrendersphere.h"
#include "llstartup.h"
#include "llstatusbar.h"
#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"
@@ -154,97 +154,85 @@
#include "lltoolmgr.h"
#include "lltoolmorph.h"
#include "lltoolpie.h"
-#include "lltoolplacer.h"
-#include "lltoolselect.h"
#include "lltoolselectland.h"
-#include "lltoolview.h"
-#include "llvieweruictrlfactory.h"
-#include "lluploaddialog.h"
+#include "lltrans.h"
+#include "lluictrlfactory.h"
#include "llurldispatcher.h" // SLURL from other app instance
+#include "llversioninfo.h"
#include "llvieweraudio.h"
#include "llviewercamera.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llviewerkeyboard.h"
+#include "llviewermedia.h"
+#include "llviewermediafocus.h"
#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
+#include "llviewershadermgr.h"
#include "llviewerstats.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
#include "pipeline.h"
#include "llappviewer.h"
-#include "llurlsimstring.h"
#include "llviewerdisplay.h"
#include "llspatialpartition.h"
+#include "llviewerjoystick.h"
+#include "llviewernetwork.h"
+#include "llpostprocess.h"
+#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"
+#include "llpaneltopinfobar.h"
#if LL_WINDOWS
-#include "llwindebug.h"
#include <tchar.h> // For Unicode conversion methods
#endif
//
// Globals
//
-void render_ui_and_swap_if_needed();
-void render_ui_and_swap();
-LLBottomPanel* gBottomPanel = NULL;
+void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
extern BOOL gDebugClicks;
extern BOOL gDisplaySwapBuffers;
+extern BOOL gDepthDirty;
extern BOOL gResizeScreenTexture;
-extern S32 gJamesInt;
LLViewerWindow *gViewerWindow = NULL;
-LLVelocityBar *gVelocityBar = NULL;
-
-LLVector3d gLastHitPosGlobal;
-LLVector3d gLastHitObjectOffset;
-LLUUID gLastHitObjectID;
-S32 gLastHitObjectFace = -1;
-BOOL gLastHitLand = FALSE;
-F32 gLastHitUCoord;
-F32 gLastHitVCoord;
-
-LLVector3d gLastHitNonFloraPosGlobal;
-LLVector3d gLastHitNonFloraObjectOffset;
-LLUUID gLastHitNonFloraObjectID;
-S32 gLastHitNonFloraObjectFace = -1;
-BOOL gLastHitParcelWall = FALSE;
-
-S32 gLastHitUIElement = 0;
-LLHUDIcon* gLastHitHUDIcon = NULL;
-
-BOOL gDebugSelect = FALSE;
-U8 gLastPickAlpha = 255;
-BOOL gUseGLPick = FALSE;
-
-// On the next pick pass (whenever that happens)
-// should we try to pick individual faces?
-// Cleared to FALSE every time a pick happens.
-BOOL gPickFaces = FALSE;
-
-LLFrameTimer gMouseIdleTimer;
LLFrameTimer gAwayTimer;
LLFrameTimer gAwayTriggerTimer;
-LLFrameTimer gAlphaFadeTimer;
BOOL gShowOverlayTitle = FALSE;
-BOOL gPickTransparent = TRUE;
-BOOL gDebugFastUIRender = FALSE;
+LLViewerObject* gDebugRaycastObject = NULL;
+LLVector3 gDebugRaycastIntersection;
+LLVector2 gDebugRaycastTexCoord;
+LLVector3 gDebugRaycastNormal;
+LLVector3 gDebugRaycastBinormal;
+S32 gDebugRaycastFaceHit;
// HUD display lines in lower right
BOOL gDisplayWindInfo = FALSE;
BOOL gDisplayCameraPos = FALSE;
-BOOL gDisplayNearestWater = FALSE;
BOOL gDisplayFOV = FALSE;
+BOOL gDisplayBadge = FALSE;
S32 CHAT_BAR_HEIGHT = 28;
S32 OVERLAY_BAR_HEIGHT = 20;
@@ -256,121 +244,36 @@ const F32 MIN_AFK_TIME = 2.f; // minimum time after setting away state before co
const F32 MAX_FAST_FRAME_TIME = 0.5f;
const F32 FAST_FRAME_INCREMENT = 0.1f;
-const S32 PICK_HALF_WIDTH = 5;
-const S32 PICK_DIAMETER = 2 * PICK_HALF_WIDTH+1;
-
-const F32 MIN_DISPLAY_SCALE = 0.85f;
-
-const S32 CONSOLE_BOTTOM_PAD = 40;
-
-#ifdef SABINRIG
-/// ALL RIG STUFF
-bool rigControl = false;
-bool voltDisplay = true;
-bool nominalX = false;
-bool nominalY = false;
-static F32 nomerX = 0.0f;
-static F32 nomerY = 0.0f;
-const BOARD_NUM = 0; // rig stuff!
-const ADRANGE = BIP10VOLTS; // rig stuff!
-static unsigned short DataVal; // rig stuff!
-static F32 oldValueX = 0;
-static F32 newValueX = 50;
-static F32 oldValueY = 0;
-static F32 newValueY = 50;
-static S32 mouseX = 50;
-static S32 mouseY = 50;
-static float VoltageX = 50; // rig stuff!
-static float VoltageY = 50; // rig stuff!
-static float nVoltX = 0;
-static float nVoltY = 0;
-static F32 temp1 = 50.f;
-static F32 temp2 = 20.f;
-LLCoordGL new_gl;
-#endif //SABINRIG
-
-char LLViewerWindow::sSnapshotBaseName[LL_MAX_PATH];
-char LLViewerWindow::sSnapshotDir[LL_MAX_PATH];
-
-char LLViewerWindow::sMovieBaseName[LL_MAX_PATH];
-
-extern void toggle_debug_menus(void*);
-
-#ifdef SABINRIG
-// static
-void LLViewerWindow::printFeedback()
-{
- if(rigControl == true)
- {
- cbAIn (BOARD_NUM, 0, ADRANGE, &DataVal);
- cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageX); //Convert raw to voltage for X-axis
- cbAIn (BOARD_NUM, 1, ADRANGE, &DataVal);
- cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageY); //Convert raw to voltage for Y-axis
- if(voltDisplay == true)
- {
- llinfos << "Current Voltages - X:" << VoltageX << " Y:" << VoltageY << llendl; //Display voltage
- }
-
- if(nVoltX == 0)
- {
- nVoltX = VoltageX;
- nVoltY = VoltageY; //First time setup of nominal values.
- }
-
- newValueX = VoltageX;
- newValueY = VoltageY; //Take in current voltage and set to a separate value for adjustment.
-
- mouseX = mCurrentMousePoint.mX;
- mouseY = mCurrentMousePoint.mY; //Take in current cursor position and set to separate value for adjustment.
-
- if( abs(newValueX - nVoltX) > nomerX )
- {
- if( (newValueX - oldValueX) < 0)
- {
- mouseX += (S32)( ((newValueX - oldValueX)*.5)) * -temp;
- }
- else
- {
- mouseX += (S32)( ((newValueX - oldValueX)*.5) * temp1);
- }
- }
- else
- {
- mouseX = getWindowWidth() / 2;
- }
- if( abs(newValueY - nVoltY) > nomerY )
- {
- if( (newValueY - oldValueY) < 0)
- {
- mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * -temp2);
- }
- else
- {
- mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * temp2);
- }
- }
- else
- {
- mouseY = getWindowHeight() / 2;
- }
- //mouseX += (S32)( (newValueX - nVoltX) * temp1 + 0.5 );
- // (newValueX - oldValueX) = difference between current position and nominal position
- // * temp1 = the amplification of the number that sets sensitivity
- // + 0.5 = fixes rounding errors
-
+const F32 MIN_DISPLAY_SCALE = 0.75f;
- //mouseY += (S32)( (newValueY - nVoltY) * temp2 + 0.5 ); //Algorithm to adjust voltage for mouse adjustment.
+std::string LLViewerWindow::sSnapshotBaseName;
+std::string LLViewerWindow::sSnapshotDir;
- oldValueX = newValueX;
- oldValueY = newValueY;
+std::string LLViewerWindow::sMovieBaseName;
- new_gl.mX = mouseX;
- new_gl.mY = mouseY; //Setup final coordinate to move mouse to.
+class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
+{
+public:
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread
- setCursorPosition(new_gl); //Set final cursor position
+ // 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);
+ //}
+ //}
}
-}
-#endif //SABINRIG
+};
////////////////////////////////////////////////////////////////////////////
//
@@ -414,7 +317,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->getWindowWidthScaled() - 350;
U32 ypos = 64;
const U32 y_inc = 20;
@@ -430,7 +333,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;
@@ -456,9 +361,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]));
}
@@ -476,11 +381,11 @@ 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]));
- tvector = LLVector4(gCamera->getAtAxis());
+ tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
camera_view_text = llformat("CameraAtAxis %f %f %f",
(F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
@@ -514,9 +419,21 @@ public:
}
if (gDisplayFOV)
{
- addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * gCamera->getView()));
+ 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())
+ {
+ addText(xpos + 200, ypos, llformat("Flycam"));
+ ypos += y_inc;
+ }*/
+
if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
{
if (gPipeline.getUseVertexShaders() == 0)
@@ -560,7 +477,7 @@ public:
if (gPipeline.mBatchCount > 0)
{
addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize,
- gPipeline.mMeanBatchSize));
+ gPipeline.mTrianglesDrawn/gPipeline.mBatchCount));
gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize;
gPipeline.mMaxBatchSize = 0;
@@ -568,6 +485,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;
@@ -577,9 +498,46 @@ public:
ypos += y_inc;
+ addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount));
+
+ ypos += y_inc;
+
LLVertexBuffer::sBindCount = LLImageGL::sBindCount =
LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
- gPipeline.mNumVisibleNodes = 0;
+ gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
+ }
+ if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
+ {
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, "Projection Matrix");
+ ypos += y_inc;
+
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3]));
+ ypos += y_inc;
+
+ addText(xpos, ypos, "View Matrix");
+ ypos += y_inc;
}
if (gSavedSettings.getBOOL("DebugShowColor"))
{
@@ -590,7 +548,7 @@ public:
ypos += y_inc;
}
// only display these messages if we are actually rendering beacons at this moment
- if (LLPipeline::getRenderBeacons(NULL) && LLPipeline::getProcessBeacons(NULL))
+ if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
{
if (LLPipeline::getRenderParticleBeacons(NULL))
{
@@ -632,9 +590,9 @@ public:
iter != mLineList.end(); ++iter)
{
const Line& line = *iter;
- LLFontGL::sMonospace->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
+ LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
LLFontGL::LEFT, LLFontGL::TOP,
- LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE);
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
}
mLineList.clear();
}
@@ -651,295 +609,159 @@ void LLViewerWindow::updateDebugText()
// LLViewerWindow
//
-BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
+BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
{
+ const char* buttonname = "";
+ const char* buttonstatestr = "";
S32 x = pos.mX;
S32 y = pos.mY;
x = llround((F32)x / mDisplayScale.mV[VX]);
y = llround((F32)y / mDisplayScale.mV[VY]);
- LLView::sMouseHandlerMessage = "";
-
- if (gDebugClicks)
- {
- llinfos << "ViewerWindow left mouse down at " << x << "," << y << llendl;
- }
+ // only send mouse clicks to UI if UI is visible
+ if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
- if (gMenuBarView)
- {
- // stop ALT-key access to menu
- gMenuBarView->resetMenuTrigger();
- }
-
- mLeftMouseDown = TRUE;
-
- // Make sure we get a coresponding mouseup event, even if the mouse leaves the window
- mWindow->captureMouse();
-
- // Indicate mouse was active
- gMouseIdleTimer.reset();
-
- // Hide tooltips on mousedown
- if( mToolTip )
- {
- mToolTipBlocked = TRUE;
- mToolTip->setVisible( FALSE );
- }
-
- // Also hide hover info on mousedown
- if (gHoverView)
- {
- gHoverView->cancelHover();
- }
-
- if (gToolMgr)
- {
- // Don't let the user move the mouse out of the window until mouse up.
- if( gToolMgr->getCurrentTool()->clipMouseWhenDown() )
- {
- mWindow->setMouseClipping(TRUE);
- }
- }
-
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
+ if (down)
{
- llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl;
- }
-
- return mouse_captor->handleMouseDown(local_x, local_y, 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 (top_ctrl->pointInView(local_x, local_y))
- {
- return top_ctrl->handleMouseDown(local_x, local_y, mask);
+ buttonstatestr = "down" ;
}
else
{
- setTopCtrl(NULL);
+ buttonstatestr = "up" ;
}
- }
-
- // Give the UI views a chance to process the click
- if( mRootView->handleMouseDown(x, y, mask) )
- {
- if (LLView::sDebugMouseHandling)
+
+ switch (clicktype)
{
- llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
+ case LLMouseHandler::CLICK_LEFT:
+ mLeftMouseDown = down;
+ buttonname = "Left";
+ break;
+ case LLMouseHandler::CLICK_RIGHT:
+ mRightMouseDown = down;
+ buttonname = "Right";
+ break;
+ case LLMouseHandler::CLICK_MIDDLE:
+ mMiddleMouseDown = down;
+ buttonname = "Middle";
+ break;
+ case LLMouseHandler::CLICK_DOUBLELEFT:
+ mLeftMouseDown = down;
+ buttonname = "Left Double Click";
+ break;
}
- return TRUE;
- }
- else if (LLView::sDebugMouseHandling)
- {
- llinfos << "Left Mouse Down not handled by view" << llendl;
- }
-
- if (gDisconnected)
- {
- return FALSE;
- }
+
+ LLView::sMouseHandlerMessage.clear();
- if (gToolMgr)
- {
- if(gToolMgr->getCurrentTool()->handleMouseDown( x, y, mask ) )
+ if (gMenuBarView)
{
- // This is necessary to force clicks in the world to cause edit
- // boxes that might have keyboard focus to relinquish it, and hence
- // cause a commit to update their value. JC
- gFocusMgr.setKeyboardFocus(NULL);
- return TRUE;
+ // stop ALT-key access to menu
+ gMenuBarView->resetMenuTrigger();
}
- }
- return FALSE;
-}
-
-BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
-{
- S32 x = pos.mX;
- S32 y = pos.mY;
- x = llround((F32)x / mDisplayScale.mV[VX]);
- y = llround((F32)y / mDisplayScale.mV[VY]);
-
- LLView::sMouseHandlerMessage = "";
+ if (gDebugClicks)
+ {
+ llinfos << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << llendl;
+ }
- if (gDebugClicks)
- {
- llinfos << "ViewerWindow left mouse double-click at " << x << "," << y << llendl;
- }
+ // Make sure we get a corresponding mouseup event, even if the mouse leaves the window
+ if (down)
+ mWindow->captureMouse();
+ else
+ mWindow->releaseMouse();
- mLeftMouseDown = TRUE;
+ // Indicate mouse was active
+ LLUI::resetMouseIdleTimer();
- // Hide tooltips
- if( mToolTip )
- {
- mToolTip->setVisible( FALSE );
- }
+ // Don't let the user move the mouse out of the window until mouse up.
+ if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
+ {
+ mWindow->setMouseClipping(down);
+ }
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ if( mouse_captor )
{
- llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl;
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
+ if (LLView::sDebugMouseHandling)
+ {
+ llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
+ }
+ return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
}
- return mouse_captor->handleDoubleClick(local_x, local_y, 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 (top_ctrl->pointInView(local_x, local_y))
+ // {
+ // return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
+ // }
+ // else
+ // {
+ // if (down)
+ // {
+ // gFocusMgr.setTopCtrl(NULL);
+ // }
+ // }
+ //}
- // Check for hit on UI.
- 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))
+ // Give the UI views a chance to process the click
+ if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
{
- return top_ctrl->handleDoubleClick(local_x, local_y, mask);
+ if (LLView::sDebugMouseHandling)
+ {
+ llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
+ }
+ return TRUE;
}
- else
+ else if (LLView::sDebugMouseHandling)
{
- setTopCtrl(NULL);
+ llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
}
}
- if (mRootView->handleDoubleClick(x, y, mask))
+ // Do not allow tool manager to handle mouseclicks if we have disconnected
+ if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
{
- if (LLView::sDebugMouseHandling)
- {
- llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
- }
return TRUE;
}
- else if (LLView::sDebugMouseHandling)
- {
- llinfos << "Left Mouse Down not handled by view" << llendl;
- }
+
- // Why is this here? JC 9/3/2002
- if (gNoRender)
- {
- return TRUE;
- }
+ // 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.
+ BOOL default_rtn = !down;
+ return default_rtn;
+}
+
+BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
+{
+ BOOL down = TRUE;
+ return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
+}
- if (gToolMgr)
+BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
+{
+ // try handling as a double-click first, then a single-click if that
+ // wasn't handled.
+ BOOL down = TRUE;
+ if (handleAnyMouseClick(window, pos, mask,
+ LLMouseHandler::CLICK_DOUBLELEFT, down))
{
- if(gToolMgr->getCurrentTool()->handleDoubleClick( x, y, mask ) )
- {
- return TRUE;
- }
+ return TRUE;
}
-
- // if we got this far and nothing handled a double click, pass a normal mouse down
return handleMouseDown(window, pos, mask);
}
BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- S32 x = pos.mX;
- S32 y = pos.mY;
- x = llround((F32)x / mDisplayScale.mV[VX]);
- y = llround((F32)y / mDisplayScale.mV[VY]);
-
- LLView::sMouseHandlerMessage = "";
-
- if (gDebugClicks)
- {
- llinfos << "ViewerWindow left mouse up" << llendl;
- }
-
- mLeftMouseDown = FALSE;
-
- // Indicate mouse was active
- gMouseIdleTimer.reset();
-
- // Hide tooltips on mouseup
- if( mToolTip )
- {
- mToolTip->setVisible( FALSE );
- }
-
- // Also hide hover info on mouseup
- if (gHoverView) gHoverView->cancelHover();
-
- BOOL handled = FALSE;
-
- mWindow->releaseMouse();
-
- LLTool *tool = NULL;
- if (gToolMgr)
- {
- tool = gToolMgr->getCurrentTool();
-
- if( tool->clipMouseWhenDown() )
- {
- mWindow->setMouseClipping(FALSE);
- }
- }
-
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
- {
- llinfos << "Left Mouse Up handled by captor " << mouse_captor->getName() << llendl;
- }
-
- return mouse_captor->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 );
- handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask);
- }
-
- if( !handled )
- {
- handled = mRootView->handleMouseUp(x, y, mask);
- }
-
- if (LLView::sDebugMouseHandling)
- {
- if (handled)
- {
- llinfos << "Left Mouse Up" << LLView::sMouseHandlerMessage << llendl;
- }
- else
- {
- llinfos << "Left Mouse Up not handled by view" << llendl;
- }
- }
-
- if( !handled )
- {
- if (tool)
- {
- handled = tool->handleMouseUp(x, y, mask);
- }
- }
-
- // Always handled as far as the OS is concerned.
- return TRUE;
+ BOOL down = FALSE;
+ return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
}
@@ -950,106 +772,19 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
x = llround((F32)x / mDisplayScale.mV[VX]);
y = llround((F32)y / mDisplayScale.mV[VY]);
- LLView::sMouseHandlerMessage = "";
-
- if (gDebugClicks)
- {
- llinfos << "ViewerWindow right mouse down at " << x << "," << y << llendl;
- }
-
- if (gMenuBarView)
- {
- // stop ALT-key access to menu
- gMenuBarView->resetMenuTrigger();
- }
-
- mRightMouseDown = TRUE;
-
- // Make sure we get a coresponding mouseup event, even if the mouse leaves the window
- mWindow->captureMouse();
-
- // Hide tooltips
- if( mToolTip )
- {
- mToolTip->setVisible( FALSE );
- }
-
- // Also hide hover info on mousedown
- if (gHoverView)
- {
- gHoverView->cancelHover();
- }
-
- if (gToolMgr)
- {
- // Don't let the user move the mouse out of the window until mouse up.
- if( gToolMgr->getCurrentTool()->clipMouseWhenDown() )
- {
- mWindow->setMouseClipping(TRUE);
- }
- }
-
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
- {
- llinfos << "Right Mouse Down handled by captor " << mouse_captor->getName() << llendl;
- }
- return mouse_captor->handleRightMouseDown(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->handleRightMouseDown(local_x, local_y, mask);
- }
- else
- {
- setTopCtrl(NULL);
- }
- }
-
- if( mRootView->handleRightMouseDown(x, y, mask) )
- {
- if (LLView::sDebugMouseHandling)
- {
- llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl;
- }
- return TRUE;
- }
- else if (LLView::sDebugMouseHandling)
- {
- llinfos << "Right Mouse Down not handled by view" << llendl;
- }
-
- if (gToolMgr)
- {
- if(gToolMgr->getCurrentTool()->handleRightMouseDown( x, y, mask ) )
- {
- // This is necessary to force clicks in the world to cause edit
- // boxes that might have keyboard focus to relinquish it, and hence
- // cause a commit to update their value. JC
- gFocusMgr.setKeyboardFocus(NULL);
- return TRUE;
- }
- }
+ BOOL down = TRUE;
+ BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
+ if (handle)
+ return handle;
// *HACK: this should be rolled into the composite tool logic, not
// hardcoded at the top level.
- if (gToolPie && (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode()) )
+ 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
// menu tool.
- gToolPie->handleRightMouseDown(x, y, mask);
+ LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
// show_context_menu( x, y, mask );
}
@@ -1058,114 +793,175 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- S32 x = pos.mX;
- S32 y = pos.mY;
- x = llround((F32)x / mDisplayScale.mV[VX]);
- y = llround((F32)y / mDisplayScale.mV[VY]);
-
- LLView::sMouseHandlerMessage = "";
-
- // Don't care about caps lock for mouse events.
- if (gDebugClicks)
- {
- llinfos << "ViewerWindow right mouse up" << llendl;
- }
+ BOOL down = FALSE;
+ return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
+}
- mRightMouseDown = FALSE;
+BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
+{
+ BOOL down = TRUE;
+ LLVoiceClient::getInstance()->middleMouseState(true);
+ handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+
+ // Always handled as far as the OS is concerned.
+ return TRUE;
+}
- // Indicate mouse was active
- gMouseIdleTimer.reset();
+LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data)
+{
+ LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE;
- // Hide tooltips on mouseup
- if( mToolTip )
+ 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 )
{
- mToolTip->setVisible( FALSE );
- }
+ 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)
+ {
+ LLSLURL dropped_slurl(data);
+ if(dropped_slurl.isSpatial())
+ {
+ if (drop)
+ {
+ LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), NULL, true );
+ return LLWindowCallbacks::DND_MOVE;
+ }
+ return LLWindowCallbacks::DND_COPY;
+ }
+ }
- // Also hide hover info on mouseup
- if (gHoverView) gHoverView->cancelHover();
+ if (prim_media_dnd_enabled)
+ {
+ LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ );
- BOOL handled = FALSE;
+ LLUUID object_id = pick_info.getObjectID();
+ S32 object_face = pick_info.mObjectFace;
+ std::string url = data;
- mWindow->releaseMouse();
+ lldebugs << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << llendl;
- LLTool *tool = NULL;
- if (gToolMgr)
- {
- tool = gToolMgr->getCurrentTool();
+ 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( tool->clipMouseWhenDown() )
- {
- mWindow->setMouseClipping(FALSE);
- }
- }
+ // can modify URL if we can modify the object or we have navigate permissions
+ bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT );
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
- {
- llinfos << "Right Mouse Up handled by captor " << mouse_captor->getName() << llendl;
+ if (te && allow_modify_url )
+ {
+ 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 ) )
+ {
+ // 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;
}
- return mouse_captor->handleRightMouseUp(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 );
- handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleRightMouseUp(local_x, local_y, mask);
- }
-
- if( !handled )
- {
- handled = mRootView->handleRightMouseUp(x, y, mask);
- }
- if (LLView::sDebugMouseHandling)
- {
- if (handled)
- {
- llinfos << "Right Mouse Up" << LLView::sMouseHandlerMessage << llendl;
- }
- else
+ if (prim_media_dnd_enabled &&
+ result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull())
{
- llinfos << "Right Mouse Up not handled by view" << llendl;
+ LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
+ mDragHoveredObject = NULL;
}
}
-
- if( !handled )
- {
- if (tool)
- {
- handled = tool->handleRightMouseUp(x, y, mask);
- }
- }
-
- // Always handled as far as the OS is concerned.
- return TRUE;
-}
-
-BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
-{
- gVoiceClient->middleMouseState(true);
-
- // Always handled as far as the OS is concerned.
- return TRUE;
+
+ return result;
}
-
+
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- gVoiceClient->middleMouseState(false);
-
- // Always handled as far as the OS is concerned.
+ BOOL down = FALSE;
+ LLVoiceClient::getInstance()->middleMouseState(false);
+ handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+
+ // Always handled as far as the OS is concerned.
return TRUE;
}
+// WARNING: this is potentially called multiple times per frame
void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
{
S32 x = pos.mX;
@@ -1178,13 +974,14 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask
// Save mouse point for access during idle() and display()
- LLCoordGL prev_saved_mouse_point = mCurrentMousePoint;
LLCoordGL mouse_point(x, y);
- saveLastMouse(mouse_point);
- BOOL mouse_actually_moved = !gFocusMgr.getMouseCapture() && // mouse is not currenty captured
- ((prev_saved_mouse_point.mX != mCurrentMousePoint.mX) || (prev_saved_mouse_point.mY != mCurrentMousePoint.mY)); // mouse moved from last recorded position
- gMouseIdleTimer.reset();
+ if (mouse_point != mCurrentMousePoint)
+ {
+ LLUI::resetMouseIdleTimer();
+ }
+
+ saveLastMouse(mouse_point);
mWindow->showCursorFromMouseMove();
@@ -1192,21 +989,6 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask
{
gAgent.clearAFK();
}
-
- if(mToolTip && mouse_actually_moved)
- {
- mToolTipBlocked = FALSE; // Blocking starts on keyboard events and (only) ends here.
- if( mToolTip->getVisible() && !mToolTipStickyRect.pointInRect( x, y ) )
- {
- mToolTip->setVisible( FALSE );
- }
- }
-
- // Activate the hover picker on mouse move.
- if (gHoverView)
- {
- gHoverView->setTyping(FALSE);
- }
}
void LLViewerWindow::handleMouseLeave(LLWindow *window)
@@ -1214,10 +996,7 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window)
// Note: we won't get this if we have captured the mouse.
llassert( gFocusMgr.getMouseCapture() == NULL );
mMouseInWindow = FALSE;
- if (mToolTip)
- {
- mToolTip->setVisible( FALSE );
- }
+ LLToolTipMgr::instance().blockToolTips();
}
BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
@@ -1237,6 +1016,7 @@ void LLViewerWindow::handleQuit(LLWindow *window)
void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height)
{
reshape(width, height);
+ mResDirty = true;
}
// The top-level window has gained focus (e.g. via ALT-TAB)
@@ -1246,12 +1026,7 @@ void LLViewerWindow::handleFocus(LLWindow *window)
LLModalDialog::onAppFocusGained();
gAgent.onAppFocusGained();
- if (gToolMgr)
- {
- gToolMgr->onAppFocusGained();
- }
-
- gShowTextEditCursor = TRUE;
+ LLToolMgr::getInstance()->onAppFocusGained();
// See if we're coming in with modifier keys held down
if (gKeyboard)
@@ -1269,10 +1044,7 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
{
gFocusMgr.setAppHasFocus(FALSE);
//LLModalDialog::onAppFocusLost();
- if( gToolMgr )
- {
- gToolMgr->onAppFocusLost();
- }
+ LLToolMgr::getInstance()->onAppFocusLost();
gFocusMgr.setMouseCapture( NULL );
if (gMenuBarView)
@@ -1282,13 +1054,8 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
}
// restore mouse cursor
- gViewerWindow->showCursor();
- gViewerWindow->getWindow()->setMouseClipping(FALSE);
-
- // JC - Leave keyboard focus, so if you're popping in and out editing
- // a script, you don't have to click in the editor again and again.
- // gFocusMgr.setKeyboardFocus( NULL );
- gShowTextEditCursor = FALSE;
+ showCursor();
+ getWindow()->setMouseClipping(FALSE);
// If losing focus while keys are down, reset them.
if (gKeyboard)
@@ -1304,7 +1071,7 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
{
// Let the voice chat code check for its PTT key. Note that this never affects event processing.
- gVoiceClient->keyDown(key, mask);
+ LLVoiceClient::getInstance()->keyDown(key, mask);
if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
{
@@ -1326,7 +1093,7 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
{
// Let the voice chat code check for its PTT key. Note that this never affects event processing.
- gVoiceClient->keyUp(key, mask);
+ LLVoiceClient::getInstance()->keyUp(key, mask);
return FALSE;
}
@@ -1334,6 +1101,7 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
+ LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
}
@@ -1347,55 +1115,41 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
mActive = TRUE;
send_agent_resume();
gAgent.clearAFK();
- if (mWindow->getFullscreen() && !mIgnoreActivate)
- {
- if (!LLApp::isExiting() )
- {
- if (LLStartUp::getStartupState() >= STATE_STARTED)
- {
- // if we're in world, show a progress bar to hide reloading of textures
- llinfos << "Restoring GL during activate" << llendl;
- restoreGL("Restoring...");
- }
- else
- {
- // otherwise restore immediately
- restoreGL();
- }
- }
- else
- {
- llwarns << "Activating while quitting" << llendl;
- }
- }
-
+
// Unmute audio
audio_update_volume();
}
else
{
mActive = FALSE;
- if (gAllowIdleAFK)
+
+ if (gSavedSettings.getS32("AFKTimeout"))
{
gAgent.setAFK();
}
// SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
- gAgent.changeCameraToDefault();
-
- send_agent_pause();
-
- if (mWindow->getFullscreen() && !mIgnoreActivate)
+ if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
{
- llinfos << "Stopping GL during deactivation" << llendl;
- stopGL();
+ gAgentCamera.changeCameraToDefault();
}
+
+ send_agent_pause();
+
// Mute audio
audio_update_volume();
}
return TRUE;
}
+BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
+{
+ //if (!activating) gAgentCamera.changeCameraToDefault();
+
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+ return FALSE;
+}
+
void LLViewerWindow::handleMenuSelect(LLWindow *window, S32 menu_item)
{
@@ -1421,24 +1175,19 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S
//SetBKColor(hdc, RGB(255, 255, 255));
FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
- LLString name_str;
- gAgent.getName(name_str);
-
- S32 len;
- char temp_str[255]; /* Flawfinder: ignore */
- snprintf(temp_str, sizeof(temp_str), "%s FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
- name_str.c_str(),
- gViewerStats->mFPSStat.getMeanPerSec(),
- gViewerStats->mSimPhysicsFPS.getPrev(0),
- gViewerStats->mSimTimeDilation.getPrev(0));
- len = strlen(temp_str); /* Flawfinder: ignore */
- TextOutA(hdc, 0, 0, temp_str, len);
+ std::string temp_str;
+ temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
+ LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
+ LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
+ LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
+ S32 len = temp_str.length();
+ TextOutA(hdc, 0, 0, temp_str.c_str(), len);
LLVector3d pos_global = gAgent.getPositionGlobal();
- snprintf(temp_str, sizeof(temp_str), "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]); /* Flawfinder: ignore */
- len = strlen(temp_str); /* Flawfinder: ignore */
- TextOutA(hdc, 0, 25, temp_str, len);
+ temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
+ len = temp_str.length();
+ TextOutA(hdc, 0, 25, temp_str.c_str(), len);
TextOutA(hdc, 0, 50, "Set \"DisableRendering FALSE\" in settings.ini file to reenable", 61);
EndPaint(window_handle, &ps);
@@ -1451,7 +1200,7 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S
void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
{
- gViewerWindow->handleScrollWheel( clicks );
+ handleScrollWheel( clicks );
}
void LLViewerWindow::handleWindowBlock(LLWindow *window)
@@ -1472,8 +1221,9 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
case SLURL_MESSAGE_TYPE:
// received URL
std::string url = (const char*)data;
- const bool from_external_browser = true;
- if (LLURLDispatcher::dispatch(url, from_external_browser))
+ LLMediaCtrl* web = NULL;
+ const bool trusted_browser = false;
+ if (LLURLDispatcher::dispatch(url, web, trusted_browser))
{
// bring window to foreground, as it has just been "launched" from a URL
mWindow->bringToFront();
@@ -1482,63 +1232,132 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
}
}
+BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
+{
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ LLViewerJoystick::getInstance()->updateStatus();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
+{
+ // give a chance to use a joystick after startup (hot-plugging)
+ if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
+ {
+ LLViewerJoystick::getInstance()->init(true);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
+{
+ LLAppViewer::instance()->pingMainloopTimeout(msg);
+}
+
+
+void LLViewerWindow::handleResumeWatchdog(LLWindow *window)
+{
+ LLAppViewer::instance()->resumeMainloopTimeout();
+}
+
+void LLViewerWindow::handlePauseWatchdog(LLWindow *window)
+{
+ LLAppViewer::instance()->pauseMainloopTimeout();
+}
+
+//virtual
+std::string LLViewerWindow::translateString(const char* tag)
+{
+ return LLTrans::getString( std::string(tag) );
+}
+
+//virtual
+std::string LLViewerWindow::translateString(const char* tag,
+ const std::map<std::string, std::string>& args)
+{
+ // LLTrans uses a special subclass of std::string for format maps,
+ // but we must use std::map<> in these callbacks, otherwise we create
+ // a dependency between LLWindow and LLFormatMapString. So copy the data.
+ LLStringUtil::format_map_t args_copy;
+ std::map<std::string,std::string>::const_iterator it = args.begin();
+ for ( ; it != args.end(); ++it)
+ {
+ args_copy[it->first] = it->second;
+ }
+ return LLTrans::getString( std::string(tag), args_copy);
+}
//
// Classes
//
LLViewerWindow::LLViewerWindow(
- char* title, char* name,
+ const std::string& title, const std::string& name,
S32 x, S32 y,
S32 width, S32 height,
- BOOL fullscreen, BOOL ignore_pixel_depth)
+ BOOL fullscreen, BOOL ignore_pixel_depth) // fullscreen is no longer used
:
+ mWindow(NULL),
mActive(TRUE),
- mWantFullscreen(fullscreen),
- mShowFullscreenProgress(FALSE),
- mWindowRect(0, height, width, 0),
- mVirtualWindowRect(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),
- mToolTip(NULL),
- mToolTipBlocked(FALSE),
mMouseInWindow( FALSE ),
mLastMask( MASK_NONE ),
mToolStored( NULL ),
- mSuppressToolbox( FALSE ),
mHideCursorPermanent( FALSE ),
- mPickPending(FALSE),
- mIgnoreActivate( FALSE )
+ mCursorHidden(FALSE),
+ mIgnoreActivate( FALSE ),
+ mResDirty(false),
+ mStatesDirty(false),
+ mCurrResolutionIndex(0),
+ mViewerWindowListener(new LLViewerWindowListener(this)),
+ mProgressView(NULL)
{
- // Default to application directory.
- strcpy(LLViewerWindow::sSnapshotBaseName, "Snapshot"); /* Flawfinder: ignore */
- strcpy(LLViewerWindow::sMovieBaseName, "SLmovie"); /* Flawfinder: ignore */
- LLViewerWindow::sSnapshotDir[0] = '\0';
+ LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
+ LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
+
+ LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
+ LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+ LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
+ llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
+ // Default to application directory.
+ LLViewerWindow::sSnapshotBaseName = "Snapshot";
+ LLViewerWindow::sMovieBaseName = "SLmovie";
+ resetSnapshotLoc();
// create window
- mWindow = LLWindowManager::createWindow(
+ mWindow = LLWindowManager::createWindow(this,
title, name, x, y, width, height, 0,
fullscreen,
gNoRender,
gSavedSettings.getBOOL("DisableVerticalSync"),
!gNoRender,
- ignore_pixel_depth);
-#if LL_WINDOWS
- if (!LLWinDebug::setupExceptionHandler())
+ ignore_pixel_depth,
+ 0); //gSavedSettings.getU32("RenderFSAASamples"));
+
+ if (!LLAppViewer::instance()->restoreErrorTrap())
{
- llwarns << " Someone took over my exception handler (post createWindow)!" << llendl;
+ LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
}
-#endif
+
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;
#else
- llwarns << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
- << llendl;
+ LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
+ << LL_ENDL;
#endif
LLAppViewer::instance()->forceExit(1);
}
@@ -1554,8 +1373,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();
@@ -1564,23 +1383,24 @@ LLViewerWindow::LLViewerWindow(
// We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
// stuff like AGP if we think that it'll crash the viewer.
//
- llinfos << "Loading feature tables." << llendl;
+ LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
- gFeatureManagerp->init();
+ LLFeatureManager::getInstance()->init();
// Initialize OpenGL Renderer
- if (!gFeatureManagerp->isFeatureAvailable("RenderVBOEnable") ||
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
!gGLManager.mHasVertexBufferObject)
{
gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
}
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"));
- if (gFeatureManagerp->isSafe()
- || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion())
+ if (LLFeatureManager::getInstance()->isSafe()
+ || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
+ || (gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass())
|| (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
{
- gFeatureManagerp->applyRecommendedSettings();
+ LLFeatureManager::getInstance()->applyRecommendedSettings();
gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
}
@@ -1588,55 +1408,55 @@ LLViewerWindow::LLViewerWindow(
if (gSavedSettings.getBOOL("RenderInitError"))
{
mInitAlert = "DisplaySettingsNoShaders";
- gFeatureManagerp->setGraphicsLevel(0, false);
+ LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
gSavedSettings.setU32("RenderQualityPerformance", 0);
-
}
- // set callbacks
- mWindow->setCallbacks(this);
-
// Init the image list. Must happen after GL is initialized and before the images that
// LLViewerWindow needs are requested.
- gImageList.init();
- LLViewerImage::initClass();
+ LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
+ gTextureList.init();
+ LLViewerTextureManager::init() ;
gBumpImageList.init();
-
+
+ // Init font system, but don't actually load the fonts yet
+ // because our window isn't onscreen and they take several
+ // seconds to parse.
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
+ mDisplayScale.mV[VX],
+ mDisplayScale.mV[VY],
+ gDirUtilp->getAppRODataDir(),
+ LLUI::getXUIPaths());
+
// Create container for all sub-views
- mRootView = new LLRootView("root", mVirtualWindowRect, FALSE);
-
- if (!gNoRender)
- {
- // Init default fonts
- initFonts();
- }
-
- // Init Resource Manager
- gResMgr = new LLResMgr();
+ LLView::Params rvp;
+ rvp.name("root");
+ 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;
-
- mPickBuffer = new U8[PICK_DIAMETER * PICK_DIAMETER * 4];
+ mCurrentMousePoint.mX = getWindowWidthScaled() / 2;
+ mCurrentMousePoint.mY = getWindowHeightScaled() / 2;
gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
mOverlayTitle = gSavedSettings.getString("OverlayTitle");
// Can't have spaces in settings.ini strings, so use underscores instead and convert them.
- LLString::replaceChar(mOverlayTitle, '_', ' ');
-
- LLAlertDialog::setDisplayCallback(alertCallback); // call this before calling any modal dialogs
+ LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
// sync the keyboard's setting with the saved setting
gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
mDebugText = new LLDebugText(this);
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
}
void LLViewerWindow::initGLDefaults()
{
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
F32 ambient[4] = {0.f,0.f,0.f,0.f };
@@ -1647,14 +1467,14 @@ void LLViewerWindow::initGLDefaults()
glPixelStorei(GL_PACK_ALIGNMENT,1);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
- glEnable(GL_TEXTURE_2D);
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
// lights for objects
glShadeModel( GL_SMOOTH );
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
glCullFace(GL_BACK);
@@ -1665,15 +1485,17 @@ 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);
- adjustRectanglesForFirstUse(full_window);
-
////////////////////
//
// Set the gamma
@@ -1682,7 +1504,7 @@ void LLViewerWindow::initBase()
F32 gamma = gSavedSettings.getF32("RenderGamma");
if (gamma != 0.0f)
{
- gViewerWindow->getWindow()->setGamma(gamma);
+ getWindow()->setGamma(gamma);
}
// Create global views
@@ -1690,313 +1512,225 @@ 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();
+ main_view->buildFromFile("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->findChild<LLPopupView>("popup_holder");
+ mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
// Constrain floaters to inside the menu and status bar regions.
- LLRect floater_view_rect = full_window;
- // make space for menu bar if we have one
- floater_view_rect.mTop -= MENU_BAR_HEIGHT;
- floater_view_rect.mBottom += STATUS_BAR_HEIGHT + 12 + 16 + 2;
-
- // Check for non-first startup
- S32 floater_view_bottom = gSavedSettings.getS32("FloaterViewBottom");
- if (floater_view_bottom >= 0)
- {
- floater_view_rect.mBottom = floater_view_bottom;
- }
- gFloaterView = new LLFloaterView("Floater View", floater_view_rect );
- gFloaterView->setVisible(TRUE);
-
- gSnapshotFloaterView = new LLSnapshotFloaterView("Snapshot Floater View", full_window);
- gSnapshotFloaterView->setVisible(TRUE);
+ gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
+ gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
+
// Console
llassert( !gConsole );
- LLRect console_rect = full_window;
- console_rect.mTop -= 24;
- console_rect.mBottom += STATUS_BAR_HEIGHT + 12 + 16 + 12;
- console_rect.mLeft += 24; //gSavedSettings.getS32("StatusBarButtonWidth") + gSavedSettings.getS32("StatusBarPad");
-
- if (gSavedSettings.getBOOL("ChatFullWidth"))
+ LLConsole::Params cp;
+ cp.name("console");
+ cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
+ cp.rect(getChatConsoleRect());
+ cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
+ cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
+ cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ gConsole = LLUICtrlFactory::create<LLConsole>(cp);
+ getRootView()->addChild(gConsole);
+
+ // optionally forward warnings to chat console/chat floater
+ // for qa runs and dev builds
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLError::addRecorder(RecordToChatConsole::getInstance());
+#else
+ if(gSavedSettings.getBOOL("QAMode"))
{
- console_rect.mRight -= 10;
+ LLError::addRecorder(RecordToChatConsole::getInstance());
}
- else
- {
- // Make console rect somewhat narrow so having inventory open is
- // less of a problem.
- console_rect.mRight = console_rect.mLeft + 2 * width / 3;
- }
-
- gConsole = new LLConsole(
- "console",
- gSavedSettings.getS32("ConsoleBufferSize"),
- console_rect,
- gSavedSettings.getS32("ChatFontSize"),
- gSavedSettings.getF32("ChatPersistTime") );
- gConsole->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
- mRootView->addChild(gConsole);
-
- // Debug view over the console
- gDebugView = new LLDebugView("gDebugView", full_window);
- gDebugView->setFollowsAll();
- gDebugView->setVisible(TRUE);
- mRootView->addChild(gDebugView);
-
- // Add floater view at the end so it will be on top, and give it tab priority over others
- mRootView->addChild(gFloaterView, -1);
- mRootView->addChild(gSnapshotFloaterView);
-
- // notify above floaters!
- LLRect notify_rect = full_window;
- //notify_rect.mTop -= 24;
- notify_rect.mBottom += STATUS_BAR_HEIGHT;
- gNotifyBoxView = new LLNotifyBoxView("notify_container", notify_rect, FALSE, FOLLOWS_ALL);
- mRootView->addChild(gNotifyBoxView, -2);
-
- // Tooltips go above floaters
- mToolTip = new LLTextBox( "tool tip", LLRect(0, 1, 1, 0 ) );
- mToolTip->setHPad( 4 );
- mToolTip->setVPad( 2 );
- mToolTip->setColor( gColors.getColor( "ToolTipTextColor" ) );
- mToolTip->setBorderColor( gColors.getColor( "ToolTipBorderColor" ) );
- mToolTip->setBorderVisible( FALSE );
- mToolTip->setBackgroundColor( gColors.getColor( "ToolTipBgColor" ) );
- mToolTip->setBackgroundVisible( TRUE );
- mToolTip->setFontStyle(LLFontGL::NORMAL);
- mToolTip->setBorderDropshadowVisible( TRUE );
- mToolTip->setVisible( FALSE );
+#endif
+
+ gDebugView = getRootView()->getChild<LLDebugView>("DebugView");
+ gDebugView->init();
+ gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
+
+ // Initialize busy response message when logged in
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
// Add the progress bar view (startup view), which overrides everything
- mProgressView = new LLProgressView("ProgressView", full_window);
- mRootView->addChild(mProgressView);
+ mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
setShowProgress(FALSE);
- setProgressCancelButtonVisible(FALSE, "");
-}
+ setProgressCancelButtonVisible(FALSE);
+ gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
-void adjust_rect_top_left(const LLString& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setLeftTopAndSize(0, window.getHeight(), r.getWidth(), r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
-
-void adjust_rect_top_right(const LLString& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setLeftTopAndSize(window.getWidth() - r.getWidth(),
- window.getHeight(),
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
+ LLMenuGL::sMenuContainer = gMenuHolder;
-void adjust_rect_bottom_center(const LLString& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- // *TODO: Adjust based on XUI XML
- const S32 TOOLBAR_HEIGHT = 64;
- r.setOriginAndSize(
- window.getWidth()/2 - r.getWidth()/2,
- TOOLBAR_HEIGHT,
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect(control, r);
- }
}
-void adjust_rect_centered_partial_zoom(const LLString& control,
- const LLRect& window)
-{
- LLRect rect = gSavedSettings.getRect(control);
- // Only adjust on first use
- if (rect.mLeft == 0 && rect.mBottom == 0)
- {
- S32 width = window.getWidth();
- S32 height = window.getHeight();
- rect.set(0, height-STATUS_BAR_HEIGHT, width, TOOL_BAR_HEIGHT);
- // Make floater fill 80% of window, leaving 20% padding on
- // the sides.
- const F32 ZOOM_FRACTION = 0.8f;
- S32 dx = (S32)(width * (1.f - ZOOM_FRACTION));
- S32 dy = (S32)(height * (1.f - ZOOM_FRACTION));
- rect.stretch(-dx/2, -dy/2);
- gSavedSettings.setRect(control, rect);
- }
-}
-
-
-// Many rectangles can't be placed until we know the screen size.
-// These rectangles have their bottom-left corner as 0,0
-void LLViewerWindow::adjustRectanglesForFirstUse(const LLRect& window)
+void LLViewerWindow::initWorldUI()
{
- LLRect r;
-
- adjust_rect_bottom_center("FloaterMoveRect2", window);
-
- adjust_rect_bottom_center("FloaterCameraRect2", window);
+ S32 height = mRootView->getRect().getHeight();
+ S32 width = mRootView->getRect().getWidth();
+ LLRect full_window(0, height, width, 0);
- adjust_rect_top_left("FloaterCustomizeAppearanceRect", window);
- adjust_rect_top_left("FloaterLandRect5", window);
+ gIMMgr = LLIMMgr::getInstance();
- adjust_rect_top_left("FloaterHUDRect", window);
+ //getRootView()->sendChildToFront(gFloaterView);
+ //getRootView()->sendChildToFront(gSnapshotFloaterView);
- adjust_rect_top_left("FloaterFindRect2", window);
+ // new bottom panel
+ 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);
- adjust_rect_top_left("FloaterGestureRect2", window);
+ LLRect morph_view_rect = full_window;
+ morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
+ morph_view_rect.mTop = full_window.mTop - 32;
+ LLMorphView::Params mvp;
+ mvp.name("MorphView");
+ mvp.rect(morph_view_rect);
+ mvp.visible(false);
+ gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
+ getRootView()->addChild(gMorphView);
- adjust_rect_top_right("FloaterMiniMapRect", window);
+ LLWorldMapView::initClass();
- adjust_rect_top_right("FloaterLagMeter", window);
-
- adjust_rect_top_left("FloaterBuildOptionsRect", window);
+ // Force gFloaterWorldMap to initialize
+ LLFloaterReg::getInstance("world_map");
+
+ // Force gFloaterTools to initialize
+ LLFloaterReg::getInstance("build");
+ LLFloaterReg::hideInstance("build");
+
+ // Status bar
+ 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->setShape(nav_bar_container->getLocalRect());
+ navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
+ nav_bar_container->addChild(navbar);
+ nav_bar_container->setVisible(TRUE);
+
+ if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
+ {
+ navbar->showNavigationPanel(FALSE);
+ }
- // bottom-right
- r = gSavedSettings.getRect("FloaterInventoryRect");
- if (r.mLeft == 0 && r.mBottom == 0)
+ if (!gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"))
{
- r.setOriginAndSize(
- window.getWidth() - r.getWidth(),
- 0,
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect("FloaterInventoryRect", r);
+ navbar->showFavoritesPanel(FALSE);
}
-}
+ // Top Info bar
+ LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
+ LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance();
-void LLViewerWindow::initWorldUI()
-{
- pre_init_menus();
+ topinfo_bar->setShape(topinfo_bar_container->getLocalRect());
- S32 height = mRootView->getRect().getHeight();
- S32 width = mRootView->getRect().getWidth();
- LLRect full_window(0, height, width, 0);
+ topinfo_bar_container->addChild(topinfo_bar);
+ topinfo_bar_container->setVisible(TRUE);
- if ( gBottomPanel == NULL ) // Don't re-enter if objects are alreay created
+ if (!gSavedSettings.getBOOL("ShowMiniLocationPanel"))
{
- // panel containing chatbar, toolbar, and overlay, over floaters
- gBottomPanel = new LLBottomPanel(mRootView->getRect());
- mRootView->addChild(gBottomPanel);
-
- // View for hover information
- gHoverView = new LLHoverView("gHoverView", full_window);
- gHoverView->setVisible(TRUE);
- mRootView->addChild(gHoverView);
-
- //
- // Map
- //
- // TODO: Move instance management into class
- gFloaterMap = new LLFloaterMap("Map");
- gFloaterMap->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(gFloaterMap, FALSE);
-
- gIMMgr = LLIMMgr::getInstance();
+ topinfo_bar->setVisible(FALSE);
+ }
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ if ( gHUDView == NULL )
+ {
+ LLRect hud_rect = full_window;
+ hud_rect.mBottom += 50;
+ if (gMenuBarView)
{
- LLFloaterChat::getInstance(LLSD())->loadHistory();
+ hud_rect.mTop -= gMenuBarView->getRect().getHeight();
}
+ gHUDView = new LLHUDView(hud_rect);
+ // put behind everything else in the UI
+ getRootView()->addChildInBack(gHUDView);
+ }
- LLRect morph_view_rect = full_window;
- morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
- morph_view_rect.mTop = full_window.mTop - 32;
- gMorphView = new LLMorphView("gMorphView", morph_view_rect );
- mRootView->addChild(gMorphView);
- gMorphView->setVisible(FALSE);
-
- gFloaterMute = LLFloaterMute::getInstance();
-
- LLWorldMapView::initClass();
-
- adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window);
-
- gFloaterWorldMap = new LLFloaterWorldMap();
- gFloaterWorldMap->setVisible(FALSE);
-
- //
- // Tools for building
- //
-
- // Toolbox floater
- init_menus();
-
- gFloaterTools = new LLFloaterTools();
- gFloaterTools->setVisible(FALSE);
-
- // Status bar
- S32 menu_bar_height = gMenuBarView->getRect().getHeight();
- LLRect root_rect = gViewerWindow->getRootView()->getRect();
- LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height);
- gStatusBar = new LLStatusBar("status", 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());
- // sync bg color with menu bar
- gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() );
-
- LLFloaterChatterBox::createInstance(LLSD());
-
- gViewerWindow->getRootView()->addChild(gStatusBar);
+ 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);
- // menu holder appears on top to get first pass at all mouse events
- gViewerWindow->getRootView()->sendChildToFront(gMenuHolder);
- }
+ // 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);
}
-
-LLViewerWindow::~LLViewerWindow()
+// Destroy the UI
+void LLViewerWindow::shutdownViews()
{
+ // clean up warning logger
+ LLError::removeRecorder(RecordToChatConsole::getInstance());
+
delete mDebugText;
+ mDebugText = NULL;
- gSavedSettings.setS32("FloaterViewBottom", gFloaterView->getRect().mBottom);
-
// Cleanup global views
if (gMorphView)
{
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;
// Automatically deleted as children of mRootView. Fix the globals.
- gFloaterTools = NULL;
gStatusBar = NULL;
- gFloaterCamera = NULL;
gIMMgr = NULL;
- gHoverView = NULL;
-
- gFloaterView = NULL;
- gMorphView = NULL;
+ gToolTipView = NULL;
- gFloaterMute = NULL;
+ gFloaterView = NULL;
+ gMorphView = NULL;
- gFloaterMap = NULL;
gHUDView = NULL;
+}
- gNotifyBoxView = NULL;
-
- delete mToolTip;
- mToolTip = NULL;
-
- delete gResMgr;
- gResMgr = NULL;
-
+void LLViewerWindow::shutdownGL()
+{
//--------------------------------------------------------
// Shutdown GL cleanly. Order is very important here.
//--------------------------------------------------------
@@ -2007,7 +1741,9 @@ LLViewerWindow::~LLViewerWindow()
gSky.cleanup();
stop_glerror();
- gImageList.shutdown();
+ LLWearableList::instance().cleanup() ;
+
+ gTextureList.shutdown();
stop_glerror();
gBumpImageList.shutdown();
@@ -2019,16 +1755,13 @@ LLViewerWindow::~LLViewerWindow()
gPipeline.cleanup();
stop_glerror();
- LLViewerImage::cleanupClass();
-
- delete[] mPickBuffer;
- mPickBuffer = NULL;
+ LLViewerTextureManager::cleanup() ;
+ LLImageGL::cleanupClass() ;
- if (gSelectMgr)
- {
- llinfos << "Cleaning up select manager" << llendl;
- gSelectMgr->cleanup();
- }
+ llinfos << "All textures and llimagegl images are destroyed!" << llendl ;
+
+ llinfos << "Cleaning up select manager" << llendl;
+ LLSelectMgr::getInstance()->cleanup();
LLVertexBuffer::cleanupClass();
@@ -2039,9 +1772,17 @@ LLViewerWindow::~LLViewerWindow()
stop_glerror();
}
+ gGL.shutdown();
+}
+// shutdownViews() and shutdownGL() need to be called first
+LLViewerWindow::~LLViewerWindow()
+{
llinfos << "Destroying Window" << llendl;
destroyWindow();
+
+ delete mDebugText;
+ mDebugText = NULL;
}
@@ -2053,18 +1794,16 @@ void LLViewerWindow::setCursor( ECursorType c )
void LLViewerWindow::showCursor()
{
mWindow->showCursor();
+
+ mCursorHidden = FALSE;
}
void LLViewerWindow::hideCursor()
{
- // Hide tooltips
- if(mToolTip ) mToolTip->setVisible( FALSE );
-
- // Also hide hover info
- if (gHoverView) gHoverView->cancelHover();
-
// And hide the cursor
mWindow->hideCursor();
+
+ mCursorHidden = TRUE;
}
void LLViewerWindow::sendShapeToSim()
@@ -2078,8 +1817,8 @@ void LLViewerWindow::sendShapeToSim()
msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
msg->nextBlockFast(_PREHASH_HeightWidthBlock);
msg->addU32Fast(_PREHASH_GenCounter, 0);
- U16 height16 = (U16) mWindowRect.getHeight();
- U16 width16 = (U16) mWindowRect.getWidth();
+ U16 height16 = (U16) mWorldViewRectRaw.getHeight();
+ U16 width16 = (U16) mWorldViewRectRaw.getWidth();
msg->addU16Fast(_PREHASH_Height, height16);
msg->addU16Fast(_PREHASH_Width, width16);
gAgent.sendReliableMessage();
@@ -2100,35 +1839,28 @@ void LLViewerWindow::reshape(S32 width, S32 height)
return;
}
- glViewport(0, 0, width, height );
+ // update our window rectangle
+ mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width;
+ mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height;
+
+ //glViewport(0, 0, width, height );
- if (height > 0 && gCamera)
+ if (height > 0)
{
- gCamera->setViewHeightInPixels( height );
- if (mWindow->getFullscreen())
- {
- // force to 4:3 aspect for odd resolutions
- gCamera->setAspect( getDisplayAspectRatio() );
- }
- else
- {
- gCamera->setAspect( width / (F32) height);
- }
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
}
- // update our window rectangle
- mWindowRect.mRight = mWindowRect.mLeft + width;
- mWindowRect.mTop = mWindowRect.mBottom + height;
calcDisplayScale();
BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
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]);
- setupViewport();
+ setup2DViewport();
// Inform lower views of the change
// round up when converting coordinates to make sure there are no gaps at edge of window
@@ -2139,39 +1871,26 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// clear font width caches
if (display_scale_changed)
{
- LLHUDText::reshape();
+ LLHUDObject::reshapeAll();
}
sendShapeToSim();
-
- // store the mode the user wants (even if not there yet)
- gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
-
// store new settings for the mode we are in, regardless
- if (mWindow->getFullscreen())
- {
- gSavedSettings.setS32("FullScreenWidth", width);
- gSavedSettings.setS32("FullScreenHeight", height);
- }
- else
- {
- // Only save size if not maximized
- BOOL maximized = mWindow->getMaximized();
- gSavedSettings.setBOOL("WindowMaximized", maximized);
+ // Only save size if not maximized
+ BOOL maximized = mWindow->getMaximized();
+ gSavedSettings.setBOOL("WindowMaximized", maximized);
- LLCoordScreen window_size;
- if (!maximized
- && mWindow->getSize(&window_size))
- {
- gSavedSettings.setS32("WindowWidth", window_size.mX);
- gSavedSettings.setS32("WindowHeight", window_size.mY);
- }
+ LLCoordScreen window_size;
+ if (!maximized
+ && mWindow->getSize(&window_size))
+ {
+ gSavedSettings.setS32("WindowWidth", window_size.mX);
+ gSavedSettings.setS32("WindowHeight", window_size.mY);
}
- gViewerStats->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
- gViewerStats->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
- gResizeScreenTexture = TRUE;
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
}
}
@@ -2179,10 +1898,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// Hide normal UI when a logon fails
void LLViewerWindow::setNormalControlsVisible( BOOL visible )
{
- if ( gBottomPanel )
+ if(LLBottomTray::instanceExists())
{
- gBottomPanel->setVisible( visible );
- gBottomPanel->setEnabled( visible );
+ LLBottomTray::getInstance()->setVisible(visible);
+ LLBottomTray::getInstance()->setEnabled(visible);
}
if ( gMenuBarView )
@@ -2192,7 +1911,7 @@ void LLViewerWindow::setNormalControlsVisible( BOOL visible )
// ...and set the menu color appropriately.
setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT,
- LLAppViewer::instance()->isInProductionGrid());
+ LLGridManager::getInstance()->isInProductionGrid());
}
if ( gStatusBar )
@@ -2200,28 +1919,43 @@ void LLViewerWindow::setNormalControlsVisible( BOOL visible )
gStatusBar->setVisible( visible );
gStatusBar->setEnabled( visible );
}
+
+ LLNavigationBar* navbarp = LLUI::getRootView()->findChild<LLNavigationBar>("navigation_bar");
+ if (navbarp)
+ {
+ navbarp->setVisible( visible );
+ }
}
void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
{
- LLString::format_map_t args;
+ LLSD args;
LLColor4 new_bg_color;
- if(god_mode && LLAppViewer::instance()->isInProductionGrid())
+ // no l10n problem because channel is always an english string
+ std::string channel = LLVersionInfo::getChannel();
+ bool isProject = (channel.find("Project") != std::string::npos);
+
+ // god more important than project, proj more important than grid
+ if(god_mode && LLGridManager::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuBarGodBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
}
- else if(god_mode && !LLAppViewer::instance()->isInProductionGrid())
+ else if(god_mode && !LLGridManager::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuNonProductionGodBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
}
- else if(!god_mode && !LLAppViewer::instance()->isInProductionGrid())
+ else if (!god_mode && isProject)
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" );
+ }
+ else if(!god_mode && !LLGridManager::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuNonProductionBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
else
{
- new_bg_color = gColors.getColor( "MenuBarBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
if(gMenuBarView)
@@ -2237,32 +1971,29 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
void LLViewerWindow::drawDebugText()
{
- gGL.start();
+ 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.stop();
+
+ gGL.flush();
}
void LLViewerWindow::draw()
{
-#if LL_DEBUG
+//#if LL_DEBUG
LLView::sIsDrawing = TRUE;
-#endif
+//#endif
stop_glerror();
LLUI::setLineWidth(1.f);
- //popup alerts from the UI
- LLAlertInfo alert;
- while (LLPanel::nextAlert(alert))
- {
- alertXml(alert.mLabel, alert.mArgs);
- }
LLUI::setLineWidth(1.f);
// Reset any left-over transforms
@@ -2272,19 +2003,24 @@ void LLViewerWindow::draw()
//S32 screen_x, screen_y;
+ if (!gSavedSettings.getBOOL("RenderUIBuffer"))
+ {
+ LLUI::sDirtyRect = getWindowRectScaled();
+ }
+
// HACK for timecode debugging
if (gSavedSettings.getBOOL("DisplayTimecode"))
{
// draw timecode block
- char text[256]; /* Flawfinder: ignore */
+ std::string text;
glLoadIdentity();
microsecondsToTimecodeString(gFrameTime,text);
- const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
+ 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);
}
@@ -2293,37 +2029,33 @@ 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;
- if (gCamera)
+ // apply camera zoom transform (for high res screenshots)
+ F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
+ S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
+ if (zoom_factor > 1.f)
{
- // apply camera zoom transform (for high res screenshots)
- F32 zoom_factor = gCamera->getZoomFactor();
- S16 sub_region = gCamera->getZoomSubRegion();
- if (zoom_factor > 1.f)
- {
- //decompose subregion number to x and y values
- int pos_y = sub_region / llceil(zoom_factor);
- int pos_x = sub_region - (pos_y*llceil(zoom_factor));
- // offset for this tile
- glTranslatef((F32)gViewerWindow->getWindowWidth() * -(F32)pos_x,
- (F32)gViewerWindow->getWindowHeight() * -(F32)pos_y,
- 0.f);
- glScalef(zoom_factor, zoom_factor, 1.f);
- LLUI::sGLScaleFactor *= zoom_factor;
- }
+ //decompose subregion number to x and y values
+ int pos_y = sub_region / llceil(zoom_factor);
+ int pos_x = sub_region - (pos_y*llceil(zoom_factor));
+ // offset for this tile
+ glTranslatef((F32)getWindowWidthScaled() * -(F32)pos_x,
+ (F32)getWindowHeightScaled() * -(F32)pos_y,
+ 0.f);
+ glScalef(zoom_factor, zoom_factor, 1.f);
+ LLUI::sGLScaleFactor *= zoom_factor;
}
- if (gToolMgr)
- {
- // Draw tool specific overlay on world
- gToolMgr->getCurrentTool()->draw();
- }
+ // Draw tool specific overlay on world
+ LLToolMgr::getInstance()->getCurrentTool()->draw();
- if( gAgent.cameraMouselook() )
+ if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() )
{
drawMouselookInstructions();
stop_glerror();
@@ -2333,6 +2065,11 @@ void LLViewerWindow::draw()
// No translation needed, this view is glued to 0,0
mRootView->draw();
+ if (LLView::sDebugRects)
+ {
+ gToolTipView->drawStickyRect();
+ }
+
// Draw optional on-top-of-everyone view
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
if (top_ctrl && top_ctrl->getVisible())
@@ -2347,192 +2084,134 @@ void LLViewerWindow::draw()
LLUI::popMatrix();
}
- // Draw tooltips
- // Adjust their rectangle so they don't go off the top or bottom
- // of the screen.
- if( mToolTip && mToolTip->getVisible() )
- {
- glMatrixMode(GL_MODELVIEW);
- LLUI::pushMatrix();
- {
- S32 tip_height = mToolTip->getRect().getHeight();
-
- S32 screen_x, screen_y;
- mToolTip->localPointToScreen(0, -24 - tip_height,
- &screen_x, &screen_y);
-
- // If tooltip would draw off the bottom of the screen,
- // show it from the cursor tip position.
- if (screen_y < tip_height)
- {
- mToolTip->localPointToScreen(0, 0, &screen_x, &screen_y);
- }
- LLUI::translate( (F32) screen_x, (F32) screen_y, 0);
- mToolTip->draw();
- }
- LLUI::popMatrix();
- }
if( gShowOverlayTitle && !mOverlayTitle.empty() )
{
// Used for special titles such as "Second Life - Special E3 2003 Beta"
const S32 DIST_FROM_TOP = 20;
- LLFontGL::sSansSerifBig->renderUTF8(
+ LLFontGL::getFontSansSerifBig()->renderUTF8(
mOverlayTitle, 0,
- llround( gViewerWindow->getWindowWidth() * 0.5f),
- gViewerWindow->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
+//#endif
}
// Takes a single keydown event, usually when UI is visible
BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
{
- if (gFocusMgr.getKeyboardFocus() && !(mask & (MASK_CONTROL | MASK_ALT)))
+ // hide tooltips on keypress
+ LLToolTipMgr::instance().blockToolTips();
+
+ if (gFocusMgr.getKeyboardFocus()
+ && !(mask & (MASK_CONTROL | MASK_ALT))
+ && !gFocusMgr.getKeystrokesOnly())
{
// We have keyboard focus, and it's not an accelerator
-
if (key < 0x80)
{
// Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
- return gFocusMgr.childHasKeyboardFocus(mRootView);
+ return (gFocusMgr.getKeyboardFocus() != NULL);
}
}
- // HACK look for UI editing keys
- if (LLView::sEditingUI)
+ // let menus handle navigation keys for navigation
+ if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
+ ||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
+ ||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
{
- if (LLFloaterEditUI::handleKey(key, mask))
- {
- return TRUE;
- }
- }
-
- // Hide tooltips on keypress
- if(mToolTip )
- {
- mToolTipBlocked = TRUE; // block until next time mouse is moved
- mToolTip->setVisible( FALSE );
- }
-
- // Also hide hover info on keypress
- if (gHoverView)
- {
- gHoverView->cancelHover();
-
- gHoverView->setTyping(TRUE);
+ return TRUE;
}
- // Explicit hack for debug menu.
- if ((MASK_ALT & mask) &&
- (MASK_CONTROL & mask) &&
- ('D' == key || 'd' == key))
- {
- toggle_debug_menus(NULL);
- }
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
- // Explicit hack for debug menu.
- if ((mask == (MASK_SHIFT | MASK_CONTROL)) &&
- ('G' == key || 'g' == key))
+ // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus
+ // as long as focus isn't locked
+ if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked())
{
- if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
+ // Check the current floater's menu first, if it has one.
+ if (gFocusMgr.keyboardFocusHasAccelerators()
+ && keyboard_focus
+ && keyboard_focus->handleKey(key,mask,FALSE))
{
- BOOL visible = ! gSavedSettings.getBOOL("ForceShowGrid");
- gSavedSettings.setBOOL("ForceShowGrid", visible);
+ return TRUE;
+ }
- // Initialize visibility (and don't force visibility - use prefs)
- LLPanelLogin::refreshLocation( false );
+ if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
+ ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
+ {
+ return TRUE;
}
}
- // Example "bug" for bug reporter web page
- if ((MASK_SHIFT & mask)
- && (MASK_ALT & mask)
- && (MASK_CONTROL & mask)
- && ('H' == key || 'h' == key))
+ // give floaters first chance to handle TAB key
+ // so frontmost floater gets focus
+ // if nothing has focus, go to first or last UI element as appropriate
+ if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL))
{
- trigger_hippo_bug(NULL);
- }
+ if (gMenuHolder) gMenuHolder->hideMenus();
- // handle escape key
- if (key == KEY_ESCAPE && mask == MASK_NONE)
- {
- if (gMenuHolder && gMenuHolder->hideMenus())
+ // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
+ gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0);
+
+ // do CTRL-TAB and CTRL-SHIFT-TAB logic
+ if (mask & MASK_SHIFT)
{
- return TRUE;
+ mRootView->focusPrevRoot();
}
-
- //if quit from menu, turn off the Keyboardmode for the menu.
- if(LLMenuGL::getKeyboardMode())
- LLMenuGL::setKeyboardMode(FALSE);
-
- if (gFocusMgr.getTopCtrl())
+ else
{
- gFocusMgr.setTopCtrl(NULL);
- return TRUE;
+ mRootView->focusNextRoot();
}
-
- // *TODO: get this to play well with mouselook and hidden
- // cursor modes, etc, and re-enable.
- //if (gFocusMgr.getMouseCapture())
- //{
- // gFocusMgr.setMouseCapture(NULL);
- // return TRUE;
- //}
- }
-
- // let menus handle navigation keys
- if (gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
- {
return TRUE;
}
- // let menus handle navigation keys
- if (gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
+ // hidden edit menu for cut/copy/paste
+ if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
{
return TRUE;
}
// Traverses up the hierarchy
- LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
+ LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL;
// arrow keys move avatar while chatting hack
- if (gChatBar && gChatBar->inputEditorHasFocus())
+ if (chat_editor && chat_editor->hasFocus())
{
- if (gChatBar->getCurrentChat().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;
}
}
}
@@ -2543,16 +2222,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
}
- if (gToolMgr)
+ if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
{
- if( gToolMgr->getCurrentTool()->handleKey(key, mask) )
- {
- return TRUE;
- }
+ return TRUE;
}
// Try for a new-format gesture
- if (gGestureManager.triggerGesture(key, mask))
+ if (LLGestureMgr::instance().triggerGesture(key, mask))
{
return TRUE;
}
@@ -2564,50 +2240,10 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
return TRUE;
}
- // Topmost view gets a chance before the hierarchy
- // *FIX: get rid of this?
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- if (top_ctrl)
- {
- if( top_ctrl->handleKey( key, mask, TRUE ) )
- {
- return TRUE;
- }
- }
-
- // give floaters first chance to handle TAB key
- // so frontmost floater gets focus
- if (key == KEY_TAB)
- {
- // if nothing has focus, go to first or last UI element as appropriate
- if (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL)
- {
- if (gMenuHolder) gMenuHolder->hideMenus();
-
- // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
- gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0);
- // do CTRL-TAB and CTRL-SHIFT-TAB logic
- if (mask & MASK_SHIFT)
- {
- mRootView->focusPrevRoot();
- }
- else
- {
- mRootView->focusNextRoot();
- }
- return TRUE;
- }
- }
-
- // give menus a chance to handle keys
- if (gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
- {
- return TRUE;
- }
-
- // give menus a chance to handle keys
- if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
+ // give menus a chance to handle unmodified accelerator keys
+ if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
+ ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
{
return TRUE;
}
@@ -2639,7 +2275,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
}
// Traverses up the hierarchy
- LLView* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
if (keyboard_focus->handleUnicodeChar(uni_char, FALSE))
@@ -2647,12 +2283,12 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
return TRUE;
}
- // Topmost view gets a chance before the hierarchy
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- if (top_ctrl && top_ctrl->handleUnicodeChar( uni_char, FALSE ) )
- {
- return TRUE;
- }
+ //// Topmost view gets a chance before the hierarchy
+ //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ //if (top_ctrl && top_ctrl->handleUnicodeChar( uni_char, FALSE ) )
+ //{
+ // return TRUE;
+ //}
return TRUE;
}
@@ -2663,16 +2299,10 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
void LLViewerWindow::handleScrollWheel(S32 clicks)
{
- LLView::sMouseHandlerMessage = "";
-
- gMouseIdleTimer.reset();
-
- // Hide tooltips
- if( mToolTip )
- {
- mToolTip->setVisible( FALSE );
- }
+ LLView::sMouseHandlerMessage.clear();
+ LLUI::resetMouseIdleTimer();
+
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
if( mouse_captor )
{
@@ -2709,384 +2339,639 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
llinfos << "Scroll Wheel not handled by view" << llendl;
}
- if (gWorldPointer)
+ // Zoom the camera in and out behavior
+
+ if(top_ctrl == 0
+ && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY)
+ && gAgentCamera.isInitialized())
+ gAgentCamera.handleScrollWheel(clicks);
+
+ return;
+}
+
+void LLViewerWindow::addPopup(LLView* popup)
+{
+ if (mPopupView)
{
- // Zoom the camera in and out behavior
- gAgent.handleScrollWheel(clicks);
+ mPopupView->addPopup(popup);
}
+}
- return;
+void LLViewerWindow::removePopup(LLView* popup)
+{
+ if (mPopupView)
+ {
+ mPopupView->removePopup(popup);
+ }
+}
+
+void LLViewerWindow::clearPopups()
+{
+ if (mPopupView)
+ {
+ mPopupView->clearPopups();
+ }
}
void LLViewerWindow::moveCursorToCenter()
{
- S32 x = mVirtualWindowRect.getWidth() / 2;
- S32 y = mVirtualWindowRect.getHeight() / 2;
+ 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);
+ //on a forced move, all deltas get zeroed out to prevent jumping
+ mCurrentMousePoint.set(x,y);
+ mLastMousePoint.set(x,y);
+ mCurrentMouseDelta.set(0,0);
- LLUI::setCursorPositionScreen(x, y);
+ LLUI::setMousePositionScreen(x, y);
+ }
}
+
//////////////////////////////////////////////////////////////////////
//
// Hover handlers
//
+void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
+{
+ if (viewp)
+ {
+ if (!params.styled_message.empty())
+ {
+ 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
+ for (LLView::root_to_view_iterator_t tooltip_it = ++viewp->beginRootToView();
+ tooltip_it != end_tooltip_it;
+ ++tooltip_it)
+ {
+ LLView* viewp = *tooltip_it;
+
+ params.styled_message.add().text(viewp->getName());
+
+ LLPanel* panelp = dynamic_cast<LLPanel*>(viewp);
+ if (panelp && !panelp->getXMLFilename().empty())
+ {
+ params.styled_message.add()
+ .text("(" + panelp->getXMLFilename() + ")")
+ .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f));
+ }
+ params.styled_message.add().text("/");
+ }
+ }
+}
+
// Update UI based on stored mouse position from mouse-move
// event processing.
-BOOL LLViewerWindow::handlePerFrameHover()
+void LLViewerWindow::updateUI()
{
- static std::string last_handle_msg;
+ static LLFastTimer::DeclareTimer ftm("Update UI");
+ LLFastTimer t(ftm);
- LLView::sMouseHandlerMessage = "";
+ static std::string last_handle_msg;
- //RN: fix for asynchronous notification of mouse leaving window not working
- LLCoordWindow mouse_pos;
- mWindow->getCursorPosition(&mouse_pos);
- if (mouse_pos.mX < 0 ||
- mouse_pos.mY < 0 ||
- mouse_pos.mX > mWindowRect.getWidth() ||
- mouse_pos.mY > mWindowRect.getHeight())
- {
- mMouseInWindow = FALSE;
- }
- else
+ if (gLoggedInTime.getStarted())
{
- mMouseInWindow = TRUE;
+ if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout"))
+ {
+ LLFirstUse::notUsingDestinationGuide();
+ }
+ if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
+ {
+ LLFirstUse::notUsingSidePanel();
+ }
}
- S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
- S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+ LLConsole::updateClass();
- LLVector2 mouse_vel;
+ // animate layout stacks so we have up to date rect for world view
+ LLLayoutStack::updateClass();
- if (gSavedSettings.getBOOL("MouseSmooth"))
- {
- static F32 fdx = 0.f;
- static F32 fdy = 0.f;
+ // use full window for world view when not rendering UI
+ bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ updateWorldViewRect(world_view_uses_full_window);
- F32 amount = 16.f;
- fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
- fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
+ LLView::sMouseHandlerMessage.clear();
- mCurrentMouseDelta.set(llround(fdx), llround(fdy));
- mouse_vel.setVec(fdx,fdy);
- }
- else
+ S32 x = mCurrentMousePoint.mX;
+ S32 y = mCurrentMousePoint.mY;
+ MASK mask = gKeyboard->currentMask(TRUE);
+
+ if (gNoRender)
{
- mCurrentMouseDelta.set(dx, dy);
- mouse_vel.setVec((F32) dx, (F32) dy);
+ return;
}
-
- mMouseVelocityStat.addValue(mouse_vel.magVec());
- if (gNoRender)
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
{
- return TRUE;
+ gDebugRaycastFaceHit = -1;
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+ &gDebugRaycastFaceHit,
+ &gDebugRaycastIntersection,
+ &gDebugRaycastTexCoord,
+ &gDebugRaycastNormal,
+ &gDebugRaycastBinormal);
}
- S32 x = mCurrentMousePoint.mX;
- S32 y = mCurrentMousePoint.mY;
- MASK mask = gKeyboard->currentMask(TRUE);
+ updateMouseDelta();
+ updateKeyboardFocus();
- // clean up current focus
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
- if (cur_focus)
+ BOOL handled = FALSE;
+
+ 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;
+
+ // 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)
{
- if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
+ root_view = mRootView;
+ }
+
+ // only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // include all ancestors of captor_view as automatically having mouse
+ if (captor_view)
{
- gFocusMgr.releaseFocusIfNeeded(cur_focus);
+ 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();
+ }
+ }
- LLUICtrl* parent = cur_focus->getParentUICtrl();
- const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
- while(parent)
+ // 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))
{
- if (parent->isCtrl() &&
- (parent->hasTabStop() || parent == focus_root) &&
- !parent->getIsChrome() &&
- parent->isInVisibleChain() &&
- parent->isInEnabledChain())
+ // iterator over contents of top_ctrl, and throw into mouse_hover_set
+ for (LLView::tree_iterator_t it = popup->beginTreeDFS();
+ it != popup->endTreeDFS();
+ ++it)
{
- if (!parent->focusFirstItem())
+ LLView* viewp = *it;
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
{
- parent->setFocus(TRUE);
+ // 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();
}
- break;
}
- parent = parent->getParentUICtrl();
}
}
- else if (cur_focus->isFocusRoot())
+
+ // 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))
{
- // focus roots keep trying to delegate focus to their first valid descendant
- // this assumes that focus roots are not valid focus holders on their own
- cur_focus->focusFirstItem();
+ // iterator over contents of top_ctrl, and throw into mouse_hover_set
+ for (LLView::tree_iterator_t it = top_ctrl->beginTreeDFS();
+ it != top_ctrl->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();
+ }
+ }
}
- }
+ else
+ {
+ // walk UI tree in depth-first order
+ for (LLView::tree_iterator_t it = root_view->beginTreeDFS();
+ it != root_view->endTreeDFS();
+ ++it)
+ {
+ LLView* viewp = *it;
+ // calculating the screen rect involves traversing the parent, so this is less than optimal
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
+ {
- gPipeline.sRenderProcessBeacons = FALSE;
- KEY key = gKeyboard->currentKey();
- if (((mask & MASK_CONTROL) && ('N' == key || 'n' == key)) || gSavedSettings.getBOOL("BeaconAlwaysOn"))
- {
- gPipeline.sRenderProcessBeacons = TRUE;
+ // if this view is mouse opaque, nothing behind it should be in mouse_hover_set
+ if (viewp->getMouseOpaque())
+ {
+ // constrain further iteration to children of this widget
+ it = viewp->beginTreeDFS();
+ }
+
+ // 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();
+ }
+ }
+ }
}
- BOOL handled = FALSE;
-
- BOOL handled_by_top_ctrl = FALSE;
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ typedef std::vector<LLHandle<LLView> > view_handle_list_t;
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
+ // call onMouseEnter() on all views which contain the mouse cursor but did not before
+ view_handle_list_t mouse_enter_views;
+ std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(),
+ mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ std::back_inserter(mouse_enter_views));
+ for (view_handle_list_t::iterator it = mouse_enter_views.begin();
+ it != mouse_enter_views.end();
+ ++it)
{
- // Pass hover events to object capturing mouse events.
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- handled = mouse_captor->handleHover(local_x, local_y, mask);
- if (LLView::sDebugMouseHandling)
+ LLView* viewp = it->get();
+ if (viewp)
{
- llinfos << "Hover handled by captor " << mouse_captor->getName() << llendl;
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
}
+ }
- if( !handled )
+ // call onMouseLeave() on all views which no longer contain the mouse cursor
+ view_handle_list_t mouse_leave_views;
+ std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ mouse_hover_set.begin(), mouse_hover_set.end(),
+ std::back_inserter(mouse_leave_views));
+ for (view_handle_list_t::iterator it = mouse_leave_views.begin();
+ it != mouse_leave_views.end();
+ ++it)
+ {
+ LLView* viewp = it->get();
+ if (viewp)
{
- lldebugst(LLERR_USER_INPUT) << "hover not handled by mouse captor" << llendl;
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
}
}
- else
- {
- if (top_ctrl)
+
+ // store resulting hover set for next frame
+ swap(mMouseHoverViews, mouse_hover_set);
+
+ // only handle hover events when UI is enabled
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+
+ if( mouse_captor )
{
- S32 local_x, local_y;
- top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
- handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
- handled_by_top_ctrl = TRUE;
- }
+ // Pass hover events to object capturing mouse events.
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
+ handled = mouse_captor->handleHover(local_x, local_y, mask);
+ if (LLView::sDebugMouseHandling)
+ {
+ llinfos << "Hover handled by captor " << mouse_captor->getName() << llendl;
+ }
- if ( !handled )
+ if( !handled )
+ {
+ lldebugst(LLERR_USER_INPUT) << "hover not handled by mouse captor" << llendl;
+ }
+ }
+ else
{
- // x and y are from last time mouse was in window
- // mMouseInWindow tracks *actual* mouse location
- if (mMouseInWindow && mRootView->handleHover(x, y, mask) )
+ if (top_ctrl)
{
- if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg)
+ S32 local_x, local_y;
+ top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
+ handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
+ handled_by_top_ctrl = TRUE;
+ }
+
+ if ( !handled )
+ {
+ // x and y are from last time mouse was in window
+ // mMouseInWindow tracks *actual* mouse location
+ if (mMouseInWindow && mRootView->handleHover(x, y, mask) )
+ {
+ if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg)
+ {
+ last_handle_msg = LLView::sMouseHandlerMessage;
+ llinfos << "Hover" << LLView::sMouseHandlerMessage << llendl;
+ }
+ handled = TRUE;
+ }
+ else if (LLView::sDebugMouseHandling)
{
- last_handle_msg = LLView::sMouseHandlerMessage;
- llinfos << "Hover" << LLView::sMouseHandlerMessage << llendl;
+ if (last_handle_msg != LLStringUtil::null)
+ {
+ last_handle_msg.clear();
+ llinfos << "Hover not handled by view" << llendl;
+ }
}
- handled = TRUE;
}
- else if (LLView::sDebugMouseHandling)
+
+ if (!handled)
{
- if (last_handle_msg != "")
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ if(mMouseInWindow && tool)
{
- last_handle_msg = "";
- llinfos << "Hover not handled by view" << llendl;
+ handled = tool->handleHover(x, y, mask);
}
}
}
- if( !handled )
+ // Show a new tool tip (or update one that is already shown)
+ BOOL tool_tip_handled = FALSE;
+ std::string tool_tip_msg;
+ if( handled
+ && !mWindow->isCursorHidden())
{
- lldebugst(LLERR_USER_INPUT) << "hover not handled by top view or root" << llendl;
- }
- }
+ LLRect screen_sticky_rect = mRootView->getLocalRect();
+ S32 local_x, local_y;
- // *NOTE: sometimes tools handle the mouse as a captor, so this
- // logic is a little confusing
- LLTool *tool = NULL;
- if (gToolMgr && gHoverView && gCamera)
- {
- tool = gToolMgr->getCurrentTool();
+ if (gSavedSettings.getBOOL("DebugShowXUINames"))
+ {
+ LLToolTip::Params params;
- if(!handled && tool)
- {
- handled = tool->handleHover(x, y, mask);
+ LLView* tooltip_view = mRootView;
+ LLView::tree_iterator_t end_it = mRootView->endTreeDFS();
+ for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it)
+ {
+ LLView* viewp = *it;
+ LLRect screen_rect;
+ viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect);
+ if (!(viewp->getVisible()
+ && screen_rect.pointInRect(x, y)))
+ {
+ it.skipDescendants();
+ }
+ // only report xui names for LLUICtrls,
+ // and blacklist the various containers we don't care about
+ else if (dynamic_cast<LLUICtrl*>(viewp)
+ && viewp != gMenuHolder
+ && viewp != gFloaterView
+ && viewp != gConsole)
+ {
+ if (dynamic_cast<LLFloater*>(viewp))
+ {
+ // constrain search to descendants of this (frontmost) floater
+ // by resetting iterator
+ it = viewp->beginTreeDFS();
+ }
+
+ // if we are in a new part of the tree (not a descendent of current tooltip_view)
+ // then push the results for tooltip_view and start with a new potential view
+ // NOTE: this emulates visiting only the leaf nodes that meet our criteria
+ if (!viewp->hasAncestor(tooltip_view))
+ {
+ append_xui_tooltip(tooltip_view, params);
+ screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
+ }
+ tooltip_view = viewp;
+ }
+ }
+
+ append_xui_tooltip(tooltip_view, params);
+ screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
+
+ params.sticky_rect = screen_sticky_rect;
+ params.max_width = 400;
- if (!mWindow->isCursorHidden())
+ LLToolTipMgr::instance().show(params);
+ }
+ // if there is a mouse captor, nothing else gets a tooltip
+ else if (mouse_captor)
{
- gHoverView->updateHover(tool);
+ mouse_captor->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = mouse_captor->handleToolTip(local_x, local_y, mask);
}
- }
- else
+ else
+ {
+ // next is top_ctrl
+ if (!tool_tip_handled && top_ctrl)
+ {
+ top_ctrl->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = top_ctrl->handleToolTip(local_x, local_y, mask );
+ }
+
+ if (!tool_tip_handled)
+ {
+ local_x = x; local_y = y;
+ tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask );
+ }
+
+ LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (!tool_tip_handled && current_tool)
+ {
+ current_tool->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = current_tool->handleToolTip(local_x, local_y, mask );
+ }
+ }
+ }
+ }
+ else
+ { // just have tools handle hover when UI is turned off
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ if(mMouseInWindow && tool)
{
- // Cancel hovering if any UI element handled the event.
- gHoverView->cancelHover();
+ handled = tool->handleHover(x, y, mask);
}
+ }
- // Suppress the toolbox view if our source tool was the pie tool,
- // and we've overridden to something else.
- mSuppressToolbox =
- (gToolMgr->getBaseTool() == gToolPie) &&
- (gToolMgr->getCurrentTool() != gToolPie);
+ updateLayout();
- }
+ mLastMousePoint = mCurrentMousePoint;
- //llinfos << (mToolTipBlocked ? "BLOCKED" : "NOT BLOCKED") << llendl;
- // Show a new tool tip (or update one that is alrady shown)
- BOOL tool_tip_handled = FALSE;
- LLString tool_tip_msg;
- F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" );
- //HACK: hack for tool-based tooltips which need to pop up more quickly
- //Also for show xui names as tooltips debug mode
- if ((mouse_captor && !mouse_captor->isView()) || LLUI::sShowXUINames)
+ // cleanup unused selections when no modal dialogs are open
+ if (LLModalDialog::activeCount() == 0)
{
- tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" );
+ LLViewerParcelMgr::getInstance()->deselectUnused();
}
- if( handled &&
- !mToolTipBlocked &&
- (gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay) &&
- !mWindow->isCursorHidden() )
+
+ if (LLModalDialog::activeCount() == 0)
{
- LLRect screen_sticky_rect;
+ LLSelectMgr::getInstance()->deselectUnused();
+ }
+}
- if (mouse_captor)
- {
- S32 local_x, local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- tool_tip_handled = mouse_captor->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
- }
- else if (handled_by_top_ctrl)
- {
- S32 local_x, local_y;
- top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
- tool_tip_handled = top_ctrl->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
- }
- else
- {
- tool_tip_handled = mRootView->handleToolTip(x, y, tool_tip_msg, &screen_sticky_rect );
- }
- if( tool_tip_handled && !tool_tip_msg.empty() )
- {
- mToolTipStickyRect = screen_sticky_rect;
- mToolTip->setWrappedText( tool_tip_msg, 200 );
- mToolTip->reshapeToFitText();
- mToolTip->setOrigin( x, y );
- LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
- mToolTip->translateIntoRect( virtual_window_rect, FALSE );
- mToolTip->setVisible( TRUE );
- }
- }
-
- if (tool && tool != gToolNull && tool != gToolInspect && tool != gToolDragAndDrop && !gSavedSettings.getBOOL("FreezeTime"))
+void LLViewerWindow::updateLayout()
+{
+ LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (gFloaterTools != NULL
+ && tool != NULL
+ && tool != gToolNull
+ && tool != LLToolCompInspect::getInstance()
+ && tool != LLToolDragAndDrop::getInstance()
+ && !gSavedSettings.getBOOL("FreezeTime"))
{
+ // Suppress the toolbox view if our source tool was the pie tool,
+ // and we've overridden to something else.
+ bool suppress_toolbox =
+ (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) &&
+ (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance());
+
LLMouseHandler *captor = gFocusMgr.getMouseCapture();
// With the null, inspect, or drag and drop tool, don't muck
// with visibility.
- if (gFloaterTools->isMinimized() ||
- (tool != gToolPie // not default tool
- && tool != gToolGun // not coming out of mouselook
- && !mSuppressToolbox // not override in third person
- && gToolMgr->getCurrentToolset() != gFaceEditToolset // not special mode
- && gToolMgr->getCurrentToolset() != gMouselookToolset
- && (!captor || captor->isView())) // not dragging
- )
+ if (gFloaterTools->isMinimized()
+ || (tool != LLToolPie::getInstance() // not default tool
+ && tool != LLToolCompGun::getInstance() // not coming out of mouselook
+ && !suppress_toolbox // not override in third person
+ && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset // not special mode
+ && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset
+ && (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging
{
// Force floater tools to be visible (unless minimized)
if (!gFloaterTools->getVisible())
{
- gFloaterTools->open(); /* Flawfinder: ignore */
+ gFloaterTools->openFloater();
}
// Update the location of the blue box tool popup
LLCoordGL select_center_screen;
- gFloaterTools->updatePopup( select_center_screen, mask );
+ gFloaterTools->updatePopup( select_center_screen, gKeyboard->currentMask(TRUE) );
}
else
{
gFloaterTools->setVisible(FALSE);
}
- // In the future we may wish to hide the tools menu unless you
- // are building. JC
- //gMenuBarView->setItemVisible("Tools", gFloaterTools->getVisible());
- //gMenuBarView->arrange();
+ //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
}
- if (gToolBar)
+
+ // Always update console
+ if(gConsole)
{
- gToolBar->refresh();
+ LLRect console_rect = getChatConsoleRect();
+ gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
+ gConsole->setRect(console_rect);
}
+}
+
+void LLViewerWindow::updateMouseDelta()
+{
+ S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
+ S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
- if (gChatBar)
+ //RN: fix for asynchronous notification of mouse leaving window not working
+ LLCoordWindow mouse_pos;
+ mWindow->getCursorPosition(&mouse_pos);
+ if (mouse_pos.mX < 0 ||
+ mouse_pos.mY < 0 ||
+ mouse_pos.mX > mWindowRectRaw.getWidth() ||
+ mouse_pos.mY > mWindowRectRaw.getHeight())
{
- gChatBar->refresh();
+ mMouseInWindow = FALSE;
}
-
- if (gOverlayBar)
+ else
{
- gOverlayBar->refresh();
+ mMouseInWindow = TRUE;
}
- // Update rectangles for the various toolbars
- if (gOverlayBar && gNotifyBoxView && gConsole && gToolBar)
+ LLVector2 mouse_vel;
+
+ if (gSavedSettings.getBOOL("MouseSmooth"))
{
- LLRect bar_rect(-1, STATUS_BAR_HEIGHT, getWindowWidth()+1, -1);
+ static F32 fdx = 0.f;
+ static F32 fdy = 0.f;
- LLRect notify_box_rect = gNotifyBoxView->getRect();
- notify_box_rect.mBottom = bar_rect.mBottom;
- gNotifyBoxView->reshape(notify_box_rect.getWidth(), notify_box_rect.getHeight());
- gNotifyBoxView->setRect(notify_box_rect);
+ F32 amount = 16.f;
+ fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
+ fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
- // make sure floaters snap to visible rect by adjusting floater view rect
- LLRect floater_rect = gFloaterView->getRect();
- if (floater_rect.mBottom != bar_rect.mBottom+1)
- {
- floater_rect.mBottom = bar_rect.mBottom+1;
- // Don't bounce the floaters up and down.
- gFloaterView->reshape(floater_rect.getWidth(), floater_rect.getHeight(),
- TRUE, ADJUST_VERTICAL_NO);
- gFloaterView->setRect(floater_rect);
- }
+ mCurrentMouseDelta.set(llround(fdx), llround(fdy));
+ mouse_vel.setVec(fdx,fdy);
+ }
+ else
+ {
+ mCurrentMouseDelta.set(dx, dy);
+ mouse_vel.setVec((F32) dx, (F32) dy);
+ }
+
+ mMouseVelocityStat.addValue(mouse_vel.magVec());
+}
- // snap floaters to top of chat bar/button strip
- LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE);
- // find top of chatbar and strate buttons, if either are visible
- if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull())
- {
- // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates
- S32 top, left;
- chatbar_and_buttons->localPointToOtherView(
- chatbar_and_buttons->getLocalBoundingRect().mLeft,
- chatbar_and_buttons->getLocalBoundingRect().mTop,
- &left,
- &top,
- gFloaterView);
- gFloaterView->setSnapOffsetBottom(top);
- }
- else if (gToolBar->getVisible())
+void LLViewerWindow::updateKeyboardFocus()
+{
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ gFocusMgr.setKeyboardFocus(NULL);
+ }
+
+ // clean up current focus
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus)
+ {
+ if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
{
- S32 top, left;
- gToolBar->localPointToOtherView(
- gToolBar->getLocalBoundingRect().mLeft,
- gToolBar->getLocalBoundingRect().mTop,
- &left,
- &top,
- gFloaterView);
- gFloaterView->setSnapOffsetBottom(top);
+ // don't release focus, just reassign so that if being given
+ // to a sibling won't call onFocusLost on all the ancestors
+ // gFocusMgr.releaseFocusIfNeeded(cur_focus);
+
+ LLUICtrl* parent = cur_focus->getParentUICtrl();
+ const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
+ while(parent)
+ {
+ if (parent->isCtrl() &&
+ (parent->hasTabStop() || parent == focus_root) &&
+ !parent->getIsChrome() &&
+ parent->isInVisibleChain() &&
+ parent->isInEnabledChain())
+ {
+ if (!parent->focusFirstItem())
+ {
+ parent->setFocus(TRUE);
+ }
+ break;
+ }
+ parent = parent->getParentUICtrl();
+ }
+
+ // if we didn't find a better place to put focus, just release it
+ // hasFocus() will return true if and only if we didn't touch focus since we
+ // are only moving focus higher in the hierarchy
+ if (cur_focus->hasFocus())
+ {
+ cur_focus->setFocus(FALSE);
+ }
}
- else
+ else if (cur_focus->isFocusRoot())
{
- gFloaterView->setSnapOffsetBottom(0);
+ // focus roots keep trying to delegate focus to their first valid descendant
+ // this assumes that focus roots are not valid focus holders on their own
+ cur_focus->focusFirstItem();
}
-
- // Always update console
- LLRect console_rect = gConsole->getRect();
- console_rect.mBottom = gHUDView->getRect().mBottom + CONSOLE_BOTTOM_PAD;
- gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
- gConsole->setRect(console_rect);
}
- mLastMousePoint = mCurrentMousePoint;
-
// last ditch force of edit menu to selection manager
- if (LLEditMenuHandler::gEditMenuHandler == NULL && gSelectMgr && gSelectMgr->getSelection()->getObjectCount())
+ if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
{
- LLEditMenuHandler::gEditMenuHandler = gSelectMgr;
+ LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance();
}
if (gFloaterView->getCycleMode())
@@ -3115,25 +3000,51 @@ BOOL LLViewerWindow::handlePerFrameHover()
gFloaterView->syncFloaterTabOrder();
}
- if (gSavedSettings.getBOOL("ChatBarStealsFocus") && gChatBar && gFocusMgr.getKeyboardFocus() == NULL && gChatBar->getVisible())
+ if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this
+ LLSideTray::getInstance()->highlightFocused();
+}
+
+static LLFastTimer::DeclareTimer FTM_UPDATE_WORLD_VIEW("Update World View");
+void LLViewerWindow::updateWorldViewRect(bool use_full_window)
+{
+ LLFastTimer ft(FTM_UPDATE_WORLD_VIEW);
+
+ // start off using whole window to render world
+ LLRect new_world_rect = mWindowRectRaw;
+
+ if (use_full_window == false && mWorldViewPlaceholder.get())
{
- gChatBar->startChat(NULL);
+ 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);
+
+ 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]);
}
- // cleanup unused selections when no modal dialogs are open
- if (gParcelMgr && LLModalDialog::activeCount() == 0)
+ if (gSavedSettings.getBOOL("SidebarCameraMovement") == FALSE)
{
- gParcelMgr->deselectUnused();
+ // use right edge of window, ignoring sidebar
+ new_world_rect.mRight = mWindowRectRaw.mRight;
}
- if (gSelectMgr && LLModalDialog::activeCount() == 0)
+ if (mWorldViewRectRaw != new_world_rect)
{
- gSelectMgr->deselectUnused();
- }
+ mWorldViewRectRaw = new_world_rect;
+ gResizeScreenTexture = TRUE;
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
- return handled;
-}
+ LLRect old_world_rect_scaled = mWorldViewRectScaled;
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
+ // sending a signal with a new WorldView rect
+ mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled);
+ }
+}
void LLViewerWindow::saveLastMouse(const LLCoordGL &point)
{
@@ -3143,9 +3054,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
{
@@ -3156,9 +3067,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
{
@@ -3171,16 +3082,15 @@ 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 )
{
- LLObjectSelectionHandle selection = gSelectMgr->getSelection();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
if (!for_hud && !for_gl_pick)
{
// Call this once and only once
- gSelectMgr->updateSilhouettes();
+ LLSelectMgr::getInstance()->updateSilhouettes();
}
// Draw fence around land selections
@@ -3188,27 +3098,27 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
{
if (pick_parcel_walls)
{
- gParcelMgr->renderParcelCollision();
+ LLViewerParcelMgr::getInstance()->renderParcelCollision();
}
}
else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) ||
(!for_hud && selection->getSelectType() != SELECT_TYPE_HUD))
{
- gSelectMgr->renderSilhouettes(for_hud);
+ LLSelectMgr::getInstance()->renderSilhouettes(for_hud);
stop_glerror();
// setup HUD render
- if (selection->getSelectType() == SELECT_TYPE_HUD && gSelectMgr->getSelection()->getObjectCount())
+ 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);
glPushMatrix();
glLoadIdentity();
F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
- glOrtho(-0.5f * gCamera->getAspect(), 0.5f * gCamera->getAspect(), -0.5f, 0.5f, 0.f, depth);
+ glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
@@ -3218,9 +3128,9 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
}
// Render light for editing
- if (LLSelectMgr::sRenderLightRadius && gToolMgr->inEdit())
+ if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit())
{
- LLImageGL::unbindTexture(0);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLEnable gls_blend(GL_BLEND);
LLGLEnable gls_cull(GL_CULL_FACE);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -3228,7 +3138,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
glPushMatrix();
if (selection->getSelectType() == SELECT_TYPE_HUD)
{
- F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom;
+ F32 zoom = gAgentCamera.mHUDCurZoom;
glScalef(zoom, zoom, zoom);
}
@@ -3264,7 +3174,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
return true;
}
} func;
- gSelectMgr->getSelection()->applyToObjects(&func);
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
glPopMatrix();
}
@@ -3273,7 +3183,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
// not be recalculated at this time. If they are, then group rotations will break.
// Draw arrows at average center of all selected objects
- LLTool* tool = gToolMgr->getCurrentTool();
+ LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
if (tool)
{
if(tool->isAlwaysRendered())
@@ -3282,15 +3192,15 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
}
else
{
- if( !gSelectMgr->getSelection()->isEmpty() )
+ if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() )
{
BOOL moveable_object_selected = FALSE;
BOOL all_selected_objects_move = TRUE;
BOOL all_selected_objects_modify = TRUE;
BOOL selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- for (LLObjectSelection::iterator iter = gSelectMgr->getSelection()->begin();
- iter != gSelectMgr->getSelection()->end(); iter++)
+ for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
{
LLSelectNode* nodep = *iter;
LLViewerObject* object = nodep->getObject();
@@ -3306,17 +3216,17 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
BOOL draw_handles = TRUE;
- if (tool == gToolTranslate && (!moveable_object_selected || !all_selected_objects_move))
+ if (tool == LLToolCompTranslate::getInstance() && (!moveable_object_selected || !all_selected_objects_move))
{
draw_handles = FALSE;
}
- if (tool == gToolRotate && (!moveable_object_selected || !all_selected_objects_move))
+ if (tool == LLToolCompRotate::getInstance() && (!moveable_object_selected || !all_selected_objects_move))
{
draw_handles = FALSE;
}
- if ( !all_selected_objects_modify && tool == gToolStretch )
+ if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() )
{
draw_handles = FALSE;
}
@@ -3347,7 +3257,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
@@ -3356,7 +3266,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;
}
@@ -3380,490 +3290,206 @@ BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewe
return intersect;
}
-void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent, BOOL pick_parcel_walls)
+void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& info), BOOL pick_transparent)
{
if (gNoRender)
{
return;
}
- render_ui_and_swap_if_needed();
- glClear(GL_DEPTH_BUFFER_BIT);
- gDisplaySwapBuffers = FALSE;
-
- S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]);
- S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]);
-
- BOOL in_build_mode = gFloaterTools && gFloaterTools->getVisible();
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
pick_transparent = TRUE;
}
- gPickTransparent = pick_transparent;
-
- gUseGLPick = FALSE;
- mPickCallback = callback;
-
- // Default to not hitting anything
- gLastHitPosGlobal.zeroVec();
- gLastHitObjectOffset.zeroVec();
- gLastHitObjectID.setNull();
- gLastHitObjectFace = -1;
-
- gLastHitNonFloraPosGlobal.zeroVec();
- gLastHitNonFloraObjectOffset.zeroVec();
- gLastHitNonFloraObjectID.setNull();
- gLastHitNonFloraObjectFace = -1;
-
- gLastHitParcelWall = FALSE;
-
- LLCamera pick_camera;
- pick_camera.setOrigin(gCamera->getOrigin());
- pick_camera.setOriginAndLookAt(gCamera->getOrigin(),
- gCamera->getUpAxis(),
- gCamera->getOrigin() + mouseDirectionGlobal(x, y_from_bot));
- pick_camera.setView(0.5f*DEG_TO_RAD);
- pick_camera.setNear(gCamera->getNear());
- pick_camera.setFar(gCamera->getFar());
- pick_camera.setAspect(1.f);
-
- // save our drawing state
- // *TODO: should we be saving using the new method here using
- // glh_get_current_projection/glh_set_current_projection? -brad
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- // build perspective transform and picking viewport
- // Perform pick on a PICK_DIAMETER x PICK_DIAMETER pixel region around cursor point.
- // Don't limit the select distance for this pick.
- // make viewport big enough to handle antialiased frame buffers
- gCamera->setPerspective(FOR_SELECTION, scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4, FALSE);
- // make viewport big enough to handle antialiased frame buffers
- gGLViewport[0] = scaled_x - (PICK_HALF_WIDTH + 2);
- gGLViewport[1] = scaled_y - (PICK_HALF_WIDTH + 2);
- gGLViewport[2] = PICK_DIAMETER + 4;
- gGLViewport[3] = PICK_DIAMETER + 4;
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- LLViewerCamera::updateFrustumPlanes(pick_camera);
- stop_glerror();
-
- glClearColor(0.f, 0.f, 0.f, 0.f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- //glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- // Draw the objects so the user can select them.
- // The starting ID is 1, since land is zero.
- gObjectList.renderObjectsForSelect(pick_camera, pick_parcel_walls);
-
- stop_glerror();
-
- // restore drawing state
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- setupViewport();
-
- mPickPoint.set(x, y_from_bot);
- mPickOffset.set(0, 0);
- mPickMask = mask;
- mPickPending = TRUE;
-
- // delay further event processing until we receive results of pick
- mWindow->delayInputProcessing();
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, TRUE, callback);
+ schedulePick(pick_info);
}
-void LLViewerWindow::hitUIElementImmediate(S32 x, S32 y, void (*callback)(S32 x, S32 y, MASK mask))
+void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
{
- // Performs the GL UI pick.
- // Stores its results in global, gLastHitUIElement
- if (gNoRender)
- {
- return;
- }
+ if (mPicks.size() >= 1024 || mWindow->getMinimized())
+ { //something went wrong, picks are being scheduled but not processed
+
+ if (pick_info.mPickCallback)
+ {
+ pick_info.mPickCallback(pick_info);
+ }
- hitUIElementAsync(x, y, gKeyboard->currentMask(TRUE), NULL);
- performPick();
- if (callback)
- {
- callback(x, y, gKeyboard->currentMask(TRUE));
- }
-}
-
-//RN: this currently doesn't do anything
-void LLViewerWindow::hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask))
-{
- if (gNoRender)
- {
return;
}
-
-// F32 delta_time = gAlphaFadeTimer.getElapsedTimeAndResetF32();
-
- gUseGLPick = FALSE;
- mPickCallback = callback;
-
- // Default to not hitting anything
- gLastHitUIElement = 0;
-
- LLCamera pick_camera;
- pick_camera.setOrigin(gCamera->getOrigin());
- pick_camera.setOriginAndLookAt(gCamera->getOrigin(),
- gCamera->getUpAxis(),
- gCamera->getOrigin() + mouseDirectionGlobal(x, y_from_bot));
- pick_camera.setView(0.5f*DEG_TO_RAD);
- pick_camera.setNear(gCamera->getNear());
- pick_camera.setFar(gCamera->getFar());
- pick_camera.setAspect(1.f);
-
- // save our drawing state
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
+ mPicks.push_back(pick_info);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- // build orthogonal transform and picking viewport
- // Perform pick on a PICK_DIAMETER x PICK_DIAMETER pixel region around cursor point.
- // Don't limit the select distance for this pick.
- gViewerWindow->setup2DRender();
- const LLVector2& display_scale = gViewerWindow->getDisplayScale();
- glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- // make viewport big enough to handle antialiased frame buffers
- glViewport(x - (PICK_HALF_WIDTH + 2), y_from_bot - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4);
- stop_glerror();
-
- glClearColor(0.f, 0.f, 0.f, 0.f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
- // Draw the objects so the user can select them.
- // The starting ID is 1, since land is zero.
- //gViewerWindow->drawForSelect();
-
- stop_glerror();
-
- // restore drawing state
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- setupViewport();
-
- mPickPoint.set(x, y_from_bot);
- mPickOffset.set(0, 0);
- mPickMask = mask;
- mPickPending = TRUE;
+ // 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();
}
+
void LLViewerWindow::performPick()
{
- if (gNoRender || !mPickPending)
+ if (gNoRender)
{
return;
}
- mPickPending = FALSE;
- U32 te_offset = NO_FACE;
-
- // find pick region that is fully onscreen
- LLCoordGL scaled_pick_point = mPickPoint;
- scaled_pick_point.mX = llclamp(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayWidth() - PICK_HALF_WIDTH);
- scaled_pick_point.mY = llclamp(llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayHeight() - PICK_HALF_WIDTH);
-
- glReadPixels(scaled_pick_point.mX - PICK_HALF_WIDTH, scaled_pick_point.mY - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
-
- S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH;
- S32 name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
- gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
-
- if (name >= (S32)GL_NAME_UI_RESERVED && name < (S32)GL_NAME_INDEX_OFFSET)
+ if (!mPicks.empty())
{
- // hit a UI element
- gLastHitUIElement = name;
- if (mPickCallback)
+ std::vector<LLPickInfo>::iterator pick_it;
+ for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
{
- mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask);
+ pick_it->fetchResults();
}
- }
- //imdebug("rgba rbga=bbba b=8 w=%d h=%d %p", PICK_DIAMETER, PICK_DIAMETER, mPickBuffer);
-
- S32 x_offset = mPickPoint.mX - llround((F32)scaled_pick_point.mX / mDisplayScale.mV[VX]);
- S32 y_offset = mPickPoint.mY - llround((F32)scaled_pick_point.mY / mDisplayScale.mV[VY]);
+ mLastPick = mPicks.back();
+ mPicks.clear();
+ }
+}
-
- // we hit nothing, scan surrounding pixels for something useful
- if (!name)
+void LLViewerWindow::returnEmptyPicks()
+{
+ std::vector<LLPickInfo>::iterator pick_it;
+ for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
{
- S32 closest_distance = 10000;
- //S32 closest_pick_name = 0;
- for (S32 col = 0; col < PICK_DIAMETER; col++)
+ mLastPick = *pick_it;
+ // just trigger callback with empty results
+ if (pick_it->mPickCallback)
{
- for (S32 row = 0; row < PICK_DIAMETER; row++)
- {
- S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH));
- pixel_index = row * PICK_DIAMETER + col;
- S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
- gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
- if (test_name && distance_squared < closest_distance)
- {
- closest_distance = distance_squared;
- name = test_name;
- gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
- mPickOffset.mX = col - PICK_HALF_WIDTH;
- mPickOffset.mY = row - PICK_HALF_WIDTH;
- }
- }
+ pick_it->mPickCallback(*pick_it);
}
}
+ mPicks.clear();
+}
- if (name)
- {
- mPickPoint.mX += llround((F32)mPickOffset.mX * mDisplayScale.mV[VX]);
- mPickPoint.mY += llround((F32)mPickOffset.mY * mDisplayScale.mV[VY]);
- }
-
- if (gPickFaces)
+// Performs the GL object/land pick.
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent)
+{
+ if (gNoRender)
{
- te_offset = ((U32)name >> 20);
- name &= 0x000fffff;
- // don't clear gPickFaces, as we still need to check for UV coordinates
+ return LLPickInfo();
}
- LLViewerObject *objectp = NULL;
-
- // Frontmost non-foreground object that isn't trees or grass
- LLViewerObject* nonflora_objectp = NULL;
- S32 nonflora_name = -1;
- S32 nonflora_te_offset = NO_FACE;
-
- if (name == (S32)GL_NAME_PARCEL_WALL)
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
+ if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
{
- gLastHitParcelWall = TRUE;
+ // build mode allows interaction with all transparent objects
+ // "Show Debug Alpha" means no object actually transparent
+ pick_transparent = TRUE;
}
- gLastHitHUDIcon = NULL;
+ // 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();
- objectp = gObjectList.getSelectedObject(name);
- if (objectp)
- {
- LLViewerObject* parent = (LLViewerObject*)(objectp->getParent());
- if (NULL == parent) {
- // if you are the parent
- parent = objectp;
- }
- if (objectp->mbCanSelect)
- {
- te_offset = (te_offset == 16) ? NO_FACE : te_offset;
-
- // If the hit object isn't a plant, store it as the frontmost non-flora object.
- LLPCode pcode = objectp->getPCode();
- if( (LL_PCODE_LEGACY_GRASS != pcode) &&
- (LL_PCODE_LEGACY_TREE != pcode) &&
- (LL_PCODE_TREE_NEW != pcode))
- {
- nonflora_objectp = objectp;
- nonflora_name = name;
- nonflora_te_offset = te_offset;
- }
- }
- else
- {
- //llinfos << "Hit object you can't select" << llendl;
- }
- }
- else
- {
- // was this name referring to a hud icon?
- gLastHitHUDIcon = LLHUDIcon::handlePick(name);
- }
-
- analyzeHit(
- mPickPoint.mX, mPickPoint.mY, objectp, te_offset,
- &gLastHitObjectID, &gLastHitObjectFace, &gLastHitPosGlobal, &gLastHitLand, &gLastHitUCoord, &gLastHitVCoord );
+ return mLastPick;
+}
- if (objectp && !gLastHitObjectID.isNull())
- {
- gLastHitObjectOffset = gAgent.calcFocusOffset(objectp, mPickPoint.mX, mPickPoint.mY);
- }
+LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
+ LLVector3* intersection)
+{
+ S32 x = mouse_x;
+ S32 y = mouse_y;
- if( objectp == nonflora_objectp )
+ if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
{
- gLastHitNonFloraObjectID = gLastHitObjectID;
- gLastHitNonFloraObjectFace = gLastHitObjectFace;
- gLastHitNonFloraPosGlobal = gLastHitPosGlobal;
- gLastHitNonFloraObjectOffset= gLastHitObjectOffset;
+ x = getCurrentMouseX();
+ y = getCurrentMouseY();
}
- else
- {
- analyzeHit( mPickPoint.mX, mPickPoint.mY, nonflora_objectp, nonflora_te_offset,
- &gLastHitNonFloraObjectID, &gLastHitNonFloraObjectFace, &gLastHitNonFloraPosGlobal,
- &gLastHitLand, &gLastHitUCoord, &gLastHitVCoord);
- if( nonflora_objectp )
- {
- gLastHitNonFloraObjectOffset = gAgent.calcFocusOffset(nonflora_objectp, mPickPoint.mX, mPickPoint.mY);
- }
- }
+ // world coordinates of mouse
+ LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
+ LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
+ LLVector3 mouse_world_start = mouse_point_global;
+ LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
- if (mPickCallback)
- {
- mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask);
- }
+ return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection);
- gPickFaces = FALSE;
+
}
-// Performs the GL object/land pick.
-// Stores its results in globals, gHit*
-void LLViewerWindow::hitObjectOrLandGlobalImmediate(S32 x, S32 y_from_bot, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent)
+LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
+ LLViewerObject *this_object,
+ S32 this_face,
+ BOOL pick_transparent,
+ S32* face_hit,
+ LLVector3 *intersection,
+ LLVector2 *uv,
+ LLVector3 *normal,
+ LLVector3 *binormal)
{
- if (gNoRender)
- {
- return;
- }
-
- hitObjectOrLandGlobalAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent);
- performPick();
- if (callback)
+ S32 x = mouse_x;
+ S32 y = mouse_y;
+
+ if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
{
- callback(x, y_from_bot, gKeyboard->currentMask(TRUE));
+ x = getCurrentMouseX();
+ y = getCurrentMouseY();
}
-}
-LLViewerObject* LLViewerWindow::getObjectUnderCursor(const F32 depth)
-{
- S32 x = getCurrentMouseX();
- S32 y = getCurrentMouseY();
+ // HUD coordinates of mouse
+ LLVector3 mouse_point_hud = mousePointHUD(x, y);
+ LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0);
+ LLVector3 mouse_hud_end = mouse_point_hud + LLVector3(depth, 0, 0);
- LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
- LLVector3 camera_pos_global = gCamera->getOrigin();
- LLVector3 pick_end = camera_pos_global + mouse_direction_global * depth;
- LLVector3 collision_point;
- return gPipeline.pickObject(camera_pos_global, pick_end, collision_point);
-}
-
-void LLViewerWindow::analyzeHit(
- S32 x, // input
- S32 y_from_bot, // input
- LLViewerObject* objectp, // input
- U32 te_offset, // input
- LLUUID* hit_object_id_p,// output
- S32* hit_face_p, // output
- LLVector3d* hit_pos_p, // output
- BOOL* hit_land, // output
- F32* hit_u_coord, // output
- F32* hit_v_coord) // output
-{
- // Clean up inputs
- S32 face = -1;
+ // world coordinates of mouse
+ LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
+ LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
- if (te_offset != NO_FACE )
- {
- face = te_offset;
- }
+ //get near clip plane
+ LLVector3 n = LLViewerCamera::getInstance()->getAtAxis();
+ LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear();
- *hit_land = FALSE;
+ //project mouse point onto plane
+ LLVector3 pos;
+ line_plane(mouse_point_global, mouse_direction_global, p, n, pos);
+ mouse_point_global = pos;
- if (objectp)
+ LLVector3 mouse_world_start = mouse_point_global;
+ LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
+
+
+ LLViewerObject* found = NULL;
+
+ if (this_object) // check only this object
{
- if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
+ if (this_object->isHUDAttachment()) // is a HUD object?
{
- // Hit land
- *hit_land = TRUE;
-
- // put global position into land_pos
- LLVector3d land_pos;
- if (mousePointOnLandGlobal(x, y_from_bot, &land_pos))
+ if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, binormal))
{
- *hit_object_id_p = LLUUID::null;
- *hit_face_p = -1;
-
- // Fudge the land focus a little bit above ground.
- *hit_pos_p = land_pos + LLVector3d(0.f, 0.f, 0.1f);
- //llinfos << "DEBUG Hit Land " << *hit_pos_p << llendl;
- return;
+ found = this_object;
}
- else
- {
- //llinfos << "Hit land but couldn't find position" << llendl;
- // Fall through to "Didn't hit anything"
}
- }
- else
+
+ else // is a world object
{
- *hit_object_id_p = objectp->mID;
- *hit_face_p = face;
-
- // Hit an object
- if (objectp->isAvatar())
+ if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, binormal))
{
- *hit_pos_p = gAgent.getPosGlobalFromAgent(((LLVOAvatar*)objectp)->mPelvisp->getWorldPosition());
+ found = this_object;
}
- else if (objectp->mDrawable.notNull())
- {
- *hit_pos_p = gAgent.getPosGlobalFromAgent(objectp->getRenderPosition());
}
- else
- {
- // regular object
- *hit_pos_p = objectp->getPositionGlobal();
}
- if (gPickFaces && face > -1 &&
- objectp->mDrawable.notNull() && objectp->getPCode() == LL_PCODE_VOLUME &&
- face < objectp->mDrawable->getNumFaces())
+ else // check ALL objects
{
- // render red-blue gradient to get 1/256 precision
- // then render green grid to get final 1/4096 precision
- S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]);
- S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]);
- const S32 UV_PICK_WIDTH = 41;
- const S32 UV_PICK_HALF_WIDTH = (UV_PICK_WIDTH - 1) / 2;
- U8 uv_pick_buffer[UV_PICK_WIDTH * UV_PICK_WIDTH * 4];
- S32 pick_face = face;
- LLFace* facep = objectp->mDrawable->getFace(pick_face);
- gCamera->setPerspective(FOR_SELECTION, scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, FALSE);
- glViewport(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH);
- gPipeline.renderFaceForUVSelect(facep);
-
- glReadPixels(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, GL_RGBA, GL_UNSIGNED_BYTE, uv_pick_buffer);
- U8* center_pixel = &uv_pick_buffer[4 * ((UV_PICK_WIDTH * UV_PICK_HALF_WIDTH) + UV_PICK_HALF_WIDTH + 1)];
- *hit_u_coord = (F32)((center_pixel[VGREEN] & 0xf) + (16.f * center_pixel[VRED])) / 4095.f;
- *hit_v_coord = (F32)((center_pixel[VGREEN] >> 4) + (16.f * center_pixel[VBLUE])) / 4095.f;
- }
- else
+ found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
+ face_hit, intersection, uv, normal, binormal);
+
+ if (!found) // if not found in HUD, look in world:
+
{
- *hit_u_coord = 0.f;
- *hit_v_coord = 0.f;
+ found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
+ face_hit, intersection, uv, normal, binormal);
}
- //llinfos << "DEBUG Hit Object " << *hit_pos_p << llendl;
- return;
- }
}
- // Didn't hit anything.
- *hit_object_id_p = LLUUID::null;
- *hit_face_p = -1;
- *hit_pos_p = LLVector3d::zero;
- *hit_u_coord = 0.f;
- *hit_v_coord = 0.f;
- //llinfos << "DEBUG Hit Nothing " << llendl;
+ return found;
}
// Returns unit vector relative to camera
@@ -3871,45 +3497,64 @@ void LLViewerWindow::analyzeHit(
LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
{
// find vertical field of view
- F32 fov = gCamera->getView();
+ F32 fov = LLViewerCamera::getInstance()->getView();
- // find screen resolution
- S32 height = getWindowHeight();
- S32 width = getWindowWidth();
+ // find world view center in scaled ui coordinates
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
// calculate pixel distance to screen
- F32 distance = (height / 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 - width / 2.f;
- F32 click_y = y - height / 2.f;
+ F32 click_x = x - center_x;
+ F32 click_y = y - center_y;
// compute mouse vector
- LLVector3 mouse_vector = distance * gCamera->getAtAxis()
- - click_x * gCamera->getLeftAxis()
- + click_y * gCamera->getUpAxis();
+ LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis()
+ - click_x * LLViewerCamera::getInstance()->getLeftAxis()
+ + click_y * LLViewerCamera::getInstance()->getUpAxis();
mouse_vector.normVec();
return mouse_vector;
}
+LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
+{
+ // find screen resolution
+ S32 height = getWorldViewHeightScaled();
+
+ // find world view center
+ 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/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom);
+}
// Returns unit vector relative to camera in camera space
// indicating direction of point on screen x,y
LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
{
// find vertical field of view
- F32 fov_height = gCamera->getView();
- F32 fov_width = fov_height * gCamera->getAspect();
+ F32 fov_height = LLViewerCamera::getInstance()->getView();
+ F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
// find screen resolution
- S32 height = getWindowHeight();
- S32 width = getWindowWidth();
+ S32 height = getWorldViewHeightScaled();
+ S32 width = getWorldViewWidthScaled();
+
+ // find world view center
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
// calculate click point relative to middle of screen
- F32 click_x = (((F32)x / (F32)width) - 0.5f) * fov_width * -1.f;
- F32 click_y = (((F32)y / (F32)height) - 0.5f) * fov_height;
+ F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f;
+ F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height;
// compute mouse vector
LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f);
@@ -3935,7 +3580,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)
@@ -3949,7 +3594,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;
}
@@ -3967,18 +3612,18 @@ 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);
probe_point_global = camera_pos_global + mouse_direction_global_d;
- regionp = gWorldPointer->resolveRegionGlobal(probe_point_region, probe_point_global);
+ regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
if (!regionp)
{
@@ -4025,7 +3670,7 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
probe_point_global = camera_pos_global + mouse_direction_global_d;
- regionp = gWorldPointer->resolveRegionGlobal(probe_point_region, probe_point_global);
+ regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
if (!regionp)
{
@@ -4062,123 +3707,81 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
}
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
-BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const LLString& extension_in)
+BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
{
- if (! raw)
+ if (!image)
{
return FALSE;
}
- LLString extension(extension_in);
- if (extension.empty())
- {
- extension = (gSavedSettings.getBOOL("CompressSnapshotsToDisk")) ? ".j2c" : ".bmp";
- }
-
LLFilePicker::ESaveFilter pick_type;
+ std::string extension("." + image->getExtension());
if (extension == ".j2c")
pick_type = LLFilePicker::FFSAVE_J2C;
else if (extension == ".bmp")
pick_type = LLFilePicker::FFSAVE_BMP;
+ else if (extension == ".jpg")
+ pick_type = LLFilePicker::FFSAVE_JPEG;
+ else if (extension == ".png")
+ pick_type = LLFilePicker::FFSAVE_PNG;
else if (extension == ".tga")
pick_type = LLFilePicker::FFSAVE_TGA;
else
pick_type = LLFilePicker::FFSAVE_ALL; // ???
- // Get a directory if this is the first time.
- if (strlen(sSnapshotDir) == 0) /* Flawfinder: ignore */
+ // Get a base file location if needed.
+ if ( ! isSnapshotLocSet())
{
- LLString proposed_name( sSnapshotBaseName );
- proposed_name.append( extension );
+ std::string proposed_name( sSnapshotBaseName );
+
+ // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
// pick a directory in which to save
LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getSaveFile(pick_type, proposed_name.c_str()))
+ if (!picker.getSaveFile(pick_type, proposed_name))
{
// Clicked cancel
return FALSE;
}
// Copy the directory + file name
- char directory[LL_MAX_PATH]; /* Flawfinder: ignore */
- strncpy(directory, picker.getFirstFile(), LL_MAX_PATH -1); /* Flawfinder: ignore */
- directory[LL_MAX_PATH -1] = '\0';
-
- // Smash the file extension
- S32 length = strlen(directory); /* Flawfinder: ignore */
- S32 index = length;
+ std::string filepath = picker.getFirstFile();
- // Back up over extension
- index -= extension.length();
- if (index >= 0 && directory[index] == '.')
- {
- directory[index] = '\0';
- }
- else
- {
- index = length;
- }
-
- // Find trailing backslash
- while (index >= 0 && directory[index] != gDirUtilp->getDirDelimiter()[0])
- {
- index--;
- }
-
- // If we found one, truncate the string there
- if (index >= 0)
- {
- if (index + 1 <= length)
- {
- strncpy(LLViewerWindow::sSnapshotBaseName, directory + index + 1, LL_MAX_PATH -1); /* Flawfinder: ignore */
- LLViewerWindow::sSnapshotBaseName[LL_MAX_PATH -1] = '\0';
- }
-
- index++;
- directory[index] = '\0';
- strncpy(LLViewerWindow::sSnapshotDir, directory, LL_MAX_PATH -1); /* Flawfinder: ignore */
- LLViewerWindow::sSnapshotDir[LL_MAX_PATH -1] = '\0';
- }
+ LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true);
+ LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath);
}
// Look for an unused file name
- LLString filepath;
+ std::string filepath;
S32 i = 1;
S32 err = 0;
do
{
filepath = sSnapshotDir;
+ filepath += gDirUtilp->getDirDelimiter();
filepath += sSnapshotBaseName;
filepath += llformat("_%.3d",i);
filepath += extension;
- struct stat stat_info;
- err = gViewerWindow->mWindow->stat( filepath.c_str(), &stat_info );
+ llstat stat_info;
+ err = LLFile::stat( filepath, &stat_info );
i++;
}
while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
- LLPointer<LLImageFormatted> formatted_image = LLImageFormatted::createFromExtension(extension);
- LLImageBase::setSizeOverride(TRUE);
- BOOL success = formatted_image->encode(raw);
- if( success )
- {
- success = formatted_image->save(filepath);
- }
- else
- {
- llwarns << "Unable to encode bmp snapshot" << llendl;
- }
- LLImageBase::setSizeOverride(FALSE);
-
- return success;
+ return image->save(filepath);
}
+void LLViewerWindow::resetSnapshotLoc()
+{
+ sSnapshotDir.clear();
+}
static S32 BORDERHEIGHT = 0;
static S32 BORDERWIDTH = 0;
+// static
void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
{
LLCoordScreen size;
@@ -4186,28 +3789,18 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
if ( (size.mX != new_width + BORDERWIDTH)
||(size.mY != new_height + BORDERHEIGHT))
{
- S32 x = gViewerWindow->getWindowWidth();
- S32 y = gViewerWindow->getWindowHeight();
+ // use actual display dimensions, not virtual UI dimensions
+ S32 x = gViewerWindow->getWindowWidthRaw();
+ S32 y = gViewerWindow->getWindowHeightRaw();
BORDERWIDTH = size.mX - x;
BORDERHEIGHT = size.mY- y;
LLCoordScreen new_size(new_width + BORDERWIDTH,
new_height + BORDERHEIGHT);
- BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync");
- if (gViewerWindow->mWindow->getFullscreen())
- {
- gViewerWindow->changeDisplaySettings(FALSE,
- new_size,
- disable_sync,
- TRUE);
- }
- else
- {
- gViewerWindow->mWindow->setSize(new_size);
- }
+ gViewerWindow->mWindow->setSize(new_size);
}
}
-BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
+BOOL LLViewerWindow::saveSnapshot( const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
{
llinfos << "Saving snapshot to: " << filepath << llendl;
@@ -4217,7 +3810,7 @@ BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S3
if (success)
{
LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
- success = bmp_image->encode(raw);
+ success = bmp_image->encode(raw, 0.0f);
if( success )
{
success = bmp_image->save(filepath);
@@ -4238,26 +3831,29 @@ BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S3
void LLViewerWindow::playSnapshotAnimAndSound()
{
+ if (gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
+ {
+ return;
+ }
gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START);
send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
}
+BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
+{
+ return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
+}
// Saves the image from the screen to the specified filename and path.
BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)
{
- //F32 image_aspect_ratio = ((F32)image_width) / ((F32)image_height);
- //F32 window_aspect_ratio = ((F32)getWindowWidth()) / ((F32)getWindowHeight());
-
- if ((!gWorldPointer) ||
- (!raw))
+ if (!raw)
{
return FALSE;
}
// PRE SNAPSHOT
- render_ui_and_swap_if_needed();
gDisplaySwapBuffers = FALSE;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -4280,71 +3876,61 @@ 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 = mWindowRectRaw.getWidth();
+ S32 window_height = mWindowRectRaw.getHeight();
+ LLRect window_rect = mWindowRectRaw;
+ BOOL use_fbo = FALSE;
+
+ LLRenderTarget target;
F32 scale_factor = 1.0f ;
- if (keep_window_aspect || is_texture) //map the entire window to snapshot
- {
+ if(!keep_window_aspect) //image cropping
+ {
+ F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
+ snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_height = (S32)(ratio * image_height) ;
+ scale_factor = llmax(1.0f, 1.0f / ratio) ;
}
- else //scale or crop
+ else //the scene(window) proportion needs to be maintained.
{
- if(snapshot_width > image_width) //crop
- {
- snapshot_width = image_width ;
- }
- if(snapshot_height > image_height)//crop
+ if(image_width > window_width || image_height > window_height) //need to enlarge the scene
{
- snapshot_height = image_height ;
- }
-
- //if (image_aspect_ratio > window_aspect_ratio)
- //{
- // snapshot_height = llround((F32)snapshot_width / image_aspect_ratio);
- //}
- //else if (image_aspect_ratio < window_aspect_ratio)
- //{
- // snapshot_width = llround((F32)snapshot_height * image_aspect_ratio);
- //}
- }
-
- LLRenderTarget target;
-
- scale_factor = llmax(1.f, (F32)image_width / snapshot_width, (F32)image_height / snapshot_height);
-
- // SNAPSHOT
- S32 window_width = mWindowRect.getWidth();
- S32 window_height = mWindowRect.getHeight();
-
- LLRect window_rect = mWindowRect;
-
- BOOL use_fbo = FALSE;
-
- if (gGLManager.mHasFramebufferObject &&
- (image_width > window_width ||
- image_height > window_height) &&
- !show_ui &&
- keep_window_aspect)
- {
- GLint max_size = 0;
- glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size);
+ if (!LLPipeline::sRenderDeferred && gGLManager.mHasFramebufferObject && !show_ui)
+ {
+ GLint max_size = 0;
+ glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size);
- if (image_width <= max_size && image_height <= max_size)
- {
- use_fbo = TRUE;
-
- snapshot_width = image_width;
- snapshot_height = image_height;
- target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB, TRUE);
- window_width = snapshot_width;
- window_height = snapshot_height;
- scale_factor = 1.f;
- mWindowRect.set(0, 0, snapshot_width, snapshot_height);
- target.bindTarget();
+ if (image_width <= max_size && image_height <= max_size) //re-project the scene
+ {
+ use_fbo = TRUE;
+
+ snapshot_width = image_width;
+ snapshot_height = image_height;
+ target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, TRUE);
+ window_width = snapshot_width;
+ window_height = snapshot_height;
+ scale_factor = 1.f;
+ mWindowRectRaw.set(0, snapshot_height, snapshot_width, 0);
+ target.bindTarget();
+ }
+ }
-
+ if(!use_fbo) //no re-projection, so tiling the scene
+ {
+ F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
+ snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_height = (S32)(ratio * image_height) ;
+ scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ }
}
+ //else: keep the current scene scale, re-scale it if necessary after reading out.
}
+ // if not showing ui, use full window to render world view
+ updateWorldViewRect(!show_ui);
+
S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
@@ -4356,21 +3942,34 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_buffer_x = llfloor(snapshot_width*scale_factor) ;
image_buffer_y = llfloor(snapshot_height *scale_factor) ;
}
- raw->resize(image_buffer_x, image_buffer_y, type == SNAPSHOT_TYPE_DEPTH ? 4 : 3);
+ if(image_buffer_x > 0 && image_buffer_y > 0)
+ {
+ raw->resize(image_buffer_x, image_buffer_y, 3);
+ }
+ else
+ {
+ return FALSE ;
+ }
+ if(raw->isBufferInvalid())
+ {
+ 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();
//rescale fonts
initFonts(scale_factor);
- LLHUDText::reshape();
+ LLHUDObject::reshapeAll();
}
S32 output_buffer_offset_y = 0;
- F32 depth_conversion_factor_1 = (gCamera->getFar() + gCamera->getNear()) / (2.f * gCamera->getFar() * gCamera->getNear());
- F32 depth_conversion_factor_2 = (gCamera->getFar() - gCamera->getNear()) / (2.f * gCamera->getFar() * gCamera->getNear());
+ F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
+ F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
+
+ gObjectList.generatePickList(*LLViewerCamera::getInstance());
for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
{
@@ -4383,22 +3982,30 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x)
{
gDisplaySwapBuffers = FALSE;
+ gDepthDirty = TRUE;
if (type == SNAPSHOT_TYPE_OBJECT_ID)
{
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- gCamera->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));
+ LLViewerCamera::getInstance()->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));
setup3DRender();
- setupViewport();
- BOOL first_time_through = (subimage_x + subimage_y == 0);
- gPickTransparent = FALSE;
- gObjectList.renderObjectsForSelect(*gCamera, FALSE, !first_time_through);
+ gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE);
}
else
{
- display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), use_fbo);
- render_ui_and_swap();
+ const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ display(do_rebuild, scale_factor, subfield, FALSE);
+ }
+ else
+ {
+ display(do_rebuild, scale_factor, subfield, TRUE);
+ // Required for showing the GUI in snapshots? See DEV-16350 for details. JC
+ render_ui(scale_factor, subfield);
+ }
}
S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
@@ -4407,49 +4014,50 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
for(U32 out_y = 0; out_y < read_height ; out_y++)
{
+ S32 output_buffer_offset = (
+ (out_y * (raw->getWidth())) // ...plus iterated y...
+ + (window_width * subimage_x) // ...plus subimage start in x...
+ + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
+ - output_buffer_offset_x // ...minus buffer padding x...
+ - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
+ ) * raw->getComponents();
+
+ // Ping the wathdog thread every 100 lines to keep us alive (arbitrary number, feel free to change)
+ if (out_y % 100 == 0)
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
+ }
+
if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)
{
glReadPixels(
subimage_x_offset, out_y + subimage_y_offset,
read_width, 1,
GL_RGB, GL_UNSIGNED_BYTE,
- raw->getData() + // current output pixel is beginning of buffer...
- (
- (out_y * (raw->getWidth())) // ...plus iterated y...
- + (window_width * subimage_x) // ...plus subimage start in x...
- + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
- - output_buffer_offset_x // ...minus buffer padding x...
- - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
- ) * 3 // times 3 bytes per pixel
+ raw->getData() + output_buffer_offset
);
}
else // SNAPSHOT_TYPE_DEPTH
{
- S32 output_buffer_offset = (
- (out_y * (raw->getWidth())) // ...plus iterated y...
- + (window_width * subimage_x) // ...plus subimage start in x...
- + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
- - output_buffer_offset_x // ...minus buffer padding x...
- - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
- ) * 4; // times 4 bytes per pixel
-
+ LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
glReadPixels(
subimage_x_offset, out_y + subimage_y_offset,
read_width, 1,
GL_DEPTH_COMPONENT, GL_FLOAT,
- raw->getData() + output_buffer_offset// current output pixel is beginning of buffer...
+ depth_line_buffer->getData()// current output pixel is beginning of buffer...
);
- for (S32 i = output_buffer_offset; i < output_buffer_offset + (S32)read_width * 4; i += 4)
+ for (S32 i = 0; i < (S32)read_width; i++)
{
- F32 depth_float = *(F32*)(raw->getData() + i);
+ F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, gCamera->getNear(), gCamera->getFar());
- *(raw->getData() + i + 0) = depth_byte;
- *(raw->getData() + i + 1) = depth_byte;
- *(raw->getData() + i + 2) = depth_byte;
- *(raw->getData() + i + 3) = 255;
+ U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
+ //write converted scanline out to result image
+ for(S32 j = 0; j < raw->getComponents(); j++)
+ {
+ *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ }
}
}
}
@@ -4461,11 +4069,12 @@ 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);
}
gDisplaySwapBuffers = FALSE;
+ gDepthDirty = TRUE;
// POST SNAPSHOT
if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
@@ -4481,21 +4090,22 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
if (high_res)
{
initFonts(1.f);
- LLHUDText::reshape();
+ LLHUDObject::reshapeAll();
}
// Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding)
// Note: this formula depends on the number of components being 3. Not obvious, but it's correct.
- image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4 ;
+ image_width += (image_width * 3) % 4;
+ BOOL ret = TRUE ;
// Resize image
if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4)
{
- raw->scale( image_width, image_height );
+ ret = raw->scale( image_width, image_height );
}
else if(image_width != image_buffer_x || image_height != image_buffer_y)
{
- raw->scale( image_width, image_height, FALSE );
+ ret = raw->scale( image_width, image_height, FALSE );
}
@@ -4516,7 +4126,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
send_agent_resume();
}
- return TRUE;
+ return ret;
}
void LLViewerWindow::destroyWindow()
@@ -4531,143 +4141,130 @@ void LLViewerWindow::destroyWindow()
void LLViewerWindow::drawMouselookInstructions()
{
- // Draw instructions for mouselook ("Press ESC to leave Mouselook" in a box at the top of the screen.)
- const char* instructions = "Press ESC to leave Mouselook.";
- const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
-
- const S32 INSTRUCTIONS_PAD = 5;
- LLRect instructions_rect;
- instructions_rect.setLeftTopAndSize(
- INSTRUCTIONS_PAD,
- gViewerWindow->getWindowHeight() - INSTRUCTIONS_PAD,
- font->getWidth( instructions ) + 2 * INSTRUCTIONS_PAD,
- llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD));
-
- {
- LLGLSNoTexture gls_no_texture;
- gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f );
- gl_rect_2d( instructions_rect );
- }
+ // 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", "Large", LLFontGL::BOLD));
+ //to be on top of Bottom bar when it is opened
+ const S32 INSTRUCTIONS_PAD = 50;
+
font->renderUTF8(
instructions, 0,
- instructions_rect.mLeft + INSTRUCTIONS_PAD,
- instructions_rect.mTop - INSTRUCTIONS_PAD,
- LLColor4( 0.0f, 0.0f, 0.0f, 1.f ),
- LLFontGL::LEFT, LLFontGL::TOP);
+ getWorldViewRectScaled().getCenterX(),
+ getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD,
+ LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ),
+ LLFontGL::HCENTER, LLFontGL::TOP,
+ LLFontGL::NORMAL,LLFontGL::DROP_SHADOW);
}
-
-// These functions are here only because LLViewerWindow used to do the work that gFocusMgr does now.
-// They let other objects continue to work without change.
-
-void LLViewerWindow::setKeyboardFocus(LLUICtrl* new_focus)
+void* LLViewerWindow::getPlatformWindow() const
{
- gFocusMgr.setKeyboardFocus( new_focus );
+ return mWindow->getPlatformWindow();
}
-LLUICtrl* LLViewerWindow::getKeyboardFocus()
+void* LLViewerWindow::getMediaWindow() const
{
- return gFocusMgr.getKeyboardFocus();
+ return mWindow->getMediaWindow();
}
-BOOL LLViewerWindow::hasKeyboardFocus(const LLUICtrl* possible_focus) const
+void LLViewerWindow::focusClient() const
{
- return possible_focus == gFocusMgr.getKeyboardFocus();
+ return mWindow->focusClient();
}
-BOOL LLViewerWindow::childHasKeyboardFocus(const LLView* parent) const
+LLRootView* LLViewerWindow::getRootView() const
{
- return gFocusMgr.childHasKeyboardFocus( parent );
+ return mRootView;
}
-void LLViewerWindow::setMouseCapture(LLMouseHandler* new_captor)
+LLRect LLViewerWindow::getWorldViewRectScaled() const
{
- gFocusMgr.setMouseCapture( new_captor );
+ return mWorldViewRectScaled;
}
-LLMouseHandler* LLViewerWindow::getMouseCaptor() const
+S32 LLViewerWindow::getWorldViewHeightScaled() const
{
- return gFocusMgr.getMouseCapture();
+ return mWorldViewRectScaled.getHeight();
}
-S32 LLViewerWindow::getWindowHeight() const
-{
- return mVirtualWindowRect.getHeight();
-}
-
-S32 LLViewerWindow::getWindowWidth() const
-{
- return mVirtualWindowRect.getWidth();
+S32 LLViewerWindow::getWorldViewWidthScaled() const
+{
+ return mWorldViewRectScaled.getWidth();
}
-S32 LLViewerWindow::getWindowDisplayHeight() const
-{
- return mWindowRect.getHeight();
-}
-S32 LLViewerWindow::getWindowDisplayWidth() const
-{
- return mWindowRect.getWidth();
+S32 LLViewerWindow::getWorldViewHeightRaw() const
+{
+ return mWorldViewRectRaw.getHeight();
}
-LLUICtrl* LLViewerWindow::getTopCtrl() const
+S32 LLViewerWindow::getWorldViewWidthRaw() const
{
- return gFocusMgr.getTopCtrl();
+ return mWorldViewRectRaw.getWidth();
}
-BOOL LLViewerWindow::hasTopCtrl(LLView* view) const
-{
- return view == gFocusMgr.getTopCtrl();
+S32 LLViewerWindow::getWindowHeightScaled() const
+{
+ return mWindowRectScaled.getHeight();
}
-void LLViewerWindow::setTopCtrl(LLUICtrl* new_top)
-{
- gFocusMgr.setTopCtrl( new_top );
+S32 LLViewerWindow::getWindowWidthScaled() const
+{
+ return mWindowRectScaled.getWidth();
}
-void LLViewerWindow::setupViewport(S32 x_offset, S32 y_offset)
-{
- gGLViewport[0] = x_offset;
- gGLViewport[1] = y_offset;
- gGLViewport[2] = mWindowRect.getWidth();
- gGLViewport[3] = mWindowRect.getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+S32 LLViewerWindow::getWindowHeightRaw() const
+{
+ return mWindowRectRaw.getHeight();
}
-void LLViewerWindow::setup3DRender()
-{
- gCamera->setPerspective(NOT_FOR_SELECTION, 0, 0, mWindowRect.getWidth(), mWindowRect.getHeight(), FALSE, gCamera->getNear(), MAX_FAR_CLIP*2.f);
+S32 LLViewerWindow::getWindowWidthRaw() const
+{
+ return mWindowRectRaw.getWidth();
}
void LLViewerWindow::setup2DRender()
{
- gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight());
+ // setup ortho camera
+ gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight());
+ setup2DViewport();
}
-// Could cache the pointer from the last hitObjectOrLand here.
-LLViewerObject *LLViewerWindow::lastObjectHit()
+void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset)
{
- return gObjectList.findObject( gLastHitObjectID );
+ 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]);
}
-const LLVector3d& LLViewerWindow::lastObjectHitOffset()
-{
- return gLastHitObjectOffset;
-}
-// Could cache the pointer from the last hitObjectOrLand here.
-LLViewerObject *LLViewerWindow::lastNonFloraObjectHit()
+void LLViewerWindow::setup3DRender()
{
- return gObjectList.findObject( gLastHitNonFloraObjectID );
+ // setup perspective camera
+ LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
+ setup3DViewport();
}
-const LLVector3d& LLViewerWindow::lastNonFloraObjectHitOffset()
+void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
{
- return gLastHitNonFloraObjectOffset;
+ if (LLRenderTarget::getCurrentBoundTarget() != NULL)
+ {
+ // 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] = mWorldViewRectRaw.mLeft + x_offset;
+ gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
+ }
+ gGLViewport[2] = mWorldViewRectRaw.getWidth();
+ gGLViewport[3] = mWorldViewRectRaw.getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
-
void LLViewerWindow::setShowProgress(const BOOL show)
{
if (mProgressView)
@@ -4681,17 +4278,7 @@ BOOL LLViewerWindow::getShowProgress() const
return (mProgressView && mProgressView->getVisible());
}
-
-void LLViewerWindow::moveProgressViewToFront()
-{
- if( mProgressView && mRootView )
- {
- mRootView->removeChild( mProgressView );
- mRootView->addChild( mProgressView );
- }
-}
-
-void LLViewerWindow::setProgressString(const LLString& string)
+void LLViewerWindow::setProgressString(const std::string& string)
{
if (mProgressView)
{
@@ -4699,7 +4286,7 @@ void LLViewerWindow::setProgressString(const LLString& string)
}
}
-void LLViewerWindow::setProgressMessage(const LLString& msg)
+void LLViewerWindow::setProgressMessage(const std::string& msg)
{
if(mProgressView)
{
@@ -4715,7 +4302,7 @@ void LLViewerWindow::setProgressPercent(const F32 percent)
}
}
-void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const LLString& label )
+void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string& label )
{
if (mProgressView)
{
@@ -4739,6 +4326,10 @@ void LLViewerWindow::dumpState()
void LLViewerWindow::stopGL(BOOL save_state)
{
+ //Note: --bao
+ //if not necessary, do not change the order of the function calls in this function.
+ //if change something, make sure it will not break anything.
+ //especially be careful to put anything behind gTextureList.destroyGL(save_state);
if (!gGLManager.mIsDisabled)
{
llinfos << "Shutting down GL..." << llendl;
@@ -4747,23 +4338,23 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLAppViewer::getTextureCache()->pause();
LLAppViewer::getImageDecodeThread()->pause();
LLAppViewer::getTextureFetch()->pause();
-
+
gSky.destroyGL();
- stop_glerror();
-
- gImageList.destroyGL(save_state);
- stop_glerror();
+ stop_glerror();
+
+ LLManipTranslate::destroyGL() ;
+ stop_glerror();
gBumpImageList.destroyGL();
stop_glerror();
- LLFontGL::destroyGL();
+ LLFontGL::destroyAllGL();
stop_glerror();
LLVOAvatar::destroyGL();
stop_glerror();
- LLDynamicTexture::destroyGL();
+ LLViewerDynamicTexture::destroyGL();
stop_glerror();
if (gPipeline.isInit())
@@ -4776,37 +4367,53 @@ void LLViewerWindow::stopGL(BOOL save_state)
gSphere.cleanupGL();
gCylinder.cleanupGL();
+ if(gPostProcess)
+ {
+ gPostProcess->invalidate();
+ }
+
+ gTextureList.destroyGL(save_state);
+ stop_glerror();
+
gGLManager.mIsDisabled = TRUE;
stop_glerror();
- llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory << " bytes" << llendl;
+ llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemoryInBytes << " bytes" << llendl;
}
}
-void LLViewerWindow::restoreGL(const LLString& progress_message)
+void LLViewerWindow::restoreGL(const std::string& progress_message)
{
+ //Note: --bao
+ //if not necessary, do not change the order of the function calls in this function.
+ //if change something, make sure it will not break anything.
+ //especially, be careful to put something before gTextureList.restoreGL();
if (gGLManager.mIsDisabled)
{
llinfos << "Restoring GL..." << llendl;
gGLManager.mIsDisabled = FALSE;
-
+
+ initGLDefaults();
+ LLGLState::restoreGL();
+
+ gTextureList.restoreGL();
+
// for future support of non-square pixels, and fonts that are properly stretched
//LLFontGL::destroyDefaultFonts();
initFonts();
- initGLDefaults();
- LLGLState::restoreGL();
+
gSky.restoreGL();
gPipeline.restoreGL();
LLDrawPoolWater::restoreGL();
LLManipTranslate::restoreGL();
- gImageList.restoreGL();
+
gBumpImageList.restoreGL();
- LLDynamicTexture::restoreGL();
+ LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
-
+
gResizeScreenTexture = TRUE;
- if (gFloaterCustomize && gFloaterCustomize->getVisible())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
LLVisualParamHint::requestHintUpdates();
}
@@ -4819,104 +4426,47 @@ void LLViewerWindow::restoreGL(const LLString& progress_message)
setProgressString(progress_message);
}
llinfos << "...Restoring GL done" << llendl;
-#if LL_WINDOWS
- if (SetUnhandledExceptionFilter(LLWinDebug::handleException) != LLWinDebug::handleException)
+ if(!LLAppViewer::instance()->restoreErrorTrap())
{
- llwarns << " Someone took over my exception handler (post restoreGL)!" << llendl;
+ llwarns << " Someone took over my signal/exception handler (post restoreGL)!" << llendl;
}
-#endif
}
}
void LLViewerWindow::initFonts(F32 zoom_factor)
{
- LLFontGL::destroyGL();
- LLFontGL::initDefaultFonts( gSavedSettings.getF32("FontScreenDPI"),
+ LLFontGL::destroyAllGL();
+ // Initialize with possibly different zoom factor
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX] * zoom_factor,
mDisplayScale.mV[VY] * zoom_factor,
- gSavedSettings.getString("FontMonospace"),
- gSavedSettings.getF32("FontSizeMonospace"),
- gSavedSettings.getString("FontSansSerif"),
- gSavedSettings.getString("FontSansSerifFallback"),
- gSavedSettings.getF32("FontSansSerifFallbackScale"),
- gSavedSettings.getF32("FontSizeSmall"),
- gSavedSettings.getF32("FontSizeMedium"),
- gSavedSettings.getF32("FontSizeLarge"),
- gSavedSettings.getF32("FontSizeHuge"),
- gSavedSettings.getString("FontSansSerifBold"),
- gSavedSettings.getF32("FontSizeMedium"),
- gDirUtilp->getAppRODataDir()
- );
-}
-void LLViewerWindow::toggleFullscreen(BOOL show_progress)
-{
- if (mWindow)
- {
- mWantFullscreen = mWindow->getFullscreen() ? FALSE : TRUE;
- mShowFullscreenProgress = show_progress;
- }
+ gDirUtilp->getAppRODataDir(),
+ LLUI::getXUIPaths());
+ // Force font reloads, which can be very slow
+ LLFontGL::loadDefaultFonts();
}
-void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height) const
+void LLViewerWindow::requestResolutionUpdate()
{
- fullscreen = mWantFullscreen;
-
- if (gViewerWindow->mWindow
- && gViewerWindow->mWindow->getFullscreen() == mWantFullscreen)
- {
- width = gViewerWindow->getWindowDisplayWidth();
- height = gViewerWindow->getWindowDisplayHeight();
- }
- else if (mWantFullscreen)
- {
- width = gSavedSettings.getS32("FullScreenWidth");
- height = gSavedSettings.getS32("FullScreenHeight");
- }
- else
- {
- width = gSavedSettings.getS32("WindowWidth");
- height = gSavedSettings.getS32("WindowHeight");
- }
+ mResDirty = true;
}
-
-BOOL LLViewerWindow::checkSettings()
+void LLViewerWindow::checkSettings()
{
- BOOL is_fullscreen = gViewerWindow->mWindow->getFullscreen();
- if (is_fullscreen && !mWantFullscreen)
+ if (mStatesDirty)
{
- gViewerWindow->changeDisplaySettings(FALSE,
- LLCoordScreen(gSavedSettings.getS32("WindowWidth"),
- gSavedSettings.getS32("WindowHeight")),
- TRUE,
- mShowFullscreenProgress);
- return TRUE;
+ gGL.refreshState();
+ LLViewerShaderMgr::instance()->setShaders();
+ mStatesDirty = false;
}
- else if (!is_fullscreen && mWantFullscreen)
+
+ // We want to update the resolution AFTER the states getting refreshed not before.
+ if (mResDirty)
{
- if (!LLStartUp::canGoFullscreen())
- {
- return FALSE;
- }
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-#endif
- gViewerWindow->changeDisplaySettings(TRUE,
- LLCoordScreen(gSavedSettings.getS32("FullScreenWidth"),
- gSavedSettings.getS32("FullScreenHeight")),
- gSavedSettings.getBOOL("DisableVerticalSync"),
- mShowFullscreenProgress);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-#endif
- return TRUE;
- }
- return FALSE;
+ reshape(getWindowWidthRaw(), getWindowHeightRaw());
+ mResDirty = false;
+ }
}
void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
@@ -4925,7 +4475,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
stopGL();
if (show_progress_bar)
{
- restoreGL("Changing Resolution...");
+ restoreGL(LLTrans::getString("ProgressChangingResolution"));
}
else
{
@@ -4933,45 +4483,35 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
}
}
-BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar)
+BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar)
{
- BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
- mWantFullscreen = fullscreen;
- mShowFullscreenProgress = show_progress_bar;
- gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
+ //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
+
+ //gResizeScreenTexture = TRUE;
- gResizeScreenTexture = TRUE;
+ //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
+ //U32 old_fsaa = mWindow->getFSAASamples();
- BOOL old_fullscreen = mWindow->getFullscreen();
- if (!old_fullscreen && fullscreen && !LLStartUp::canGoFullscreen())
+ // if not maximized, use the request size
+ if (!mWindow->getMaximized())
{
- // we can't do this now, so do it later
-
- gSavedSettings.setS32("FullScreenWidth", size.mX);
- gSavedSettings.setS32("FullScreenHeight", size.mY);
- //gSavedSettings.setBOOL("DisableVerticalSync", disable_vsync);
-
- return TRUE; // a lie..., because we'll get to it later
+ mWindow->setSize(size);
}
- // going from windowed to windowed
- if (!old_fullscreen && !fullscreen)
+ //if (fsaa == old_fsaa)
{
- // if not maximized, use the request size
- if (!mWindow->getMaximized())
- {
- mWindow->setSize(size);
- }
return TRUE;
}
+/*
+
// Close floaters that don't handle settings change
- LLFloaterSnapshot::hide(0);
+ LLFloaterReg::hideInstance("snapshot");
BOOL result_first_try = FALSE;
BOOL result_second_try = FALSE;
- LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
send_agent_pause();
llinfos << "Stopping GL during changeDisplaySettings" << llendl;
stopGL();
@@ -4979,20 +4519,15 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
LLCoordScreen old_size;
LLCoordScreen old_pos;
mWindow->getSize(&old_size);
- BOOL got_position = mWindow->getPosition(&old_pos);
- if (!old_fullscreen && fullscreen && got_position)
- {
- // switching from windowed to fullscreen, so save window position
- gSavedSettings.setS32("WindowX", old_pos.mX);
- gSavedSettings.setS32("WindowY", old_pos.mY);
- }
-
- result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync);
+ //mWindow->setFSAASamples(fsaa);
+
+ result_first_try = mWindow->switchContext(false, size, disable_vsync);
if (!result_first_try)
{
// try to switch back
- result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync);
+ //mWindow->setFSAASamples(old_fsaa);
+ result_second_try = mWindow->switchContext(false, old_size, disable_vsync);
if (!result_second_try)
{
@@ -5007,7 +4542,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
{
@@ -5016,27 +4551,16 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
if (!result_first_try)
{
- LLStringBase<char>::format_map_t args;
- args["[RESX]"] = llformat("%d",size.mX);
- args["[RESY]"] = llformat("%d",size.mY);
- alertXml("ResolutionSwitchFail", args);
+ LLSD args;
+ args["RESX"] = llformat("%d",size.mX);
+ args["RESY"] = llformat("%d",size.mY);
+ LLNotificationsUtil::add("ResolutionSwitchFail", args);
size = old_size; // for reshape below
}
BOOL success = result_first_try || result_second_try;
- if (success)
- {
-#if LL_WINDOWS
- // Only trigger a reshape after switching to fullscreen; otherwise rely on the windows callback
- // (otherwise size is wrong; this is the entire window size, reshape wants the visible window size)
- if (fullscreen)
-#endif
- {
- reshape(size.mX, size.mY);
- }
- }
- if (!mWindow->getFullscreen() && success)
+ if (success)
{
// maximize window if was maximized, else reposition
if (was_maximized)
@@ -5054,75 +4578,16 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
mIgnoreActivate = FALSE;
gFocusMgr.setKeyboardFocus(keyboard_focus);
- mWantFullscreen = mWindow->getFullscreen();
- mShowFullscreenProgress = FALSE;
return success;
-}
+ */
+}
-F32 LLViewerWindow::getDisplayAspectRatio() const
+F32 LLViewerWindow::getWorldViewAspectRatio() const
{
- if (mWindow->getFullscreen())
- {
- if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
- {
- return mWindow->getNativeAspectRatio();
- }
- else
- {
- return gSavedSettings.getF32("FullScreenAspectRatio");
- }
- }
- else
- {
- return mWindow->getNativeAspectRatio();
- }
-}
-
-
-void LLViewerWindow::drawPickBuffer() const
-{
- if (mPickBuffer)
- {
- gGL.start();
- gGL.pushMatrix();
- LLGLDisable no_blend(GL_BLEND);
- LLGLDisable no_alpha_test(GL_ALPHA_TEST);
- LLGLSNoTexture no_texture;
- glPixelZoom(10.f, 10.f);
- glRasterPos2f(((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),
- ((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f));
- glDrawPixels(PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
- glPixelZoom(1.f, 1.f);
- gGL.color4fv(LLColor4::white.mV);
- gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)),
- FALSE);
- gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f + 10.f));
- gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)),
- llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f + 10.f),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f));
- gGL.translatef(10.f, 10.f, 0.f);
- gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f),
- llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]),
- FALSE);
- gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX)* 10.f),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY + 1) * 10.f),
- llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX + 1) * 10.f),
- llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY) * 10.f),
- FALSE);
- gGL.popMatrix();
- gGL.stop();
- }
+ F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight();
+ return world_aspect;
}
void LLViewerWindow::calcDisplayScale()
@@ -5130,27 +4595,13 @@ 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;
- if(mWindow->getFullscreen())
- {
- display_scale *= (ui_scale_factor * height_normalization);
- }
- else
- {
- display_scale *= ui_scale_factor;
- }
+ display_scale *= ui_scale_factor;
// limit minimum display scale
if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE)
{
display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]);
}
-
- 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());
- }
if (display_scale != mDisplayScale)
{
@@ -5162,152 +4613,324 @@ 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]);
-// static
-bool LLViewerWindow::alertCallback(S32 modal)
+ return res;
+}
+
+S32 LLViewerWindow::getChatConsoleBottomPad()
{
- if (gNoRender)
+ S32 offset = 0;
+
+ if(LLBottomTray::instanceExists())
+ offset += LLBottomTray::getInstance()->getRect().getHeight();
+
+ return offset;
+}
+
+LLRect LLViewerWindow::getChatConsoleRect()
+{
+ LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0);
+ LLRect console_rect = full_window;
+
+ const S32 CONSOLE_PADDING_TOP = 24;
+ const S32 CONSOLE_PADDING_LEFT = 24;
+ const S32 CONSOLE_PADDING_RIGHT = 10;
+
+ console_rect.mTop -= CONSOLE_PADDING_TOP;
+ console_rect.mBottom += getChatConsoleBottomPad();
+
+ console_rect.mLeft += CONSOLE_PADDING_LEFT;
+
+ static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth");
+
+ if (CHAT_FULL_WIDTH)
{
- return false;
+ console_rect.mRight -= CONSOLE_PADDING_RIGHT;
}
else
{
-// if (modal) // we really always want to take you out of mouselook
- {
- // 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() )
- {
- gAgent.changeCameraToDefault();
- }
- }
- return true;
+ // Make console rect somewhat narrow so having inventory open is
+ // less of a problem.
+ console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3;
}
-}
-LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename,
- LLAlertDialog::alert_callback_t callback, void* user_data)
-{
- LLString::format_map_t args;
- return alertXml( xml_filename, args, callback, user_data );
+ return console_rect;
}
+//----------------------------------------------------------------------------
+
-LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename, const LLString::format_map_t& args,
- LLAlertDialog::alert_callback_t callback, void* user_data)
+//static
+bool LLViewerWindow::onAlert(const LLSD& notify)
{
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
if (gNoRender)
{
- llinfos << "Alert: " << xml_filename << llendl;
- if (callback)
- {
- callback(-1, user_data);
- }
- return NULL;
+ llinfos << "Alert: " << notification->getName() << llendl;
+ notification->respond(LLSD::emptyMap());
+ LLNotifications::instance().cancel(notification);
+ return false;
}
// 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;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// LLPickInfo
+//
+LLPickInfo::LLPickInfo()
+ : mKeyMask(MASK_NONE),
+ mPickCallback(NULL),
+ mPickType(PICK_INVALID),
+ mWantSurfaceInfo(FALSE),
+ mObjectFace(-1),
+ mUVCoords(-1.f, -1.f),
+ mSTCoords(-1.f, -1.f),
+ mXYCoords(-1, -1),
+ mIntersection(),
+ mNormal(),
+ mBinormal(),
+ mHUDIcon(NULL),
+ mPickTransparent(FALSE)
+{
+}
- // Note: object adds, removes, and destroys itself.
- return LLAlertDialog::showXml( xml_filename, args, callback, user_data );
+LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
+ MASK keyboard_mask,
+ BOOL pick_transparent,
+ BOOL pick_uv_coords,
+ void (*pick_callback)(const LLPickInfo& pick_info))
+ : mMousePt(mouse_pos),
+ mKeyMask(keyboard_mask),
+ mPickCallback(pick_callback),
+ mPickType(PICK_INVALID),
+ mWantSurfaceInfo(pick_uv_coords),
+ mObjectFace(-1),
+ mUVCoords(-1.f, -1.f),
+ mSTCoords(-1.f, -1.f),
+ mXYCoords(-1, -1),
+ mNormal(),
+ mBinormal(),
+ mHUDIcon(NULL),
+ mPickTransparent(pick_transparent)
+{
}
-LLAlertDialog* LLViewerWindow::alertXmlEditText(const std::string& xml_filename, const LLString::format_map_t& args,
- LLAlertDialog::alert_callback_t callback, void* user_data,
- LLAlertDialog::alert_text_callback_t text_callback, void *text_data,
- const LLString::format_map_t& edit_args, BOOL draw_asterixes)
+void LLPickInfo::fetchResults()
{
- if (gNoRender)
+
+ S32 face_hit = -1;
+ LLVector3 intersection, normal, binormal;
+ LLVector2 uv;
+
+ LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
+
+ F32 icon_dist = 0.f;
+ if (hit_icon)
{
- llinfos << "Alert: " << xml_filename << llendl;
- if (callback)
- {
- callback(-1, user_data);
- }
- return NULL;
+ icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec();
}
+ LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
+ NULL, -1, mPickTransparent, &face_hit,
+ &intersection, &uv, &normal, &binormal);
+
+ mPickPt = mMousePt;
- // 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() )
+ U32 te_offset = face_hit > -1 ? face_hit : 0;
+
+ //unproject relative clicked coordinate from window coordinate using GL
+
+ LLViewerObject* objectp = hit_object;
+
+ if (hit_icon &&
+ (!objectp ||
+ icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec()))
{
- gAgent.changeCameraToDefault();
+ // was this name referring to a hud icon?
+ mHUDIcon = hit_icon;
+ mPickType = PICK_ICON;
+ mPosGlobal = mHUDIcon->getPositionGlobal();
}
-
- // Note: object adds, removes, and destroys itself.
- LLAlertDialog* alert = LLAlertDialog::createXml( xml_filename, args, callback, user_data );
- if (alert)
+ else if (objectp)
{
- if (text_callback)
+ if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
{
- alert->setEditTextCallback(text_callback, text_data);
- }
- alert->setEditTextArgs(edit_args);
- alert->setDrawAsterixes(draw_asterixes);
- alert->show();
- }
- return alert;
-}
+ // Hit land
+ mPickType = PICK_LAND;
+ mObjectID.setNull(); // land has no id
-////////////////////////////////////////////////////////////////////////////
+ // put global position into land_pos
+ LLVector3d land_pos;
+ if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos))
+ {
+ // The selected point is beyond the draw distance or is otherwise
+ // not selectable. Return before calling mPickCallback().
+ return;
+ }
-LLBottomPanel::LLBottomPanel(const LLRect &rect) :
- LLPanel("", rect, FALSE),
- mIndicator(NULL)
-{
- // bottom panel is focus root, so Tab moves through the toolbar and button bar, and overlay
- setFocusRoot(TRUE);
- // flag this panel as chrome so buttons don't grab keyboard focus
- setIsChrome(TRUE);
+ // Fudge the land focus a little bit above ground.
+ mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f;
+ }
+ else
+ {
+ if(isFlora(objectp))
+ {
+ mPickType = PICK_FLORA;
+ }
+ else
+ {
+ mPickType = PICK_OBJECT;
+ }
+ mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
+ mObjectID = objectp->mID;
+ mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
- mFactoryMap["toolbar"] = LLCallbackMap(createToolBar, NULL);
- mFactoryMap["overlay"] = LLCallbackMap(createOverlayBar, NULL);
- mFactoryMap["hud"] = LLCallbackMap(createHUD, NULL);
- gUICtrlFactory->buildPanel(this, "panel_bars.xml", &getFactoryMap());
+ mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
+
+ if (mWantSurfaceInfo)
+ {
+ getSurfaceInfo();
+ }
+ }
+ }
- setOrigin(rect.mLeft, rect.mBottom);
- reshape(rect.getWidth(), rect.getHeight());
+ if (mPickCallback)
+ {
+ mPickCallback(*this);
+ }
}
-void LLBottomPanel::setFocusIndicator(LLView * indicator)
+LLPointer<LLViewerObject> LLPickInfo::getObject() const
{
- mIndicator = indicator;
+ return gObjectList.findObject( mObjectID );
}
-void LLBottomPanel::draw()
+void LLPickInfo::updateXYCoords()
{
- if(mIndicator)
+ if (mObjectFace > -1)
{
- BOOL hasFocus = gFocusMgr.childHasKeyboardFocus(this);
- mIndicator->setVisible(hasFocus);
- mIndicator->setEnabled(hasFocus);
+ const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
+ LLPointer<LLViewerTexture> imagep = LLViewerTextureManager::getFetchedTexture(tep->getID());
+ if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
+ {
+ mXYCoords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth());
+ mXYCoords.mY = llround((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight());
+ }
}
- LLPanel::draw();
}
-void* LLBottomPanel::createHUD(void* data)
+void LLPickInfo::getSurfaceInfo()
{
- delete gHUDView;
- gHUDView = new LLHUDView();
- return gHUDView;
+ // set values to uninitialized - this is what we return if no intersection is found
+ mObjectFace = -1;
+ mUVCoords = LLVector2(-1, -1);
+ mSTCoords = LLVector2(-1, -1);
+ mXYCoords = LLCoordScreen(-1, -1);
+ mIntersection = LLVector3(0,0,0);
+ mNormal = LLVector3(0,0,0);
+ mBinormal = LLVector3(0,0,0);
+
+ LLViewerObject* objectp = getObject();
+
+ if (objectp)
+ {
+ if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,
+ objectp, -1, mPickTransparent,
+ &mObjectFace,
+ &mIntersection,
+ &mSTCoords,
+ &mNormal,
+ &mBinormal))
+ {
+ // if we succeeded with the intersect above, compute the texture coordinates:
+
+ if (objectp->mDrawable.notNull() && mObjectFace > -1)
+ {
+ LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
+
+ mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ }
+
+ // and XY coords:
+ updateXYCoords();
+
+ }
+ }
}
-void* LLBottomPanel::createOverlayBar(void* data)
+/* code to get UV via a special UV render - removed in lieu of raycast method
+LLVector2 LLPickInfo::pickUV()
{
- delete gOverlayBar;
- gOverlayBar = new LLOverlayBar();
- return gOverlayBar;
-}
+ LLVector2 result(-1.f, -1.f);
+
+ LLViewerObject* objectp = getObject();
+ if (!objectp)
+ {
+ return result;
+ }
+
+ if (mObjectFace > -1 &&
+ objectp->mDrawable.notNull() && objectp->getPCode() == LL_PCODE_VOLUME &&
+ mObjectFace < objectp->mDrawable->getNumFaces())
+ {
+ S32 scaled_x = llround((F32)mPickPt.mX * gViewerWindow->getDisplayScale().mV[VX]);
+ S32 scaled_y = llround((F32)mPickPt.mY * gViewerWindow->getDisplayScale().mV[VY]);
+ const S32 UV_PICK_WIDTH = 5;
+ const S32 UV_PICK_HALF_WIDTH = (UV_PICK_WIDTH - 1) / 2;
+ U8 uv_pick_buffer[UV_PICK_WIDTH * UV_PICK_WIDTH * 4];
+ LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
+ if (facep)
+ {
+ LLGLState scissor_state(GL_SCISSOR_TEST);
+ scissor_state.enable();
+ LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, FALSE);
+ //glViewport(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH);
+ glScissor(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
-void* LLBottomPanel::createToolBar(void* data)
+ facep->renderSelectedUV();
+
+ glReadPixels(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, GL_RGBA, GL_UNSIGNED_BYTE, uv_pick_buffer);
+ U8* center_pixel = &uv_pick_buffer[4 * ((UV_PICK_WIDTH * UV_PICK_HALF_WIDTH) + UV_PICK_HALF_WIDTH + 1)];
+
+ result.mV[VX] = (F32)((center_pixel[VGREEN] & 0xf) + (16.f * center_pixel[VRED])) / 4095.f;
+ result.mV[VY] = (F32)((center_pixel[VGREEN] >> 4) + (16.f * center_pixel[VBLUE])) / 4095.f;
+ }
+ }
+
+ return result;
+} */
+
+
+//static
+bool LLPickInfo::isFlora(LLViewerObject* object)
{
- delete gToolBar;
- gToolBar = new LLToolBar();
- return gToolBar;
+ if (!object) return false;
+
+ LLPCode pcode = object->getPCode();
+
+ if( (LL_PCODE_LEGACY_GRASS == pcode)
+ || (LL_PCODE_LEGACY_TREE == pcode)
+ || (LL_PCODE_TREE_NEW == pcode))
+ {
+ return true;
+ }
+ return false;
}