Toasts – Diff between revs 58 and 59
?pathlinks?
Rev 58 | Rev 59 | |||
---|---|---|---|---|
Line 22... | Line 22... | |||
22 | using System.Windows.Forms; |
22 | using System.Windows.Forms; |
|
23 | using System.Xml.Linq; |
23 | using System.Xml.Linq; |
|
24 | using TheArtOfDev.HtmlRenderer.WinForms; |
24 | using TheArtOfDev.HtmlRenderer.WinForms; |
|
25 | using Toasts.Properties; |
25 | using Toasts.Properties; |
|
26 | using Toasts.Utilities; |
26 | using Toasts.Utilities; |
|
- | 27 | using static System.Net.Mime.MediaTypeNames; |
||
- | 28 | using Image = System.Drawing.Image; |
||
Line 27... | Line 29... | |||
27 | |
29 | |
|
28 | namespace Toasts |
30 | namespace Toasts |
|
29 | { |
31 | { |
|
30 | public partial class ToastForm : Form |
32 | public partial class ToastForm : Form |
|
Line 78... | Line 80... | |||
78 | |
80 | |
|
79 | /// <summary> |
81 | /// <summary> |
|
80 | /// |
82 | /// |
|
81 | /// </summary> |
83 | /// </summary> |
|
82 | /// <remarks>clone the image for safety</remarks> |
84 | /// <remarks>clone the image for safety</remarks> |
|
83 | public Image Image |
85 | public System.Drawing.Image Image |
|
84 | { |
86 | { |
|
85 | get |
87 | get |
|
86 | { |
88 | { |
|
87 | if(_image == null) |
89 | if(_image == null) |
|
Line 148... | Line 150... | |||
148 | |
150 | |
|
Line 149... | Line 151... | |||
149 | private string _title; |
151 | private string _title; |
|
Line -... | Line 152... | |||
- | 152 | |
||
- | 153 | private string _body; |
||
- | 154 | |
||
- | 155 | private TaskCompletionSource<int> _imageLoadedTaskCompletionSource; |
||
150 | |
156 | |
|
Line 151... | Line 157... | |||
151 | private string _body; |
157 | private readonly ConcurrentDictionary<string, Image> _imagePreload = new ConcurrentDictionary<string, Image>(); |
|
152 | |
158 | |
|
153 | protected override bool ShowWithoutActivation => true; |
159 | protected override bool ShowWithoutActivation => true; |
|
Line 308... | Line 314... | |||
308 | } |
314 | } |
|
309 | } |
315 | } |
|
Line 310... | Line 316... | |||
310 | |
316 | |
|
311 | private async void ToastForm_Load(object sender, EventArgs e) |
317 | private async void ToastForm_Load(object sender, EventArgs e) |
|
- | 318 | { |
||
- | 319 | Opacity = 0; |
||
312 | { |
320 | |
|
313 | if (EnableChime) |
321 | if (EnableChime) |
|
314 | { |
322 | { |
|
315 | try |
323 | try |
|
316 | { |
324 | { |
|
Line 343... | Line 351... | |||
343 | |
351 | |
|
Line 344... | Line 352... | |||
344 | } |
352 | } |
|
345 | |
353 | |
|
- | 354 | // compute notification height from body |
||
346 | // compute notification height from body |
355 | var maxWidth = tableLayoutPanel4.Width; |
|
347 | var maxWidth = tableLayoutPanel4.Width; |
356 | var hasImage = false; |
|
348 | switch (ContentType) |
357 | switch (ContentType) |
|
349 | { |
358 | { |
|
350 | case "text/markdown": |
359 | case "text/markdown": |
|
Line 355... | Line 364... | |||
355 | if (htmlDocument.DocumentNode != null && htmlDocument.DocumentNode.Descendants().Any()) |
364 | if (htmlDocument.DocumentNode != null && htmlDocument.DocumentNode.Descendants().Any()) |
|
356 | { |
365 | { |
|
357 | var imgNodes = htmlDocument.DocumentNode.SelectNodes("//img"); |
366 | var imgNodes = htmlDocument.DocumentNode.SelectNodes("//img"); |
|
358 | if (imgNodes != null && imgNodes.Any()) |
367 | if (imgNodes != null && imgNodes.Any()) |
|
359 | { |
368 | { |
|
- | 369 | hasImage = true; |
||
360 | foreach (var node in imgNodes) |
370 | foreach (var node in imgNodes) |
|
361 | { |
371 | { |
|
362 | node.SetAttributeValue("style", $"max-width: {maxWidth}px"); |
372 | node.SetAttributeValue("style", $"max-width: {maxWidth}px"); |
|
363 | } |
373 | } |
|
364 | } |
374 | } |
|
365 | } |
375 | } |
|
Line 366... | Line 376... | |||
366 | |
376 | |
|
367 | _body = htmlDocument.DocumentNode.WriteTo(); |
377 | _body = htmlDocument.DocumentNode.WriteTo(); |
|
368 | } |
378 | } |
|
369 | break; |
- | ||
370 | default: |
- | ||
371 | break; |
379 | break; |
|
Line -... | Line 380... | |||
- | 380 | } |
||
- | 381 | |
||
- | 382 | |
||
- | 383 | if (hasImage) |
||
- | 384 | { |
||
- | 385 | _imageLoadedTaskCompletionSource = new TaskCompletionSource<int>(); |
||
- | 386 | |
||
372 | } |
387 | } |
|
373 | |
388 | |
|
374 | using (var image = HtmlRender.RenderToImage(_body, maxWidth, 0, Color.Empty)) |
- | ||
375 | { |
389 | using (var image = HtmlRender.RenderToImage(_body, maxWidth, 0, Color.Empty, null, null, PreloadImage)) |
|
376 | var height = image.Height + labelTitle.Height; |
390 | { |
|
- | 391 | switch(hasImage) |
||
- | 392 | { |
||
- | 393 | case true: |
||
- | 394 | { |
||
- | 395 | var imageHeight = await _imageLoadedTaskCompletionSource.Task; |
||
- | 396 | if(imageHeight == 0) |
||
- | 397 | { |
||
- | 398 | imageHeight = image.Height; |
||
- | 399 | } |
||
- | 400 | var height = imageHeight + labelTitle.Height; |
||
377 | if (height > Height) |
401 | if (height > Height) |
|
- | 402 | { |
||
- | 403 | Height = height; |
||
- | 404 | } |
||
- | 405 | } |
||
- | 406 | break; |
||
- | 407 | default: |
||
- | 408 | { |
||
- | 409 | var height = image.Height + labelTitle.Height; |
||
- | 410 | if (height > Height) |
||
- | 411 | { |
||
- | 412 | Height = height; |
||
- | 413 | } |
||
378 | { |
414 | } |
|
379 | Height = height; |
415 | break; |
|
Line 380... | Line 416... | |||
380 | } |
416 | } |
|
381 | } |
417 | } |
|
Line 432... | Line 468... | |||
432 | |
468 | |
|
433 | // set the location of the toast |
469 | // set the location of the toast |
|
Line 434... | Line 470... | |||
434 | Location = new Point(_screenWidth - Width, _screenHeight - Height); |
470 | Location = new Point(_screenWidth - Width, _screenHeight - Height); |
|
435 | |
- | ||
436 | OpenNotifications.Add(this); |
471 | |
|
437 | // show the form |
472 | OpenNotifications.Add(this); |
|
Line 438... | Line 473... | |||
438 | //Opacity = 1; |
473 | Opacity = 1; |
|
439 | } |
474 | } |
|
440 | |
475 | |
|
441 | // set up the timer when the notification should be removed |
476 | // set up the timer when the notification should be removed |
|
442 | _toastTimer = new System.Timers.Timer { Enabled = true, AutoReset = false, Interval = LingerTime }; |
477 | _toastTimer = new System.Timers.Timer { Enabled = true, AutoReset = false, Interval = LingerTime }; |
|
Line 443... | Line 478... | |||
443 | _toastTimer.Elapsed += ToastTimer_Elapsed; |
478 | _toastTimer.Elapsed += ToastTimer_Elapsed; |
|
444 | _toastTimer.Start(); |
479 | _toastTimer.Start(); |
|
445 | } |
480 | } |
|
446 | |
481 | |
|
447 | private async void HtmlPanel1_ImageLoad(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e) |
482 | private async void PreloadImage(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e) |
|
448 | { |
483 | { |
|
Line 465... | Line 500... | |||
465 | { |
500 | { |
|
466 | var image = Image.FromStream(responseStream); |
501 | var image = Image.FromStream(responseStream); |
|
Line 467... | Line 502... | |||
467 | |
502 | |
|
468 | e.Callback(image); |
503 | e.Callback(image); |
|
- | 504 | e.Handled = true; |
||
- | 505 | |
||
- | 506 | _imagePreload.TryAdd(e.Src, Image.FromStream(responseStream)); |
||
- | 507 | |
||
- | 508 | if (_imageLoadedTaskCompletionSource != null) |
||
- | 509 | { |
||
- | 510 | var ratio = image.Height / (float)image.Width; |
||
- | 511 | var width = tableLayoutPanel4.Width * ratio; |
||
- | 512 | _imageLoadedTaskCompletionSource.TrySetResult((int)Math.Ceiling(width)); |
||
469 | e.Handled = true; |
513 | } |
|
470 | } |
514 | } |
|
471 | } |
515 | } |
|
472 | } |
516 | } |
|
473 | catch |
517 | catch |
|
474 | { |
518 | { |
|
- | 519 | Debug.WriteLine("Error downloading image."); |
||
- | 520 | |
||
- | 521 | if (_imageLoadedTaskCompletionSource != null) |
||
- | 522 | { |
||
- | 523 | _imageLoadedTaskCompletionSource.TrySetResult(0); |
||
- | 524 | } |
||
- | 525 | } |
||
- | 526 | } |
||
- | 527 | |
||
- | 528 | private void HtmlPanel1_ImageLoad(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e) |
||
- | 529 | { |
||
- | 530 | if(_imagePreload.TryRemove(e.Src, out var image)) |
||
- | 531 | { |
||
- | 532 | e.Callback(image); |
||
475 | Debug.WriteLine("Error downloading image."); |
533 | e.Handled = true; |
|
476 | } |
534 | } |
|
Line 477... | Line 535... | |||
477 | } |
535 | } |
|
478 | |
536 | |