llconsole.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llconsole.h"
00035 
00036 // linden library includes
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 
00051 // Used for LCD display
00052 extern void AddNewDebugConsoleToLCD(const LLWString &newLine);
00053 
00054 LLConsole* gConsole = NULL;  // Created and destroyed in LLViewerWindow.
00055 
00056 const F32 FADE_DURATION = 2.f;
00057 const S32 MIN_CONSOLE_WIDTH = 200;
00058  
00059 LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, 
00060                                          S32 font_size_index, F32 persist_time ) 
00061         : 
00062         LLFixedBuffer(max_lines),
00063         LLView(name, rect, FALSE),
00064         mLastBoxHeight(0),
00065         mLastBoxWidth(0)
00066 {
00067         mLinePersistTime = persist_time;                // seconds
00068         mFadeTime = persist_time - FADE_DURATION;
00069 
00070         setFontSize( font_size_index );
00071         setMaxLines(gSavedSettings.getS32("ConsoleMaxLines"));
00072 }
00073 
00074 LLConsole::~LLConsole()
00075 {
00076         mColors.clear();
00077 }
00078 
00079 void LLConsole::setLinePersistTime(F32 seconds)
00080 {
00081         mLinePersistTime = seconds;
00082         mFadeTime = mLinePersistTime - FADE_DURATION;
00083 }
00084 
00085 void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
00086 {
00087         S32 new_width = llmax(50, llmin(getRect().getWidth(), gViewerWindow->getWindowWidth()));
00088         S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), gViewerWindow->getWindowHeight()));
00089 
00090         LLView::reshape(new_width, new_height, called_from_parent);
00091 }
00092 
00093 void LLConsole::setFontSize(S32 size_index)
00094 {
00095         if (-1 == size_index)
00096         {
00097                 mFont = LLFontGL::sMonospace;
00098         }
00099         else if (0 == size_index)
00100         {
00101                 mFont = LLFontGL::sSansSerif;
00102         }
00103         else if (1 == size_index)
00104         {
00105                 mFont = LLFontGL::sSansSerifBig;
00106         }
00107         else
00108         {
00109                 mFont = LLFontGL::sSansSerifHuge;
00110         }
00111 }
00112 
00113 void LLConsole::draw()
00114 {
00115         LLGLSUIDefault gls_ui;
00116 
00117         addQueuedLines();
00118 
00119         // skip lines added more than mLinePersistTime ago
00120         F32 cur_time = mTimer.getElapsedTimeF32();
00121         
00122         if( LLStartUp::getStartupState() != STATE_STARTED )
00123         {
00124                 S32 count = mLines.size();
00125                 S32 i = 0;
00126                 while( count-- )
00127                 {
00128                         mAddTimes[i] = cur_time;
00129                         i = (i+1) % mMaxLines;
00130                 }
00131         }
00132 
00133         F32 skip_time = cur_time - mLinePersistTime;
00134         F32 fade_time = cur_time - mFadeTime;
00135 
00136         // draw remaining lines
00137         F32 x_pos = 0.f;
00138         F32 y_pos = 0.f;
00139 
00140         S32 line_count = mLines.size();
00141 
00142         // remove stale lines
00143         for (S32 line_num = 0; line_num < line_count; line_num++)
00144         {
00145                 if((mLinePersistTime > 0.f) && (mAddTimes[0] - skip_time)/(mLinePersistTime - mFadeTime) <= 0.f)
00146                 {
00147                         mLines.pop_front();
00148                         mAddTimes.pop_front();
00149                         mLineLengths.pop_front();
00150                         mColors.pop_front();
00151                 }
00152         }
00153 
00154         line_count = mLines.size();
00155 
00156         S32 i;
00157         if (line_count == 0)
00158         {
00159                 mLastBoxHeight = 0;
00160                 mLastBoxWidth = 0;
00161                 return;
00162         }
00163         else
00164         {
00165                 LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
00166 
00167                 F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
00168                 LLColor4 color = gColors.getColor("ConsoleBackground");
00169                 color.mV[VALPHA] *= console_opacity;
00170 
00171                 S32 max_width = 0;
00172                 for (i = 0; i < line_count; i++)
00173                 {
00174                         max_width = llmax(max_width, mFont->getWidth(mLines[i].c_str()) + 30);
00175                 }
00176                 max_width = llmin(max_width, gViewerWindow->getWindowWidth());
00177 
00178                 F32 u = 1.f;//LLCriticalDamp::getInterpolant(0.1f);
00179                 S32 target_height = llfloor(line_count * mFont->getLineHeight() + 15);
00180                 S32 target_width = max_width;
00181                 mLastBoxHeight = llmax(target_height, (S32)lerp((F32)mLastBoxHeight, (F32)target_height, u));
00182                 mLastBoxWidth = llmax(MIN_CONSOLE_WIDTH, llmax(target_width, (S32)lerp((F32)mLastBoxWidth, (F32)target_width, u)));
00183                 imagep->drawSolid(-15, -10, mLastBoxWidth + 15, mLastBoxHeight, color);
00184         }
00185 
00186         y_pos += (line_count-1) * mFont->getLineHeight();
00187 
00188 
00189         for (i = 0; i < line_count; i++)
00190         {
00191                 F32 alpha;
00192 
00193                 if ((mLinePersistTime > 0.f) && (mAddTimes[i] < fade_time))
00194                 {
00195                         alpha = (mAddTimes[i] - skip_time)/(mLinePersistTime - mFadeTime);
00196                 }
00197                 else
00198                 {
00199                         alpha = 1.0f;
00200                 }
00201 
00202                 if( alpha > 0.f )
00203                 {
00204                         // text line itself
00205                         mFont->render(mLines[i], 0, x_pos, y_pos,
00206                                 LLColor4(
00207                                         mColors[i].mV[VRED], 
00208                                         mColors[i].mV[VGREEN], 
00209                                         mColors[i].mV[VBLUE], 
00210                                         mColors[i].mV[VALPHA]*alpha),
00211                                 LLFontGL::LEFT, 
00212                                 LLFontGL::BASELINE,
00213                                 LLFontGL::DROP_SHADOW,
00214                                 S32_MAX,
00215                                 mLastBoxWidth
00216                                 );
00217                 }
00218 
00219                 y_pos -= mFont->getLineHeight();
00220         }
00221 }
00222 
00223 void LLConsole::addLine(const LLString& utf8line)
00224 {
00225         LLWString wline = utf8str_to_wstring(utf8line);
00226         addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00227 }
00228 
00229 void LLConsole::addLine(const LLWString& wline)
00230 {
00231         addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00232 }
00233 
00234 void LLConsole::addLine(const LLString& utf8line, F32 size, const LLColor4 &color)
00235 {
00236         LLWString wline = utf8str_to_wstring(utf8line);
00237         addLine(wline, size, color);
00238 }
00239 
00240 void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
00241 {
00242         while (mLineQueue.size() >= mMaxLines)
00243         {
00244                 mLineQueue.pop_front();
00245         }
00246         mLineQueue.push_back(LineInfo(wline, size, color, mTimer.getElapsedTimeF32()));
00247 #if LL_WINDOWS && LL_LCD_COMPILE
00248         // add to LCD screen
00249         AddNewDebugConsoleToLCD(wline);
00250 #endif  
00251 }
00252 
00253 void LLConsole::addQueuedLines()
00254 {
00255         for (line_queue_t::iterator iter = mLineQueue.begin();
00256                  iter != mLineQueue.end(); ++iter)
00257         {
00258                 LineInfo& line_info = *iter;
00259                 LLWString wline = line_info.wline;
00260                 //F32 size = line_info.size;
00261                 LLColor4 color = line_info.color;
00262                 if (!wline.empty() && mFont != NULL)
00263                 {
00264                         // Wrap lines that are longer than the view is wide.
00265                         S32 line_start_offset = 0;
00266                         while( line_start_offset < (S32)wline.length() )
00267                         {
00268                                 // Find the next '\n', if any
00269                                 LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), line_start_offset);
00270                                 if (LLWString::npos == line_end)
00271                                 {
00272                                         // no more '\n's, try to use the whole line
00273                                         line_end = wline.size();
00274                                 }
00275                                 // Find how many characters will reasonably fit in the allowed width
00276                                 U32 drawable = mFont->maxDrawableChars(wline.c_str()+line_start_offset, (F32)getRect().getWidth(), line_end-line_start_offset, TRUE);
00277                                 if (drawable != 0)
00278                                 {
00279                                         LLFixedBuffer::addLine(wline.substr(line_start_offset, drawable));
00280                                         mAddTimes[mAddTimes.size()-1] = line_info.add_time;
00281                                         
00282                                         // move the line_start_offset by the number of characters we were able to draw, up to an implicit or explicit line-break.
00283                                         line_start_offset += drawable;
00284                                 }
00285                                 else
00286                                 {
00287                                         // no drawable characters - force a blank line and try the next character.
00288                                         LLFixedBuffer::addLine(" ");
00289                                         line_start_offset++;
00290                                 }
00291                                 mColors.push_back(color);
00292                                 // if this was an *explicit* line-break or the end of the text, then increment the offset for the start of the next line (if any).
00293                                 if (line_start_offset == line_end)
00294                                 {
00295                                         line_start_offset++;
00296                                 }
00297                         }
00298                 }
00299         }
00300         mLineQueue.clear();
00301 }
00302 
00303 void LLConsole::removeExtraLines()
00304 {
00305         while((S32)mColors.size() > llmax(0, (S32)(mMaxLines - 1)))
00306         {
00307                 mColors.pop_front();
00308         }
00309         LLFixedBuffer::removeExtraLines();
00310 }

Generated on Fri May 16 08:33:16 2008 for SecondLife by  doxygen 1.5.5