00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llconsole.h"
00035
00036
00037 #include "llmath.h"
00038 #include "llviewercontrol.h"
00039 #include "llcriticaldamp.h"
00040 #include "llfontgl.h"
00041 #include "llgl.h"
00042 #include "llui.h"
00043 #include "llviewerimage.h"
00044 #include "llviewerimagelist.h"
00045 #include "llviewerwindow.h"
00046 #include "llfontgl.h"
00047 #include "llmath.h"
00048
00049 #include "llstartup.h"
00050 #include "viewer.h"
00051
00052
00053 extern void AddNewDebugConsoleToLCD(const LLWString &newLine);
00054
00055 LLConsole* gConsole = NULL;
00056
00057 const F32 FADE_DURATION = 2.f;
00058 const S32 MIN_CONSOLE_WIDTH = 200;
00059
00060 LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect,
00061 S32 font_size_index, F32 persist_time )
00062 :
00063 LLFixedBuffer(max_lines),
00064 LLView(name, rect, FALSE),
00065 mLastBoxHeight(0),
00066 mLastBoxWidth(0)
00067 {
00068 mLinePersistTime = persist_time;
00069 mFadeTime = persist_time - FADE_DURATION;
00070
00071 setFontSize( font_size_index );
00072 setMaxLines(gSavedSettings.getS32("ConsoleMaxLines"));
00073 }
00074
00075 LLConsole::~LLConsole()
00076 {
00077 mColors.clear();
00078 }
00079
00080 EWidgetType LLConsole::getWidgetType() const
00081 {
00082 return WIDGET_TYPE_CONSOLE;
00083 }
00084
00085 LLString LLConsole::getWidgetTag() const
00086 {
00087 return LL_CONSOLE_TAG;
00088 }
00089
00090 void LLConsole::setLinePersistTime(F32 seconds)
00091 {
00092 mLinePersistTime = seconds;
00093 mFadeTime = mLinePersistTime - FADE_DURATION;
00094 }
00095
00096 void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
00097 {
00098 S32 new_width = llmax(50, llmin(mRect.getWidth(), gViewerWindow->getWindowWidth()));
00099 S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(mRect.getHeight(), gViewerWindow->getWindowHeight()));
00100
00101 LLView::reshape(new_width, new_height, called_from_parent);
00102 }
00103
00104 void LLConsole::setFontSize(S32 size_index)
00105 {
00106 if (-1 == size_index)
00107 {
00108 mFont = LLFontGL::sMonospace;
00109 }
00110 else if (0 == size_index)
00111 {
00112 mFont = LLFontGL::sSansSerif;
00113 }
00114 else if (1 == size_index)
00115 {
00116 mFont = LLFontGL::sSansSerifBig;
00117 }
00118 else
00119 {
00120 mFont = LLFontGL::sSansSerifHuge;
00121 }
00122 }
00123
00124 void LLConsole::draw()
00125 {
00126 LLGLSUIDefault gls_ui;
00127
00128 addQueuedLines();
00129
00130
00131 F32 cur_time = mTimer.getElapsedTimeF32();
00132
00133 if( LLStartUp::getStartupState() != STATE_STARTED )
00134 {
00135 S32 count = mLines.size();
00136 S32 i = 0;
00137 while( count-- )
00138 {
00139 mAddTimes[i] = cur_time;
00140 i = (i+1) % mMaxLines;
00141 }
00142 }
00143
00144 F32 skip_time = cur_time - mLinePersistTime;
00145 F32 fade_time = cur_time - mFadeTime;
00146
00147
00148 F32 x_pos = 0.f;
00149 F32 y_pos = 0.f;
00150
00151 S32 line_count = mLines.size();
00152
00153
00154 for (S32 line_num = 0; line_num < line_count; line_num++)
00155 {
00156 if((mLinePersistTime > 0.f) && (mAddTimes[0] - skip_time)/(mLinePersistTime - mFadeTime) <= 0.f)
00157 {
00158 mLines.pop_front();
00159 mAddTimes.pop_front();
00160 mLineLengths.pop_front();
00161 mColors.pop_front();
00162 }
00163 }
00164
00165 line_count = mLines.size();
00166
00167 S32 i;
00168 if (line_count == 0)
00169 {
00170 mLastBoxHeight = 0;
00171 mLastBoxWidth = 0;
00172 return;
00173 }
00174 else
00175 {
00176 LLUUID image_id;
00177 image_id.set(gViewerArt.getString("rounded_square.tga"));
00178 LLViewerImage* imagep = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE);
00179
00180 F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
00181 LLColor4 color(0.f, 0.f, 0.f, console_opacity);
00182
00183 S32 max_width = 0;
00184 for (i = 0; i < line_count; i++)
00185 {
00186 max_width = llmax(max_width, mFont->getWidth(mLines[i].c_str()) + 30);
00187 }
00188 max_width = llmin(max_width, gViewerWindow->getWindowWidth());
00189
00190 F32 u = 1.f;
00191 S32 target_height = llfloor(line_count * mFont->getLineHeight() + 15);
00192 S32 target_width = max_width;
00193 mLastBoxHeight = llmax(target_height, (S32)lerp((F32)mLastBoxHeight, (F32)target_height, u));
00194 mLastBoxWidth = llmax(MIN_CONSOLE_WIDTH, llmax(target_width, (S32)lerp((F32)mLastBoxWidth, (F32)target_width, u)));
00195 gl_draw_scaled_image_with_border(-15, -10, 16, 16, mLastBoxWidth + 15, mLastBoxHeight,
00196 imagep, color, TRUE );
00197 }
00198
00199 y_pos += (line_count-1) * mFont->getLineHeight();
00200
00201
00202 for (i = 0; i < line_count; i++)
00203 {
00204 F32 alpha;
00205
00206 if ((mLinePersistTime > 0.f) && (mAddTimes[i] < fade_time))
00207 {
00208 alpha = (mAddTimes[i] - skip_time)/(mLinePersistTime - mFadeTime);
00209 }
00210 else
00211 {
00212 alpha = 1.0f;
00213 }
00214
00215 if( alpha > 0.f )
00216 {
00217
00218 mFont->render(mLines[i], 0, x_pos, y_pos,
00219 LLColor4(
00220 mColors[i].mV[VRED],
00221 mColors[i].mV[VGREEN],
00222 mColors[i].mV[VBLUE],
00223 mColors[i].mV[VALPHA]*alpha),
00224 LLFontGL::LEFT,
00225 LLFontGL::BASELINE,
00226 LLFontGL::DROP_SHADOW,
00227 S32_MAX,
00228 mLastBoxWidth
00229 );
00230 }
00231
00232 y_pos -= mFont->getLineHeight();
00233 }
00234 }
00235
00236 void LLConsole::addLine(const LLString& utf8line)
00237 {
00238 LLWString wline = utf8str_to_wstring(utf8line);
00239 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00240 }
00241
00242 void LLConsole::addLine(const LLWString& wline)
00243 {
00244 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00245 }
00246
00247 void LLConsole::addLine(const LLString& utf8line, F32 size, const LLColor4 &color)
00248 {
00249 LLWString wline = utf8str_to_wstring(utf8line);
00250 addLine(wline, size, color);
00251 }
00252
00253 void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
00254 {
00255 while (mLineQueue.size() >= mMaxLines)
00256 {
00257 mLineQueue.pop_front();
00258 }
00259 mLineQueue.push_back(LineInfo(wline, size, color, mTimer.getElapsedTimeF32()));
00260 #if LL_WINDOWS && LL_LCD_COMPILE
00261
00262 AddNewDebugConsoleToLCD(wline);
00263 #endif
00264 }
00265
00266 void LLConsole::addQueuedLines()
00267 {
00268 for (line_queue_t::iterator iter = mLineQueue.begin();
00269 iter != mLineQueue.end(); ++iter)
00270 {
00271 LineInfo& line_info = *iter;
00272 LLWString wline = line_info.wline;
00273
00274 LLColor4 color = line_info.color;
00275 if (!wline.empty() && mFont != NULL)
00276 {
00277
00278 S32 offset = 0;
00279 while( offset < (S32)wline.length() )
00280 {
00281 S32 skip_chars;
00282
00283 LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), offset);
00284 if (line_end != LLWString::npos)
00285 {
00286 skip_chars = 1;
00287 }
00288 else
00289 {
00290 line_end = wline.size();
00291 skip_chars = 0;
00292 }
00293 U32 drawable = mFont->maxDrawableChars(wline.c_str()+offset, (F32)mRect.getWidth(), line_end-offset, TRUE);
00294 if (drawable != 0)
00295 {
00296 LLFixedBuffer::addLine(wline.substr(offset, drawable));
00297 mAddTimes[mAddTimes.size()-1] = line_info.add_time;
00298 }
00299 else
00300 {
00301
00302 LLFixedBuffer::addLine(" ");
00303 }
00304 mColors.push_back(color);
00305 offset += (drawable + skip_chars);
00306 }
00307 }
00308 }
00309 mLineQueue.clear();
00310 }
00311
00312 void LLConsole::removeExtraLines()
00313 {
00314 while((S32)mColors.size() > llmax(0, (S32)(mMaxLines - 1)))
00315 {
00316 mColors.pop_front();
00317 }
00318 LLFixedBuffer::removeExtraLines();
00319 }