Created
August 8, 2010 00:17
-
-
Save peterdn/513381 to your computer and use it in GitHub Desktop.
Simple SL control for an URL shortener service that copies text to clipboard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Author: Peter Nelson / @_peterdn - A simple SL control that copies text | |
to the user's clipboard. Currently used in my URL (not-so) shortener | |
at http://u.peterdn.com, on supported clients. --> | |
<UserControl x:Class="UrlShortenerTextBox.UrlShortenerTextBox" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
mc:Ignorable="d" | |
d:DesignHeight="49" d:DesignWidth="500" Loaded="UserControl_Loaded" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> | |
<Grid x:Name="LayoutRoot" Background="White" Height="32" Width="390"> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="103*" /> | |
<ColumnDefinition Width="397*" /> | |
</Grid.ColumnDefinitions> | |
<sdk:Label Height="32" Background="#E3FDC1" | |
BorderBrush="#BBB" HorizontalAlignment="Left" | |
Name="textBoxUrl" VerticalAlignment="Center" | |
Width="390" FontFamily="Georgia" FontSize="20" | |
Foreground="#555" Grid.ColumnSpan="2" | |
Cursor="Hand" Canvas.ZIndex="1" | |
MouseLeftButtonDown="textBoxUrl_MouseLeftButtonDown" | |
Padding="9,0,0,0" BorderThickness="1" | |
MouseEnter="textBoxUrl_MouseEnter" MouseLeave="textBoxUrl_MouseLeave"> | |
<TextBlock>http://u.peterdn.com</TextBlock> | |
</sdk:Label> | |
<sdk:Label Grid.Column="1" Height="32" | |
HorizontalAlignment="Center" Margin="174,0,0,0" | |
Name="statusLabel" VerticalAlignment="Center" | |
Width="0" Background="#FFF" FontFamily="Georgia" | |
FontSize="20" Foreground="#F0B000" BorderBrush="#BBB" | |
BorderThickness="1" MouseLeftButtonDown="statusLabel_MouseLeftButtonDown" | |
MouseEnter="textBoxUrl_MouseEnter" MouseLeave="textBoxUrl_MouseLeave" | |
Canvas.ZIndex="2" Cursor="Hand" /> | |
</Grid> | |
</UserControl> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Author: Peter Nelson / @_peterdn - A simple SL control that copies text | |
to the user's clipboard. Currently used in my URL (not-so) shortener | |
at http://u.peterdn.com, on supported clients. | |
*/ | |
using System; | |
using System.Security; | |
using System.Windows; | |
using System.Windows.Browser; | |
using System.Windows.Controls; | |
using System.Windows.Input; | |
using System.Windows.Threading; | |
namespace UrlShortenerTextBox | |
{ | |
public partial class UrlShortenerTextBox : UserControl | |
{ | |
// config-ish constants | |
private const int ANIMATE_INTERVAL_MS = 10; | |
private const int ANIMATE_DELAY = 80; | |
private const int ANIMATE_DX = 10; | |
private const int MAX_STATUS_WIDTH = 135; | |
private const string COPY_TEXT = "Click to Copy"; | |
private const string COPIED_TEXT = "Copied!"; | |
private const string NOTCOPIED_TEXT = "Not Copied"; | |
public UrlShortenerTextBox() | |
{ | |
InitializeComponent(); | |
} | |
private void UserControl_Loaded(object sender, RoutedEventArgs e) | |
{ | |
// Assumes that the shortened url key is in the last segment of | |
// the url, e.g. as in scheme://my.url/view/details/KEY. | |
// Constructs a shortened url of the form http://my.url/KEY. | |
var uri = HtmlPage.Document.DocumentUri; | |
var segments = uri.ToString().Split('/'); | |
textBoxUrl.Content = "http://" + uri.Host + /* ":" + port + */ | |
"/" + segments[segments.Length - 1]; | |
_animateTimer.Tick += new EventHandler(timer_Tick); | |
_animateTimer.Interval = new TimeSpan(0, 0, 0, 0, ANIMATE_INTERVAL_MS); | |
} | |
private void statusLabel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) | |
{ | |
copyToClipboard(); | |
} | |
private void textBoxUrl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) | |
{ | |
copyToClipboard(); | |
} | |
private void copyToClipboard() | |
{ | |
try | |
{ | |
Clipboard.SetText(textBoxUrl.Content.ToString()); | |
statusLabel.Content = COPIED_TEXT; | |
} | |
catch (SecurityException) | |
{ | |
// User denied the operation. Ideally we would | |
// redirect them to a non-SL page at this point. | |
statusLabel.Content = NOTCOPIED_TEXT; | |
} | |
_delay = ANIMATE_DELAY; | |
} | |
private void textBoxUrl_MouseEnter(object sender, MouseEventArgs e) | |
{ | |
statusLabel.Content = COPY_TEXT; | |
_delay = ANIMATE_DELAY; | |
this.animate(true); | |
} | |
private void textBoxUrl_MouseLeave(object sender, MouseEventArgs e) | |
{ | |
this.animate(false); | |
} | |
private void animate(bool Show) | |
{ | |
_showing = Show; | |
if (!_animateTimer.IsEnabled) | |
_animateTimer.Start(); | |
} | |
// Animation state vars | |
DispatcherTimer _animateTimer = new DispatcherTimer(); | |
private bool _showing = false; | |
private int _delay = 0; | |
private void timer_Tick(object sender, EventArgs e) | |
{ | |
// Do a simple bit of animation by adjusting widths and margins. | |
// There's probably a more SL way of doing this with storyboards | |
// and what not, but I'm going to stick with this method for the | |
// moment. Saying that, it needs tweaking to work nicely for | |
// the case when MAX_STATUS_WIDTH != 135... | |
if (_showing || _delay > 0) | |
{ | |
// Display the status label. | |
statusLabel.Width = statusLabel.Width <= (MAX_STATUS_WIDTH - ANIMATE_DX) ? | |
statusLabel.Width + ANIMATE_DX : MAX_STATUS_WIDTH; | |
var margin = statusLabel.Margin; | |
margin.Right = statusLabel.Width - MAX_STATUS_WIDTH; | |
statusLabel.Margin = margin; | |
if (statusLabel.Width == MAX_STATUS_WIDTH && _delay == 0) | |
((DispatcherTimer)sender).Stop(); | |
} | |
else | |
{ | |
// Hide the status label. | |
statusLabel.Width = statusLabel.Width >= ANIMATE_DX ? | |
statusLabel.Width - ANIMATE_DX : 0; | |
var margin = statusLabel.Margin; | |
margin.Right = statusLabel.Width - MAX_STATUS_WIDTH; | |
statusLabel.Margin = margin; | |
if (statusLabel.Width == 0 && _delay == 0) | |
((DispatcherTimer)sender).Stop(); | |
} | |
if (_delay > 0) | |
_delay--; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment