aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llconsole.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-09-06 18:24:57 -0500
committerJacek Antonelli2008-09-06 18:25:07 -0500
commit798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch)
tree1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llconsole.cpp
parentSecond Life viewer sources 1.20.15 (diff)
downloadmeta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz
Second Life viewer sources 1.21.0-RC
Diffstat (limited to 'linden/indra/newview/llconsole.cpp')
-rw-r--r--linden/indra/newview/llconsole.cpp366
1 files changed, 232 insertions, 134 deletions
diff --git a/linden/indra/newview/llconsole.cpp b/linden/indra/newview/llconsole.cpp
index 08ef124..c2aaa01 100644
--- a/linden/indra/newview/llconsole.cpp
+++ b/linden/indra/newview/llconsole.cpp
@@ -43,6 +43,7 @@
43#include "llviewerimage.h" 43#include "llviewerimage.h"
44#include "llviewerimagelist.h" 44#include "llviewerimagelist.h"
45#include "llviewerwindow.h" 45#include "llviewerwindow.h"
46#include "llsd.h"
46#include "llfontgl.h" 47#include "llfontgl.h"
47#include "llmath.h" 48#include "llmath.h"
48 49
@@ -60,9 +61,7 @@ LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect
60 S32 font_size_index, F32 persist_time ) 61 S32 font_size_index, F32 persist_time )
61 : 62 :
62 LLFixedBuffer(max_lines), 63 LLFixedBuffer(max_lines),
63 LLView(name, rect, FALSE), 64 LLView(name, rect, FALSE)
64 mLastBoxHeight(0),
65 mLastBoxWidth(0)
66{ 65{
67 mLinePersistTime = persist_time; // seconds 66 mLinePersistTime = persist_time; // seconds
68 mFadeTime = persist_time - FADE_DURATION; 67 mFadeTime = persist_time - FADE_DURATION;
@@ -71,11 +70,6 @@ LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect
71 setMaxLines(gSavedSettings.getS32("ConsoleMaxLines")); 70 setMaxLines(gSavedSettings.getS32("ConsoleMaxLines"));
72} 71}
73 72
74LLConsole::~LLConsole()
75{
76 mColors.clear();
77}
78
79void LLConsole::setLinePersistTime(F32 seconds) 73void LLConsole::setLinePersistTime(F32 seconds)
80{ 74{
81 mLinePersistTime = seconds; 75 mLinePersistTime = seconds;
@@ -87,7 +81,21 @@ void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
87 S32 new_width = llmax(50, llmin(getRect().getWidth(), gViewerWindow->getWindowWidth())); 81 S32 new_width = llmax(50, llmin(getRect().getWidth(), gViewerWindow->getWindowWidth()));
88 S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), gViewerWindow->getWindowHeight())); 82 S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), gViewerWindow->getWindowHeight()));
89 83
84 if ( mConsoleWidth == new_width
85 && mConsoleHeight == new_height )
86 {
87 return;
88 }
89
90 mConsoleWidth = new_width;
91 mConsoleHeight= new_height;
92
90 LLView::reshape(new_width, new_height, called_from_parent); 93 LLView::reshape(new_width, new_height, called_from_parent);
94
95 for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
96 {
97 (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true);
98 }
91} 99}
92 100
93void LLConsole::setFontSize(S32 size_index) 101void LLConsole::setFontSize(S32 size_index)
@@ -108,91 +116,104 @@ void LLConsole::setFontSize(S32 size_index)
108 { 116 {
109 mFont = LLFontGL::sSansSerifHuge; 117 mFont = LLFontGL::sSansSerifHuge;
110 } 118 }
119
120 for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
121 {
122 (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true);
123 }
111} 124}
112 125
113void LLConsole::draw() 126void LLConsole::draw()
114{ 127{
115 LLGLSUIDefault gls_ui; 128 LLGLSUIDefault gls_ui;
116 129
117 addQueuedLines();
118
119 // skip lines added more than mLinePersistTime ago 130 // skip lines added more than mLinePersistTime ago
120 F32 cur_time = mTimer.getElapsedTimeF32(); 131 F32 cur_time = mTimer.getElapsedTimeF32();
121 132
122 if( LLStartUp::getStartupState() != STATE_STARTED )
123 {
124 S32 count = mLines.size();
125 S32 i = 0;
126 while( count-- )
127 {
128 mAddTimes[i] = cur_time;
129 i = (i+1) % mMaxLines;
130 }
131 }
132
133 F32 skip_time = cur_time - mLinePersistTime; 133 F32 skip_time = cur_time - mLinePersistTime;
134 F32 fade_time = cur_time - mFadeTime; 134 F32 fade_time = cur_time - mFadeTime;
135 135
136 // draw remaining lines 136 if (mParagraphs.empty()) //No text to draw.
137 F32 x_pos = 0.f; 137 {
138 F32 y_pos = 0.f; 138 return;
139 }
139 140
140 S32 line_count = mLines.size(); 141 U32 num_lines=0;
141 142
142 // remove stale lines 143 paragraph_t::reverse_iterator paragraph_it;
143 for (S32 line_num = 0; line_num < line_count; line_num++) 144 paragraph_it = mParagraphs.rbegin();
145 U32 paragraph_num=mParagraphs.size();
146
147 while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend())
144 { 148 {
145 if((mLinePersistTime > 0.f) && (mAddTimes[0] - skip_time)/(mLinePersistTime - mFadeTime) <= 0.f) 149 num_lines += (*paragraph_it).mLines.size();
146 { 150 if(num_lines > mMaxLines
147 mLines.pop_front(); 151 || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f))
148 mAddTimes.pop_front(); 152 { //All lines above here are done. Lose them.
149 mLineLengths.pop_front(); 153 for (U32 i=0;i<paragraph_num;i++)
150 mColors.pop_front(); 154 {
155 if (!mParagraphs.empty())
156 mParagraphs.pop_front();
157 }
158 break;
151 } 159 }
160 paragraph_num--;
161 paragraph_it++;
152 } 162 }
153 163
154 line_count = mLines.size(); 164 if (mParagraphs.empty())
155
156 S32 i;
157 if (line_count == 0)
158 { 165 {
159 mLastBoxHeight = 0;
160 mLastBoxWidth = 0;
161 return; 166 return;
162 } 167 }
163 else 168
164 { 169 // draw remaining lines
165 LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga"); 170 F32 y_pos = 0.f;
166 171
167 F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); 172 LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
168 LLColor4 color = gColors.getColor("ConsoleBackground");
169 color.mV[VALPHA] *= console_opacity;
170 173
171 S32 max_width = 0; 174 F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
172 for (i = 0; i < line_count; i++) 175 LLColor4 color = gColors.getColor("ConsoleBackground");
173 { 176 color.mV[VALPHA] *= console_opacity;
174 max_width = llmax(max_width, mFont->getWidth(mLines[i].c_str()) + 30);
175 }
176 max_width = llmin(max_width, gViewerWindow->getWindowWidth());
177
178 F32 u = 1.f;//LLCriticalDamp::getInterpolant(0.1f);
179 S32 target_height = llfloor(line_count * mFont->getLineHeight() + 15);
180 S32 target_width = max_width;
181 mLastBoxHeight = llmax(target_height, (S32)lerp((F32)mLastBoxHeight, (F32)target_height, u));
182 mLastBoxWidth = llmax(MIN_CONSOLE_WIDTH, llmax(target_width, (S32)lerp((F32)mLastBoxWidth, (F32)target_width, u)));
183 imagep->drawSolid(-15, -10, mLastBoxWidth + 15, mLastBoxHeight, color);
184 }
185 177
186 y_pos += (line_count-1) * mFont->getLineHeight(); 178 F32 line_height = mFont->getLineHeight();
187 179
180 S32 message_spacing=4;
181
182//080813 Spatters: This section makes a single huge black box behind all the text.
183 S32 bkg_height=4;
184 S32 bkg_width=0;
185 for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++)
186 {
187 S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + message_spacing);
188 S32 target_width = llfloor( (*paragraph_it).mMaxWidth +15);
189
190 bkg_height+= target_height;
191 if (target_width > bkg_width) bkg_width=target_width;
192
193 y_pos += ((*paragraph_it).mLines.size()) * line_height;
194 y_pos += message_spacing; //Extra spacing between messages.
195 }
196 imagep->drawSolid(-14, (S32)(y_pos + line_height - bkg_height - message_spacing), bkg_width, bkg_height, color);
197 y_pos = 0.f;
198//End screen-eating black void
188 199
189 for (i = 0; i < line_count; i++) 200 for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++)
190 { 201 {
202//080813 Spatters: Dainty per-message block boxes
203// S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8);
204 S32 target_width = llfloor( (*paragraph_it).mMaxWidth +15);
205
206 y_pos += ((*paragraph_it).mLines.size()) * line_height;
207//080813 Spatters: Dainty per-message block boxes
208// imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color);
209
210 F32 y_off=0;
211
191 F32 alpha; 212 F32 alpha;
192 213
193 if ((mLinePersistTime > 0.f) && (mAddTimes[i] < fade_time)) 214 if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time))
194 { 215 {
195 alpha = (mAddTimes[i] - skip_time)/(mLinePersistTime - mFadeTime); 216 alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime);
196 } 217 }
197 else 218 else
198 { 219 {
@@ -201,26 +222,35 @@ void LLConsole::draw()
201 222
202 if( alpha > 0.f ) 223 if( alpha > 0.f )
203 { 224 {
204 // text line itself 225 for (lines_t::iterator line_it=(*paragraph_it).mLines.begin();
205 mFont->render(mLines[i], 0, x_pos, y_pos, 226 line_it != (*paragraph_it).mLines.end();
206 LLColor4( 227 line_it ++)
207 mColors[i].mV[VRED], 228 {
208 mColors[i].mV[VGREEN], 229 for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin();
209 mColors[i].mV[VBLUE], 230 seg_it != (*line_it).mLineColorSegments.end();
210 mColors[i].mV[VALPHA]*alpha), 231 seg_it++)
211 LLFontGL::LEFT, 232 {
212 LLFontGL::BASELINE, 233 mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off,
213 LLFontGL::DROP_SHADOW, 234 LLColor4(
214 S32_MAX, 235 (*seg_it).mColor.mV[VRED],
215 mLastBoxWidth 236 (*seg_it).mColor.mV[VGREEN],
216 ); 237 (*seg_it).mColor.mV[VBLUE],
238 (*seg_it).mColor.mV[VALPHA]*alpha),
239 LLFontGL::LEFT,
240 LLFontGL::BASELINE,
241 LLFontGL::DROP_SHADOW,
242 S32_MAX,
243 target_width
244 );
245 }
246 y_off += line_height;
247 }
217 } 248 }
218 249 y_pos += message_spacing; //Extra spacing between messages.
219 y_pos -= mFont->getLineHeight();
220 } 250 }
221} 251}
222 252
223void LLConsole::addLine(const LLString& utf8line) 253void LLConsole::addLine(const std::string& utf8line)
224{ 254{
225 LLWString wline = utf8str_to_wstring(utf8line); 255 LLWString wline = utf8str_to_wstring(utf8line);
226 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); 256 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
@@ -231,80 +261,148 @@ void LLConsole::addLine(const LLWString& wline)
231 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); 261 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
232} 262}
233 263
234void LLConsole::addLine(const LLString& utf8line, F32 size, const LLColor4 &color) 264void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color)
235{ 265{
236 LLWString wline = utf8str_to_wstring(utf8line); 266 LLWString wline = utf8str_to_wstring(utf8line);
237 addLine(wline, size, color); 267 addLine(wline, size, color);
238} 268}
239 269
240void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color) 270//Generate highlight color segments for this paragraph. Pass in default color of paragraph.
271void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
241{ 272{
242 while (mLineQueue.size() >= mMaxLines) 273 LLSD paragraph_color_segments;
243 { 274 LLColor4 lcolor=color;
244 mLineQueue.pop_front(); 275
276 paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
277 LLSD color_sd = color.getValue();
278 paragraph_color_segments[0]["color"]=color_sd;
279
280 for(LLSD::array_const_iterator color_segment_it = paragraph_color_segments.beginArray();
281 color_segment_it != paragraph_color_segments.endArray();
282 ++color_segment_it)
283 {
284 LLSD color_llsd = (*color_segment_it)["color"];
285 std::string color_str = (*color_segment_it)["text"].asString();
286
287 ParagraphColorSegment color_segment;
288
289 color_segment.mColor.setValue(color_llsd);
290 color_segment.mNumChars = color_str.length();
291
292 mParagraphColorSegments.push_back(color_segment);
245 } 293 }
246 mLineQueue.push_back(LineInfo(wline, size, color, mTimer.getElapsedTimeF32()));
247#if LL_WINDOWS && LL_LCD_COMPILE
248 // add to LCD screen
249 AddNewDebugConsoleToLCD(wline);
250#endif
251} 294}
252 295
253void LLConsole::addQueuedLines() 296//Called when a paragraph is added to the console or window is resized.
297void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool force_resize)
254{ 298{
255 for (line_queue_t::iterator iter = mLineQueue.begin(); 299 if ( !force_resize )
256 iter != mLineQueue.end(); ++iter) 300 {
301 if ( mMaxWidth >= 0.0f
302 && mMaxWidth < screen_width )
303 {
304 return; //No resize required.
305 }
306 }
307
308 screen_width = screen_width - 30; //Margin for small windows.
309
310 if ( mParagraphText.empty()
311 || mParagraphColorSegments.empty()
312 || font == NULL)
313 {
314 return; //Not enough info to complete.
315 }
316
317 mLines.clear(); //Chuck everything.
318 mMaxWidth = 0.0f;
319
320 paragraph_color_segments_t::iterator current_color = mParagraphColorSegments.begin();
321 U32 current_color_length = (*current_color).mNumChars;
322
323 S32 paragraph_offset = 0; //Offset into the paragraph text.
324
325 // Wrap lines that are longer than the view is wide.
326 while( paragraph_offset < (S32)mParagraphText.length() )
257 { 327 {
258 LineInfo& line_info = *iter; 328 S32 skip_chars; // skip '\n'
259 LLWString wline = line_info.wline; 329 // Figure out if a word-wrapped line fits here.
260 //F32 size = line_info.size; 330 LLWString::size_type line_end = mParagraphText.find_first_of(llwchar('\n'), paragraph_offset);
261 LLColor4 color = line_info.color; 331 if (line_end != LLWString::npos)
262 if (!wline.empty() && mFont != NULL) 332 {
333 skip_chars = 1; // skip '\n'
334 }
335 else
263 { 336 {
264 // Wrap lines that are longer than the view is wide. 337 line_end = mParagraphText.size();
265 S32 line_start_offset = 0; 338 skip_chars = 0;
266 while( line_start_offset < (S32)wline.length() ) 339 }
340
341 U32 drawable = font->maxDrawableChars(mParagraphText.c_str()+paragraph_offset, screen_width, line_end - paragraph_offset, TRUE);
342
343 if (drawable != 0)
344 {
345 F32 x_position = 0; //Screen X position of text.
346
347 mMaxWidth = llmax( mMaxWidth, (F32)font->getWidth( mParagraphText.substr( paragraph_offset, drawable ).c_str() ) );
348 Line line;
349
350 U32 left_to_draw = drawable;
351 U32 drawn = 0;
352
353 while (left_to_draw >= current_color_length
354 && current_color != mParagraphColorSegments.end() )
267 { 355 {
268 // Find the next '\n', if any 356 LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, current_color_length );
269 LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), line_start_offset); 357 line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line.
270 if (LLWString::npos == line_end) 358 (*current_color).mColor,
271 { 359 x_position ) );
272 // no more '\n's, try to use the whole line 360
273 line_end = wline.size(); 361 x_position += font->getWidth( color_text.c_str() ); //Set up next screen position.
274 } 362
275 // Find how many characters will reasonably fit in the allowed width 363 drawn += current_color_length;
276 U32 drawable = mFont->maxDrawableChars(wline.c_str()+line_start_offset, (F32)getRect().getWidth(), line_end-line_start_offset, TRUE); 364 left_to_draw -= current_color_length;
277 if (drawable != 0) 365
366 current_color++; //Goto next paragraph color record.
367
368 if (current_color != mParagraphColorSegments.end())
278 { 369 {
279 LLFixedBuffer::addLine(wline.substr(line_start_offset, drawable)); 370 current_color_length = (*current_color).mNumChars;
280 mAddTimes[mAddTimes.size()-1] = line_info.add_time;
281
282 // move the line_start_offset by the number of characters we were able to draw, up to an implicit or explicit line-break.
283 line_start_offset += drawable;
284 }
285 else
286 {
287 // no drawable characters - force a blank line and try the next character.
288 LLFixedBuffer::addLine(" ");
289 line_start_offset++;
290 }
291 mColors.push_back(color);
292 // 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).
293 if (line_start_offset == line_end)
294 {
295 line_start_offset++;
296 } 371 }
297 } 372 }
373
374 if (left_to_draw > 0 && current_color != mParagraphColorSegments.end() )
375 {
376 LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, left_to_draw );
377
378 line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line.
379 (*current_color).mColor,
380 x_position ) );
381
382 current_color_length -= left_to_draw;
383 }
384 mLines.push_back(line); //Append line to paragraph line list.
298 } 385 }
386 paragraph_offset += (drawable + skip_chars);
299 } 387 }
300 mLineQueue.clear();
301} 388}
302 389
303void LLConsole::removeExtraLines() 390//Pass in the string and the default color for this block of text.
391LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width)
392 : mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
304{ 393{
305 while((S32)mColors.size() > llmax(0, (S32)(mMaxLines - 1))) 394 makeParagraphColorSegments(color);
306 { 395 updateLines( screen_width, font );
307 mColors.pop_front(); 396}
308 } 397
309 LLFixedBuffer::removeExtraLines(); 398void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
399{
400 Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() );
401
402 mParagraphs.push_back ( paragraph );
403
404#if LL_WINDOWS && LL_LCD_COMPILE
405 // add to LCD screen
406 AddNewDebugConsoleToLCD(wline);
407#endif
310} 408}