My hobbyist coding updates and releases as the mysterious "Mr. Tines"

Sunday 14 December 2008

Persisting user settings in Silverlight

Many years ago, the first GUI application I wrote (in X with Motif) was a little orrery-cum-clock thing, with the clock face doubling as a view of the sky, showing the classical planets. Some time in the intermediate past, I thought about doing this as a Java applet, but it never got anywhere, because out on the web, it would have to be settable to the user's geographic location, and I never figured a good way to persist that data between page visits.

Having done the basic tinkering with IronPython and Silverlight to get the two working together, I thought about resurrecting the project. And the first thing to solve is the settings persistence.

But now, I have an easy API to get at the current URL and such via System.Windows.Browser.HtmlPage.Document -- so I can read the values from its query string; and set the values in a hyperlink for bookmarking purposes, thus (app.py):

from System.Windows import Application
from System.Windows.Controls import Canvas
import System
import System.Windows.Browser

xaml = Application.Current.LoadRootVisual(Canvas(), "astroclock.xaml")
xaml.hyperlink.NavigateUri = System.Windows.Browser.HtmlPage.Document.DocumentUri
thisPage = System.Windows.Browser.HtmlPage.Document.DocumentUri.GetComponents(
  System.UriComponents.SchemeAndServer | System.UriComponents.Path,
  System.UriFormat.SafeUnescaped)
query = System.Windows.Browser.HtmlPage.Document.QueryString
  
try:
  xaml.slider1.Value = float(query['lat'])
except:
  pass
try:
  xaml.slider2.Value = float(query['long'])
except:
  pass
 
def latValueChanged(s, e):
  v = xaml.slider1.Value
  if v > 0:
 xaml.label1.Text = "Latitude %.2fN" % (v)
  elif v < 0:
 xaml.label1.Text = "Latitude %.2fS" % (-v)
  else: 
 xaml.label1.Text = "Latitude 0"
 xaml.hyperlink.NavigateUri = System.Uri("%s?lat=%f&long=%f" % (thisPage, v, xaml.slider2.Value))

xaml.slider1.ValueChanged += latValueChanged
latValueChanged(None, None)

def longValueChanged(s, e):
  v = xaml.slider2.Value
  if v > 0:
 xaml.label2.Text = "Longitude %.2fE" % (v)
  elif v < 0:
 xaml.label2.Text = "Longitude %.2fW" % (-v)
  else:
 xaml.label2.Text = "Longitude 0"
 xaml.hyperlink.NavigateUri = System.Uri("%s?lat=%f&long=%f" % (thisPage, xaml.slider1.Value, v))
 
xaml.slider2.ValueChanged += longValueChanged
longValueChanged(None, None)

driving some UI described by (astroclock.xaml)

<Canvas 
  x:Class="System.Windows.Controls.Canvas"
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Name="parentCanvas">
    <Grid>
        <Canvas Name="canvas1" Margin="0,0,0,129" Background="Black" Width="480" Height="240"/>
        <Slider Height="22" Margin="128,0,0,93" Name="slider1" VerticalAlignment="Bottom" Maximum="90" Minimum="-90" Value="52" LargeChange="10" SmallChange="1" Width="360"/>
        <TextBlock Height="28" Margin="0,0,0,87" Name="label1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="120">Latitude</TextBlock>
        <TextBlock Height="28" HorizontalAlignment="Left" Margin="0,0,0,62" Name="label2" VerticalAlignment="Bottom" Width="120">Longitude</TextBlock>
        <Slider Height="22" Margin="128,0,0,65" Name="slider2" VerticalAlignment="Bottom" Maximum="180" Minimum="-180" LargeChange="10" SmallChange="1" Width="360"/>
        <HyperlinkButton Height="28" HorizontalAlignment="Left" Margin="0,0,0,17" Name="hyperlink" VerticalAlignment="Bottom" Width="87" NavigateUri="astroclock.html" Content="Permalink" />
    </Grid>
</Canvas>

Evolving implementation here.

No comments: