Click here to Skip to main content
Click here to Skip to main content

iPod touch UI

, 6 Jan 2009
Rate this:
Please Sign up or sign in to vote.
It's a Media Player that works with transparency effects, plays MP3 and Wav files, displays the tag if present, and displays the album art image if present.
iPodTouchUI/SampleImage2.gif

Contents

Introduction

It's a Media Player that works with transparency effects. It also plays MP3 and wav files, displays the tags if present and displays the album art image if present.

Original Media Player user interface is impossible to control using your finger. Here I have tried to solve this problem.

As a sample, I used an interface just like the iPod touch one. In this tutorial, mostly I continue to explain a better way to work with transparency on Windows Mobile. For an introduction to this article, I suggest you read my previous article on transparency iPhone UI[^].

In this article, you can also read about:

  • Resolution-aware and Orientation-aware
  • Dynamic graphic text resize
  • Mouse gesture
  • Intercepting button
  • Work with Windows Media Player OCX on Windows Mobile

Background

I found some problem with sound files in particular for retrieving the tag info and the current position time, after a long search, I chose to use the Windows Media Player OCX. The article Audio Book Player [^] by brochpirate gives you a fast way to use the OCX on Mobile through the OpenNETCF.org, it's a great working sample. Here, I explain a bit about how you can play with it.

How to Work with WMP

To use the Windows Media Player, you only need to import this DLL as reference:

  • OcxControls
  • OpenNETCF.Windows.Forms.AxHost
  • WMPLib

And add the cPlayer to your app. Now you are ready to get control of WMP, really cool, isn't it?

Using the Code

The Solution

Going deep into the solution, you can find:

  • iPlayer class, the main form with: Resolution-aware, dynamic graphic text resize, mouse gesture, and work also with Windows Media Player COM
  • cPlayer class, this class works with Media Player OCX, it's under the abPlayer. I add only few properties - the loop and the volume
  • FilesManger class, this class gets all the MP3 and Wav files of your mobile device
  • ImageButtons class, a class button with transparency and other stuff
  • PlatformAPIs class, it is the class to manage the P/Invoke
  • SlideButton class, the class that moves the Image (progress)
  • BMPs folder, it contains all the BMPs used in the code

iPlayer Class

This is the main form of the app. I paint all the forms in the method myPaint(Graphics dc). The myPaint can be called from the Paint eventhandler and use the e.Graphics or can be called when a state changes and the dc used is the CreateGraphics(). Then my paint draws all the screen with all the controls inside, beginning with the background, the TopBar, the SongBar, LocationBar (if needed), BottomBar, and the various buttons used.

The Background

The bitmapBackImage Bitmap is loaded as a background and the default image of the first image found in the song directory. To choose the image, I preferred to display the "Folder.jpg" if it exists because it is the default used by the default internet CD searching.

This is the code:

private void SearchBGImage()
{
    if (FormListScanFiles.lvwSoundFiles.Items.Count != 0)
    {
        string path = Player.PlayingPath.Remove(Player.PlayingPath.LastIndexOf(@"\"), 
		Player.PlayingPath.Length - Player.PlayingPath.LastIndexOf(@"\"));
        String[] ImageFiles = GetImageFiles(path);
        if (ImageFiles.Length != 0)
        {
            foreach (string ImageFile in ImageFiles)
            {
                //If you use the internet CD databases you can have more 
                //than a picture inside the folder
                //This method chooses the one that best fit screen
                if (ImageFile.Remove(0, ImageFile.LastIndexOf(@"\") + 1).ToLower() == 
				"folder.jpg")
                {
                    bitmapBackImage = new Bitmap(ImageFile);
                    return;

                }
            }
            bitmapBackImage = new Bitmap(ImageFiles[0]);
            return;
        }
    }         
    bitmapBackImage = bitmapBackImageDefault;
}

The default image:

iPodTouchUI/wallpaperDefault2.gif

If I need to stretch the image, I use this code:

Rectangle srcRect = new Rectangle(0, 0, bitmapBackImage.Width, bitmapBackImage.Height);
Rectangle destRect = new Rectangle(0, 0, this.Width, this.Height);
gxBuffer.DrawImage(bitmapBackImage, destRect, srcRect, GraphicsUnit.Pixel); 

else I draw centre & unscaled:

int x = (this.Width - this.bitmapBackImage.Width) / 2;
int y = (this.Height - this.bitmapBackImage.Height) / 2;
gxBuffer.DrawImage(this.bitmapBackImage, x, y);

The Topbar

This part is similar to the iPhone UI article but here I change the position of the images dynamically. The Topbar is divided in 4 images and the time text:

  • The Battery level, with a left anchor with no stretch
  • The timeline, with left anchor (the battery level width), right anchor (the GSM level width +
  • Current Player status width), use the stretch
  • Current Player status, with left anchor (timeline width+ battery level width), right anchor (the battery level width) no stretch
  • The GSM level, with a right anchor with no stretch
  • The time is drowned in the middle of the screen width and in the middle centred in the middle of the timeline (timeline height/2- text height/2)

All the images:

  • Battery Level Bitmaps

    iPodTouchUI/AllBatteryLevelBitmaps.gif

  • GSM Level Bitmaps

    iPodTouchUI/AllGSMLevel.gif

  • Top Player status

    iPodTouchUI/AllTopPlayerStatus.gif

and these two samples of the view:

iPodTouchUI/TopBar1.gif

iPodTouchUI/TopBar2.gif

The SongBar with text resize

This part is a stretch of a single bitmap to all the width of the screen and with a fixed height.

This is the original bitmap:

 iPodTouchUI/SongBar.gif

And these are two stretch samples:

iPodTouchUI/SongBarSample_.gif

Over it, I put two ImageButtons, one for Exit and one for the files list. The buttons are centred in the middle of the SongTopBar bitmap height, and the exit has the left anchor, the right has the right anchor.

In the middle of the screen, I put the Artist name, the song name and the album name. The strings are the tags retrieved from the current file selected.

Here I use my DynamicGraphicTextResizing for a "Dynamic graphic text resize". If the width of the displayed string is much greater than the display width, I modify the string with the minimum size that fits the screen weight and I add to the end "..."

private void DynamicGraphicTextResizing(ref string text, 
	ref SizeF size, Font songTitleFont)
{
    while (size.Width > this.Width - buttonExit.Image.Width - buttonList.Image.Width)
    {
        text = text.Remove(text.Length - 4, 4);
        text = text + "...";
        size = gxBuffer.MeasureString(text, songTitleFont);
    }
} 

To draw the string, I use this code:

string title = Player.GetMediaTAG(eTagNames.TITLE); 

SizeF sizeTitle = gxBuffer.MeasureString(title, FontsongTitle);
DynamicGraphicTextResizing(ref title, ref sizeTitle, FontsongTitle);
xSong = this.Width / 2 - (int)sizeTitle.Width / 2 + buttonExit.Image.Width / 2;
gxBuffer.DrawString(title, FontSong, BrushWhite, xSong, 
	bitmapTopHeader.Height + sizeTitle.Height - 2);

iPodTouchUI/Info.png Info: brochpirate in his article adds a way to scroll the text. Take a look there, I think you can find it useful.

These are all the images used:

iPodTouchUI/SongTopbar.gif

This is a sample on how it works:

iPodTouchUI/SongBarSample2.gif

The LocationBar

iPodTouchUI/Info.pngInfo: This part is shown only if the users click on the SongBar, it displays the current location, the song duration, and a progress bar for the current location.

To show the Location bar, I use an internal bool value ShowTimeLine and I decide to draw it if you click over the SongBar. When the LocationBar is shown, it enables a timer every second to draw the current location and to draw the step for the progress.

private bool SongMouseUp(MouseEventArgs e)
{
    if (ClientAreaSong().Contains(e.X, e.Y))
    {
        ShowTimeLine = !ShowTimeLine;
        timerDrawLocation.Enabled = SetTimerDrawLocation();
        return true;
        }
    return false;
}

The LocationBar is divided in 8 parts.

  • Repeat button with 2 states, pressed On, Off
  • Current Location time + the background
  • Progress of the song is divided in 2 parts, the played and not played
  • Duration time + the background
  • Shuffle button with 2 states, pressed On, Off

Note: Here I've not covered everything in the algorithm but I believe that you will understand these easily.

The Repeat button is set to the WMP repeat state. The anchor is left and it's not stretched.

The current location time and the duration time are string retrieved from the player Player.LocationString Player.DurationString. The Background image is this:

The progress is divided in 2 parts, the played and not played, I use two images and I calculate the location position on the screen iWidthProgressPlayed. After I draw the PlayedProgress from a fixed start to the iWidthProgressPlayed and the NotPlayedProgress from iWidthProgressPlayed with a dynamic width (all the size possible less than played) iWidthTotal - iWidthProgressPlayed.

The Shuffle button is set to the WMP repeat state.

All the images used:

iPodTouchUI/AllTimelineBitmaps.gif

These are 3 samples on how it works:

iPodTouchUI/LocationBarSample.gif

iPodTouchUI/LocationBarSample3.gif

iPodTouchUI/Warning.png Attention: I tried the app under a few devices and sometimes I found it slow, I suggest you to use the LocationBar only if needed. The program starts with the LocationBar hidden.

Middle of the screen

If the search doesn't find a file (MP3 or wav), it displays a text in the middle of the screen "No files found".

This is the code:

private void DrawSongNumber(Graphics gx)
{
    if (FormListScanFiles.lvwSoundFiles.Items.Count == 0)
    {
        NoFilesFound = "No files found";
        SizeF sizeNoFilesFound = 
		gxBuffer.MeasureString(songname, FontSongNoFilesFound);
        int xSong = this.Width / 2 - (int)sizeNoFilesFound.Width / 2;
        int ySong = this.Height / 2 - (int)sizeNoFilesFound.Height / 2;

        int widthMessage = (int)sizeNoFilesFound.Width ;
        int xMessage = (this.Width / 2 - (int)widthMessage / 2 )-10;
                
        int yMessage = this.Height / 2 - (int)bitmapMessage.Height / 2;

        DrawAlphaStretchX(gxBuffer, bitmapMessage, 
		170, xMessage, yMessage, widthMessage);
                
        gxBuffer.DrawString(NoFilesFound, 
		FontSongNoFilesFound, BrushWhite, xSong, ySong);
    }
}

and this is a sample:

iPodTouchUI/FilesNotFound2.gif

The Bottom bar

For the bottom, I used a large background with the left anchor and the right anchor.

The bitmap is divided in two sections (the first half and the second half).

In the first half, I put the Player controls: Previous, Play/Pause, Next. These images are stored in three ImageButtons. Also the player status is over in the Topbar.

The second half contains the volume slide, it's a SlideButton. Here I add a modification on the previous posted in the iPhone UI. I add possibility to interact with the progress, and set it with a percentage. When the mouse is moved over the Slide button, the volume changes and it displays the percentage is similar to the used in the location bar.
These are all the images used:

iPodTouchUI/AllBottomBitmaps.gif

These are two samples:

iPodTouchUI/BottomBarSample.gif

Points of Interest

I would like to remind that this program is not a complete interface. This article adds some features used in the iPhone UI and I hope you find them useful.

Note: I believe that the article contains some translation errors, please humour me and go ahead reading the article. Soon I'll translate it better.

Links

  • Audio Book Player here[^], many thanks for your help BrochPirate.
  • The Hosting ActiveX Controls in the .NET Compact Framework 2.0 here[^]
  • The introduction of this article iPhone UI[^]

History

  • 7 Jan 2009 - First release
  • 10 Jan 2009 - Second release
    • Minor bug fixes
    • Hidden the LocationBar at the start
    • Added the Message bitmap

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dr.Luiji
Software Developer (Senior) Imagicle
Italy Italy
Bertoneri Luigi, alias Dr.Luiji
Bachelor of Science in Computer Science, year 2K - University of Pisa (Italy).
 
I'm a developer with more than 10 years of experience. I like the new technology, Windows, iOS and Android.
I love challenges.
 
Skills:
- Language: Android, Objective-C, C++, C#, Java
- Platform: Windows, .NET
- Technology: Too much...
 
I currently work and live in Italy.
Music I listen to: Tool, Slipknot, NIN, Korn, Perfect Circle, Dry Kill Logic, Godsmack, and more.

Comments and Discussions

 
GeneralCant believe I missed this one PinmvpSacha Barber1-Feb-11 22:03 
Excellent stuff man...5
Sacha Barber
  • Microsoft Visual C# MVP 2008-2011
  • Codeproject MVP 2008-2011
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Cant believe I missed this one PinmemberDr.Luiji2-Feb-11 0:55 
Questionproblem finding libraries Pinmembermjbroekhuijsen14-Dec-10 2:50 
GeneralGreat work PinmemberDaniel Vaughan22-Dec-09 11:04 
GeneralRe: Great work PinmemberDr.Luiji23-Dec-09 2:30 
GeneralTerrific. [modified] Pinmembervictorbos7-Nov-09 4:39 
GeneralRe: Terrific. PinmemberDr.Luiji8-Nov-09 6:30 
GeneralRe: Terrific. Pinmembervictorbos9-Nov-09 11:50 
GeneralRe: Terrific. PinmemberDr.Luiji9-Nov-09 20:42 
GeneralGood Job PinmemberPavanPareta9-Aug-09 6:31 
GeneralRe: Good Job PinmemberDr.Luiji10-Aug-09 7:38 
GeneralGood job PinmemberJustx27-Jul-09 22:36 
GeneralRe: Good job PinmemberDr.Luiji28-Jul-09 2:28 
GeneralDrawSongName thows exception PinmemberVIJAY151030-Apr-09 6:10 
GeneralRe: DrawSongName thows exception PinmemberDr.Luiji4-May-09 1:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 6 Jan 2009
Article Copyright 2009 by Dr.Luiji
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid