Silverlight Recipes
Short tutorials for building Silverlight applications
Wednesday, February 2, 2011
What I have seen in Tahrir
Today we were discussing if we will trust Mubarak's statements with two groups, I was pro going back home and leaving a symbolic camp to allow normal flow in Egypt. Towards the middle of the day Pro Mubarak demos started entering Tahrir Square, we rushed to peacefully stand and defend the square. For around 30 minutes it was just chants. A group of Mubarak supporters split, and naively I thought that this was a sign of chaos in the pro Mubarak group and the demos will end soon. Suddenly stones came from what seems to be the split group, I can't confirm that it was them, but it seems that stones coming from their side on the bigger Mubarak's supporters, and clashes started and lasted for a while until a point of calmness where we though the end of the violence. We began chanting "We are all Egyptians" when suddenly a group of people riding horses and camels stormed towards us beating the demonstrators mercilessly re-igniting the clashes. We have caught a police officer in civilian clothes and a group of employees in the government claiming that they were directed to end the demos in Tahrir or else they will not receive their salaries.
The organizers of the anti-regime protests were extremely cautious not to use violence. To join the group I had to be searched multiple times to make sure I or anyone carries any weapons of any sort, but the regime wanted violence. I just hope that you can support us by spreading the word.
We have Microsoft Egypt employees and local community activists among the demonstrators. Wael Ghoneim, local Google executive who is also an activist has been missing since Thursday. Please help us end the oppression.
Thursday, April 15, 2010
Human Centered ALM with Telerik TeamPulse and Team Foundation Server
Most of software applications are built to be used by humans, this is why Rich UX is a very important factor in the success or failure of software projects. Rich UX often discussed from the technology perspective, although in my opinion UX requires a process and mentality where the human is at the center, not the technology.
Lightweight processes under the Agile umbrella are a great candidate for managing human centric applications with their assertion on feedback and change as a core value. Also valuing individuals and interactions in Agile processes puts the human as programmer, designer, project manager, customer or even the end user over the technology or the tool adds to the human centricity of the Agile processes.
I have been using Microsoft Team Foundation Server for a while for managing the software development lifecycle. The product provides very good integration with Visual Studio IDE, a very good infrastructure especially with TFS 2010 for managing the complete application development workflow, but because the product is covering a wide range of processes including formal processes like CMMI and lightweight empirical processes like Scrum, it lacks the focus of opinionated products that embraces a specific philosophy, which leaves a good space for extension and innovation to fill these gaps, that is where a product like Telerik TeamPulse shines, and can provide very good additions to Microsoft TFS for managing Human Centered Rich Applications following an Agile process. Please note that this post is not intended as a full review of the product, but just a listing of some of the cool features that I like in the product.
Defining the Who!
The first thing I love about TeamPulse is the centricity of the humans in the tool represented by Personas. Personas in TeamPulse are both simple yet comprehensive. The Persona Management view lets you define the Persona position and name beside adding a descriptive picture, but what is really useful is the objectives window. In the objective window you can press control + space and create/link to stories/personas from within the windows. The following screenshot shows a persona that I defined with two stories and one related persona created without leaving the editor.
Then I can simply click on the hyperlink of a story and define its details using the same neat rich editor in the persona view, and can link to other stories/personas which made me really productive in defining the product backlog. The following screenshot shows the story editor in TeamPulse
Prioritization
Prioritization is key to delivering rich UX because mostly the features that you start with are the features that will get the most attention and as you go deeper in the project, deadlines come, important customers request demos, budgets are cut which is why a good ALM tool have prioritization as a first class citizen and this is what you feel in TeamPulse.
In Storyboard view, priority is not only represented by a number, but also with a progress bar that shows you the relative weight of the story related to other stories, which simplifies selecting stories with highest priority. With the story grid view you can sort/filter/group by priority to efficiently select stories with proper priority enabled by the powerful RadGrid from Telerik. This comes really handy in the planning view while manipulating the iteration backlog as shown in the following shot
Embracing Uncertainty
Another feature I love about TeamPulse is the way it manages certainty and maturity which is very useful in the backlog planning and stories management in Storyboard view. The story is represented by a different color according to its maturity level which makes it super easy to pick which stories to start working on.
Work in Progress Visibility
TeamPulse has a great Storyboard view that makes work in progress visible to the team, which encourages limiting work in progress and pushing current stories to the done state. According to TeamPulse roadmap Work In Progress limits will be added which will simplify using TeamPulse with Kan-Ban.
What is next?
Download TeamPulse Beta from Telerik’s website http://www.telerik.com/team-productivity-tools/teampulse.aspx
One final note, is that TeamPulse can be used as a stand-alone product, but it can be more useful by connecting it to a TFS server for an end to end Application Lifecycle Management.
Sunday, November 29, 2009
Silverlight 4 Native Arabic Support Deep Dive
Finally Silverlight received native RTL support in its fourth release. In this post I will take a deep look into the basic and advanced features of the Arabic typography and how Silverlight 4 supports them.
1- Basic Bi-directional ordering and shaping
The Arabic language is written from right to left and each character is represented by a different glyph according to its position in a sentence. Basic tests show that Silverlight 4 correctly performs Arabic bi-directional ordering and shaping. The following screenshot shows Arabic text rendered in SIlverlight 4
2- Mixed Text
In Arabic rendering the situation gets a little bit more complex when Arabic text is mixed with English text. Silverlight 4 will not render mixed text correctly unless the FlowDirection property is set to RightToLeft. The following screenshot shows the rendering of mixed text with the FlowDirection set to RightToLeft and LeftToRight
3- Arabic Diacritics (Tashkeel):
Arabic Diacritics are special glyphs placed over or under a character that affects the pronunciation and the meaning of a word. When rendering Tashkeel with the built-in Arial font, the Tashkeel glyphs are trimmed off tall characters like AlefThe following screenshot shows this behavior
After closer investigation, it turned out that the font was the issue not the rendering engine. The following screenshot shows the same text rendered using Decotype’s Naskh font
4- Optional Ligatures
Some fonts has special glyphs for specific character sequences to enhance the visual look. I was very pleased to find out that the rendering engine supports optional ligatures. The following screenshot shows a sentence rendered in Silverlight 4 using Naskh font with optional ligature
5- Arabic Indic Numbers
In eastern Arab world, the Arabic-Indic numbers is used for representing numeric glyphs. I am not sure if it is not supported or I am missing a setting to enable this feature.
6- Calendar
Since Silverlight 2 and the built-in Calendar control uses the application culture to render month names, this caused the text to be unreadable in Silverlight 2 and 3 but it is now fixed in Silverlight 4. The following screenshot shows a calendar control with the culture set to ar-EG. The numbers here are western Arabic numerals, while it should have been Arabic-Indic.
Unfortunately there is a bug with the Calendar control as result of the control using the local calendar for date calculation, which is the Hijri calendar in the case of Saudi culture, but the Georgian calendar was used for displaying data. Instead of fixing this issue, the control disables the date localization in case of Saudi culture. I hope this issue is fixed by Silverlight 4 release. The following screenshot shows the rendering of a Calendar control with the culture set to ar-SA
7- Word Wrapping and Text Trimming
Word wrapping seems to work fine with Arabic text, but unfortunately the new Text Trimming feature of Silverlight 4 does not work correctly. The following screenshot show how Silverlight 4 renders trimmed text and the wrong position of the elipsis
8- Designer Support
Unfortunately the situation gets very ugly here, Blend 4 Preview does not support FlowDirection at all. Visual Studio 10 supports FlowDirection settings but very buggy. Grid columns resizing behaves oddly when FLowDirection is RightToLeft, and controls are rendered in the wrong position. The following screenshot shows a TextBlock with margin set to 0, but rendered using a negative margin
Conclusion
It is very exciting to finally have RTL support in Silverlight 4. The text rendering engine is descent, but the built-in fonts has poor support for Arabic typography. There are some issues includign the support for Arabic-Indic numbers, but the biggest issue is lack of designer support which will make developing Arabic Silverlight applications a real pain. I hope that we will get designer support soon. This post was a basic test of RTL features, I need to perform more tests with the new RichText, printing, working out of browser, performance, mac OS X rendering … etc. So stay tuned for a follow-up post soon.
Sunday, March 8, 2009
Adding RTL Support to Silverlight Using SilverlightRTL Library – Part 1
In the previous post, options to display Arabic text with Silverlight has been explored. In this post we will explore how to use the Open Source SilverlightRTL library available from http://www.codeplex.com/silverlightRTL to add RTL support for Silverlight Applications.
Using SilverlightRTL From Visual Studio
First you will need to download the bits from CodePlex site, you can either download the latest release from http://silverlightrtl.codeplex.com/Release/ProjectReleases.aspx or if you want the most recent update, you can download the source code from http://silverlightrtl.codeplex.com/SourceControl/ListDownloadableCommits.aspx. I recommend download the source code, so you get the latest updates, and you can debug into the source code if you happen to face any problem.
Now add reference to the BidiControls assembly or the project if you are using the source code directly from your project.
The next step is to add a namespace reference to your XAML file. Please note that you need to compile the project first if you are using project reference or intellisense to work. The XMLNS declaration should look like the following snippet:
1: clr-namespace:System.Windows.BidiControls;assembly=BidiControls
And Visual Studio screen should look like the following figure:
![]()
Now you can declare a BIDI control by prefixing the control with bidi: namespace, for example:
1: <bidi:TextBlock Text="أهلا عالم" FontSize="18" />
Using SilverlightRTL from Blend
Firstyou will need to add reference to the BidiControls.dll assembly or the System.Windows.BidiControls project. To add a control You can open the “Asset Library” at the bottom of the Toolbox. Select “Custom Controls” tab. You should find the BIDI controls available. You can search for a specific control using search box. The following screenshot shows that
Please stay tuned. I will post more about the specific controls implemented, how you can use and style them, and how the controls were implemented.
Monday, February 16, 2009
Displaying Arabic Text in Silverlight
When it comes to typography Arabic has a distinctive rich set of features coming from a long history of calligraphy as the center of Arabic art. If you are interested in more information about Arabic calligraphy, you can check Wikipedia's article about the subject http://en.wikipedia.org/wiki/Islamic_calligraphy.
So let's talk more specific about these features that makes Arabic language so special, and difficult to implement especially in a platform independent platform like Silverlight.
- The first and most obvious feature is the RTL (Right to Left) or more precisely the Bidirectional nature of Arabic, and other scripts like Urdu, Persian, and Hebrew. RTL languages as the name suggests are written primarily starting from right to left, which presents a challenge to Software platforms designed to render the Latin languages from left to right. In the simplest case the solution to render Arabic text correctly is by reversing the characters order in the string array, but in real RTL text the situation is more complicated than that. First the text needs to be split into separate paragraphs, numbers needs to be preserved in LTR order, if there is Latin text mixed with the RTL text, its order needs to be preserved. Unicode standard has an annex with details for the algorithm of handling bidirectional text including how to handle special Unicode control characters that affects the text rendering. You can find the Annex here http://www.unicode.org/reports/tr9/.
- Shaping is the second challenge in implementing Arabic support, shaping refers to the fact that Arabic characters are rendered to a different glyph according to its position. So let me explain the difference between characters and glyphs first. Character are an abstract representation of a piece of information, this can be a letter, number, punctuation mark, or a control character. Glyph is the visual representation of characters, a glyph can be a ligature which is a combination of more than one character, or it can represent a single characters, or in the case of control characters, no visual glyph is associated with them. So in Arabic the letter Ha' for example can be represented as one of the following four glyphs based on its position in the word
- Ligature is another challenge where character sequence like Lam, Alef must be represented as a single glyph. Ligature can greatly improve the aesthetics of a word, the following picture shows a series of characters with ligature on the right, and on the left the same characters without ligature
- Tashkeel or Harkat refers to special characters that controls how a word is pronounced. The Tashkeel character needs to be placed above or under a character. The following picture shows how the position of the Tashkeel character is adjusted according to the height and depth of the affected character
In this blog post I will talk about different options to display Arabic text in Silverlight, and the pros and cons of each. In a future post I will talk about options for text input, and adding Arabic support to controls like Button, Calendar, and DataGrid.
The simplest method to display Arabic text in Silverlight is to display it as an image. This has the obvious problem of the big size and lack of scalability of the bitmaps, but it may be a good option when you are trying to display an artistic text that can not be displayed using computer glyphs, this link shows an example of such text http://en.wikipedia.org/wiki/File:Mirror_writing2.jpg.
Another option to work around the limitation in Silverlight is by overlaying HTML text over the Silverlight content. This requires the Silverlight plugin to be configured in windowless mode which affects the application performance, also the text will have the limitation of the DHTML experience, but this option may be the way to go if you are using Silverlight 1.0.
The third option is to use the SilverlightRTL library available on CodePlex at http://www.codeplex.com/SilverlightRTL. You can use the TextBlock control included in the library. You will get integrated experience where you can use all the features of Silverlight with the control like Animation, Brushes … etc. The drawback of this approach is that currently optional ligature is not implemented, the only ligature available now is the mandatory Lam-Alef ligature. Also Tashkeel characters is not displayed correctly because Silverlight will display the Tashkeel glyph beside the affected glyph and not over or under it. Arabic-Indic numbers are not supported yet too.
The fourth option is to use the Glyph element, which gives extreme control over how the text will be displayed. It can let you specify the indices of the glyph to be displayed, which can be used to implement optional ligatures. The offset of the glyph can be specified, which can be used to properly display Tashkeel characters. The problem with the Glyph approach is that it is not easy to retrieve the glyph indices for a font, and set the offset manually, one way to achieve that is to print the text as XPS and collect the Glyph element from the .fpage file in the XPS file (XPS files are simply zip files, you can find an fpage file, which is a XAML file representing a page).
The fifth option is to render the text as a path. This gives extreme flexibility in defining the appearance of the text, and you can even animate the path nodes to make the text dance. The drawback of this approach is that to render the text with good quality you will need great number of nodes which will bloat the size of the content, and will overload the rendering engine if there is much text. You can get the path for the text using Vector design application like Illustrator, Expression Blend has a convert text to path feature, but unfortunately it does not work with Arabic text.
In conclusion, there are many options to display Arabic text in Silverlight, each with some advantages and limitations. My recommendation is to use Glyphs when possible, which is mostly feasible with static text, but for text coming dynamically from a DataBase for example SilverlightRTL library may be the best option.
Thursday, March 6, 2008
Silverlight 2.0 Deep Zoom using MultiScaleImage Control
Displaying Deep Zoom Content
This is the simplest task, all you need to do is inserting a MultiScaleImage control and set its Source property. But there are a couple of tricks here, first you need to copy the folder that "Deep Zoom Composer" generated to your clientbin folder. The second is that the Source property should refer to your items.bin file if you exported your content with "Create Collection" option selected, or info.bin file otherwise.
Zooming
You can zoom either by using ViewPortWidth property, or better using ZoomAboutLogicalPoint method, the method takes zooming factor, and logical x, y co-ordinates to zoom around. The following code sample shows how to use this method
this.DeepZoom.ZoomAboutLogicalPoint(1.5, this.DeepZoom.ElementToLogicalPoint(e.GetPosition(this.DeepZoom)).X, this.DeepZoom.ElementToLogicalPoint(e.GetPosition(this.DeepZoom)).Y);
else
this.DeepZoom.ZoomAboutLogicalPoint(0.75, this.DeepZoom.ElementToLogicalPoint(e.GetPosition(this.DeepZoom)).X, this.DeepZoom.ElementToLogicalPoint(e.GetPosition(this.DeepZoom)).Y);
private void DeepZoom_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Ctrl)
isCtrlDown = true;
}
private void DeepZoom_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Ctrl)
isCtrlDown = false;
}
Moving Content
This is the most tricky part because of the logic needed to handle dragging. But when it comes to the MuliScaleImage control, it is relatively easy and require only one line of code to modify the ViewportOrigin property, here is some sample code
if (isDragging)
{
Point newOrigin = new Point();
newOrigin.X = this.DeepZoom.ViewportOrigin.X - ((e.GetPosition(this.DeepZoom).X - lastMousePosition.X)/this.DeepZoom.ActualWidth);
newOrigin.Y = this.DeepZoom.ViewportOrigin.Y - ((e.GetPosition(this.DeepZoom).Y - lastMousePosition.Y) / this.DeepZoom.ActualHeight);
this.DeepZoom.ViewportOrigin = newOrigin;
}
You can download the complete sample project with source code from here
Tuesday, November 27, 2007
Silverlight 1.0 Animation: Checkerboard, blinds, and comb
This post describes how to create a Silverlight 1.0 based checkerboard, blinds, and comb animation. The effect is added to my animation library so you can reuse the effect using a single line of code. You can download the complete source from here. Below is a working sample.
Recipe:
To create your own checkerboard animation using my animation library download the source code and include Animator.jas and XamlObjectFactory.js in your project and reference them in your Silverlight host page. To create an across checkerboard effect, use the following line:
SilverlightRecipes.Animator.checkerAcross('CheckerAcross', sender.findName('ToAnimate'), '1', 10, 10);
The first parameter is a unique ID for the animation storyboard. The ID is required because storyboards added to a UIElment resources must be named. The second parameter is the animation target. The target can be any UIElement. The third parameter is the animation duration in seconds. The third parameter is the number of horizontal checkers, and the fourth parameter is the number of vertical checkers.
To create a top down checkerboard animation use the following line of code:
SilverlightRecipes.Animator.checkerDown('CheckerDown', sender.findName('ToAnimate'), '1', 10, 10);
To create a vertical blinds animation use the following line of code:
SilverlightRecipes.Animator.blindsV('BlindsV', sender.findName('ToAnimate'), '1', 10);
To create a horizontal blinds animation use the following line of code:
SilverlightRecipes.Animator.blindsH('BlindsH', sender.findName('ToAnimate'), '1', 10);
To create a vertical comb animation use the following line of code:
SilverlightRecipes.Animator.combV('CombV', sender.findName('ToAnimate'), '1', 20);
To create a horizontal comb animation use the following line of code:
SilverlightRecipes.Animator.combH('CombH', sender.findName('ToAnimate'), '1', 20);
The idea behind these animations is to use multiple wipe animations with different clippings, start times, and durations to generate the desired effect. For example the clipping for 2*2 checkerboard is a PathGeometry with four PathFigure instances to represent each rectangle of the checkerboard:
<PathGeometry>
<PathGeometry.Figures>
<PathFigure IsClosed="True" StartPoint="0,0" >
<PathFigure.Segments>
<LineSegment Point="0,0" />
<LineSegment Point="0,135" />
<LineSegment Point="0,135" />
</PathFigure.Segments>
</PathFigure>
<PathFigure IsClosed="True" StartPoint="0,135" >
<PathFigure.Segments>
<LineSegment Point="0,135" />
<LineSegment Point="0,270" />
<LineSegment Point="0,270" />
</PathFigure.Segments>
</PathFigure>
<PathFigure IsClosed="True" StartPoint="200,0" >
<PathFigure.Segments>
<LineSegment Point="200,0" />
<LineSegment Point="200,135" />
<LineSegment Point="200,135" />
</PathFigure.Segments>
</PathFigure>
<PathFigure IsClosed="True" StartPoint="200,135" >
<PathFigure.Segments>
<LineSegment Point="200,135" />
<LineSegment Point="200,270" />
<LineSegment Point="200,270" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
And the animation is done by a single storyboard with three PointAnimation instances to generate the wipe effect. The following is an example for a 2*2 checkerboard animation:
<Storyboard Duration="00:00:01" Name="CheckerAcross" >
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(LineSegment.Point)" To="200,0" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(LineSegment.Point)" To="200,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(LineSegment.Point)" To="0,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[1].(PathFigure.Segments)[0].(LineSegment.Point)" To="200,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[1].(PathFigure.Segments)[1].(LineSegment.Point)" To="200,270" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[1].(PathFigure.Segments)[2].(LineSegment.Point)" To="0,270" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[2].(PathFigure.Segments)[0].(LineSegment.Point)" To="400,0" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[2].(PathFigure.Segments)[1].(LineSegment.Point)" To="400,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:00" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[2].(PathFigure.Segments)[2].(LineSegment.Point)" To="200,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[3].(PathFigure.Segments)[0].(LineSegment.Point)" To="400,135" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[3].(PathFigure.Segments)[1].(LineSegment.Point)" To="400,270" />
<PointAnimation Duration="00:00:0.5" BeginTime="00:00:0.5" Storyboard.TargetName="ToAnimate" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[3].(PathFigure.Segments)[2].(LineSegment.Point)" To="200,270" />
</Storyboard>