PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llprogressview.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 426 lines | 298 code | 69 blank | 59 comment | 48 complexity | 38227b99a123892cb6192111cc248cbf MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llprogressview.cpp
  3. * @brief LLProgressView class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llprogressview.h"
  28. #include "indra_constants.h"
  29. #include "llmath.h"
  30. #include "llgl.h"
  31. #include "llrender.h"
  32. #include "llui.h"
  33. #include "llfontgl.h"
  34. #include "lltimer.h"
  35. #include "lltextbox.h"
  36. #include "llglheaders.h"
  37. #include "llagent.h"
  38. #include "llbutton.h"
  39. #include "llfocusmgr.h"
  40. #include "llnotifications.h"
  41. #include "llprogressbar.h"
  42. #include "llstartup.h"
  43. #include "llviewercontrol.h"
  44. #include "llviewertexturelist.h"
  45. #include "llviewerwindow.h"
  46. #include "llappviewer.h"
  47. #include "llweb.h"
  48. #include "lluictrlfactory.h"
  49. #include "llpanellogin.h"
  50. LLProgressView* LLProgressView::sInstance = NULL;
  51. S32 gStartImageWidth = 1;
  52. S32 gStartImageHeight = 1;
  53. const F32 FADE_TO_WORLD_TIME = 1.0f;
  54. static LLRegisterPanelClassWrapper<LLProgressView> r("progress_view");
  55. // XUI: Translate
  56. LLProgressView::LLProgressView()
  57. : LLPanel(),
  58. mPercentDone( 0.f ),
  59. mMediaCtrl( NULL ),
  60. mMouseDownInActiveArea( false ),
  61. mUpdateEvents("LLProgressView"),
  62. mFadeToWorldTimer(),
  63. mFadeFromLoginTimer(),
  64. mStartupComplete(false)
  65. {
  66. mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));
  67. }
  68. BOOL LLProgressView::postBuild()
  69. {
  70. mProgressBar = getChild<LLProgressBar>("login_progress_bar");
  71. // media control that is used to play intro video
  72. mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel");
  73. mMediaCtrl->setVisible( false ); // hidden initially
  74. mMediaCtrl->addObserver( this ); // watch events
  75. LLViewerMedia::setOnlyAudibleMediaTextureID(mMediaCtrl->getTextureID());
  76. mCancelBtn = getChild<LLButton>("cancel_btn");
  77. mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
  78. mFadeToWorldTimer.stop();
  79. mFadeFromLoginTimer.stop();
  80. getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
  81. getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
  82. // hidden initially, until we need it
  83. LLPanel::setVisible(FALSE);
  84. LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1));
  85. sInstance = this;
  86. return TRUE;
  87. }
  88. LLProgressView::~LLProgressView()
  89. {
  90. gFocusMgr.releaseFocusIfNeeded( this );
  91. sInstance = NULL;
  92. }
  93. BOOL LLProgressView::handleHover(S32 x, S32 y, MASK mask)
  94. {
  95. if( childrenHandleHover( x, y, mask ) == NULL )
  96. {
  97. gViewerWindow->setCursor(UI_CURSOR_WAIT);
  98. }
  99. return TRUE;
  100. }
  101. BOOL LLProgressView::handleKeyHere(KEY key, MASK mask)
  102. {
  103. // Suck up all keystokes except CTRL-Q.
  104. if( ('Q' == key) && (MASK_CONTROL == mask) )
  105. {
  106. LLAppViewer::instance()->userQuit();
  107. }
  108. return TRUE;
  109. }
  110. void LLProgressView::revealIntroPanel()
  111. {
  112. // if user hasn't yet seen intro video
  113. std::string intro_url = gSavedSettings.getString("PostFirstLoginIntroURL");
  114. if ( intro_url.length() > 0 &&
  115. gSavedSettings.getBOOL("BrowserJavascriptEnabled") &&
  116. gSavedSettings.getBOOL("PostFirstLoginIntroViewed" ) == FALSE )
  117. {
  118. // hide the progress bar
  119. getChild<LLView>("stack1")->setVisible(false);
  120. // navigate to intro URL and reveal widget
  121. mMediaCtrl->navigateTo( intro_url );
  122. mMediaCtrl->setVisible( TRUE );
  123. // flag as having seen the new user post login intro
  124. gSavedSettings.setBOOL("PostFirstLoginIntroViewed", TRUE );
  125. mMediaCtrl->setFocus(TRUE);
  126. }
  127. mFadeFromLoginTimer.start();
  128. }
  129. void LLProgressView::setStartupComplete()
  130. {
  131. mStartupComplete = true;
  132. // if we are not showing a video, fade into world
  133. if (!mMediaCtrl->getVisible())
  134. {
  135. mFadeFromLoginTimer.stop();
  136. mFadeToWorldTimer.start();
  137. }
  138. }
  139. void LLProgressView::setVisible(BOOL visible)
  140. {
  141. // hiding progress view
  142. if (getVisible() && !visible)
  143. {
  144. LLPanel::setVisible(FALSE);
  145. }
  146. // showing progress view
  147. else if (visible && (!getVisible() || mFadeToWorldTimer.getStarted()))
  148. {
  149. setFocus(TRUE);
  150. mFadeToWorldTimer.stop();
  151. LLPanel::setVisible(TRUE);
  152. }
  153. }
  154. void LLProgressView::drawStartTexture(F32 alpha)
  155. {
  156. gGL.pushMatrix();
  157. if (gStartTexture)
  158. {
  159. LLGLSUIDefault gls_ui;
  160. gGL.getTexUnit(0)->bind(gStartTexture.get());
  161. gGL.color4f(1.f, 1.f, 1.f, alpha);
  162. F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;
  163. S32 width = getRect().getWidth();
  164. S32 height = getRect().getHeight();
  165. F32 view_aspect = (F32)width / (F32)height;
  166. // stretch image to maintain aspect ratio
  167. if (image_aspect > view_aspect)
  168. {
  169. gGL.translatef(-0.5f * (image_aspect / view_aspect - 1.f) * width, 0.f, 0.f);
  170. gGL.scalef(image_aspect / view_aspect, 1.f, 1.f);
  171. }
  172. else
  173. {
  174. gGL.translatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * height, 0.f);
  175. gGL.scalef(1.f, view_aspect / image_aspect, 1.f);
  176. }
  177. gl_rect_2d_simple_tex( getRect().getWidth(), getRect().getHeight() );
  178. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  179. }
  180. else
  181. {
  182. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  183. gGL.color4f(0.f, 0.f, 0.f, 1.f);
  184. gl_rect_2d(getRect());
  185. }
  186. gGL.popMatrix();
  187. }
  188. void LLProgressView::draw()
  189. {
  190. static LLTimer timer;
  191. if (mFadeFromLoginTimer.getStarted())
  192. {
  193. F32 alpha = clamp_rescale(mFadeFromLoginTimer.getElapsedTimeF32(), 0.f, FADE_TO_WORLD_TIME, 0.f, 1.f);
  194. LLViewDrawContext context(alpha);
  195. if (!mMediaCtrl->getVisible())
  196. {
  197. drawStartTexture(alpha);
  198. }
  199. LLPanel::draw();
  200. if (mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
  201. {
  202. mFadeFromLoginTimer.stop();
  203. LLPanelLogin::closePanel();
  204. }
  205. return;
  206. }
  207. // handle fade out to world view when we're asked to
  208. if (mFadeToWorldTimer.getStarted())
  209. {
  210. // draw fading panel
  211. F32 alpha = clamp_rescale(mFadeToWorldTimer.getElapsedTimeF32(), 0.f, FADE_TO_WORLD_TIME, 1.f, 0.f);
  212. LLViewDrawContext context(alpha);
  213. drawStartTexture(alpha);
  214. LLPanel::draw();
  215. // faded out completely - remove panel and reveal world
  216. if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
  217. {
  218. mFadeToWorldTimer.stop();
  219. LLViewerMedia::setOnlyAudibleMediaTextureID(LLUUID::null);
  220. // Fade is complete, release focus
  221. gFocusMgr.releaseFocusIfNeeded( this );
  222. // turn off panel that hosts intro so we see the world
  223. LLPanel::setVisible(FALSE);
  224. // stop observing events since we no longer care
  225. mMediaCtrl->remObserver( this );
  226. // hide the intro
  227. mMediaCtrl->setVisible( false );
  228. // navigate away from intro page to something innocuous since 'unload' is broken right now
  229. //mMediaCtrl->navigateTo( "about:blank" );
  230. // FIXME: this causes a crash that i haven't been able to fix
  231. mMediaCtrl->unloadMediaSource();
  232. gStartTexture = NULL;
  233. }
  234. return;
  235. }
  236. drawStartTexture(1.0f);
  237. // draw children
  238. LLPanel::draw();
  239. }
  240. void LLProgressView::setText(const std::string& text)
  241. {
  242. getChild<LLUICtrl>("progress_text")->setValue(text);
  243. }
  244. void LLProgressView::setPercent(const F32 percent)
  245. {
  246. mProgressBar->setValue(percent);
  247. }
  248. void LLProgressView::setMessage(const std::string& msg)
  249. {
  250. mMessage = msg;
  251. getChild<LLUICtrl>("message_text")->setValue(mMessage);
  252. }
  253. void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label)
  254. {
  255. mCancelBtn->setVisible( b );
  256. mCancelBtn->setEnabled( b );
  257. mCancelBtn->setLabelSelected(label);
  258. mCancelBtn->setLabelUnselected(label);
  259. }
  260. // static
  261. void LLProgressView::onCancelButtonClicked(void*)
  262. {
  263. // Quitting viewer here should happen only when "Quit" button is pressed while starting up.
  264. // Check for startup state is used here instead of teleport state to avoid quitting when
  265. // cancel is pressed while teleporting inside region (EXT-4911)
  266. if (LLStartUp::getStartupState() < STATE_STARTED)
  267. {
  268. LLAppViewer::instance()->requestQuit();
  269. }
  270. else
  271. {
  272. gAgent.teleportCancel();
  273. sInstance->mCancelBtn->setEnabled(FALSE);
  274. sInstance->setVisible(FALSE);
  275. }
  276. }
  277. // static
  278. void LLProgressView::onClickMessage(void* data)
  279. {
  280. LLProgressView* viewp = (LLProgressView*)data;
  281. if ( viewp != NULL && ! viewp->mMessage.empty() )
  282. {
  283. std::string url_to_open( "" );
  284. size_t start_pos;
  285. start_pos = viewp->mMessage.find( "https://" );
  286. if (start_pos == std::string::npos)
  287. start_pos = viewp->mMessage.find( "http://" );
  288. if (start_pos == std::string::npos)
  289. start_pos = viewp->mMessage.find( "ftp://" );
  290. if ( start_pos != std::string::npos )
  291. {
  292. size_t end_pos = viewp->mMessage.find_first_of( " \n\r\t", start_pos );
  293. if ( end_pos != std::string::npos )
  294. url_to_open = viewp->mMessage.substr( start_pos, end_pos - start_pos );
  295. else
  296. url_to_open = viewp->mMessage.substr( start_pos );
  297. LLWeb::loadURLExternal( url_to_open );
  298. }
  299. }
  300. }
  301. bool LLProgressView::handleUpdate(const LLSD& event_data)
  302. {
  303. LLSD message = event_data.get("message");
  304. LLSD desc = event_data.get("desc");
  305. LLSD percent = event_data.get("percent");
  306. if(message.isDefined())
  307. {
  308. setMessage(message.asString());
  309. }
  310. if(desc.isDefined())
  311. {
  312. setText(desc.asString());
  313. }
  314. if(percent.isDefined())
  315. {
  316. setPercent(percent.asReal());
  317. }
  318. return false;
  319. }
  320. bool LLProgressView::onAlertModal(const LLSD& notify)
  321. {
  322. // if the progress view is visible, it will obscure the notification window
  323. // in this case, we want to auto-accept WebLaunchExternalTarget notifications
  324. if (isInVisibleChain() && notify["sigtype"].asString() == "add")
  325. {
  326. LLNotificationPtr notifyp = LLNotifications::instance().find(notify["id"].asUUID());
  327. if (notifyp && notifyp->getName() == "WebLaunchExternalTarget")
  328. {
  329. notifyp->respondWithDefault();
  330. }
  331. }
  332. return false;
  333. }
  334. void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
  335. {
  336. // the intro web content calls javascript::window.close() when it's done
  337. if( event == MEDIA_EVENT_CLOSE_REQUEST )
  338. {
  339. if (mStartupComplete)
  340. {
  341. //make sure other timer has stopped
  342. mFadeFromLoginTimer.stop();
  343. mFadeToWorldTimer.start();
  344. }
  345. else
  346. {
  347. // hide the media ctrl and wait for startup to be completed before fading to world
  348. mMediaCtrl->setVisible(false);
  349. if (mMediaCtrl->getMediaPlugin())
  350. {
  351. mMediaCtrl->getMediaPlugin()->stop();
  352. }
  353. // show the progress bar
  354. getChild<LLView>("stack1")->setVisible(true);
  355. }
  356. }
  357. }