From ea361055b975ba6d51bffe18a869f0c1200ad354 Mon Sep 17 00:00:00 2001
From: XenHat <commits@xenh.at>
Date: Sat, 31 Oct 2020 22:56:03 -0400
Subject: [PATCH] Port Cinematic Mode to this viewer. This feature aims at
 emulating the "Hide all UI" shortcut, without the downside of preventing
 interaction with the world and still allowing floaters to be shown on demand.

---
 indra/newview/CMakeLists.txt                  |  2 +
 indra/newview/alcinematicmode.cpp             | 58 +++++++++++++++++++
 indra/newview/alcinematicmode.h               | 32 ++++++++++
 indra/newview/alviewermenu.cpp                | 35 +++++++++++
 .../newview/app_settings/settings_alchemy.xml | 11 ++++
 indra/newview/llhudtext.cpp                   |  5 ++
 indra/newview/lltoolpie.cpp                   |  5 ++
 indra/newview/llviewerdisplay.cpp             |  5 +-
 indra/newview/llvoavatar.cpp                  |  1 +
 .../skins/default/xui/en/menu_viewer.xml      |  8 +++
 .../skins/default/xui/en/notifications.xml    | 15 +++++
 .../xui/en/panel_preferences_graphics1.xml    | 14 ++++-
 12 files changed, 188 insertions(+), 3 deletions(-)
 create mode 100644 indra/newview/alcinematicmode.cpp
 create mode 100644 indra/newview/alcinematicmode.h

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4a1de70396b..e70c6ce3c76 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -113,6 +113,7 @@ include_directories(SYSTEM
     )
 
 set(viewer_SOURCE_FILES
+    alcinematicmode.cpp
     alaoengine.cpp
     alaoset.cpp
     alavataractions.cpp
@@ -773,6 +774,7 @@ set(VIEWER_BINARY_NAME "alchemy-bin" CACHE STRING
 set(viewer_HEADER_FILES
     CMakeLists.txt
     ViewerInstall.cmake
+    alcinematicmode.h
     alaoengine.h
     alaoset.h
     alavataractions.h
diff --git a/indra/newview/alcinematicmode.cpp b/indra/newview/alcinematicmode.cpp
new file mode 100644
index 00000000000..b65df18aedf
--- /dev/null
+++ b/indra/newview/alcinematicmode.cpp
@@ -0,0 +1,58 @@
+/**
+* @file alcinematicmode.cpp
+* @brief Cinematic UI Mode
+*
+* $LicenseInfo:firstyear=2017&license=viewerlgpl$
+* Copyright (C) 2017-2020 XenHat <me@xenh.at>
+*
+* 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.
+*
+* 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.
+* $/LicenseInfo$
+**/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "alcinematicmode.h"
+#include "llviewerwindow.h"
+#include "llmoveview.h"
+#include "llnavigationbar.h"
+#include "llchicletbar.h"
+#include "llhudtext.h"
+#include <llagentcamera.h>
+
+bool ALCinematicMode::_enabled = false;
+
+// static
+void ALCinematicMode::toggle()
+{
+	if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+	{
+		LL_INFOS() << "Toggling Cinematic Mode" << LL_ENDL;
+		// Ordered to have a nice effect
+		if (_enabled)
+		{
+			// Showing elements again
+			LLChicletBar::getInstance()->setVisible(TRUE);
+			LLPanelStandStopFlying::getInstance()->setVisible(TRUE); // FIXME: that doesn't always work
+			LLNavigationBar::getInstance()->setVisible(TRUE);
+			gViewerWindow->setUIVisibility(TRUE);
+		}
+		else
+		{
+			// Hiding Elements
+			gViewerWindow->setUIVisibility(FALSE);
+			LLNavigationBar::getInstance()->setVisible(FALSE);
+			LLPanelStandStopFlying::getInstance()->setVisible(FALSE); // FIXME: that doesn't always work
+			LLChicletBar::getInstance()->setVisible(FALSE);
+		}
+		_enabled = !_enabled;
+		LLHUDText::refreshAllObjectText();
+	}
+}
diff --git a/indra/newview/alcinematicmode.h b/indra/newview/alcinematicmode.h
new file mode 100644
index 00000000000..c625ac0080c
--- /dev/null
+++ b/indra/newview/alcinematicmode.h
@@ -0,0 +1,32 @@
+/**
+* @file alcinematicmode.h
+* @brief Cinematic UI Mode for Metaverse clients
+*
+* $LicenseInfo:firstyear=2017&license=viewerlgpl$
+* Copyright (C) 2017-2020 XenHat <me@xenh.at>
+*
+* 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.
+*
+* 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.
+* $/LicenseInfo$
+**/
+
+#ifndef AL_CINEMATICMODE_H
+#define AL_CINEMATICMODE_H
+#pragma once
+
+// Hides various UI Elements to provide a more cinematic experience
+class ALCinematicMode
+{
+	static bool _enabled;
+public:
+	static void toggle();
+	static bool isEnabled() { return _enabled; };
+};
+#endif
\ No newline at end of file
diff --git a/indra/newview/alviewermenu.cpp b/indra/newview/alviewermenu.cpp
index 2d0e3ff8278..9680a020908 100644
--- a/indra/newview/alviewermenu.cpp
+++ b/indra/newview/alviewermenu.cpp
@@ -27,9 +27,12 @@
 
 // newview
 #include "alavataractions.h"
+#include "alcinematicmode.h"
 #include "alfloaterparticleeditor.h"
 #include "llagent.h"
 #include "llhudobject.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
 #include "llselectmgr.h"
 #include "llviewermenu.h"
 #include "llviewerobject.h"
@@ -194,6 +197,36 @@ namespace
 	}
 }
 
+
+void confirm_cinematic_mode(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option == 0) // OK
+	{
+		ALCinematicMode::toggle();
+	}
+}
+
+bool toggle_cinematic_mode()
+{
+	LLNotification::Params params("CinematicConfirmHideUI");
+	params.functor.function(boost::bind(&confirm_cinematic_mode, _1, _2));
+	LLSD substitutions;
+	substitutions["SHORTCUT"] = "Alt+Shift+C";
+	params.substitutions = substitutions;
+	if (!ALCinematicMode::isEnabled())
+	{
+		// hiding, so show notification
+		LLNotifications::instance().add(params);
+	}
+	else
+	{
+		LLNotifications::instance().forceResponse(params, 0);
+	}
+	return true;
+}
+
+
 ////////////////////////////////////////////////////////
 
 void ALViewerMenu::initialize_menus()
@@ -215,4 +248,6 @@ void ALViewerMenu::initialize_menus()
 
 	commit.add("World.ClearEffects",	[](LLUICtrl* ctrl, const LLSD& param) { world_clear_effects(); });
 	commit.add("World.SyncAnimations",	[](LLUICtrl* ctrl, const LLSD& param) { world_sync_animations(); });
+
+	commit.add("View.ToggleCinematicMode", [](LLUICtrl* ctrl, const LLSD& param) { toggle_cinematic_mode(); });
 }
diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml
index 7780613a362..3832d350e9e 100644
--- a/indra/newview/app_settings/settings_alchemy.xml
+++ b/indra/newview/app_settings/settings_alchemy.xml
@@ -211,6 +211,17 @@
       <key>Value</key>
       <string>/tp2cam</string>
     </map>
+    <key>AlchemyCinematicModeHideHoverText</key>
+    <map>
+      <key>Comment</key>
+      <string>Hide Hover Text in cinematic mode.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AlchemyDisableCameraCollision</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 1623999b1a8..62314039b4c 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -51,6 +51,7 @@
 #include "rlvcommon.h"
 // [/RLVa:KB]
 #include <boost/tokenizer.hpp>
+#include "alcinematicmode.h"
 
 const F32 HORIZONTAL_PADDING = 15.f;
 const F32 VERTICAL_PADDING = 12.f;
@@ -242,6 +243,10 @@ void LLHUDText::setString(const std::string &text_utf8)
 //	addLine(text_utf8, mColor);
 // [RLVa:KB] - Checked: RLVa-2.0.3
 	// NOTE: setString() is called for debug and map beacons as well
+	if (ALCinematicMode::isEnabled() && gSavedSettings.getBool("AlchemyCinematicModeHideHoverText"))
+	{
+		return;
+	}
 	if (RlvActions::isRlvEnabled())
 	{
 		std::string text(text_utf8);
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 8429198777b..d456a570e3c 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -74,6 +74,7 @@
 #include "rlvactions.h"
 #include "rlvhandler.h"
 // [/RLVa:KB]
+#include "alcinematicmode.h"
 
 extern BOOL gDebugClicks;
 
@@ -1408,6 +1409,10 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
 	std::string tooltip_msg;
 	std::string line;
 
+	if (ALCinematicMode::isEnabled())
+	{
+		return TRUE;
+	}
 	if ( hover_object )
 	{
 		handleTooltipObject(hover_object, line, tooltip_msg  );
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 8c56da204c1..01df8686b95 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -82,6 +82,7 @@
 // [/RLVa:KB]
 
 #include "llenvironment.h"
+#include "alcinematicmode.h"
 
 extern LLPointer<LLViewerTexture> gStartTexture;
 extern bool gShiftFrame;
@@ -421,7 +422,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	static const LLCachedControl<S32> av_name_tag_mode(gSavedSettings, "AvatarNameTagMode");
 	static const LLCachedControl<bool> name_tag_show_grp_title(gSavedSettings, "NameTagShowGroupTitles");
 
-	LLVOAvatar::sRenderName = av_name_tag_mode;
+	LLVOAvatar::sRenderName = (ALCinematicMode::isEnabled() ? 0 : (S32)av_name_tag_mode);;
 	LLVOAvatar::sRenderGroupTitles = (name_tag_show_grp_title && av_name_tag_mode);
 	
 	gPipeline.mBackfaceCull = TRUE;
@@ -1121,7 +1122,7 @@ void render_hud_attachments()
 	// smoothly interpolate current zoom level
 	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f));
 
-	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
+	if (!ALCinematicMode::isEnabled() && LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
 	{
 		LLPipeline::sRenderingHUDs = TRUE;
 		LLCamera hud_cam = *LLViewerCamera::getInstance();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 49678a9a441..9264e6cc8f6 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -119,6 +119,7 @@
 #include "llrendersphere.h"
 
 #include <boost/lexical_cast.hpp>
+#include "alcinematicmode.h"
 
 extern F32 SPEED_ADJUST_MAX;
 extern F32 SPEED_ADJUST_MAX_SEC;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 66f4be32762..2cbabd842d2 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -263,6 +263,14 @@
              function="Floater.Toggle"
              parameter="toybox" />
         </menu_item_call>
+      <menu_item_call
+          label="Cinematic Mode"
+          name="CinematicMode"
+          shortcut="alt|shift|c">
+        <menu_item_call.on_click
+            function="View.ToggleCinematicMode" >
+        </menu_item_call.on_click>
+      </menu_item_call>
          <menu_item_call
          label="Hide all controls"
          name="Hide UI"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f2f1a44d317..6f8ef720215 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -12197,5 +12197,20 @@ Always Run enabled.
     type="notifytip">
 Always Run disabled.
   </notification>
+
+  <notification
+     name="CinematicConfirmHideUI"
+     label=""
+     type="alertmodal">
+    <unique/>
+    <tag>confirm</tag>
+    Cinematic Mode hides most of the UI, hover text, the voice dots and your huds.
+    To get them back, press [SHORTCUT].
+    <usetemplate
+    name="okcancelignore"
+    yestext="OK"
+    notext="Cancel"
+    ignoretext="Confirm before enabling Cinematic Mode"/>
+  </notification>
   
 </notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 5aff7a51276..c0686fea9e0 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -258,7 +258,19 @@
     <check_box.commit_callback
       function="Pref.RenderOptionUpdate" />
   </check_box>
-  
+  <check_box
+    control_name="AlchemyCinematicModeHideHoverText"
+    height="16"
+    initial_value="true"
+    label="Hide Hover Text in Cinematic Mode"
+    layout="topleft"
+    left="30"
+    name="HideHoverTextInCinematicMode"
+    top_delta="24"
+    width="256">
+    <check_box.commit_callback
+      function="Pref.RenderOptionUpdate" />
+  </check_box>
   <slider
     control_name="IndirectMaxComplexity"
     tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
-- 
GitLab