@@ -37,6 +37,8 @@ class ToolTipForm : Form
3737 // Various graphics object cached
3838 Brush _textBrush ;
3939 Brush _linkBrush ;
40+ Color _textColor ;
41+ Color _linkColor ;
4042 Pen _borderPen ;
4143 Pen _borderLightPen ;
4244 Dictionary < FontStyle , Font > _fonts ;
@@ -60,8 +62,10 @@ public ToolTipForm(IntPtr hwndOwner)
6062
6163 } ;
6264 //_textBrush = new SolidBrush(Color.FromArgb(68, 68, 68)); // Best matches Excel's built-in color, but I think a bit too light
63- _textBrush = new SolidBrush ( Color . FromArgb ( 52 , 52 , 52 ) ) ;
64- _linkBrush = new SolidBrush ( Color . Blue ) ;
65+ _textColor = Color . FromArgb ( 60 , 60 , 60 ) ;
66+ _linkColor = Color . Blue ;
67+ _textBrush = new SolidBrush ( _textColor ) ;
68+ _linkBrush = new SolidBrush ( _linkColor ) ;
6569 _borderPen = new Pen ( Color . FromArgb ( 195 , 195 , 195 ) ) ;
6670 _borderLightPen = new Pen ( Color . FromArgb ( 225 , 225 , 225 ) ) ;
6771 SetStyle ( ControlStyles . UserMouse | ControlStyles . UserPaint | ControlStyles . AllPaintingInWmPaint , true ) ;
@@ -311,7 +315,129 @@ Point GetMouseLocation(IntPtr lParam)
311315 #endregion
312316
313317 #region Painting
318+
319+ bool oldPaint = false ;
320+
314321 protected override void OnPaint ( PaintEventArgs e )
322+ {
323+ //if (oldPaint)
324+ //{
325+ // OnPaint_Plus(e);
326+ // return;
327+ //}
328+ if ( oldPaint )
329+ {
330+ _textBrush = Brushes . Red ;
331+ _linkBrush = Brushes . Pink ;
332+ OnPaint_Plus ( e ) ;
333+ }
334+
335+ base . OnPaint ( e ) ;
336+
337+ List < int > lineWidths = new List < int > ( ) ;
338+ const int maxWidth = 1000 ; // Should depend on screen width?
339+ const int maxHeight = 500 ;
340+ const int leftPadding = 6 ;
341+ const int linePadding = 0 ;
342+ const int widthPadding = 12 ;
343+ const int heightPadding = 2 ;
344+ const int minLineHeight = 16 ;
345+
346+ int layoutLeft = ClientRectangle . Location . X + leftPadding ;
347+ int layoutTop = ClientRectangle . Location . Y ;
348+
349+ var textFormatFlags = TextFormatFlags . Left |
350+ TextFormatFlags . Top |
351+ TextFormatFlags . NoPadding |
352+ TextFormatFlags . SingleLine |
353+ TextFormatFlags . ExternalLeading ;
354+
355+ int currentHeight = 0 ; // Measured from layoutTop, going down
356+ foreach ( var line in _text )
357+ {
358+ currentHeight += linePadding ;
359+ int lineHeight = minLineHeight ;
360+ int lineWidth = 0 ;
361+ foreach ( var run in line )
362+ {
363+ // We support only a single link, for now
364+ Font font ;
365+ Brush brush ;
366+ Color color ;
367+ if ( run . IsLink && _linkActive )
368+ {
369+ font = _fonts [ FontStyle . Underline ] ;
370+ color = _linkColor ;
371+ brush = _linkBrush ;
372+ }
373+ else
374+ {
375+ font = _fonts [ run . Style ] ;
376+ color = _textColor ;
377+ brush = _textBrush ;
378+ }
379+
380+ foreach ( var text in getRunParts ( run . Text ) ) // Might split on space too?
381+ {
382+ if ( text == "" ) continue ;
383+
384+ // How wide is this part?
385+ var proposedSize = new Size ( maxWidth - lineWidth , maxHeight - currentHeight ) ;
386+ var textSize = TextRenderer . MeasureText ( e . Graphics , text , font , proposedSize , textFormatFlags ) ;
387+ if ( textSize . Width <= proposedSize . Width )
388+ {
389+ // Draw it in this line
390+ TextRenderer . DrawText ( e . Graphics , text , font , new Point ( layoutLeft + lineWidth , layoutTop + currentHeight ) , color , textFormatFlags ) ;
391+ }
392+ else
393+ {
394+ // Make a new line and definitely draw it there (maybe with ellipses?)
395+ lineWidths . Add ( lineWidth ) ;
396+ currentHeight += lineHeight ;
397+ currentHeight += linePadding ;
398+
399+ lineHeight = minLineHeight ;
400+ lineWidth = 2 ; // Little bit of indent on these lines
401+ TextRenderer . DrawText ( e . Graphics , text , font , new Rectangle ( layoutLeft + lineWidth , layoutTop + currentHeight , maxWidth , maxHeight - currentHeight ) , color , textFormatFlags |= TextFormatFlags . EndEllipsis ) ;
402+ }
403+
404+ if ( run . IsLink )
405+ {
406+ _linkClientRect = new Rectangle ( layoutLeft + lineWidth , layoutTop + currentHeight , textSize . Width , textSize . Height ) ;
407+ _linkAddress = run . LinkAddress ;
408+ }
409+
410+ lineWidth += textSize . Width ; // + 1;
411+ lineHeight = Math . Max ( lineHeight , textSize . Height ) ;
412+ }
413+ }
414+ lineWidths . Add ( lineWidth ) ;
415+ currentHeight += lineHeight ;
416+ }
417+
418+ var width = lineWidths . Max ( ) + widthPadding ;
419+ var height = currentHeight + heightPadding ;
420+
421+ UpdateLocation ( width , height ) ;
422+ DrawRoundedRectangle ( e . Graphics , new RectangleF ( 0 , 0 , Width - 1 , Height - 1 ) , 2 , 2 ) ;
423+ }
424+
425+ IEnumerable < string > getRunParts ( string runText )
426+ {
427+ int lastStart = 0 ;
428+ for ( int i = 0 ; i < runText . Length ; i ++ )
429+ {
430+ if ( runText [ i ] == ',' )
431+ {
432+ yield return runText . Substring ( lastStart , i - lastStart + 1 ) ;
433+ lastStart = i + 1 ;
434+ }
435+ }
436+ yield return runText . Substring ( lastStart ) ;
437+ }
438+
439+ #region This is the original text painting, based on GDI+ calls
440+ protected void OnPaint_Plus ( PaintEventArgs e )
315441 {
316442 const int leftPadding = 6 ;
317443 const int linePadding = 0 ;
@@ -357,7 +483,7 @@ protected override void OnPaint(PaintEventArgs e)
357483 // TODO: Empty strings are a problem....
358484 var text = run . Text == "" ? " " : run . Text ;
359485
360- DrawString ( e . Graphics , brush , ref layoutRect , out textSize , format , text , font ) ;
486+ DrawString_Plus ( e . Graphics , brush , ref layoutRect , out textSize , format , text , font ) ;
361487
362488 if ( run . IsLink )
363489 {
@@ -385,7 +511,7 @@ protected override void OnPaint(PaintEventArgs e)
385511 DrawRoundedRectangle ( e . Graphics , new RectangleF ( 0 , 0 , Width - 1 , Height - 1 ) , 2 , 2 ) ;
386512 }
387513
388- void DrawString ( Graphics g , Brush brush , ref Rectangle rect , out Size used ,
514+ void DrawString_Plus ( Graphics g , Brush brush , ref Rectangle rect , out Size used ,
389515 StringFormat format , string text , Font font )
390516 {
391517 using ( StringFormat copy = ( StringFormat ) format . Clone ( ) )
@@ -408,8 +534,8 @@ void DrawString(Graphics g, Brush brush, ref Rectangle rect, out Size used,
408534 rect . Width -= width ;
409535 }
410536 }
537+ #endregion
411538
412-
413539 void DrawRoundedRectangle ( Graphics g , RectangleF r , float radiusX , float radiusY )
414540 {
415541 var oldMode = g . SmoothingMode ;
0 commit comments