Merge lp:~mandel/ubuntuone-windows-installer/improve_sso_ui into lp:ubuntuone-windows-installer/beta

Proposed by Manuel de la Peña
Status: Merged
Approved by: Rick McBride
Approved revision: 90
Merged at revision: 92
Proposed branch: lp:~mandel/ubuntuone-windows-installer/improve_sso_ui
Merge into: lp:ubuntuone-windows-installer/beta
Prerequisite: lp:~mandel/ubuntuone-windows-installer/sso_di
Diff against target: 777 lines (+682/-17)
6 files modified
src/Canonical.Ubuntu.SSO.Views/Canonical.Ubuntu.SSO.Views.csproj (+12/-0)
src/Canonical.Ubuntu.SSO.Views/LoginDialog.xaml (+32/-17)
src/Canonical.Ubuntu.SSO.Views/Resources/Resources.Designer.cs (+108/-0)
src/Canonical.Ubuntu.SSO.Views/Resources/Resources.resx (+135/-0)
src/Canonical.Ubuntu.SSO.Views/WatermarkAdorner.cs (+141/-0)
src/Canonical.Ubuntu.SSO.Views/WatermarkService.cs (+254/-0)
To merge this branch: bzr merge lp:~mandel/ubuntuone-windows-installer/improve_sso_ui
Reviewer Review Type Date Requested Status
Rick McBride (community) Approve
John Lenton (community) Approve
Review via email: mp+37587@code.launchpad.net

Description of the change

Improves the login view used in the Ubuntu SSO to match better the one present in linux.

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) :
review: Approve
Revision history for this message
Rick McBride (rmcbride) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/Canonical.Ubuntu.SSO.Views/Canonical.Ubuntu.SSO.Views.csproj'
--- src/Canonical.Ubuntu.SSO.Views/Canonical.Ubuntu.SSO.Views.csproj 2010-10-05 11:24:46 +0000
+++ src/Canonical.Ubuntu.SSO.Views/Canonical.Ubuntu.SSO.Views.csproj 2010-10-05 11:24:47 +0000
@@ -72,11 +72,23 @@
72 <DependentUpon>Settings.settings</DependentUpon>72 <DependentUpon>Settings.settings</DependentUpon>
73 <DesignTimeSharedInput>True</DesignTimeSharedInput>73 <DesignTimeSharedInput>True</DesignTimeSharedInput>
74 </Compile>74 </Compile>
75 <Compile Include="Resources\Resources.Designer.cs">
76 <AutoGen>True</AutoGen>
77 <DesignTime>True</DesignTime>
78 <DependentUpon>Resources.resx</DependentUpon>
79 </Compile>
80 <Compile Include="WatermarkAdorner.cs" />
81 <Compile Include="WatermarkService.cs" />
75 <EmbeddedResource Include="Properties\Resources.resx">82 <EmbeddedResource Include="Properties\Resources.resx">
76 <Generator>ResXFileCodeGenerator</Generator>83 <Generator>ResXFileCodeGenerator</Generator>
77 <LastGenOutput>Resources.Designer.cs</LastGenOutput>84 <LastGenOutput>Resources.Designer.cs</LastGenOutput>
78 <SubType>Designer</SubType>85 <SubType>Designer</SubType>
79 </EmbeddedResource>86 </EmbeddedResource>
87 <EmbeddedResource Include="Resources\Resources.resx">
88 <Generator>PublicResXFileCodeGenerator</Generator>
89 <LastGenOutput>Resources.Designer.cs</LastGenOutput>
90 <SubType>Designer</SubType>
91 </EmbeddedResource>
80 <None Include="Properties\Settings.settings">92 <None Include="Properties\Settings.settings">
81 <Generator>SettingsSingleFileGenerator</Generator>93 <Generator>SettingsSingleFileGenerator</Generator>
82 <LastGenOutput>Settings.Designer.cs</LastGenOutput>94 <LastGenOutput>Settings.Designer.cs</LastGenOutput>
8395
=== modified file 'src/Canonical.Ubuntu.SSO.Views/LoginDialog.xaml'
--- src/Canonical.Ubuntu.SSO.Views/LoginDialog.xaml 2010-10-05 11:24:46 +0000
+++ src/Canonical.Ubuntu.SSO.Views/LoginDialog.xaml 2010-10-05 11:24:47 +0000
@@ -1,8 +1,10 @@
1<Window x:Class="Canonical.Ubuntu.SSO.Views.LoginDialog"1<Window x:Class="Canonical.Ubuntu.SSO.Views.LoginDialog"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Login" Height="300" Width="300">4 xmlns:controls="clr-namespace:Canonical.Ubuntu.SSO.Views"
5 <Grid>5 xmlns:resx="clr-namespace:Canonical.Ubuntu.SSO.Views.Resources"
6 Title="Login" Height="350" Width="550">
7 <Grid Margin="10">
6 <Grid.RowDefinitions>8 <Grid.RowDefinitions>
7 <RowDefinition Height="*" />9 <RowDefinition Height="*" />
8 <RowDefinition Height="28" />10 <RowDefinition Height="28" />
@@ -12,35 +14,48 @@
12 <RowDefinition Height="*" />14 <RowDefinition Height="*" />
13 <RowDefinition Height="34" />15 <RowDefinition Height="34" />
14 <RowDefinition Height="34" />16 <RowDefinition Height="34" />
17 <RowDefinition Height="34" />
15 <RowDefinition Height="*" />18 <RowDefinition Height="*" />
16 </Grid.RowDefinitions>19 </Grid.RowDefinitions>
17 <Grid Grid.Row="0">20 <Grid Grid.Row="0">
18 <Grid.RowDefinitions>21 <Grid.RowDefinitions>
19 <RowDefinition Height="32" />22 <RowDefinition Height="*" />
20 <RowDefinition Height="*" />23 <RowDefinition Height="*" />
21 </Grid.RowDefinitions>24 </Grid.RowDefinitions>
22 <Label Name="InfoLabel" Grid.Row="0" Margin="3" >Please provide the email you used register in</Label>25 <TextBlock Name="TitleLabel" Grid.Row="0" Margin="3" FontSize="20" FontFamily="Calibry" Text="{x:Static resx:Resources.LoginViewTitle}"></TextBlock>
23 <Label Grid.Row="1">Ubuntu One and you password.</Label>26 <TextBlock Name="InfoText" Grid.Row="1" Margin="3" FontFamily="Calibry" Text="{x:Static resx:Resources.LoginViewInfo}"></TextBlock>
24 </Grid>27 </Grid>
25 <Grid Grid.Row="1">28 <Grid Grid.Row="1">
26 <Grid.ColumnDefinitions>29 <Grid.ColumnDefinitions>
27 <ColumnDefinition Width="*"/>30 <ColumnDefinition Width="*"/>
28 <ColumnDefinition Width="120"/>31 <ColumnDefinition Width="240"/>
29 <ColumnDefinition Width="120"/>
30 <ColumnDefinition Width="*"/>32 <ColumnDefinition Width="*"/>
31 </Grid.ColumnDefinitions>33 </Grid.ColumnDefinitions>
32 <Label Name="MessageLabel" Grid.Column="1" Margin="3">Email</Label>34 <TextBox Name="EmailTextBox" Grid.Column="1" Margin="3">
33 <TextBox Name="EmailTextBox" Grid.Column="2" Margin="3"></TextBox>35 <controls:WatermarkService.Watermark>
36 <TextBlock Text="{x:Static resx:Resources.LoginEmailAddressWatermark}"></TextBlock>
37 </controls:WatermarkService.Watermark>
38 </TextBox>
34 </Grid>39 </Grid>
35 <Grid Grid.Row="2">40 <Grid Grid.Row="2">
36 <Grid.ColumnDefinitions>41 <Grid.ColumnDefinitions>
37 <ColumnDefinition Width="*"/>42 <ColumnDefinition Width="*"/>
38 <ColumnDefinition Width="120"/>43 <ColumnDefinition Width="240"/>
39 <ColumnDefinition Width="120"/>44 <ColumnDefinition Width="*"/>
40 <ColumnDefinition Width="*"/>45 </Grid.ColumnDefinitions>
41 </Grid.ColumnDefinitions>46 <PasswordBox Name="PasswordTextBox" Grid.Column="1" Margin="3" PasswordChar="*">
42 <Label Name="PasswordLabel" Grid.Column="1" Margin="3">Password</Label>47 <controls:WatermarkService.Watermark>
43 <PasswordBox Name="PasswordTextBox" Grid.Column="2" Margin="3" PasswordChar="*"></PasswordBox >48 <TextBlock Text="{x:Static resx:Resources.LoginPasswordWatermark}"></TextBlock>
49 </controls:WatermarkService.Watermark>
50 </PasswordBox >
51 </Grid>
52 <Grid Grid.Row="3">
53 <Grid.ColumnDefinitions>
54 <ColumnDefinition Width="*"/>
55 <ColumnDefinition Width="240"/>
56 <ColumnDefinition Width="*"/>
57 </Grid.ColumnDefinitions>
58 <TextBlock Name="ForgottenLink" Grid.Column="1" Margin="3" TextAlignment="Center"><Hyperlink >I've forgotten my password.</Hyperlink></TextBlock>
44 </Grid>59 </Grid>
45 </Grid>60 </Grid>
46 <Grid Grid.Row="1">61 <Grid Grid.Row="1">
@@ -49,7 +64,7 @@
49 <ColumnDefinition Width="85"/>64 <ColumnDefinition Width="85"/>
50 <ColumnDefinition Width="85"/>65 <ColumnDefinition Width="85"/>
51 </Grid.ColumnDefinitions>66 </Grid.ColumnDefinitions>
52 <Button Name="LoginButton" Grid.Column="1" Margin="3" Click="LoginButton_Click">Login</Button>67 <Button Name="LoginButton" Grid.Column="1" Margin="3" Click="LoginButton_Click">Connect</Button>
53 <Button Name="CancelButton" Grid.Column="2" Margin="3" Click="CancelButton_Click">Cancel</Button>68 <Button Name="CancelButton" Grid.Column="2" Margin="3" Click="CancelButton_Click">Cancel</Button>
54 </Grid>69 </Grid>
55 </Grid>70 </Grid>
5671
=== added directory 'src/Canonical.Ubuntu.SSO.Views/Resources'
=== added file 'src/Canonical.Ubuntu.SSO.Views/Resources/Resources.Designer.cs'
--- src/Canonical.Ubuntu.SSO.Views/Resources/Resources.Designer.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Views/Resources/Resources.Designer.cs 2010-10-05 11:24:47 +0000
@@ -0,0 +1,108 @@
1//------------------------------------------------------------------------------
2// <auto-generated>
3// This code was generated by a tool.
4// Runtime Version:2.0.50727.4952
5//
6// Changes to this file may cause incorrect behavior and will be lost if
7// the code is regenerated.
8// </auto-generated>
9//------------------------------------------------------------------------------
10
11namespace Canonical.Ubuntu.SSO.Views.Resources {
12 using System;
13
14
15 /// <summary>
16 /// A strongly-typed resource class, for looking up localized strings, etc.
17 /// </summary>
18 // This class was auto-generated by the StronglyTypedResourceBuilder
19 // class via a tool like ResGen or Visual Studio.
20 // To add or remove a member, edit your .ResX file then rerun ResGen
21 // with the /str option, or rebuild your VS project.
22 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
23 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 public class Resources {
26
27 private static global::System.Resources.ResourceManager resourceMan;
28
29 private static global::System.Globalization.CultureInfo resourceCulture;
30
31 [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 internal Resources() {
33 }
34
35 /// <summary>
36 /// Returns the cached ResourceManager instance used by this class.
37 /// </summary>
38 [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 public static global::System.Resources.ResourceManager ResourceManager {
40 get {
41 if (object.ReferenceEquals(resourceMan, null)) {
42 global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Canonical.Ubuntu.SSO.Views.Resources.Resources", typeof(Resources).Assembly);
43 resourceMan = temp;
44 }
45 return resourceMan;
46 }
47 }
48
49 /// <summary>
50 /// Overrides the current thread's CurrentUICulture property for all
51 /// resource lookups using this strongly typed resource class.
52 /// </summary>
53 [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 public static global::System.Globalization.CultureInfo Culture {
55 get {
56 return resourceCulture;
57 }
58 set {
59 resourceCulture = value;
60 }
61 }
62
63 /// <summary>
64 /// Looks up a localized string similar to Email address.
65 /// </summary>
66 public static string LoginEmailAddressWatermark {
67 get {
68 return ResourceManager.GetString("LoginEmailAddressWatermark", resourceCulture);
69 }
70 }
71
72 /// <summary>
73 /// Looks up a localized string similar to I&apos;ve forgotten my password..
74 /// </summary>
75 public static string LoginForgottenLink {
76 get {
77 return ResourceManager.GetString("LoginForgottenLink", resourceCulture);
78 }
79 }
80
81 /// <summary>
82 /// Looks up a localized string similar to Password.
83 /// </summary>
84 public static string LoginPasswordWatermark {
85 get {
86 return ResourceManager.GetString("LoginPasswordWatermark", resourceCulture);
87 }
88 }
89
90 /// <summary>
91 /// Looks up a localized string similar to To connect this computer to Ubuntu One enter your details below..
92 /// </summary>
93 public static string LoginViewInfo {
94 get {
95 return ResourceManager.GetString("LoginViewInfo", resourceCulture);
96 }
97 }
98
99 /// <summary>
100 /// Looks up a localized string similar to Connect to Ubuntu One.
101 /// </summary>
102 public static string LoginViewTitle {
103 get {
104 return ResourceManager.GetString("LoginViewTitle", resourceCulture);
105 }
106 }
107 }
108}
0109
=== added file 'src/Canonical.Ubuntu.SSO.Views/Resources/Resources.resx'
--- src/Canonical.Ubuntu.SSO.Views/Resources/Resources.resx 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Views/Resources/Resources.resx 2010-10-05 11:24:47 +0000
@@ -0,0 +1,135 @@
1<?xml version="1.0" encoding="utf-8"?>
2<root>
3 <!--
4 Microsoft ResX Schema
5
6 Version 2.0
7
8 The primary goals of this format is to allow a simple XML format
9 that is mostly human readable. The generation and parsing of the
10 various data types are done through the TypeConverter classes
11 associated with the data types.
12
13 Example:
14
15 ... ado.net/XML headers & schema ...
16 <resheader name="resmimetype">text/microsoft-resx</resheader>
17 <resheader name="version">2.0</resheader>
18 <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19 <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20 <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
21 <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22 <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23 <value>[base64 mime encoded serialized .NET Framework object]</value>
24 </data>
25 <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26 <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
27 <comment>This is a comment</comment>
28 </data>
29
30 There are any number of "resheader" rows that contain simple
31 name/value pairs.
32
33 Each data row contains a name, and value. The row also contains a
34 type or mimetype. Type corresponds to a .NET class that support
35 text/value conversion through the TypeConverter architecture.
36 Classes that don't support this are serialized and stored with the
37 mimetype set.
38
39 The mimetype is used for serialized objects, and tells the
40 ResXResourceReader how to depersist the object. This is currently not
41 extensible. For a given mimetype the value must be set accordingly:
42
43 Note - application/x-microsoft.net.object.binary.base64 is the format
44 that the ResXResourceWriter will generate, however the reader can
45 read any of the formats listed below.
46
47 mimetype: application/x-microsoft.net.object.binary.base64
48 value : The object must be serialized with
49 : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
50 : and then encoded with base64 encoding.
51
52 mimetype: application/x-microsoft.net.object.soap.base64
53 value : The object must be serialized with
54 : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
55 : and then encoded with base64 encoding.
56
57 mimetype: application/x-microsoft.net.object.bytearray.base64
58 value : The object must be serialized into a byte array
59 : using a System.ComponentModel.TypeConverter
60 : and then encoded with base64 encoding.
61 -->
62 <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
63 <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
64 <xsd:element name="root" msdata:IsDataSet="true">
65 <xsd:complexType>
66 <xsd:choice maxOccurs="unbounded">
67 <xsd:element name="metadata">
68 <xsd:complexType>
69 <xsd:sequence>
70 <xsd:element name="value" type="xsd:string" minOccurs="0" />
71 </xsd:sequence>
72 <xsd:attribute name="name" use="required" type="xsd:string" />
73 <xsd:attribute name="type" type="xsd:string" />
74 <xsd:attribute name="mimetype" type="xsd:string" />
75 <xsd:attribute ref="xml:space" />
76 </xsd:complexType>
77 </xsd:element>
78 <xsd:element name="assembly">
79 <xsd:complexType>
80 <xsd:attribute name="alias" type="xsd:string" />
81 <xsd:attribute name="name" type="xsd:string" />
82 </xsd:complexType>
83 </xsd:element>
84 <xsd:element name="data">
85 <xsd:complexType>
86 <xsd:sequence>
87 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
88 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
89 </xsd:sequence>
90 <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
91 <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
92 <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
93 <xsd:attribute ref="xml:space" />
94 </xsd:complexType>
95 </xsd:element>
96 <xsd:element name="resheader">
97 <xsd:complexType>
98 <xsd:sequence>
99 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
100 </xsd:sequence>
101 <xsd:attribute name="name" type="xsd:string" use="required" />
102 </xsd:complexType>
103 </xsd:element>
104 </xsd:choice>
105 </xsd:complexType>
106 </xsd:element>
107 </xsd:schema>
108 <resheader name="resmimetype">
109 <value>text/microsoft-resx</value>
110 </resheader>
111 <resheader name="version">
112 <value>2.0</value>
113 </resheader>
114 <resheader name="reader">
115 <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
116 </resheader>
117 <resheader name="writer">
118 <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119 </resheader>
120 <data name="LoginEmailAddressWatermark" xml:space="preserve">
121 <value>Email address</value>
122 </data>
123 <data name="LoginForgottenLink" xml:space="preserve">
124 <value>I've forgotten my password.</value>
125 </data>
126 <data name="LoginPasswordWatermark" xml:space="preserve">
127 <value>Password</value>
128 </data>
129 <data name="LoginViewInfo" xml:space="preserve">
130 <value>To connect this computer to Ubuntu One enter your details below.</value>
131 </data>
132 <data name="LoginViewTitle" xml:space="preserve">
133 <value>Connect to Ubuntu One</value>
134 </data>
135</root>
0\ No newline at end of file136\ No newline at end of file
1137
=== added file 'src/Canonical.Ubuntu.SSO.Views/WatermarkAdorner.cs'
--- src/Canonical.Ubuntu.SSO.Views/WatermarkAdorner.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Views/WatermarkAdorner.cs 2010-10-05 11:24:47 +0000
@@ -0,0 +1,141 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System.Windows;
21using System.Windows.Controls;
22using System.Windows.Data;
23using System.Windows.Documents;
24using System.Windows.Media;
25
26namespace Canonical.Ubuntu.SSO.Views
27{
28 /// <summary>
29 /// Adorner for the watermark
30 /// </summary>
31 internal class WatermarkAdorner : Adorner
32 {
33 #region Private Fields
34
35 /// <summary>
36 /// <see cref="ContentPresenter"/> that holds the watermark
37 /// </summary>
38 private readonly ContentPresenter _contentPresenter;
39
40 #endregion
41
42 #region Constructor
43
44 /// <summary>
45 /// Initializes a new instance of the <see cref="WatermarkAdorner"/> class
46 /// </summary>
47 /// <param name="adornedElement"><see cref="UIElement"/> to be adorned</param>
48 /// <param name="watermark">The watermark</param>
49 public WatermarkAdorner(UIElement adornedElement, object watermark) :
50 base(adornedElement)
51 {
52 IsHitTestVisible = false;
53
54 _contentPresenter = new ContentPresenter
55 {
56 Content = watermark,
57 Opacity = 0.5,
58 Margin =
59 new Thickness(Control.Margin.Left + Control.Padding.Left,
60 Control.Margin.Top + Control.Padding.Top, 0, 0)
61 };
62
63 if (Control is ItemsControl && !(Control is ComboBox))
64 {
65 _contentPresenter.VerticalAlignment = VerticalAlignment.Center;
66 _contentPresenter.HorizontalAlignment = HorizontalAlignment.Center;
67 }
68
69 // Hide the control adorner when the adorned element is hidden
70 var binding = new Binding("IsVisible")
71 {
72 Source = adornedElement,
73 Converter = new BooleanToVisibilityConverter()
74 };
75 SetBinding(VisibilityProperty, binding);
76 }
77
78 #endregion
79
80 #region Protected Properties
81
82 /// <summary>
83 /// Gets the number of children for the <see cref="ContainerVisual"/>.
84 /// </summary>
85 protected override int VisualChildrenCount
86 {
87 get { return 1; }
88 }
89
90 #endregion
91
92 #region Private Properties
93
94 /// <summary>
95 /// Gets the control that is being adorned
96 /// </summary>
97 private Control Control
98 {
99 get { return (Control)AdornedElement; }
100 }
101
102 #endregion
103
104 #region Protected Overrides
105
106 /// <summary>
107 /// Returns a specified child <see cref="Visual"/> for the parent <see cref="ContainerVisual"/>.
108 /// </summary>
109 /// <param name="index">A 32-bit signed integer that represents the index value of the child <see cref="Visual"/>. The value of index must be between 0 and <see cref="VisualChildrenCount"/> - 1.</param>
110 /// <returns>The child <see cref="Visual"/>.</returns>
111 protected override Visual GetVisualChild(int index)
112 {
113 return _contentPresenter;
114 }
115
116 /// <summary>
117 /// Implements any custom measuring behavior for the adorner.
118 /// </summary>
119 /// <param name="constraint">A size to constrain the adorner to.</param>
120 /// <returns>A <see cref="Size"/> object representing the amount of layout space needed by the adorner.</returns>
121 protected override Size MeasureOverride(Size constraint)
122 {
123 // Here's the secret to getting the adorner to cover the whole control
124 _contentPresenter.Measure(Control.RenderSize);
125 return Control.RenderSize;
126 }
127
128 /// <summary>
129 /// When overridden in a derived class, positions child elements and determines a size for a <see cref="FrameworkElement"/> derived class.
130 /// </summary>
131 /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
132 /// <returns>The actual size used.</returns>
133 protected override Size ArrangeOverride(Size finalSize)
134 {
135 _contentPresenter.Arrange(new Rect(finalSize));
136 return finalSize;
137 }
138
139 #endregion
140 }
141}
0\ No newline at end of file142\ No newline at end of file
1143
=== added file 'src/Canonical.Ubuntu.SSO.Views/WatermarkService.cs'
--- src/Canonical.Ubuntu.SSO.Views/WatermarkService.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Views/WatermarkService.cs 2010-10-05 11:24:47 +0000
@@ -0,0 +1,254 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System;
21using System.Collections.Generic;
22using System.ComponentModel;
23using System.Windows;
24using System.Windows.Controls;
25using System.Windows.Controls.Primitives;
26using System.Windows.Documents;
27
28namespace Canonical.Ubuntu.SSO.Views
29{
30 /// <summary>
31 /// Class that provides the Watermark attached property
32 /// </summary>
33 public static class WatermarkService
34 {
35 /// <summary>
36 /// Watermark Attached Dependency Property
37 /// </summary>
38 public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
39 "Watermark",
40 typeof(object),
41 typeof(WatermarkService),
42 new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnWatermarkChanged)));
43
44 #region Private Fields
45
46 /// <summary>
47 /// Dictionary of ItemsControls
48 /// </summary>
49 private static readonly Dictionary<object, ItemsControl> _itemsControls = new Dictionary<object, ItemsControl>();
50
51 #endregion
52
53 /// <summary>
54 /// Gets the Watermark property. This dependency property indicates the watermark for the control.
55 /// </summary>
56 /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
57 /// <returns>The value of the Watermark property</returns>
58 public static object GetWatermark(DependencyObject d)
59 {
60 return d.GetValue(WatermarkProperty);
61 }
62
63 /// <summary>
64 /// Sets the Watermark property. This dependency property indicates the watermark for the control.
65 /// </summary>
66 /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
67 /// <param name="value">value of the property</param>
68 public static void SetWatermark(DependencyObject d, object value)
69 {
70 d.SetValue(WatermarkProperty, value);
71 }
72
73 /// <summary>
74 /// Handles changes to the Watermark property.
75 /// </summary>
76 /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
77 /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
78 private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
79 {
80 var control = (Control)d;
81 control.Loaded += ControlLoaded;
82
83 if (d is ComboBox || d is TextBox || d is PasswordBox)
84 {
85 control.GotKeyboardFocus += ControlGotKeyboardFocus;
86 control.LostKeyboardFocus += ControlLoaded;
87 }
88
89 if (d is ItemsControl && !(d is ComboBox))
90 {
91 var i = (ItemsControl)d;
92
93 // for Items property
94 i.ItemContainerGenerator.ItemsChanged += ItemsChanged;
95 _itemsControls.Add(i.ItemContainerGenerator, i);
96
97 // for ItemsSource property
98 DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, i.GetType());
99 prop.AddValueChanged(i, ItemsSourceChanged);
100 }
101 }
102
103 #region Event Handlers
104
105 /// <summary>
106 /// Handle the GotFocus event on the control
107 /// </summary>
108 /// <param name="sender">The source of the event.</param>
109 /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
110 private static void ControlGotKeyboardFocus(object sender, RoutedEventArgs e)
111 {
112 var c = (Control)sender;
113 if (ShouldShowWatermark(c))
114 {
115 RemoveWatermark(c);
116 }
117 }
118
119 /// <summary>
120 /// Handle the Loaded and LostFocus event on the control
121 /// </summary>
122 /// <param name="sender">The source of the event.</param>
123 /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
124 private static void ControlLoaded(object sender, RoutedEventArgs e)
125 {
126 var control = (Control)sender;
127 if (ShouldShowWatermark(control))
128 {
129 ShowWatermark(control);
130 }
131 }
132
133 /// <summary>
134 /// Event handler for the items source changed event
135 /// </summary>
136 /// <param name="sender">The source of the event.</param>
137 /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
138 private static void ItemsSourceChanged(object sender, EventArgs e)
139 {
140 var c = (ItemsControl)sender;
141 if (c.ItemsSource != null)
142 {
143 if (ShouldShowWatermark(c))
144 {
145 ShowWatermark(c);
146 }
147 else
148 {
149 RemoveWatermark(c);
150 }
151 }
152 else
153 {
154 ShowWatermark(c);
155 }
156 }
157
158 /// <summary>
159 /// Event handler for the items changed event
160 /// </summary>
161 /// <param name="sender">The source of the event.</param>
162 /// <param name="e">A <see cref="ItemsChangedEventArgs"/> that contains the event data.</param>
163 private static void ItemsChanged(object sender, ItemsChangedEventArgs e)
164 {
165 ItemsControl control;
166 if (_itemsControls.TryGetValue(sender, out control))
167 {
168 if (ShouldShowWatermark(control))
169 {
170 ShowWatermark(control);
171 }
172 else
173 {
174 RemoveWatermark(control);
175 }
176 }
177 }
178
179 #endregion
180
181 #region Helper Methods
182
183 /// <summary>
184 /// Remove the watermark from the specified element
185 /// </summary>
186 /// <param name="control">Element to remove the watermark from</param>
187 private static void RemoveWatermark(UIElement control)
188 {
189 AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);
190
191 // layer could be null if control is no longer in the visual tree
192 if (layer != null)
193 {
194 Adorner[] adorners = layer.GetAdorners(control);
195 if (adorners == null)
196 {
197 return;
198 }
199
200 foreach (Adorner adorner in adorners)
201 {
202 if (adorner is WatermarkAdorner)
203 {
204 adorner.Visibility = Visibility.Hidden;
205 layer.Remove(adorner);
206 }
207 }
208 }
209 }
210
211 /// <summary>
212 /// Show the watermark on the specified control
213 /// </summary>
214 /// <param name="control">Control to show the watermark on</param>
215 private static void ShowWatermark(Control control)
216 {
217 AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);
218
219 // layer could be null if control is no longer in the visual tree
220 if (layer != null)
221 {
222 layer.Add(new WatermarkAdorner(control, GetWatermark(control)));
223 }
224 }
225
226 /// <summary>
227 /// Indicates whether or not the watermark should be shown on the specified control
228 /// </summary>
229 /// <param name="c"><see cref="Control"/> to test</param>
230 /// <returns>true if the watermark should be shown; false otherwise</returns>
231 private static bool ShouldShowWatermark(Control c)
232 {
233 if (c is ComboBox)
234 {
235 return (c as ComboBox).Text == string.Empty;
236 }
237 if (c is TextBoxBase)
238 {
239 return (c as TextBox).Text == string.Empty;
240 }
241 if(c is PasswordBox)
242 {
243 return (c as PasswordBox).Password == string.Empty;
244 }
245 if (c is ItemsControl)
246 {
247 return (c as ItemsControl).Items.Count == 0;
248 }
249 return false;
250 }
251
252 #endregion
253 }
254}

Subscribers

People subscribed via source and target branches

to all changes: