llstatgraph.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * @file llstatgraph.cpp
  3. * @brief Simpler compact stat graph with tooltip
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, Linden Research, Inc.
  8. * Copyright (c) 2009-2021, Henri Beauchamp.
  9. * Changes by Henri Beauchamp:
  10. * - Allow a special color with full bar display for out of range indications.
  11. * - Allow the use of a logarithmic scale indicator.
  12. * - Allow the use of a multiplier for the unit and a suffix for the tool tip.
  13. *
  14. * Second Life Viewer Source Code
  15. * The source code in this file ("Source Code") is provided by Linden Lab
  16. * to you under the terms of the GNU General Public License, version 2.0
  17. * ("GPL"), unless you have obtained a separate licensing agreement
  18. * ("Other License"), formally executed by you and Linden Lab. Terms of
  19. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  20. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  21. *
  22. * There are special exceptions to the terms and conditions of the GPL as
  23. * it is applied to this Source Code. View the full text of the exception
  24. * in the file doc/FLOSS-exception.txt in this software distribution, or
  25. * online at
  26. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  27. *
  28. * By copying, modifying or distributing this software, you acknowledge
  29. * that you have read and understood your obligations described above,
  30. * and agree to abide by those obligations.
  31. *
  32. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  33. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  34. * COMPLETENESS OR PERFORMANCE.
  35. * $/LicenseInfo$
  36. */
  37. #include "linden_common.h"
  38. #include "llstatgraph.h"
  39. #include "llgl.h"
  40. #include "llrender.h"
  41. LLStatGraph::LLStatGraph(const std::string& name, const LLRect& rect)
  42. : LLView(name, rect, true),
  43. mStatp(NULL),
  44. mMin(0.f),
  45. mMax(125.f),
  46. mLogScale(false),
  47. mPerSec(true),
  48. mValue(0.f),
  49. mDivisor(0.f),
  50. mPrecision(0),
  51. mClickedCallback(NULL),
  52. mCallbackUserData(NULL)
  53. {
  54. setToolTip(name);
  55. mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f);
  56. mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f);
  57. mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f);
  58. mThresholdColors[3] = LLColor4(0.75f, 0.75f, 0.75f, 1.f);
  59. mThresholds[0] = 50.f;
  60. mThresholds[1] = 75.f;
  61. mThresholds[2] = 95.f;
  62. updateRange();
  63. }
  64. void LLStatGraph::updateRange()
  65. {
  66. if (mMax <= mMin)
  67. {
  68. mRange = 0.f;
  69. return;
  70. }
  71. mRange = mMax - mMin;
  72. if (mLogScale)
  73. {
  74. mRange = logf(mRange);
  75. F32 max = llmax(mThresholds[0], mThresholds[1], mThresholds[2]);
  76. if (max <= 0.f || max > 1.f)
  77. {
  78. // Logarithmic indicators thresholds are always expressed in
  79. // percent of the full range...
  80. mThresholds[0] = 0.5f;
  81. mThresholds[1] = 0.75f;
  82. mThresholds[2] = 0.95f;
  83. }
  84. }
  85. }
  86. //virtual
  87. void LLStatGraph::draw()
  88. {
  89. if (mStatp)
  90. {
  91. if (mPerSec)
  92. {
  93. mValue = mStatp->getMeanPerSec();
  94. }
  95. else
  96. {
  97. mValue = mStatp->getMean();
  98. }
  99. }
  100. // Note: we want to draw a full bar (with the special mThresholdColors[3]
  101. // color) when mMax <= mMin (used in the status bar bandwidth indicator for
  102. // disconnected network condition). HB
  103. F32 frac = 1.f;
  104. if (mValue <= mMin)
  105. {
  106. frac = 0.f;
  107. }
  108. else if (mRange > 0.f)
  109. {
  110. if (mLogScale)
  111. {
  112. frac = logf(mValue - mMin) / mRange;
  113. }
  114. else
  115. {
  116. frac = (mValue - mMin) / mRange;
  117. }
  118. if (frac > 1.f)
  119. {
  120. frac = 1.f;
  121. }
  122. }
  123. if (mUpdateTimer.getElapsedTimeF32() > 0.5f)
  124. {
  125. mUpdateTimer.reset();
  126. std::string format_str = llformat("%%s%%.%df%%s", mPrecision);
  127. F32 value = mValue;
  128. const char* unit;
  129. if (mDivisor > 0.f && value >= mDivisor && !mUnit2.empty())
  130. {
  131. unit = mUnit2.c_str();
  132. value /= mDivisor;
  133. }
  134. else
  135. {
  136. unit = mUnit1.c_str();
  137. }
  138. std::string tooltip = llformat(format_str.c_str(), mLabel.c_str(),
  139. value, unit);
  140. if (!mLabelSuffix.empty())
  141. {
  142. tooltip += mLabelSuffix;
  143. }
  144. setToolTip(tooltip);
  145. }
  146. static const LLColor4 bg_color(LLUI::sMenuDefaultBgColor);
  147. gGL.color4fv(bg_color.mV);
  148. gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, true);
  149. gGL.color4fv(LLColor4::black.mV);
  150. gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, false);
  151. LLColor4* color;
  152. if (mMax <= mMin)
  153. {
  154. color = &mThresholdColors[3];
  155. }
  156. else
  157. {
  158. F32 val = mLogScale ? frac : mValue;
  159. U32 i;
  160. for (i = 0; i < 2; ++i)
  161. {
  162. if (mThresholds[i] > val)
  163. {
  164. break;
  165. }
  166. }
  167. color = &mThresholdColors[i];
  168. }
  169. gGL.color4fv(color->mV);
  170. gl_rect_2d(1, ll_round(frac * getRect().getHeight()),
  171. getRect().getWidth() - 1, 0, true);
  172. }
  173. bool LLStatGraph::handleMouseDown(S32 x, S32 y, MASK mask)
  174. {
  175. if (mClickedCallback)
  176. {
  177. (*mClickedCallback)(mCallbackUserData);
  178. return true;
  179. }
  180. return LLView::handleMouseDown(x, y, mask);
  181. }
  182. bool LLStatGraph::handleMouseUp(S32 x, S32 y, MASK mask)
  183. {
  184. // If we handled the mouse down event ourselves as a "click", then we must
  185. // handle the mouse up event as well (click = mouse down + mouse up)...
  186. return mClickedCallback || LLView::handleMouseUp(x, y, mask);
  187. }
  188. void LLStatGraph::setClickedCallback(void (*cb)(void*), void* userdata)
  189. {
  190. mClickedCallback = cb;
  191. if (userdata)
  192. {
  193. mCallbackUserData = userdata;
  194. }
  195. }