Mobile Store - Image Threads (part 6)

by Chris 26. February 2010 18:20

One important feature in most mobile store apps is the ability to show images of products (or services). In most cases, it's not possible to store all those images on the mobile device. It could be because products are added or removed, that the images change over time, or that they would simple take up to much space in the device's memory (or even on a storage card).

A possible solution to these problems would be to get the images on demand over the network. But even if the image size was kept to a minimum, most wireless connections (especially if you are out of 3G coverage) wouldn't be able to deliver the images fast enough to create a responsive user experience. The solution could be to show a temporary image at once, load the images on background threads, and replace the temporary image when the downloads is complete. That is what I will show you how to do here.

When the image is first shown, which could be in the list or detail dialog, code similar to the following is run:

if(this.image == null)
{
   
this.image = Common.Values.LoadBitmap("dummy.jpg", 70, 52);
    Thread loadImageThread = new Thread(new ThreadStart(loadImage));
    loadImageThread.Start();
    loadingImage =
true;
}

If the image is not set, it's the first time this image is to be shown, we start by loading a dummy image while the real image is loading. Then we start a background thread to load the image, and it's code look like this:

private void loadImage()
{
   
Bitmap image = Common.Values.LoadBitmap(
        new Uri(Common.Values.ImageUrl + car.ImageFileName), 70, 52);
   
lock(this.image)
       
this.image = image;
    loadingImage =
false;
}

The download of the image is started, and when it's done, the image is set and the background thread ends. The actual loading of the image from an URL looks like this:

public Bitmap LoadBitmap(Uri uri, int width, int height)
{
   
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
   
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
   
Bitmap image = LoadBitmap(resp.GetResponseStream(), width, height);
    resp.GetResponseStream().Close();
   
return image;
}

Just a simple web request with the resulting stream directly used to create a bitmap image.

While the image is loading, the Paint event will do something similar to the following:

lock(this.image)
    g.DrawImage(image, position.Left, position.Top);
if(loadingImage)
    g.DrawString(
"Loading...", SmallFont, FontBrush,
        position.Left + 4, position.Top + 2);

 

 

 

The locking of the image variable is necessary to avoid thread concurrency problems, and we are also adding a text to the dummy image while the real one is loading.

This simple technique can be used in many situations to increase the user experience.

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

Mobile Store - Service Client (part 5)

by Chris 19. February 2010 11:02

Now we have come to the client implementation part of the mobile store architecture, and the first thing to do is to create a connection (proxy) to the service. To do this, make sure you have the Power Toys for CF or, if you are running Vista or Windows 7, you should get your copy of the NETCFSvcUtil utility here. Take a look at this blog post on the details of doing this. All the code can be found in the CodePlex project for this series.

As we now have a connection from the mobile client to the server, the next step is to do the actual implementation of the user interface of the mobile client. I therefore recommend you to read through the various blog posts related to the ToucHUI framework. Most of what is implemented in the mobile client of the mobile store is covered in that series, and there are just a few additional features that I will talk about in the rest of this series.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Architecture | Chris | Compact Framework | Windows Mobile

Mobile Store - Service (part 4)

by chris 12. February 2010 06:39

Let's continue with the implementation of the mobile store architecture, and now it's time for the middle tier with the business domain logic as well as the actual WCF service. Here is a screencast of me doing that:

Get Microsoft Silverlight

If you prefer, you can also download the screencast and watch it offline. All the code can be found in the CodePlex project for this series.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Architecture | Chris | Compact Framework | Windows Mobile

Mobile Store - Data Service (part 3)

by chris 5. February 2010 06:28

It's time to start the implementation of the mobile store architecture, and I will start with the server side. More specifically, I will start with the data services tier, and here is a screencast of me doing that:

Get Microsoft Silverlight

If you prefer, you can also download the screencast and watch it offline. All the code can be found in the CodePlex project for this series.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Architecture | Chris | Compact Framework | Windows Mobile

Mobile Store - Architecture (part 2)

by Chris 29. January 2010 05:48

A solid design always starts with a solid architecture. The architecture used for this app (series) is the KISS Architecture, and it builds on the collective knowledge in the developer community. It's a classical three tiered architecture on both the server and on the device:

image

Hopefully, this picture is not revolutionary to anyone, and it makes the best use of the latest technologies on the Microsoft platform:

  • .NET Framework - the treasure chest
  • C# - my language of choice
  • Visual Studio - the worlds greatest development tool
  • SQL Server - my database of choice (on both server and device)
  • ADO.NET Entity Framework and LINQ to Entities - the way forward on ORMs (for the ADO.NET team)
  • ADO.NET Data Services - how to make (REST) data access loosely coupled
  • WCF - on discussion, this is the RPC of our time
  • .NET Compact Framework – the mobile treasure chest
  • Windows Phone – the premier platform for .NET

With this architecture in place, our app is ready for multiple deployment scenarios, and it's especially suited to be deployed in "the cloud".

In the next part, let's get started in implementing this architecture.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Architecture | Chris | Compact Framework | Windows Mobile

Mobile Store - Introduction (part 1)

by Chris 22. January 2010 05:25

I think that one of the hot app trends of 2010 will be companies extending their product and/or services to "anyplace". When I read about the success story of PizzaHut's iPhone app sales, it makes me think of all the companies that haven't yet made their presence in this most lucrative channel.

The first generation mobile apps was about proving it could be done, and we proved it a number of times. Now, it's time for the next generation apps where the main achievement is making it right. I mean, how should we build mobile apps in the right way, with the right architecture, and making sure that they reach the customers not only on a practical, but also on an emotional level. How do we create apps that are both beautiful inside as well as outside?

My take on that is building on a solid architecture, the KISS Architecture, adding an appealing user interface, the TouchUI framework, and putting together something that can be reused. I finally settled for an app where you could buy used cars that looks like this:

image image image

In this series I will walk you through building this app from the ground up. I will start with the server side with the core data, and the build my way through data service, business logic, a service, and all the way to the mobile app with a nice user experience.

Come along, and I hope you will enjoyed this as much as I did putting it all together.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

TouchUI - Summary (part 14)

by chris 8. January 2010 05:21

image This is the final post in this series, and for a complete reference, here are the previous parts:

  • Part 1 gave some background
  • Part 2 looked at some of the alternatives
  • Part 3 was a general introduction
  • Part 4 gave an introduction to GDI
  • Part 5 promoted one form and many dialogs
  • Part 6 showed how the painting is done
  • Part 7 discussed how to build an active UI
  • Part 8 started the walkthrough of the controls
  • Part 9 covered the ScrollControl base class
  • Part 10 talked about the ScrollList control
  • Part 11 was about the ScrollPanel control
  • Part 12 demonstrated animated navigation
  • Part 13 showed how to be resolution/orientation aware

The TouchUI framework is published on CodePlex in a project called TouchUI, and this means that you can access the full source code as well as discuss it, come with suggested improvements, etc.

On the upper right you see the UX of the sample included in the code, and it's a beginning of a simple shopping app that allows for scrolling through articles (in this case only strawberries) and then touching them to see more details.

Even if this series is complete, I will probably continue to build further on the framework, and any suggestions on things to add are most welcome. Any other feedback, for that matter, is also welcome!

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

TouchUI - Resolution/Orientation Aware (part 13)

by Chris 1. January 2010 10:06

As I have shown in several places in the previous parts of this series, the painting of things is always related to the bound of the current item (dialog, control, etc). This approach is essential to handle the quite extensive number of resolutions on WinPhone. That's especially true if you want to support all phones since WinMo 5, and even the non-touch devices. Another important reason is the fact that many devices with non-square screens allow the screen to be rotated between portrait and landscape mode.

The magical event that tells our app about the resolution and any change in orientation is the Resize event, and in the TouchUI sample, the code looks like this:

private void MainForm_Resize(object sender, EventArgs e)
{
   
Common.Instance.ClientRectangle = Screen.PrimaryScreen.WorkingArea;
   
if(loaded)
       
foreach(Dialog dialog in dialogStack)
            dialog.Resize(
Common.Instance.ClientRectangle);
   
this.Refresh();
}

The working area of the screen (excluding the title and menu bars) can be retrieved from a static method (PrimaryScreen) on the Screen class (in the System.Windows.Forms namespace). We save that in our app singleton (Common.Instance) and use it to inform all dialogs about the new dimensions.

Each dialog can adapt to the new resolution or orientation, and this is the code in the main dialog:

public override void Resize(Rectangle r)
{
   
this.Rectangle = r;
    scrollList.Rectangle =
new Rectangle(0, headerHeight,
        r.Width, r.Height - headerHeight);
}

It simply update the bounds of its ScrollList control, that in turn will adapt by using the new dimensions in its Paint method. With these simple measures, the app can run on any device with the same code and even the same executable. Here are some different resolutions and orientation examples...

image image

image

...and they all have their original resolution in the following order (width x height): 176 x 220 (non-touch), 400 x 240, and 480 x 800 (both touch). The beautiful strawberry graphics is from a photo by Tina Phillips / FreeDigitalPhotos.net.

Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

TouchUI - Animated Navigation (part 12)

by Chris 25. December 2009 10:02

nontouchanim Now we come to one of the nicest additions that the TouchUI bring to the table - the animated navigation. This is, as so many other things in modern mobile user experience design, inspired by the way things work on the iPhone.

When the user select an item in a list (in a dialog), the following code is run in the main form:

private void navigateForward()
{
    Common.Instance.PaintCopyGraphics.DrawImage
        (Common.Instance.PaintBitmap, 0, 0);

   
if(dialogStack.Last() is MainDialog)
    {
       
MainDialog mainDialog = (MainDialog)dialogStack.Last();
       
DetailDialog detailDialog = new DetailDialog(Common.Instance.ScreenFactor,
            Common.Instance.ClientRectangle, mainDialog.SelectedLine + 1);
        dialogStack.Add(detailDialog);
    }
    animationOffset =
Common.Instance.ClientRectangle.Width / 4;
    animationLeft =
Common.Instance.ClientRectangle.Width;
}

As you may remember from the painting part of this series, the PaintBitmap (in the app's singleton class Common.Instance) is used to do all the painting in the app. Then, it is used in the OnPaint method to do the actual painting to the screen. The first thing that happen in the code above, is that a copy of the current screen is made (into the PaintCopyBitmap that is pointed to by PaintCopyGraphics). The navigation is done (the details form is added to the dialog stack), and then the animations horizontal start position (animationLeft) is set along with the offset to move the new screen into place for each frame (animationOffset, in this case it's in four steps making the animation take about a third of a second). The navigation backward (up the dialog stack) is done in a similar fashion, but then the animationLeft and animationOffset are both negative. Btw, the beautiful strawberry graphics is from a photo by Tina Phillips / FreeDigitalPhotos.net.

With this in place, the actual painting is done in the OnPaint method, and it looks like this:

protected override void OnPaint(PaintEventArgs e)
{
   
base.OnPaint(e);

    dialogStack.Last().Paint(
Common.Instance.PaintGraphics);
   
Rectangle r = Common.Instance.ClientRectangle;
   
if(animationLeft != 0)
    {
        e.Graphics.DrawImage(
Common.Instance.PaintCopyBitmap,
           
new Rectangle(animationLeft - r.Width * animationLeft.CompareTo(0),
            0, r.Width, r.Height), r, GraphicsUnit.Pixel);
        e.Graphics.DrawImage(
Common.Instance.PaintBitmap,
            new Rectangle(animationLeft, 0, r.Width, r.Height), r,
            GraphicsUnit.Pixel);
        animationLeft -= animationOffset;
       
if(Math.Abs(animationLeft) < Math.Abs(animationOffset))
            animationLeft = 0;
    }
   
else
        e.Graphics.DrawImage(Common.Instance.PaintBitmap, r, r,
            GraphicsUnit.Pixel);
}

First, the dialog is painted (updating the PaintBitmap with the new content), and then both the old and new bitmaps are painted according to the step in the animation (controlled by animationLeft). When the animation is complete (animationLeft is zero), only the new dialog is painted.

A similar approach is used for the switching of images in the detail dialog in the sample, so be sure to check that out as an example of responding to sweep gestures.

Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

TouchUI - ScrollPanel (part 11)

by Chris 18. December 2009 10:01

Another controls that inherit from the ScrollControl (described in a previous part of this series) is the ScrollPanel control. As the name implies, this is a panel that implement modern features like soft (kinetics) scrolling, and the design and functionality was inspired by the scroll view control on iPhone.

The ScrollPanel itself does not implement much logic, it mainly functions as a way for the app to implement a scrolling panel. In the TouchUI sample app, that is done in the DetailScrollPanel that inherits from ScrollPanel (and in turn from ScrollControl). The painting of the panel is done like this:

public override void Paint(Graphics g)
{
   
base.Paint(g);

    imageHeight = Rectangle.Width * image.Size.Height / image.Size.Width;
    g.DrawImage(imagenew Rectangle(Rectangle.Left,
        Rectangle.Top + ScrollTop, Rectangle.Width, imageHeight),
        new Rectangle(0, 0, image.Width, image.Height),
        GraphicsUnit.Pixel);

   
string s = "Lorem ipsum dolor sit amet, consectetur adipisicing...";

    g.DrawString(s,
Common.Instance.Font, Common.Instance.FontBrush,
        new RectangleF(Rectangle.Left + 8 * ScreenFactor,
        Rectangle.Top + ScrollTop + imageHeight + 8,
        Rectangle.Width - 16 * ScreenFactor,
        ScrollHeight - imageHeight - 16 * ScreenFactor),
       
new StringFormat());
}

It draws the image at the top, and some Latin text as the bottom, and note that the use of the control's placement and size (Rectangle) will make both the image and the test resize with the screen. Dynamically that useful when switching between portrait and landscape, but it also means that different resolutions on different devices are handled.

This simple setup provides for full controls while still allowing for any use of the panel area. It could be of any height, and it could include any number of items. Although not included in the sample, it could also include traditional WinForms controls to allow input (text and combo boxes).

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Chris | Compact Framework | User Interface | Windows Mobile

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen