// OpenTween - Client of Twitter
// Copyright (c) 2012 kim_upsilon (@kim_upsilon)
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see , or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
#nullable enable
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenTween.Thumbnail;
namespace OpenTween
{
public partial class TweetThumbnailControl : UserControl
{
private readonly MouseWheelMessageFilter filter = new();
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public TweetThumbnail Model { get; } = new();
public TweetThumbnailControl()
{
this.InitializeComponent();
this.filter.Register(this.pictureBox);
this.Model.PropertyChanged +=
(s, e) => this.TryInvoke(() => this.Model_PropertyChanged(s, e));
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.components?.Dispose();
this.filter.Dispose();
}
base.Dispose(disposing);
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(TweetThumbnail.ThumbnailAvailable):
this.UpdateThumbnailAvailability();
break;
case nameof(TweetThumbnail.SelectedIndex):
this.UpdateSelectedIndex();
break;
default:
break;
}
}
private void UpdateThumbnailAvailability()
{
if (this.Model.ThumbnailAvailable)
{
this.UpdateSelectedIndex();
var hasMultipleThumbnails = this.Model.Thumbnails.Length > 1;
this.scrollBar.Enabled = hasMultipleThumbnails;
this.scrollBar.Visible = hasMultipleThumbnails;
if (hasMultipleThumbnails)
{
this.scrollBar.Value = 0;
this.scrollBar.Maximum = this.Model.Thumbnails.Length - 1;
}
}
else
{
this.pictureBox.Image = null;
this.pictureBox.AccessibleDescription = "";
this.toolTip.SetToolTip(this.pictureBox, "");
this.scrollBar.Visible = false;
}
}
private void UpdateSelectedIndex()
{
if (!this.Model.ThumbnailAvailable)
return;
this.scrollBar.Value = this.Model.SelectedIndex;
var thumbnail = this.Model.CurrentThumbnail;
this.pictureBox.PlayableMark = thumbnail.IsPlayable;
this.pictureBox.AccessibleDescription = thumbnail.TooltipText;
this.toolTip.SetToolTip(this.pictureBox, thumbnail.TooltipText);
_ = this.pictureBox.SetImageFromTask(this.Model.LoadSelectedThumbnail);
}
public async Task OpenImageInBrowser()
{
if (!this.Model.ThumbnailAvailable)
return;
var thumbnail = this.Model.CurrentThumbnail;
var mediaUrl = thumbnail.FullSizeImageUrl ?? thumbnail.MediaPageUrl;
await MyCommon.OpenInBrowserAsync(this, mediaUrl);
}
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
OTBaseForm.ScaleChildControl(this.scrollBar, factor);
}
private void ScrollBar_ValueChanged(object sender, EventArgs e)
=> this.Model.SelectedIndex = this.scrollBar.Value;
private void PictureBox_MouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta > 0)
this.Model.ScrollUp();
else
this.Model.ScrollDown();
}
private async void PictureBox_DoubleClick(object sender, EventArgs e)
=> await this.OpenImageInBrowser();
private async void SearchSimilarImageMenuItem_Click(object sender, EventArgs e)
{
var searchUri = this.Model.GetImageSearchUriGoogle();
await MyCommon.OpenInBrowserAsync(this, searchUri);
}
private async void SearchImageSauceNaoMenuItem_Click(object sender, EventArgs e)
{
var searchUri = this.Model.GetImageSearchUriSauceNao();
await MyCommon.OpenInBrowserAsync(this, searchUri);
}
private async void OpenMenuItem_Click(object sender, EventArgs e)
=> await this.OpenImageInBrowser();
private void CopyUrlMenuItem_Click(object sender, EventArgs e)
{
try
{
var thumb = this.Model.CurrentThumbnail;
Clipboard.SetText(thumb.FullSizeImageUrl ?? thumb.MediaPageUrl);
}
catch (ExternalException ex)
{
MessageBox.Show(ex.Message);
}
}
private void CopyToClipboardMenuItem_Click(object sender, EventArgs e)
{
try
{
if (this.pictureBox.Image is { } memoryImage)
Clipboard.SetImage(memoryImage.Image);
}
catch (ExternalException ex)
{
MessageBox.Show(ex.Message);
}
}
}
}