Skip to content

Instantly share code, notes, and snippets.

@peterdn
Created August 8, 2010 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterdn/513381 to your computer and use it in GitHub Desktop.
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
<!-- 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>
/*
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