@@ -84,42 +84,91 @@ protected override void OnPaint(PaintEventArgs e) {
8484 // Avoid division by zero.
8585 if ( sampler ? . MaximumSpeed > 0 ) {
8686 // Use entire graph area regardless of clipping region.
87- Rectangle surface = GraphRectangle ;
87+ PaintGraph ( e . Graphics , GraphRectangle ) ;
88+ }
89+ else {
90+ PaintWarning ( e . Graphics , ClientRectangle , "Please choose an adapter" ) ;
91+ }
92+
93+ // Paint entire border regardless of clipping region.
94+ ControlPaint . DrawBorder3D ( e . Graphics , ClientRectangle , Border3DStyle . SunkenOuter ) ;
95+ }
8896
89- // Drawing start point on x-axis.
90- var x = surface . Right - 1 ;
97+ private void PaintGraph ( Graphics g , Rectangle surface ) {
98+ // Drawing start point on x-axis.
99+ var x = surface . Right - 1 ;
91100
92- foreach ( var sample in sampler ) {
93- var downstream = sample . Downstream / ( float ) sampler . MaximumSpeed ;
94- var upstream = sample . Upstream / ( float ) sampler . MaximumSpeed ;
95- var downDominant = downstream > upstream ;
96- var hybridHeight = surface . Height * ( 1 - ( downDominant ? upstream : downstream ) * ( 1 - HEADROOM ) ) + surface . Top ;
97- var dominantHeight = surface . Height * ( 1 - ( downDominant ? downstream : upstream ) * ( 1 - HEADROOM ) ) + surface . Top ;
101+ foreach ( var sample in sampler ) {
102+ var downstream = sample . Downstream / ( float ) sampler . MaximumSpeed ;
103+ var upstream = sample . Upstream / ( float ) sampler . MaximumSpeed ;
104+ var downDominant = downstream > upstream ;
105+ var hybridHeight = surface . Height * ( 1 - ( downDominant ? upstream : downstream ) * ( 1 - HEADROOM ) ) + surface . Top ;
106+ var dominantHeight = surface . Height * ( 1 - ( downDominant ? downstream : upstream ) * ( 1 - HEADROOM ) ) + surface . Top ;
98107
99- // Draw hybrid bar.
100- e . Graphics . DrawLine ( ppapPen , x , hybridHeight , x , surface . Bottom ) ;
108+ // Draw hybrid bar.
109+ g . DrawLine ( ppapPen , x , hybridHeight , x , surface . Bottom ) ;
101110
102- // Draw upload/download bar.
103- e . Graphics . DrawLine ( downDominant ? applePen : pineapplePen , x , dominantHeight , x , hybridHeight ) ;
111+ // Draw upload/download bar.
112+ g . DrawLine ( downDominant ? applePen : pineapplePen , x , dominantHeight , x , hybridHeight ) ;
104113
105- // Draw period separator.
106- if ( sampleIndexes [ sample ] % 30 == 0 ) {
107- for ( var i = surface . Top ; i < surface . Bottom ; i += 4 ) {
108- e . Graphics . DrawLine ( ( i - surface . Top ) % 8 == 0 ? periodPen : lightPeriodPen , x , i , x , i + 3 ) ;
109- }
114+ // Draw period separator.
115+ if ( sampleIndexes [ sample ] % 30 == 0 ) {
116+ for ( var i = surface . Top ; i < surface . Bottom ; i += 4 ) {
117+ g . DrawLine ( ( i - surface . Top ) % 8 == 0 ? periodPen : lightPeriodPen , x , i , x , i + 3 ) ;
110118 }
111-
112- // Do not draw more samples than surface width permits.
113- if ( -- x < surface . Left ) break ;
114119 }
115120
116- // Draw headroom bar.
117- var headroomY = surface . Height * HEADROOM ;
118- e . Graphics . DrawLine ( headroomPen , x + 1 , headroomY , surface . Right , headroomY ) ;
121+ // Do not draw more samples than surface width permits.
122+ if ( -- x < surface . Left ) break ;
119123 }
120124
121- // Paint entire border regardless of clipping region.
122- ControlPaint . DrawBorder3D ( e . Graphics , ClientRectangle , Border3DStyle . SunkenOuter ) ;
125+ // Draw headroom bar.
126+ var headroomY = surface . Height * HEADROOM ;
127+ g . DrawLine ( headroomPen , x + 1 , headroomY , surface . Right , headroomY ) ;
128+ }
129+
130+ private void PaintWarning ( Graphics g , Rectangle surface , string warning ) {
131+ const int MARGIN = 4 ;
132+ var indicatorSize = new SizeF ( 40 , 40 ) ;
133+ var warningSize = g . MeasureString ( warning , Font ) ;
134+ var totalSize = new SizeF ( indicatorSize . Width + MARGIN + warningSize . Width , indicatorSize . Height ) ;
135+
136+ g . SmoothingMode = SmoothingMode . HighQuality ;
137+
138+ // Draw indicator.
139+ using ( var brush = new SolidBrush ( Color . FromArgb ( 128 , BackColor . Darken ( .4f ) ) ) ) {
140+ g . FillEllipse ( brush , new RectangleF (
141+ new PointF (
142+ ( float ) Math . Round ( surface . Width / 2 - totalSize . Width / 2 ) ,
143+ ( float ) Math . Round ( surface . Height / 2 - indicatorSize . Height / 2 )
144+ ) ,
145+ indicatorSize
146+ ) ) ;
147+ }
148+
149+ // Draw indicator text.
150+ using ( var font = new Font ( "Segoe UI" , 25 , FontStyle . Bold ) ) {
151+ var fontSize = g . MeasureString ( "?" , font ) ;
152+
153+ g . DrawString (
154+ "?" ,
155+ font ,
156+ SystemBrushes . Control ,
157+ ( float ) Math . Round ( surface . Width / 2 - totalSize . Width / 2 + indicatorSize . Width / 2 - fontSize . Width / 2 + 1.5 ) ,
158+ ( float ) Math . Round ( surface . Height / 2 - fontSize . Height / 2 + 1.5 )
159+ ) ;
160+ }
161+
162+ // Draw warning text.
163+ using ( var brush = new SolidBrush ( Color . FromArgb ( 192 , ForeColor ) ) ) {
164+ g . DrawString (
165+ warning ,
166+ Font ,
167+ brush ,
168+ ( float ) Math . Round ( surface . Width / 2 + indicatorSize . Width - totalSize . Width / 2 + MARGIN ) ,
169+ ( float ) Math . Round ( surface . Height / 2 - warningSize . Height / 2 + 1.5 )
170+ ) ;
171+ }
123172 }
124173
125174 protected override void OnPaintBackground ( PaintEventArgs e ) {
0 commit comments