MVC - Rendering View Elements in a Specified Order

In my current project, I had to render elements in the view based on a setting provided by the model(basically it is a configurable thing). Few clients need view element to be rendered in a particular order and few others in a different way. What we did was, saved this elements order in a settings file which could be changed based on the clients. Then created an extension to render this based on the order.

This is what was I was trying to explain. for Client 1 the Login section to be displayed first followed by Password reminder section

Client 1 requirement

For Client 2 , these sections needs be ordered differently

Client 2 requirement

In order to achieve this, I came up with an HtmlHelper extension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/// <summary>
/// Renders the render items in the provided sequence order.
/// </summary>
/// <param name="htmlHelper">The HTML helper which is extended.</param>
/// <param name="sequenceOrder">The order in which items to be rendered. Sequence starts at an index of 0.</param>
/// <param name="renderItems">The items to be rendered in order.</param>
/// <remarks>
/// Values in the sequence order should match with the total number of render items.
/// Invalid sequnce numbers are ignored.
/// </remarks>
public static void OrderBy(this HtmlHelper htmlHelper, int[] sequenceOrder, params Action<HtmlHelper>[] renderItems)
{
if (sequenceOrder != null && renderItems != null)
{
foreach (var sequnce in sequenceOrder)
{
// CHeck whether the sequence is with inthe bounds
if (sequnce < renderItems.Length && sequnce >= 0)
{
renderItems[sequnce].Invoke(htmlHelper);
}
}
}
else if (renderItems != null)
{
// If the sequence order is not provided, render it in normal order in which items are declared.
foreach (var renderItem in renderItems)
{
renderItem.Invoke(htmlHelper);
}
}
else
{
// Do Nothing
}
}

In the view, you could do

1
2
3
4
5
6
7
<% Html.OrderBy(this.Model.LoginDisplayOrder, (html) => { %>
<div class="container"></div>
<% Html.RenderPartial("LoginSection", this.Model); %>
<% }, (html) => { %>
<div class="container"></div>
<% Html.RenderPartial("ReminderPassword", this.Model); %>
<% }); %>

Here Model.LoginDisplayOrder is just an array of integers in which the items to be rendered.

Hope this will help.

Create a Live Aquarium Wallpaper in Android

Final Result 1
Final Result 2

Few weeks ago I started learning Android programming, so this article is an outcome of that out-side office study :). Here I will be explaining – how to create a live wallpaper which looks like an aquarium with fishes swimming across the screen. The fish animation is done using sprite technique.

Fish sprite used here is from a code project article

Lets get started…

Creating a new Android project in eclipse (I am not familiar with any other IDEs for Android development :) ). Now create a class for your live wallpaper service, I called it as AquariumWallpaperService, then instantiate the AquariumWallpaperEngine which is responsible for creating the actual Aquarium class which does all the rendering logic. It also controls the flow of Aquarium based Surface callbacks Below is the code for AquariumWallpaperService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class AquariumWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new AquariumWallpaperEngine();
}

class AquariumWallpaperEngine extends Engine{

private Aquarium _aquarium;

public AquariumWallpaperEngine() {
this._aquarium = new Aquarium();
this._aquarium.initialize(getBaseContext(), getSurfaceHolder());
}

@Override
public void onVisibilityChanged(boolean visible) {
if(visible){
this._aquarium.render();
}
}

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
}

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
this._aquarium.start();
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
this._aquarium.stop();
}
}
}

Aquarium class wraps all the rendering logic, as well as creating the fishes. This also starts a thread which is responsible for updating the view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class Aquarium {

private AquariumThread _aquariumThread;
private SurfaceHolder _surfaceHolder;
private ArrayList<Renderable> _fishes;
private Bitmap _backgroundImage;
private Context _context;

public void render(){
Canvas canvas = null;
try{

canvas = this._surfaceHolder.lockCanvas(null);
synchronized (this._surfaceHolder) {
this.onDraw(canvas);
}

}finally{
if(canvas != null){
this._surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}

protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._fishes) {
renderable.render(canvas);
}
};

public void start(){
this._aquariumThread.switchOn();
}

public void stop(){
boolean retry = true;
this._aquariumThread.switchOff();
while (retry) {
try {
this._aquariumThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}

public int getLeft() {
return 0;
}

public int getRight() {
return this._backgroundImage.getWidth();
}

public void initialize(Context context, SurfaceHolder surfaceHolder) {
this._aquariumThread = new AquariumThread(this);
this._surfaceHolder = surfaceHolder;
this._fishes = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this._backgroundImage = BitmapFactory.decodeResource(context.getResources(), com.plugai.android.livewallpapers.R.drawable.aquarium, options);
this.addFishes();
}

private void addFishes() {
Point startPoint = new Point(100, 100);
this._fishes.add(new ClownFish(this._context, this, startPoint, 90));
Point startPoint1 = new Point(100, 300);
this._fishes.add(new ClownFish(this._context, this, startPoint1, 50));

Point startPoint2 = new Point(200, 200);
this._fishes.add(new ClownFish(this._context, this, startPoint2, 15));
}

private void renderBackGround(Canvas canvas)
{
canvas.drawBitmap(this._backgroundImage, 0, 0, null);
}
}

Here is the code for AquariumThread class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class AquariumThread extends Thread {

private Aquarium _aquarium;
private boolean _running;

public AquariumThread(Aquarium aquarium) {
this._aquarium = aquarium;
}

public void switchOn(){
this._running = true;
this.start();
}

public void pause(){
this._running = false;
synchronized(this){
this.notify();
}
}

public void switchOff(){
this._running = false;
synchronized(this){
this.notify();
}
}

@Override
public void run() {
while(this._running){
this._aquarium.render();
}
}
}

All the renderable object in the aquarium must implement an interface Renderable, which has got one single method called render(…)

1
2
3
4
5
6
7
package com.plugai.android.livewallpapers;

import android.graphics.Canvas;

public interface Renderable {
void render(Canvas canvas);
}

This interface helps to render an object other than a fish, like plants etc… in future. I have created another abstract class which has common functionalities like changing the position and direction of a fish after a particular interval and called it as AquaticAnimal, this is because I could create specific fishes which just differ by it’s look by extending from this class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public abstract class AquaticAnimal implements Renderable {

private static int MAX_SPEED = 100;
private Context _context;
private Aquarium _aquarium;
private FishSprite _leftSprite;
private FishSprite _rightSprite;

private int _direction = -1;
private int _speedFraction;
private long _previousTime;

public AquaticAnimal(Context context, Aquarium aquarium){
this._context = context;
this._aquarium = aquarium;
}

protected void initialize(Bitmap leftBitmap, Bitmap rightBitmap, int fps, int totalFrames, Point startPoint, int speed){
this._leftSprite = new FishSprite(leftBitmap, fps, totalFrames, startPoint);
this._rightSprite = new FishSprite(rightBitmap, fps, totalFrames, startPoint);
this._speedFraction = (MAX_SPEED / speed) * 10;
}

private FishSprite getSprite(){
if(this._direction < 0){
return this._leftSprite;
}
return this._rightSprite;
}

public int getDirection(){
FishSprite sprite = this.getSprite();
int xPos = sprite.getXPos();
if(this._direction < 0){
xPos += sprite.getWidth();
}
if(xPos < this._aquarium.getLeft()){
this._direction = 1;
}else if(xPos > this._aquarium.getRight()){
this._direction = -1;
}else{
// Do nothing
}

return this._direction;
}

public Context getContext(){
return this._context;
}

public Aquarium getAquarium(){
return this._aquarium;
}

@Override
public void render(Canvas canvas){
long currentTime = System.currentTimeMillis();
this.getSprite().render(canvas, currentTime);
this.swim(currentTime);
}

public void swim(long currentTime){
long diff = currentTime - this._previousTime;
if(diff > this._speedFraction){
int currentX = this.getSprite().getXPos();
this.getSprite().setXPos(currentX + this.getDirection());
this._previousTime = currentTime;
}
}

}

The sprite animation is moved into a specific class FishSprite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class FishSprite {

/**
* Private fields
*/
private Bitmap _currentSpriteBitmap;
private Rect _drawRect;
private int _fps;
private int _noOfFrames;
private int _currentFrame;
private long _timer;
private int _spriteWidth;
private int _spriteHeight;
private Point _position;

public FishSprite(Bitmap spriteBitmap, int fps, int frameCount, Point startPoint) {

this.initialize();

this._position = startPoint;
this._currentSpriteBitmap = spriteBitmap;
this._spriteHeight = spriteBitmap.getHeight();
this._spriteWidth = spriteBitmap.getWidth() / frameCount;
this._drawRect = new Rect(0,0, this._spriteWidth, this._spriteHeight);
this._fps = 1000 / fps;
this._noOfFrames = frameCount;
}

private void initialize() {
this._drawRect = new Rect(0,0,0,0);
this._timer = 0;
this._currentFrame = 0;
}

private void Update(long currentTime) {
if(currentTime > this._timer + this._fps ) {
this._timer = currentTime;
this._currentFrame +=1;

if(this._currentFrame >= this._noOfFrames) {
this._currentFrame = 0;
}
}

this._drawRect.left = this._currentFrame * this._spriteWidth;
this._drawRect.right = this._drawRect.left + this._spriteWidth;
}

public void render(Canvas canvas, long currentTime) {

this.Update(currentTime);

Rect dest = new Rect(getXPos(), getYPos(), getXPos() + this._spriteWidth,
getYPos() + this._spriteHeight);

canvas.drawBitmap(this._currentSpriteBitmap, this._drawRect, dest, null);
}

public Point getPosition() {
return _position;
}

public void setPosition(Point position) {
this._position = position;
}

public int getYPos() {
return this._position.y;
}

public int getXPos() {
return this._position.x;
}

public void setYPos(int y) {
this._position.y = y;
}

public void setXPos(int x) {
this._position.x = x;
}

public int getWidth(){
return this._spriteWidth;
}

public int getHeight(){
return this._spriteHeight;
}

}

Now to the final bit, that is creating a fish. you might have noticed that I have created an object of ClownFishin the Aquarium class. ClownFish is just a derived class from AquaticAnimal, with a specific sprite image. So if you have sprite images for a shark, you could simple extend a new class for a shark with that image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ClownFish extends AquaticAnimal {
private static final int TOTAL_FRAMES_IN_SPRITE = 20;
private static final int CLOWN_FISH_FPS = 20;

public ClownFish(Context context, Aquarium aquarium, Point startPoint, int speed){
super(context, aquarium);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
Bitmap leftBitmap = BitmapFactory.decodeResource(getContext().getResources(), com.plugai.android.livewallpapers.R.drawable.left, options);
BitmapFactory.Options options1 = new BitmapFactory.Options();
options1.inPurgeable = true;
Bitmap rightBitmap = BitmapFactory.decodeResource(getContext().getResources(), com.plugai.android.livewallpapers.R.drawable.right, options1);
this.initialize(leftBitmap, rightBitmap, CLOWN_FISH_FPS, TOTAL_FRAMES_IN_SPRITE, startPoint, speed);
}

public void render(Canvas canvas){
super.render(canvas);
}
}

Please feel free to go through the code, If I haven’t explained clearly. Hope this article helped some way or other.

Happy new year!!!

Full source code is available here

Create a Live Aquarium Wallpaper in Android

Final Result 1
Final Result 2

Few weeks ago I started learning Android programming, so this article is an outcome of that out-side office study :). Here I will be explaining – how to create a live wallpaper which looks like an aquarium with fishes swimming across the screen. The fish animation is done using sprite technique.

Fish sprite used here is from a code project article

Lets get started…

Creating a new Android project in eclipse (I am not familiar with any other IDEs for Android development :) ). Now create a class for your live wallpaper service, I called it as AquariumWallpaperService, then instantiate the AquariumWallpaperEngine which is responsible for creating the actual Aquarium class which does all the rendering logic. It also controls the flow of Aquarium based Surface callbacks Below is the code for AquariumWallpaperService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class AquariumWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new AquariumWallpaperEngine();
}

class AquariumWallpaperEngine extends Engine{

private Aquarium _aquarium;

public AquariumWallpaperEngine() {
this._aquarium = new Aquarium();
this._aquarium.initialize(getBaseContext(), getSurfaceHolder());
}

@Override
public void onVisibilityChanged(boolean visible) {
if(visible){
this._aquarium.render();
}
}

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
}

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
this._aquarium.start();
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
this._aquarium.stop();
}
}
}

Aquarium class wraps all the rendering logic, as well as creating the fishes. This also starts a thread which is responsible for updating the view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class Aquarium {

private AquariumThread _aquariumThread;
private SurfaceHolder _surfaceHolder;
private ArrayList<Renderable> _fishes;
private Bitmap _backgroundImage;
private Context _context;

public void render(){
Canvas canvas = null;
try{

canvas = this._surfaceHolder.lockCanvas(null);
synchronized (this._surfaceHolder) {
this.onDraw(canvas);
}

}finally{
if(canvas != null){
this._surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}

protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._fishes) {
renderable.render(canvas);
}
};

public void start(){
this._aquariumThread.switchOn();
}

public void stop(){
boolean retry = true;
this._aquariumThread.switchOff();
while (retry) {
try {
this._aquariumThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}

public int getLeft() {
return 0;
}

public int getRight() {
return this._backgroundImage.getWidth();
}

public void initialize(Context context, SurfaceHolder surfaceHolder) {
this._aquariumThread = new AquariumThread(this);
this._surfaceHolder = surfaceHolder;
this._fishes = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this._backgroundImage = BitmapFactory.decodeResource(context.getResources(), com.plugai.android.livewallpapers.R.drawable.aquarium, options);
this.addFishes();
}

private void addFishes() {
Point startPoint = new Point(100, 100);
this._fishes.add(new ClownFish(this._context, this, startPoint, 90));
Point startPoint1 = new Point(100, 300);
this._fishes.add(new ClownFish(this._context, this, startPoint1, 50));

Point startPoint2 = new Point(200, 200);
this._fishes.add(new ClownFish(this._context, this, startPoint2, 15));
}

private void renderBackGround(Canvas canvas)
{
canvas.drawBitmap(this._backgroundImage, 0, 0, null);
}
}

Here is the code for AquariumThread class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class AquariumThread extends Thread {

private Aquarium _aquarium;
private boolean _running;

public AquariumThread(Aquarium aquarium) {
this._aquarium = aquarium;
}

public void switchOn(){
this._running = true;
this.start();
}

public void pause(){
this._running = false;
synchronized(this){
this.notify();
}
}

public void switchOff(){
this._running = false;
synchronized(this){
this.notify();
}
}

@Override
public void run() {
while(this._running){
this._aquarium.render();
}
}
}

All the renderable object in the aquarium must implement an interface Renderable, which has got one single method called render(…)

1
2
3
4
5
6
7
package com.plugai.android.livewallpapers;

import android.graphics.Canvas;

public interface Renderable {
void render(Canvas canvas);
}

This interface helps to render an object other than a fish, like plants etc… in future. I have created another abstract class which has common functionalities like changing the position and direction of a fish after a particular interval and called it as AquaticAnimal, this is because I could create specific fishes which just differ by it’s look by extending from this class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public abstract class AquaticAnimal implements Renderable {

private static int MAX_SPEED = 100;
private Context _context;
private Aquarium _aquarium;
private FishSprite _leftSprite;
private FishSprite _rightSprite;

private int _direction = -1;
private int _speedFraction;
private long _previousTime;

public AquaticAnimal(Context context, Aquarium aquarium){
this._context = context;
this._aquarium = aquarium;
}

protected void initialize(Bitmap leftBitmap, Bitmap rightBitmap, int fps, int totalFrames, Point startPoint, int speed){
this._leftSprite = new FishSprite(leftBitmap, fps, totalFrames, startPoint);
this._rightSprite = new FishSprite(rightBitmap, fps, totalFrames, startPoint);
this._speedFraction = (MAX_SPEED / speed) * 10;
}

private FishSprite getSprite(){
if(this._direction < 0){
return this._leftSprite;
}
return this._rightSprite;
}

public int getDirection(){
FishSprite sprite = this.getSprite();
int xPos = sprite.getXPos();
if(this._direction < 0){
xPos += sprite.getWidth();
}
if(xPos < this._aquarium.getLeft()){
this._direction = 1;
}else if(xPos > this._aquarium.getRight()){
this._direction = -1;
}else{
// Do nothing
}

return this._direction;
}

public Context getContext(){
return this._context;
}

public Aquarium getAquarium(){
return this._aquarium;
}

@Override
public void render(Canvas canvas){
long currentTime = System.currentTimeMillis();
this.getSprite().render(canvas, currentTime);
this.swim(currentTime);
}

public void swim(long currentTime){
long diff = currentTime - this._previousTime;
if(diff > this._speedFraction){
int currentX = this.getSprite().getXPos();
this.getSprite().setXPos(currentX + this.getDirection());
this._previousTime = currentTime;
}
}

}

The sprite animation is moved into a specific class FishSprite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class FishSprite {

/**
* Private fields
*/
private Bitmap _currentSpriteBitmap;
private Rect _drawRect;
private int _fps;
private int _noOfFrames;
private int _currentFrame;
private long _timer;
private int _spriteWidth;
private int _spriteHeight;
private Point _position;

public FishSprite(Bitmap spriteBitmap, int fps, int frameCount, Point startPoint) {

this.initialize();

this._position = startPoint;
this._currentSpriteBitmap = spriteBitmap;
this._spriteHeight = spriteBitmap.getHeight();
this._spriteWidth = spriteBitmap.getWidth() / frameCount;
this._drawRect = new Rect(0,0, this._spriteWidth, this._spriteHeight);
this._fps = 1000 / fps;
this._noOfFrames = frameCount;
}

private void initialize() {
this._drawRect = new Rect(0,0,0,0);
this._timer = 0;
this._currentFrame = 0;
}

private void Update(long currentTime) {
if(currentTime > this._timer + this._fps ) {
this._timer = currentTime;
this._currentFrame +=1;

if(this._currentFrame >= this._noOfFrames) {
this._currentFrame = 0;
}
}

this._drawRect.left = this._currentFrame * this._spriteWidth;
this._drawRect.right = this._drawRect.left + this._spriteWidth;
}

public void render(Canvas canvas, long currentTime) {

this.Update(currentTime);

Rect dest = new Rect(getXPos(), getYPos(), getXPos() + this._spriteWidth,
getYPos() + this._spriteHeight);

canvas.drawBitmap(this._currentSpriteBitmap, this._drawRect, dest, null);
}

public Point getPosition() {
return _position;
}

public void setPosition(Point position) {
this._position = position;
}

public int getYPos() {
return this._position.y;
}

public int getXPos() {
return this._position.x;
}

public void setYPos(int y) {
this._position.y = y;
}

public void setXPos(int x) {
this._position.x = x;
}

public int getWidth(){
return this._spriteWidth;
}

public int getHeight(){
return this._spriteHeight;
}

}

Now to the final bit, that is creating a fish. you might have noticed that I have created an object of ClownFishin the Aquarium class. ClownFish is just a derived class from AquaticAnimal, with a specific sprite image. So if you have sprite images for a shark, you could simple extend a new class for a shark with that image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ClownFish extends AquaticAnimal {
private static final int TOTAL_FRAMES_IN_SPRITE = 20;
private static final int CLOWN_FISH_FPS = 20;

public ClownFish(Context context, Aquarium aquarium, Point startPoint, int speed){
super(context, aquarium);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
Bitmap leftBitmap = BitmapFactory.decodeResource(getContext().getResources(), com.plugai.android.livewallpapers.R.drawable.left, options);
BitmapFactory.Options options1 = new BitmapFactory.Options();
options1.inPurgeable = true;
Bitmap rightBitmap = BitmapFactory.decodeResource(getContext().getResources(), com.plugai.android.livewallpapers.R.drawable.right, options1);
this.initialize(leftBitmap, rightBitmap, CLOWN_FISH_FPS, TOTAL_FRAMES_IN_SPRITE, startPoint, speed);
}

public void render(Canvas canvas){
super.render(canvas);
}
}

Please feel free to go through the code, If I haven’t explained clearly. Hope this article helped some way or other.

Happy new year!!!

Full source code is available here

It’s Better to Automate, Instead of Checklists

In my day to day activities I have seen many checklists like

  1. Code review checklist
  2. Source control check-in checklist
  3. Developer checklist

All these are good because it helps to reduce failures but does everyone follow these all the time?. Sometimes I (or any developer) forgot to go through the checklist due to many reasons like time constraints, lack of concentration etc… and I don’t think we should blame anyone for missing this because - We all are humans and we tends to forget.

Only way we could reduce these mistakes is to automate!!! wherever possible. In my current project, all the aspx page should have direction(dir) attribute in the html tag as part of the localization work. As usual an email with checklist for localizing an aspx page was sent to all the developers, out of that one item was to include dir attribute whenever they add new aspx file.

Everybody followed this in the initial stages but later we started forgetting about this requirement, which caused extra hours of effort to fix it in all the pages.

It could have been avoided if we had a automated process which verifies this. In order to automate, one way is to write a custom MSBuild task which could verify whether a aspx file has dir attribute, if it doesn’t fails build (this whole idea came from http://blogs.msdn.com/b/simonince/archive/2009/07/10/enforcing-unobtrusive-javascript.aspx). If you want to learn about writing a custom MSBuild task, I suggest http://msdn.microsoft.com/en-us/library/t9883dzc.aspx.

So here is the code which creates this custom MS Build task

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System.Linq;
using HtmlAgilityPack;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace StaticFileAnalysisTask
{
/// <summary>
/// Custom MSBuild task which analyse the HTML code validation.
/// </summary>
public class HTMLCodingStandard : Task
{
#region Private fields

/// <summary>
/// Variable that holds the status of this task execution.
/// </summary>
private bool _success;

#endregion

#region Public properties

/// <summary>
/// Gets or sets the source file list.
/// </summary>
/// <value>The source file list.</value>
[Required]
public ITaskItem[] SourceFiles { get; set; }

/// <summary>
/// Gets or sets the list of files to be excluded.
/// </summary>
/// <value>The excluded files.</value>
public ITaskItem[] ExcludeFiles { get; set; }

#endregion

/// <summary>
/// Executes this task.
/// </summary>
/// <returns><c>true</c> if task executed successfully; Otherwise, <c>false</c>.</returns>
public override bool Execute()
{
this._success = true;

foreach (ITaskItem current in SourceFiles)
{
// If the items is in the exluded list, then skip
if(this.IsInExlcudedList(current))
{
continue;
}

string path = current.ItemSpec;
if (path.EndsWith(".aspx"))
{
this.ValidateFile(path);
}
}
return this._success;
}

/// <summary>
/// Method that is responsible for validating the file.
/// </summary>
/// <param name="path">The full path to the file.</param>
private void ValidateFile(string path)
{
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.Load(path);
HtmlNode node = htmlDocument.DocumentNode.SelectSingleNode("//html");
if(node != null)
{
if(!node.Attributes.Contains("dir"))
{
this.BuildEngine.LogErrorEvent(new BuildErrorEventArgs(
"Invalid HTML coding standard",
"SFAT-HTML-1",
path,
node.Line,
node.LinePosition,
node.LinePosition,
node.LinePosition + node.OuterHtml.Length,
"SFAT-HTML-1: Direction(dir) tag is missing",
null,
"HTMLCodingStandardTask"
));
this._success = false;
}

}
}

/// <summary>
/// Determines whether an item is in the excluded list.
/// </summary>
/// <param name="taskItem">The task item which needs to checked.</param>
/// <returns>
/// <c>true</c> if item is in exlcuded list; otherwise, <c>false</c>.
/// </returns>
private bool IsInExlcudedList(ITaskItem taskItem)
{
if(this.ExcludeFiles == null)
{
return false;
}

return this.ExcludeFiles.Any(x => x.ItemSpec == taskItem.ItemSpec);
}
}
}

For including this in the your web project, open the project file in a text editor and add the below lines

1
2
3
4
5
6
7
8
9
10
11
<UsingTask AssemblyFile="..\output\StaticFileAnalysisTask.dll" TaskName="HTMLCodingStandard" />
<Target Name="BeforeBuild">
<HTMLCodingStandard SourceFiles="@(Content)" />
</Target> If you want to exclude any files from this verification process, then define an ItemGroup
<ItemGroup>
<ExcludedContents Include="WebForm2.aspx" />
</ItemGroup> and add that to the build action like below
<UsingTask AssemblyFile="..\output\StaticFileAnalysisTask.dll" TaskName="HTMLCodingStandard" />
<Target Name="BeforeBuild">
<HTMLCodingStandard SourceFiles="@(Content)" ExcludeFiles="@(ExcludedContents)" />
</Target>

Hope this helps you.

Download code sample from here

It’s Better to Automate, Instead of Checklists

In my day to day activities I have seen many checklists like

  1. Code review checklist
  2. Source control check-in checklist
  3. Developer checklist

All these are good because it helps to reduce failures but does everyone follow these all the time?. Sometimes I (or any developer) forgot to go through the checklist due to many reasons like time constraints, lack of concentration etc… and I don’t think we should blame anyone for missing this because - We all are humans and we tends to forget.

Only way we could reduce these mistakes is to automate!!! wherever possible. In my current project, all the aspx page should have direction(dir) attribute in the html tag as part of the localization work. As usual an email with checklist for localizing an aspx page was sent to all the developers, out of that one item was to include dir attribute whenever they add new aspx file.

Everybody followed this in the initial stages but later we started forgetting about this requirement, which caused extra hours of effort to fix it in all the pages.

It could have been avoided if we had a automated process which verifies this. In order to automate, one way is to write a custom MSBuild task which could verify whether a aspx file has dir attribute, if it doesn’t fails build (this whole idea came from http://blogs.msdn.com/b/simonince/archive/2009/07/10/enforcing-unobtrusive-javascript.aspx). If you want to learn about writing a custom MSBuild task, I suggest http://msdn.microsoft.com/en-us/library/t9883dzc.aspx.

So here is the code which creates this custom MS Build task

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System.Linq;
using HtmlAgilityPack;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace StaticFileAnalysisTask
{
/// <summary>
/// Custom MSBuild task which analyse the HTML code validation.
/// </summary>
public class HTMLCodingStandard : Task
{
#region Private fields

/// <summary>
/// Variable that holds the status of this task execution.
/// </summary>
private bool _success;

#endregion

#region Public properties

/// <summary>
/// Gets or sets the source file list.
/// </summary>
/// <value>The source file list.</value>
[Required]
public ITaskItem[] SourceFiles { get; set; }

/// <summary>
/// Gets or sets the list of files to be excluded.
/// </summary>
/// <value>The excluded files.</value>
public ITaskItem[] ExcludeFiles { get; set; }

#endregion

/// <summary>
/// Executes this task.
/// </summary>
/// <returns><c>true</c> if task executed successfully; Otherwise, <c>false</c>.</returns>
public override bool Execute()
{
this._success = true;

foreach (ITaskItem current in SourceFiles)
{
// If the items is in the exluded list, then skip
if(this.IsInExlcudedList(current))
{
continue;
}

string path = current.ItemSpec;
if (path.EndsWith(".aspx"))
{
this.ValidateFile(path);
}
}
return this._success;
}

/// <summary>
/// Method that is responsible for validating the file.
/// </summary>
/// <param name="path">The full path to the file.</param>
private void ValidateFile(string path)
{
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.Load(path);
HtmlNode node = htmlDocument.DocumentNode.SelectSingleNode("//html");
if(node != null)
{
if(!node.Attributes.Contains("dir"))
{
this.BuildEngine.LogErrorEvent(new BuildErrorEventArgs(
"Invalid HTML coding standard",
"SFAT-HTML-1",
path,
node.Line,
node.LinePosition,
node.LinePosition,
node.LinePosition + node.OuterHtml.Length,
"SFAT-HTML-1: Direction(dir) tag is missing",
null,
"HTMLCodingStandardTask"
));
this._success = false;
}

}
}

/// <summary>
/// Determines whether an item is in the excluded list.
/// </summary>
/// <param name="taskItem">The task item which needs to checked.</param>
/// <returns>
/// <c>true</c> if item is in exlcuded list; otherwise, <c>false</c>.
/// </returns>
private bool IsInExlcudedList(ITaskItem taskItem)
{
if(this.ExcludeFiles == null)
{
return false;
}

return this.ExcludeFiles.Any(x => x.ItemSpec == taskItem.ItemSpec);
}
}
}

For including this in the your web project, open the project file in a text editor and add the below lines

1
2
3
4
5
6
7
8
9
10
11
<UsingTask AssemblyFile="..\output\StaticFileAnalysisTask.dll" TaskName="HTMLCodingStandard" />
<Target Name="BeforeBuild">
<HTMLCodingStandard SourceFiles="@(Content)" />
</Target> If you want to exclude any files from this verification process, then define an ItemGroup
<ItemGroup>
<ExcludedContents Include="WebForm2.aspx" />
</ItemGroup> and add that to the build action like below
<UsingTask AssemblyFile="..\output\StaticFileAnalysisTask.dll" TaskName="HTMLCodingStandard" />
<Target Name="BeforeBuild">
<HTMLCodingStandard SourceFiles="@(Content)" ExcludeFiles="@(ExcludedContents)" />
</Target>

Hope this helps you.

Download code sample from here

User Experience Makes Applications Stand-out

What makes your application different from others? I strongly feel the user experience that you provides plays an important role to be successful. Some of us might have felt that(at least myself), you woke up one day with a brand new idea but later you realize that somebody had implemented that an year back. Which is a frustrated feeling, I have been to that situation so many times. So even if that idea exists already, how to make that idea a successful one.

Stand-out

Say if you are going to enter in to a world where there are n number of similar applications, how will you attract the users? A great example may be GMail, IMHO they entered to the party when Yahoo and Microsoft where ruling email market. But now GMail is much popular than other email service providers. One reason I could think of for this success is the experience that you get as a user.

Not sure whether anybody has noted this or not but today when was about to send an email to my friend, I got a message box saying Did you mean to attach files?

Screenshot

Yes, GMail reminded me to attach the file. I was surprised to see this, GMail has intelligently scanned what I have typed in the email message and gave me suggestion before sending…. WOW!!!!!. I checked whether Yahoo mail has got this feature, not yet. That makes GMail stand-out from others.

User Experience Makes Applications Stand-out

What makes your application different from others? I strongly feel the user experience that you provides plays an important role to be successful. Some of us might have felt that(at least myself), you woke up one day with a brand new idea but later you realize that somebody had implemented that an year back. Which is a frustrated feeling, I have been to that situation so many times. So even if that idea exists already, how to make that idea a successful one.

Stand-out

Say if you are going to enter in to a world where there are n number of similar applications, how will you attract the users? A great example may be GMail, IMHO they entered to the party when Yahoo and Microsoft where ruling email market. But now GMail is much popular than other email service providers. One reason I could think of for this success is the experience that you get as a user.

Not sure whether anybody has noted this or not but today when was about to send an email to my friend, I got a message box saying Did you mean to attach files?

Screenshot

Yes, GMail reminded me to attach the file. I was surprised to see this, GMail has intelligently scanned what I have typed in the email message and gave me suggestion before sending…. WOW!!!!!. I checked whether Yahoo mail has got this feature, not yet. That makes GMail stand-out from others.

Asp.Net MVC - Fluent Html Helper for FlexiGrid

There are so many free JQuery Grid plugins out there, in that I liked FlexiGrid just because of it’s look and style. In order to use it in your MVC application you may have to put the Javascript code into your view, which requires the property names of your model in order to generates the Grid columns as well the search options etc… as everybody knows when you deal with hard coded string as the property names in any code, it is error prone.

In order to avoid this problem I thought of creating a html extension which is tightly coupled with your data that is going to bound to the Grid. Which helps the developer from writing any javascript codes.

Full source code can found in this Git repo mvc-fluent-jquery-plugin-controls

Asp.Net MVC - Fluent Html Helper for FlexiGrid

There are so many free JQuery Grid plugins out there, in that I liked FlexiGrid just because of it’s look and style. In order to use it in your MVC application you may have to put the Javascript code into your view, which requires the property names of your model in order to generates the Grid columns as well the search options etc… as everybody knows when you deal with hard coded string as the property names in any code, it is error prone.

In order to avoid this problem I thought of creating a html extension which is tightly coupled with your data that is going to bound to the Grid. Which helps the developer from writing any javascript codes.

Full source code can found in this Git repo mvc-fluent-jquery-plugin-controls

JQueryUI Datepicker in ASP.Net MVC

Datepicker is nice and cool plugin for displaying the calendar with ease. It is very easy to use JQuery plugin, it comes as part of JQueryUI library, so if you want to use this – first download JQueryUI from http://jqueryui.com/download and also download JQuery(http://jquery.com/download/) if you haven’t done yet.

Assume you have a form like one below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<% using(Html.BeginForm()){%>
<fieldset>
<legend>Event Information</legend>
<p>
<label for="EventName">Event Name:</label>
<%= Html.TextBox("EventName")%>
</p>
<p>
<label for="StartDate">Start Date:</label>
<%= Html.TextBox("StartDate")%>
</p>
<p>
<label for="EndDate">End Date:</label>
<%= Html.TextBox("EndDate")%>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% }%>

and you want to attach datepicker to StartDate and EndDate input fields, what you needs to do is call the datepicker function on the these input field selector like below.

1
2
3
4
$(document).ready(function() {
$('#StartDate').datepicker();
$('#EndDate').datepicker();
});

This works fine as we expected :)

###Difference in Date format patterns

Consider a scenario where your MVC application supports localization, then the selected date displayed in the input fields also should display the in the same date format of the current culture(This format could be custom one or default one).

This leads to you another issue – Datepicker plugin given by the JQueryUI supports different date formats, but it is different from one that is available in .NET. For e.g. in order to display a long day name (“Thursday”) .NET uses dddd* its equivalent in Datepicker is DD.

In order to solve this disparity between the .NET world and Datepicker world, I have created a html helper function, which could generate the Datepicker format from a .Net date format.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/// <summary>
/// JQuery UI DatePicker helper.
/// </summary>
public static class JQueryUIDatePickerHelper
{
/// <summary>
/// Converts the .net supported date format current culture format into JQuery Datepicker format.
/// </summary>
/// <param name="html">HtmlHelper object.</param>
/// <returns>Format string that supported in JQuery Datepicker.</returns>
public static string ConvertDateFormat(this HtmlHelper html)
{
return ConvertDateFormat(html, Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern);
}

/// <summary>
/// Converts the .net supported date format current culture format into JQuery Datepicker format.
/// </summary>
/// <param name="html">HtmlHelper object.</param>
/// <param name="format">Date format supported by .NET.</param>
/// <returns>Format string that supported in JQuery Datepicker.</returns>
public static string ConvertDateFormat(this HtmlHelper html, string format)
{
/*
* Date used in this comment : 5th - Nov - 2009 (Thursday)
*
* .NET JQueryUI Output Comment
* --------------------------------------------------------------
* d d 5 day of month(No leading zero)
* dd dd 05 day of month(two digit)
* ddd D Thu day short name
* dddd DD Thursday day long name
* M m 11 month of year(No leading zero)
* MM mm 11 month of year(two digit)
* MMM M Nov month name short
* MMMM MM November month name long.
* yy y 09 Year(two digit)
* yyyy yy 2009 Year(four digit) *
*/

string currentFormat = format;

// Convert the date
currentFormat = currentFormat.Replace("dddd", "DD");
currentFormat = currentFormat.Replace("ddd", "D");

// Convert month
if (currentFormat.Contains("MMMM"))
{
currentFormat = currentFormat.Replace("MMMM", "MM");
}
else if (currentFormat.Contains("MMM"))
{
currentFormat = currentFormat.Replace("MMM", "M");
}
else if (currentFormat.Contains("MM"))
{
currentFormat = currentFormat.Replace("MM", "mm");
}
else
{
currentFormat = currentFormat.Replace("M", "m");
}

// Convert year
currentFormat = currentFormat.Contains("yyyy") ? currentFormat.Replace("yyyy", "yy") : currentFormat.Replace("yy", "y");

return currentFormat;
}
}

So how we could make use this helper method, just replace the datepicker initialization code we have written earlier with this

1
2
3
4
$(document).ready(function() {
$('#StartDate').datepicker({ dateFormat: '<%= Html.ConvertDateFormat() %>' });
$('#EndDate').datepicker({ dateFormat: '<%= Html.ConvertDateFormat() %>' });
});

Hope this helps.