From 17f2234a96d11a78726a77285b77dd25721ab8ce Mon Sep 17 00:00:00 2001
From: Vadim Savchuk <vsavchuk@productengine.com>
Date: Tue, 27 Apr 2010 16:39:19 +0300
Subject: [PATCH] Implemented perpetual loading indicator widget (EXT-6596).

Simple perpetual loading indicator a la MacOS X or YouTube.
Implements spinning by changing pre-defined images.
The images are hardcoded, shared by all instances of the widget.
Number of rotations per second can be changed via params.

Reviewed by Mike at https://codereview.productengine.com/secondlife/r/320/

--HG--
branch : product-engine
---
 .../llui_libtest/llwidgetreg.cpp              |   2 +
 indra/llui/CMakeLists.txt                     |   2 +
 indra/llui/llloadingindicator.cpp             | 135 ++++++++++++++++++
 indra/llui/llloadingindicator.h               |  93 ++++++++++++
 indra/llui/llui.cpp                           |   4 +
 indra/llui/lluifwd.h                          |   1 +
 .../default/textures/icons/Progress_1.png     | Bin 0 -> 464 bytes
 .../default/textures/icons/Progress_10.png    | Bin 0 -> 461 bytes
 .../default/textures/icons/Progress_11.png    | Bin 0 -> 471 bytes
 .../default/textures/icons/Progress_12.png    | Bin 0 -> 457 bytes
 .../default/textures/icons/Progress_2.png     | Bin 0 -> 461 bytes
 .../default/textures/icons/Progress_3.png     | Bin 0 -> 487 bytes
 .../default/textures/icons/Progress_4.png     | Bin 0 -> 466 bytes
 .../default/textures/icons/Progress_5.png     | Bin 0 -> 477 bytes
 .../default/textures/icons/Progress_6.png     | Bin 0 -> 460 bytes
 .../default/textures/icons/Progress_7.png     | Bin 0 -> 483 bytes
 .../default/textures/icons/Progress_8.png     | Bin 0 -> 467 bytes
 .../default/textures/icons/Progress_9.png     | Bin 0 -> 483 bytes
 .../skins/default/textures/textures.xml       |  13 ++
 .../xui/en/widgets/loading_indicator.xml      |   8 ++
 20 files changed, 258 insertions(+)
 create mode 100644 indra/llui/llloadingindicator.cpp
 create mode 100644 indra/llui/llloadingindicator.h
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_1.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_10.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_11.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_12.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_2.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_3.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_4.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_5.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_6.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_7.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_8.png
 create mode 100644 indra/newview/skins/default/textures/icons/Progress_9.png
 create mode 100644 indra/newview/skins/default/xui/en/widgets/loading_indicator.xml

diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
index c6e2e79a09f..57c39243fbe 100644
--- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
@@ -37,6 +37,7 @@
 #include "llcombobox.h"
 #include "llcontainerview.h"
 #include "lliconctrl.h"
+#include "llloadingindicator.h"
 #include "llmenubutton.h"
 #include "llmenugl.h"
 #include "llmultislider.h"
@@ -72,6 +73,7 @@ void LLWidgetReg::initClass(bool register_widgets)
 		LLDefaultChildRegistry::Register<LLFlyoutButton> flyout_button("flyout_button");
 		LLDefaultChildRegistry::Register<LLContainerView> container_view("container_view");
 		LLDefaultChildRegistry::Register<LLIconCtrl> icon("icon");
+		LLDefaultChildRegistry::Register<LLLoadingIndicator> loading_indicator("loading_indicator");
 		LLDefaultChildRegistry::Register<LLLineEditor> line_editor("line_editor");
 		LLDefaultChildRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator");
 		LLDefaultChildRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call");
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 532b6b6524b..3ecab907564 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -52,6 +52,7 @@ set(llui_SOURCE_FILES
     llkeywords.cpp
     lllayoutstack.cpp
     lllineeditor.cpp
+    llloadingindicator.cpp
     lllocalcliprect.cpp
     llmenubutton.cpp
     llmenugl.cpp
@@ -144,6 +145,7 @@ set(llui_HEADER_FILES
     lllayoutstack.h
     lllazyvalue.h
     lllineeditor.h
+    llloadingindicator.h
     lllocalcliprect.h
     llmenubutton.h
     llmenugl.h
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
new file mode 100644
index 00000000000..8dec6ea9df0
--- /dev/null
+++ b/indra/llui/llloadingindicator.cpp
@@ -0,0 +1,135 @@
+/** 
+ * @file llloadingindicator.cpp
+ * @brief Perpetual loading indicator
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * 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://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * 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://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * 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.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llloadingindicator.h"
+
+// Linden library includes
+#include "llsingleton.h"
+
+// Project includes
+#include "lluictrlfactory.h"
+#include "lluiimage.h"
+
+static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
+
+///////////////////////////////////////////////////////////////////////////////
+// LLLoadingIndicator::Data class
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Pre-loaded images shared by all instances of the widget
+ */
+class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data>
+{
+public:
+	/*virtual*/ void		initSingleton(); // from LLSingleton
+
+	LLPointer<LLUIImage>	getNextImage(S8& idx) const;
+	U8						getImagesCount() const	{ return NIMAGES; }
+private:
+
+	static const U8			NIMAGES = 12;
+	LLPointer<LLUIImage>	mImages[NIMAGES];
+};
+
+// virtual
+// Called right after the instance gets constructed.
+void LLLoadingIndicator::Data::initSingleton()
+{
+	// Load images.
+	for (U8 i = 0; i < NIMAGES; ++i)
+	{
+		std::string img_name = llformat("Progress_%d", i+1);
+		mImages[i] = LLUI::getUIImage(img_name, 0);
+		llassert(mImages[i]);
+	}
+}
+
+LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const
+{
+	// Actually selects previous image because
+	// current images seem to be in wrong order;
+	// performs array bounds checking.
+	idx = idx > 0 ? llmin(NIMAGES-1, idx-1) : NIMAGES-1;
+	return mImages[idx];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LLLoadingIndicator class
+///////////////////////////////////////////////////////////////////////////////
+
+LLLoadingIndicator::LLLoadingIndicator(const Params& p)
+:	LLUICtrl(p)
+	, mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f)
+	, mCurImageIdx(-1)
+{
+	// Select initial image.
+	mCurImagep = Data::instance().getNextImage(mCurImageIdx);
+
+	// Start timer for switching images.
+	start();
+}
+
+void LLLoadingIndicator::draw()
+{
+	// Time to switch to the next image?
+	if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())
+	{
+		// Switch to the next image.
+		mCurImagep = Data::instance().getNextImage(mCurImageIdx);
+
+		// Restart timer.
+		start();
+	}
+
+	// Draw current image.
+	if( mCurImagep.notNull() )
+	{
+		mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
+	}
+
+	LLUICtrl::draw();
+}
+
+void LLLoadingIndicator::stop()
+{
+	mImageSwitchTimer.stop();
+}
+
+void LLLoadingIndicator::start()
+{
+	mImageSwitchTimer.start();
+	F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec);
+	mImageSwitchTimer.setTimerExpirySec(period);
+}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
new file mode 100644
index 00000000000..32dd1fead80
--- /dev/null
+++ b/indra/llui/llloadingindicator.h
@@ -0,0 +1,93 @@
+/** 
+ * @file llloadingindicator.h
+ * @brief Perpetual loading indicator
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * 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://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * 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://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * 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.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLOADINGINDICATOR_H
+#define LL_LLLOADINGINDICATOR_H
+
+#include "lluictrl.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// class LLLoadingIndicator
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Perpetual loading indicator (a la MacOSX or YouTube)
+ * 
+ * Number of rotations per second can be overriden
+ * with the "roations_per_sec" parameter.
+ * 
+ * Can start/stop spinning.
+ * 
+ * @see start()
+ * @see stop()
+ */
+class LLLoadingIndicator
+: public LLUICtrl
+{
+	LOG_CLASS(LLLoadingIndicator);
+public:
+	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+	{
+		Optional<F32>	rotations_per_sec;
+		Params()
+		:	rotations_per_sec("rotations_per_sec", 1.0f)
+		{}
+	};
+
+	virtual ~LLLoadingIndicator() {}
+
+	// llview overrides
+	virtual void draw();
+
+	/**
+	 * Stop spinning.
+	 */
+	void stop();
+
+	/**
+	 * Start spinning.
+	 */
+	void start();
+
+private:
+	LLLoadingIndicator(const Params&);
+	friend class LLUICtrlFactory;
+
+	class Data;
+
+	F32						mRotationsPerSec;
+	S8						mCurImageIdx;
+	LLPointer<LLUIImage>	mCurImagep;
+	LLFrameTimer			mImageSwitchTimer;
+};
+
+#endif // LL_LLLOADINGINDICATOR_H
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index f9a4ed7285d..bf12384a284 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -56,6 +56,7 @@
 #include "llfloaterreg.h"
 #include "llmenugl.h"
 #include "llmenubutton.h"
+#include "llloadingindicator.h"
 #include "llwindow.h"
 
 // for registration
@@ -94,7 +95,10 @@ std::list<std::string> gUntranslated;
 static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
 static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button");
 static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
+
+// register other widgets which otherwise may not be linked in
 static LLDefaultChildRegistry::Register<LLMenuButton> register_menu_button("menu_button");
+static LLDefaultChildRegistry::Register<LLLoadingIndicator> register_loading_indicator("loading_indicator");
 
 
 //
diff --git a/indra/llui/lluifwd.h b/indra/llui/lluifwd.h
index f99bb39fdde..d6047b943cd 100644
--- a/indra/llui/lluifwd.h
+++ b/indra/llui/lluifwd.h
@@ -39,6 +39,7 @@ class LLComboBox;
 class LLDragHandle;
 class LLFloater;
 class LLIconCtrl;
+class LLLoadingIndicator;
 class LLLineEditor;
 class LLMenuGL;
 class LLPanel;
diff --git a/indra/newview/skins/default/textures/icons/Progress_1.png b/indra/newview/skins/default/textures/icons/Progress_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..58b56003c40a1c50fb38a02ad749862278fee619
GIT binary patch
literal 464
zcmV;>0WbcEP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUza!Eu%RCwBA{Qv(y11$j)1C7DZw}1s*
zfRT|Ar(y>O$Mrx;;J|_Xj=0pI$0-Xw+kplq0IB&v90)XY1ITcYFg1hd0hI2iY8*sF
zL?r;R1JKn6fLxHv6@b2JfJ%R$C=Q@tKGdQOU%q^q_~pxIP_W1Y@kELv843cS!4km3
z!{e}J%O*jxlMyJ^kuh3OH30E^O3Y)y68`I<sRafm;xWtsEdhLh`W|l(Atyy*B2)p2
zLEr#MLDbmPS^&iJ@%W$sgh>h_sKEhHuPZ=(k%+^NdXSHS2IT|kLSQMd0i$F<cQvS}
z09pVO+yIROP`qqVQ&)$@2Pg>Zb+oktb+k1>h6h0PVwi_3Cxcw<SYKBSim-fWygY>Z
zYCSBju3WvA4>S{`#u1k<vHAchs6Z~=4=OT%mMJb@xdy~`hzt*51hVf#gU}JkKY**S
zV<IAjfIuM@xk5BGq-QjA0Ce?ws4s{%k8!k49&if)0t^6n<HX~X{nWYu0000<MNUMn
GLSTXsM7Wv&

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_10.png b/indra/newview/skins/default/textures/icons/Progress_10.png
new file mode 100644
index 0000000000000000000000000000000000000000..07fe0be8a3999b4713a0fa26ffaf9263a831b15e
GIT binary patch
literal 461
zcmV;;0W$uHP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzZ%IT!RCwC#RZU96Kp1tzWdwVJx>PqF
zAvu8!2v%3k31ZfQt%7Uo39{1)!o(9KM{v>Vvhf7=2JwCR3Zcm~3AMQCz+)!UnfJb*
zmsDk0wzbZoHUgDH1oEgjtAV%?UqgX7;~`9)?059mB`~Fc{nr9Qd`WUG`%lj=Hqa{*
zC^T6qwM^icONqKao_x6D$-9qrM>fyTP78e7jV!0s8!-f0AlD>M0k`bV&Wa|yVdO*8
zfr5Z-J26WjV+MFh5=Vyn37}E```oirmBEY$>yDI|->v_mA)5gZ8tZd=7XpK2e5Eb|
zsWeW~Zc9`sQOh9kg=vo&1pVu)Xpzs<WX(CUtlfuh_d<xI53jO$aCme=_lR@mHkCUC
zkDF}jNwW~SYgv}hC_hOSaxHs4qITI>uh!Qz|Dqvsag(?z9gQCM@%-a3tQE>LWeFXK
zB>5gRdC}UOgOcBZg)^&vu91Oe7Pa{{f0_R;@GZaqduUe^)qWsM00000NkvXXu0mjf
DWf00z

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_11.png b/indra/newview/skins/default/textures/icons/Progress_11.png
new file mode 100644
index 0000000000000000000000000000000000000000..215d68cc465fa2c7597c650b0bb5251b08f46f83
GIT binary patch
literal 471
zcmV;|0Vw{7P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzc}YY;RCwC#RZC98Fc7U#4^Wf~lqGNp
z=L94Yg2JktAjuku0upPQ6J!SgfzqBJxdBIL*f*j#2yfI$Wtn_cRcvbM$zywF-i&9Q
zh&<1GyBr6-9gjUh^PnQD=wN5%>oKnNw*|q131nviDa|n;Yn;36JmR%1GSU52)gS<3
zkVL?+LT3f|OcJwA>mu7g3Ru9Gekg>P0*4SI)=Al>TagjH3j_^U<<|M@>qc}fm<Gz0
zUqukUe<qa0>)XdOZ_(ORb^0ZC<h&?w+M=OSMQ^1a{vk+`coV^BbbXKM4473or$FXc
zm*>-s%|+g8%77eG;VA7PM|D#{FrkcbMGj^UM6<>Wctkvtfe*qTl8;YL=e$o@Sy`6Z
zhG96|Nn|71wkbtyhT#jfp2KzdW;tMakS&)EqPDrPrCAESHPPSdRY`tCDaei<9-l~-
zle=31dBIm`Vx6dM+U09nykf89%+qwX|C%D|h_h(zPwfB6|4#5LzyMlS4(+9ZTao|(
N002ovPDHLkV1l$o%>4iW

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_12.png b/indra/newview/skins/default/textures/icons/Progress_12.png
new file mode 100644
index 0000000000000000000000000000000000000000..d75558862140ee581dcf463bd903829c987155b1
GIT binary patch
literal 457
zcmV;)0XF`LP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzYe_^wRCwC#RY6L_Korf02T(9>jT?K7
z$q8&gu)3-zNV*nm6<n8`AUmxfB%UC-fk&{Oz}_If4=)m?O)?RSn|^rAOqluqzxU@)
zR9TkJHf_(@vh4zN+P?WgDfKhg+8<*`fS@Sy%*LU4X}TCJInMu7BFP-k$hyE%GWW2a
zwPdY<ai1E9EIFK}7-L`soNRFH0kS9OneH0U0?INJLSS;(u<so>pp=uwqSRqXH3O0s
zX(B<JzcmJ<(RIqKDvMicC^eeH(K**EvTv10oa@?wF7t>gpuI$369J79J-@t0f?g8Q
z@sLIK$l|6U##9(1NGL_Vy1dA2Z&AuIbKT?k{^9Y9{qQCq&jtgJ&PDH#w@uC{+dhzt
z{l(%bIC9;Pb@`;Tq*kjCSxXSViKQ}iufIjeT(gOm)4SVKtYxk-SCHj{68Z>I{Pr!X
zZpWr3nizYW-i>A&7^Gxj?N9Cg$^RbUTYv!oS9->d*7aUp00000NkvXXu0mjfAx6*(

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_2.png b/indra/newview/skins/default/textures/icons/Progress_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6640ee227ba754700c2d29014eb47dc06f765d84
GIT binary patch
literal 461
zcmV;;0W$uHP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzZ%IT!RCwC#RZU96KostX2Z*G5>rFBz
zutCx2Mm<5=wP20Vb;t?gN-GHF1|3ggc6R9v;`ho6Oyf*CAxJk3e9Zs*`QA@NRaJxk
z{KQ^CX9YqC>*XMjOAJ3sEko0}$=Jg-?NM}niy;TX#p0zP9e`qGV+<d_9TYy>WE^bq
zu;ei{oTZIB?i8`*C9GDMla*v`vRZxLu)t4X1{6A7T`0<#BBCW@YL0;^pPy1Jv~_0>
z#!SJ81i_Odmy9uHByH+w1o;ujT~o3ti|~h{<Y`Wvd)ijkrw&Xp@R;)f^W5)iqX^zi
zfV}1HgwTm17Q7K;Dkh5#N>vYnV$P_-DT|<>-Yop#F!Oz%;*!)=99^6RESzc}<~mtF
zcdcZySk4~qLkN$xpr_m(>R81vh?Gd1m#xk2_3fQ3r3P1CU7nv{P4fVAdiTW?O1x3F
zI@s2WMm(A-cG|epzg@$Fb&bFS=~~JAU*_%={0cAtlzQ1gTq;&A00000NkvXXu0mjf
DITFkJ

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_3.png b/indra/newview/skins/default/textures/icons/Progress_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..5decbe977e25de8cd5ed19dd1cc844df0a04e715
GIT binary patch
literal 487
zcmV<D0T}*?P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUziAh93RCwC#RZ&XAKoISU2Z&(5jYseX
z$q7tQH2P&up#2tXBlz8f9>9KS1tIYQX1#$oFn(E#(B2@v(Fv5eo2F>-rwhZRyRY-+
z&15#BD2moHmsk-jOdy2Nf<5mzg`18>H?HbjmF#*QI|81-UBg@iP2eq<q%+I19k>|g
zOPLOJG1lfN%-Hu8XZ;GMd5MC{E6P0UUYtv)pe!ld0Coy{9*^Ii;JdH{*}G6f%FHx<
z95y8=H<OP%kMjJTNT@^)v<ZS;CUu#Vo?9RgO?%*S37pM#+ZqhQjmkNZ`N(_%Z*ZA9
zsz6Etl!gK%P|}0nswpwyUQwo=4)B8jL1WIUT#@e22<*?B1C;`UUq@Qgr4HKd-TfK)
zqr?5MNwCI)hQJOt*<=;rpDF-BG1J6|CpPd7_9X9HJO?|#XLSm6lT6LCQJV5SFPk3E
zOt7Ju@P&FnnbHN9fo!|@21{UUJic%VZTyytDkzu9UNuCW3g-9MHLzdTH872@>(wXo
d{|P<?7yxbOw{1Xj7>57=002ovPDHLkV1f?O*0%rv

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_4.png b/indra/newview/skins/default/textures/icons/Progress_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..56e81c17aa0258e691da8cd3db02a377b4f044d4
GIT binary patch
literal 466
zcmV;@0WJQCP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzbV)=(RCwC#RZC97P!#PmEC5$v$LfG3
zlod!56VZ{Z02rGHm^cPjKu3y+N$U#w+<_ByXk7seI<M!3L((+;JWygxJjuzWyvzNZ
zd;3sHl32UMp0#8A{RFk_7fPu@=XU!dgjvq#cW#kScBZwm?4z68OPCqx4z8~PSO?Th
z)`IcD4ib9XN)*wKbI!&YpIoSHOCk{~k5IM7XQ@)E9lgK3c41$@XK(-pBA4Sdr88UW
z&@+{2Mu|k0DWy3OIe2~|vxwt(is0)41YYHk36~Pc4;^%}pE;Mr9Ry#%)+tlpXp00K
zXn+oeth@-~_X%l+#%p^2@aVIuHToq9p1>|T3HiKa_oW@wsd?pw5RFtp+GvYX-Sots
zpPf!j-&~_DLf{sMY_sjjPv1p8g9pb)hc2pGfIYAw{MKDW$i7FAMk8Q)=sxGtv^LQ!
z&CHpTtnk5SLAXi0s=LTGSk>)2$ngy+nQ=Vz|DXKp3BCjv03@r-jzv1!3IG5A07*qo
IM6N<$g3*@HRR910

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_5.png b/indra/newview/skins/default/textures/icons/Progress_5.png
new file mode 100644
index 0000000000000000000000000000000000000000..a89bf2ac62d0c3175ccb5cbcd2fbbed8a28e9047
GIT binary patch
literal 477
zcmV<30V4j1P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUze@R3^RCwC#RZB|4P!vtX1+;VlW()4%
zbp<9MSRL7sAcE;wuvBndyMj8>3PR!v8h4-rb!cXG(9rH6JqK^3rg?ph;4Bvom*(Af
z?zx|&cABQvf0|t-Fd7pqW1aP`uE#)7hHu+IcnmiLyzb>i2(N&MXRX$e3&&*b(dh10
z$FXH7Fc#l0IP2$PHk*NM+t&TVBbCR82m6t<glc=hIq>rF{`L&t1wyFzPz@_{SV^8w
z*CMusiNYjF2FY|vf*rO)&i8;hFaUWbfVR>qT>?*9;5Hf!b#{7E&z*A~ZII94Ytp7p
z5m8|Rw1xyBD)0?6V%#fQbE6AbNdVG7RAtuDU7k$7o>-|;&1~S@u%@YknyjO7LzZH)
zxOu4;4ZnRt#|-5|z+cB#xTbjK%8(tZ!n3+2!LK1l(KyWW>0Y!z$T>t0mu8wub|uD<
zJJzOa%6*TaJOXik=syO<RPLb?B}uHZGf?Tbeg5_1Y5Ep9rd6%}(W(U2LVy7P5E1r@
TLSo&Q00000NkvXXu0mjf2yxUR

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_6.png b/indra/newview/skins/default/textures/icons/Progress_6.png
new file mode 100644
index 0000000000000000000000000000000000000000..233c4795407ddf79ca93d1895da1baa4ad011f82
GIT binary patch
literal 460
zcmV;-0W<!IP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzZb?KzRCwC#RWVM(KoI0m9zcHJr`Rtb
zmXHWk@e2~yNCc3mLtfxi5G16S7uftDl%c`YK_WjeGh$CN=FYwpRLM%Kz1Vj<v$K1S
zD$DZVKTYicT8#izZ?fx~+YG+gCSRv%^TXrQ03m^gXQwAAq7TmntcO6bXnc7wv*kE!
zDX@?@F}$19_PF&xDW#bgV4Y)4mSh{htyW{iCHw`>bqe-jzkklky!rfoR?laXC=rP$
z%T%PHMG}wUo6q%nisYIA?T=J8fKVjhK_8WLYwrmhA^8{Lk;oLA5*Y!cp(!dDwe*Pl
zULnn$Z9~T}W?4m&;%9=a0MC>YmFR|Z!h*I6HhL5tZCN|(e$nuIM7L%3{UCu~HRUso
zDW3JD$sSqZS=R#atI2turLJSTs5CJ)F_#JBv<+p=Gs^WQbKV0m58<Yp`XS7RU>!<h
zBj=m!VyNO>Bn$wOS9`F{x2Vaqbl(0SZN~w=1sDMRO3|dNCN}s00000<MNUMnLSTX)
Cm&|<t

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_7.png b/indra/newview/skins/default/textures/icons/Progress_7.png
new file mode 100644
index 0000000000000000000000000000000000000000..631d7a6819ddd0763c90fc1834ce4eb9c51292a5
GIT binary patch
literal 483
zcmV<90UZ8`P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzg-Jv~RCwC#RZU96P!R5uF0;@Rn6-L{
z<OC)lSY6o@#H<CYg6rB7)Rk5c8c&et4RoPWH`WtaF#Gs@Fadq$*HS@nV3^m*yqWpt
z=T)U?+FB$nwH8c&KS0}5D5VOGFR!j+h}q8emS1FJ_Ox9V9S-*(hF~8~BS;6V`R(}R
z)Pop<yS>AM^PiSzDzcyRt#8=mk}@H&M9?wwDb5-wm?g6f!2$KplgTY)4;&$TA83fo
zCKA(M5dxMahVgh~eQm(Hi{6(&tD+mgITMKGPHhC9l)$DV=vMMB!}%M;vXm(Vf~Z!L
z;gAib@qR^*Xm=0CXSK%^PGgyttbv6i`Skd3!_ss*yII3IVQv+ISvHC_>CU+OeK9_B
z6GG<9{;14fZj&1X_|oLj=pt&g$tF3D>&bDGyOAV`Z&_9#d%|&5^FDS%S+-YZo+R%9
zvi7C1-P(Ilf`G<a>)6HlMfSwSZ(a1*&GTG`BJD=cbp`2c6p?k5SM$me{r_eDdVmiB
Z1^|>VwpNe{lobE~002ovPDHLkV1l%f-h2Q6

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_8.png b/indra/newview/skins/default/textures/icons/Progress_8.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac0e3f13f7b214eeb491a33fd3a057cc2f81e368
GIT binary patch
literal 467
zcmV;^0WAKBP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzbxA})RCwC#Rb5KMKoHJ~2dHoLt=?pF
z0viylKE)H%J`4VV&q+_vK4}HPc!K5z))QC{5X=qY_u&NMvPm~BMFa<i%<fL-oB3vT
ztBRuVwkbQ_mgVmQ?AkV!QdZ}O$EP_y`N{E7P#4hbX=4R&4vTN;%a(?A1gsA&py4JI
zE#(_o&LYFd9Y8YIpen^Of%dRIFM}a#+C83uuJq>iPD4ZI9zZ4n#NcD0h7we$%CjsR
zBk(iqlESGgKp+(Ghpc4JIA1_x1pkztu(DB`DPrb{(9$IId%L>4h+B<m1t?wt@IpFK
zN!f7r%y$NGltsnPtrx>oR~ZaWC(!Grc*+*A?j~CRel&SDyHCt`D=E_2=e)m4L&>?<
z?d~7SgmK!2Vsl*8I*(l>S$;^cNNny6k#!)AJ+lr<6Gh0L7m5$uGEL_PSku<973g`F
z+w21*UF)%v0A9@{8W}!b>k2IWAkQ6C;JZH8>i<9a*8#o+7yy>_v2lUfq(uM#002ov
JPDHLkV1kOi&cy%#

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/icons/Progress_9.png b/indra/newview/skins/default/textures/icons/Progress_9.png
new file mode 100644
index 0000000000000000000000000000000000000000..17fb4a0335da68fb3f50fdc50cbe1cec529cf75e
GIT binary patch
literal 483
zcmV<90UZ8`P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzg-Jv~RCwC#Rn1DnKoHJ~50HX|daG};
z>kF8GVD;2KLF`%3w$O9iC&*1J2#rtBJc8GHF<y;e-ynWdC(v$pYoZnr9GL86b~At9
z%tmBc=4_L8oGsJecd%<x3L%V#f!73!i+yD?sAIY@0~~H<ALOyh1xpfcZtpyB25x?*
zL<z40!`?tUQ{Dke5o3wKb!2g#8${G3*J<zc<T%E=v}IBR<TiM|B>OCrZUn=G%M=_I
z23gC3N>I_%58xq;zcDTeJ1_6x6YA0fWg3=h)1ve^n^ELpx7W`BC(P7OW{{W5S;A#~
zFm%pIO4R{}*824N6n$rtJz=^{l{)me&#4vXaXhV99ISwRb$Jo#_G~4Z@Jcf<LKb8w
zs@3-IS$_ofUenayt5yS&`5RGm4qB85BB!1YILc?1Lzdk%eF+e?&%m~fZEh-2e%T>%
z$wQRD*+HXmMzS1_uLa~ME}_DE{H4o|4LFt|YHMel(i!N4s2A5YA})Mgi~oP}uRC}b
ZU;yDEv<5{}dm{h<002ovPDHLkV1ny4(jWi;

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 84a99ba92a9..1080ff347ce 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -580,4 +580,17 @@ with the same filename but different name
   <texture name="default_profile_picture.j2c" />
   <texture name="locked_image.j2c" />
 
+  <texture name="Progress_1" file_name="icons/Progress_1.png" preload="false" />
+  <texture name="Progress_2" file_name="icons/Progress_2.png" preload="false" />
+  <texture name="Progress_3" file_name="icons/Progress_3.png" preload="false" />
+  <texture name="Progress_4" file_name="icons/Progress_4.png" preload="false" />
+  <texture name="Progress_5" file_name="icons/Progress_5.png" preload="false" />
+  <texture name="Progress_6" file_name="icons/Progress_6.png" preload="false" />
+  <texture name="Progress_7" file_name="icons/Progress_7.png" preload="false" />
+  <texture name="Progress_8" file_name="icons/Progress_8.png" preload="false" />
+  <texture name="Progress_9" file_name="icons/Progress_9.png" preload="false" />
+  <texture name="Progress_10" file_name="icons/Progress_10.png" preload="false" />
+  <texture name="Progress_11" file_name="icons/Progress_11.png" preload="false" />
+  <texture name="Progress_12" file_name="icons/Progress_12.png" preload="false" />
+
 </textures>
diff --git a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
new file mode 100644
index 00000000000..6040d241285
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<loading_indicator
+    follows="left|top"
+    mouse_opaque="false"
+    name="loading_indicator"
+    rotations_per_sec="1.0"
+    tab_stop="false"
+/>
-- 
GitLab