Wednesday, June 17, 2009

Fantastic, absolutely fantastic!

Guess what folks. Yesterday evening I checked my OU course page and I have a big Pass printed next to M801! I have my MSc!!!

 HappyFeet_ani

Tuesday, June 16, 2009

Marvellous, absolutely marvellous!

And so I attended the Mass Writing session that Darrel organised on Monday the 15th of June. It was brilliant!

The first and best realisation (as one of the student speakers) was that we were all quite terrified of one another. Boyd was worried that we were all going to say the same and that since he was neither an artist nor a professional programmer that he would be out of his depth. Ira was worried that he as an artist was going to have to speak to a room full of computer scientists. One of the guys mentioned that he has never done this kind of presentation before and I was starting to wonder where I fitted in with the artistic flair of a black spot.

Just to make absolutely sure that we were total wrecks, Darrel reminded us that the session will be webcasted.

Darryl and Ira preparing for the presentation

However, things went really well. It was great to meet some of you guys in person. Meeting Ira, listening to his experiences and how he goes about doing things was absolutely enlightening and enthusing.

Darrel’s arrangements couldn’t be faulted and it was great to be introduced to his fantastic secretary and see his glitzy building where he is currently chief in charge of Computer Science. We had a lovely lunch between sessions and despite my tendency to fall asleep when I’m nervous, the sessions were so interesting that sleeping never crossed my mind … or my mind never crossed over to sleeping.

I said it then and I’ll say it now: Many thanks to Darrel  for a marvellous day and a marvellous opportunity to have been part of this project.

Wednesday, June 10, 2009

Rotating Photo Frame

Using the gifAnimation library it was quite simple to create this little animation.

export

01 import gifAnimation.*;
02 
03 int i = 0;
04 PImage i1,i2,i3;
05 boolean looping = true;
06 int direction = 1;
07 GifMaker gifExport;
08 int frames = -1;
09 
10 void setup() {
11   size(400,300, P3D);
12   frameRate(24);
13   gifExport = new GifMaker(this, "export.gif");
14   gifExport.setRepeat(0);        // make it an "endless" animation
15 
16   i1 = loadImage("img1a.jpg");
17   i2 = loadImage("img2.jpg");
18   i3 = loadImage("img3.jpg");
19 }
20 
21 void draw() {
22   frames++;
23   background(255);
24   translate(width/2,height/3);
25   rotateY(direction * (frameCount*PI/100));
26   createCube();
27   gifExport.setDelay(1);
28   gifExport.addFrame();
29   if (frames == 199) noLoop();
30 }
31 
32 void createCube() {
33 
34   beginShape(QUADS);
35   texture(i1);
36   vertex(0,0,0,0,0); // top left
37   vertex(100,0,0,100,0); // top right
38   vertex(100,100,0,100,100); // bottom right
39   vertex(0,100,0,0,100); // bottom left
40   endShape();
41 
42 
43   beginShape(QUADS);
44   texture(i2);
45   vertex(0,0,-100,100,0); // top right
46   vertex(100,0,-100,0,0); // top left
47   vertex(100,100,-100,0,100); // bottom left
48   vertex(0,100,-100,100,100); // bottom right
49   endShape();
50 
51   beginShape(QUADS);
52   texture(i3);
53   vertex(0,0,0,100,0);
54   vertex(0,0,-100,0,0);
55   vertex(0,100,-100,0,100);
56   vertex(0,100,0,100,100);
57   endShape();
58 }
59 
60 

Friday, May 15, 2009

Running Noise

Right now, watching running noise is much more interesting than my work …

running_nose

Running Noise Applet

Wednesday, May 13, 2009

Book Fragment 84

 

Advanced buttons 1

In the previous chapter we created basic buttons that can be used to start and stop processes. However, we would like buttons to be much more interesting than just little squares. It would give us a much friendlier user interface if we could put some text or images on the buttons so that people know what the buttons are for.

Adding a label

Adding the following few lines of code to the program developed in the previous chapter will add the label “Bulb” to the button.

01 // little square
02   fill(button_top_colour);
03   rect(button_top_left_x + 3, button_top_left_y + 3, button_width - 6, button_width – 6);
04 
05   // Place text on button
06   textMode(SCREEN);
07   textAlign(CENTER, CENTER);
08   font = loadFont("Verdana-10.vlw");
09   textFont(font);
10   fill(color(0,0,05));
11   text("Bulb", button_top_left_x + (button_width/2),
12     button_top_left_y + (button_width/2));

Before this code will work it is necessary to generate the font that will be used for the text. Processing can do this for you. On the Processing menu, click Tools and then Create Font as in the illustration below:

 

Illustration 1: Select Create Font on the menu

Select the font you wish to use and the size. For our code samples we selected Verdana with a size of 10 pixels:

SelectFont

Illustration 2: Select the font and enter a font size.

When you click OK, Processing will create a sub-directory called data in the directory where your program is stored. In the data directory it will create the font file. By default the file is named after the font and its size. So if you, like us, selected Verdana with a size of 10, then the file name will be Verdana-10.vlw.

Drawing a rectangular button

The code above still draws a square button. We often require rectangular buttons, especially if we are going to place text on them. Illustration 3 shows a button and the illustration 4 shows the shapes used to create the button:

button_rectangular

Illustration 3: A rectangular button

button_components

Illustration 4: The shapes used to create a rectangular button

The listing below shows how we draw and colour these shapes, using the method rect for the rectangle and the method quad for the polygons that make the bevel. The mouse event handlers are in place to switch the light bulb on and also notice that the label on the button will change. The bold lines show the code required to generate and place the label on the button:

001 int button_top_left_x = 10;
002 int button_top_left_y = 10;
003 int button_width = 150;
004 int button_height = 40;
005 int bevel_size = 3;
006 int bevel_up_colour = color(0xD0, 0xD0, 0xD0);
007 int bevel_down_colour = color(0x88, 0x88, 0x88);
008 int bevel_colour_left = bevel_up_colour;
009 int bevel_colour_right = bevel_down_colour;
010 boolean bulb_on = false;
011 int button_up_colour = color(0xD0, 0xD0, 0xD0); // grey
012 int button_over_colour = color(0xB0, 0xB0, 0xB0);
013 int button_down_colour = color(0xA0, 0xA0, 0xA0); // white
014 int button_colour_top = button_up_colour;
015 String button_label = "Switch Bulb On";
016 // Declare the variable that will hold the font
017 PFont font;
019 void setup() {
020   size(300,300);
021   // Load the font to be used for the label
022   font = loadFont("Verdana-10.vlw");
023 }
025 void draw() {
026   rectMode(CORNER);
027   // top and left bevels
028   fill(bevel_colour_left);
029   quad(button_top_left_x,
030     button_top_left_y,
031     button_top_left_x + button_width + (bevel_size * 2),
032     button_top_left_y,
033     button_top_left_x + button_width + bevel_size,
034     button_top_left_y + bevel_size,
035     button_top_left_x + bevel_size,
036     button_top_left_y + bevel_size);
038   quad(button_top_left_x,
039     button_top_left_y,
040     button_top_left_x + bevel_size,
041     button_top_left_y + bevel_size,
042     button_top_left_x + bevel_size,
043     button_top_left_y + button_height + bevel_size,
044     button_top_left_x,
045     button_top_left_y + button_height + (bevel_size * 2));
047   // bottom and right bevels
048   fill(bevel_colour_right);
049   quad(button_top_left_x,
050     button_top_left_y + button_height + (bevel_size * 2),
051     button_top_left_x + button_width + (bevel_size * 2),
052     button_top_left_y + button_height + (bevel_size * 2),
053     button_top_left_x + button_width + bevel_size,
054     button_top_left_y + button_height + bevel_size,
055     button_top_left_x + bevel_size,
056     button_top_left_y + button_height + bevel_size);
058   quad(button_top_left_x + button_width + (bevel_size * 2),
059     button_top_left_y,
060     button_top_left_x + button_width + (bevel_size * 2),
061     button_top_left_y + button_height + (bevel_size * 2),
062     button_top_left_x + button_width + bevel_size,
063     button_top_left_y + button_height + bevel_size,
064     button_top_left_x + button_width + bevel_size,
065     button_top_left_y + bevel_size);
067   // top of button
068   fill(button_colour_top);
069   rect(button_top_left_x + bevel_size,
070     button_top_left_y + bevel_size,
071     button_width,
072     button_height);
073  
074   // Place text on button
075   textMode(SCREEN);
076   textAlign(CENTER, TOP);
077   textFont(font);
078   fill(color(0x00, 0x00, 0x00));
079   text(button_label, (button_top_left_x + button_width + (bevel_size * 2)) / 2,
080     (button_top_left_y + button_height + (bevel_size * 2)) / 2);
081  
082   // draw bulb
083   if (bulb_on) {
084     bulb_on();
085   } else {
086     bulb_off();
087   }
088 }
090 void bulb_on() {
091   bulb_on = true;
092   // Change the text to be displayed on the button
093   button_label = "Switch Bulb Off";
094   // draw the light bulb base
095   fill(0x40, 0x40, 0x40);
096   rectMode(CENTER);
097   rect(100,100,15,20);
098   fill(0xFF, 0xCC, 0x33); // an orange fill when the bulb is on
099   ellipseMode(CENTER);
100   ellipse(100,80,30,30);
101 }
103 void bulb_off() {
104   bulb_on = false;
105   // Change the text to be displayed on the button
106   button_label = "Switch Bulb On";
107   // draw the light bulb base
108   fill(0x40, 0x40, 0x40);
109   rectMode(CENTER);
110   rect(100,100,15,20);
111   fill(0xFF, 0xFf, 0xFF); // a white fill when the bulb is off
112   ellipseMode(CENTER);
113   ellipse(100,80,30,30);
114 }
116 void mousePressed() {
117   if (mouseX >= button_top_left_x &&
118     mouseX <= (button_top_left_x + button_width + (bevel_size * 2)) &&
119     mouseY >= button_top_left_y &&
120     mouseY <= (button_top_left_y + button_height + (bevel_size * 2))) {
121       button_colour_top = button_down_colour;
122       bevel_colour_left = bevel_down_colour;
123       bevel_colour_right = bevel_up_colour;
124     } else {
125       button_colour_top = button_up_colour;
126       bevel_colour_left = bevel_up_colour;
127       bevel_colour_right = bevel_down_colour;
128     }
129 }
131 void mouseMoved() {
132   if (mouseX >= button_top_left_x &&
133     mouseX <= (button_top_left_x + button_width + (bevel_size * 2)) &&
134     mouseY >= button_top_left_y &&
135     mouseY <= (button_top_left_y + button_height + (bevel_size * 2))) {
136       button_colour_top = button_over_colour;
137     } else {
138       button_colour_top = button_up_colour;
139     }
140 }
142 void mouseReleased() {
143   if (mouseX >= button_top_left_x &&
144   mouseX <= button_top_left_x + button_width + (bevel_size * 2) &&
145   mouseY >= button_top_left_y &&
146   mouseY <= (button_top_left_y + button_height + (bevel_size * 2))) {
147     if (bulb_on) bulb_on = false; else bulb_on = true;
148     // When the mouse button is released, switch the button bevel colours
149     // so that the button displays in its upper position
150     button_colour_top = button_over_colour;
151     bevel_colour_left = bevel_up_colour;
152     bevel_colour_right = bevel_down_colour;
153   } else {
154     button_colour_top = button_up_colour;
155     bevel_colour_left = bevel_up_colour;
156     bevel_colour_right = bevel_down_colour;
157   }
158 }
Adding an icon

Although text on buttons could be a requirement in some cases, it does take up a great deal of space. So often it is advantageous to have a fairly small button with only an image on it. Modern software often give the user the choice to use buttons with text only, text and images or images only.

To add an icon to the button we can move the text in the button to the right and add an icon to the left as is shown in illustrations 5 and 6.

button_with_drawn_icon_1

Illustration 5: Button to switch bulb on

button_with_drawn_icon_2

Illustration 6: Button to switch bulb off

All we need to do to achieve the above is add the following snippet of code to draw():

01 // draw icon on button
02   fill(0x00, 0x00, 0x00);
03   rect(button_top_left_x + bevel_size + 10,
04     button_top_left_y + bevel_size + 20,
05     10, 10);
06   if (bulb_on) {
07     fill(0xFF, 0xFF, 0xFF);
08   } else {
09     fill(0xFF, 0xCC, 0x33);
10   }
11   ellipseMode(CENTER);
12   ellipse(button_top_left_x + bevel_size + 15,
13     button_top_left_y + bevel_size + 15,
14     20, 20);

Listing 1: Drawing an icon on the button

Drawing icons in this way could become tedious and complex, especially if we want good looking images. An easier alternative would be to use a pre-prepared image for the icon.

Processing can work with four image types, i.e..gif, .jpg, .tga, .png. If you browse the web you will find thousands of free buttons or you can create your own. We found these two buttons on the web1:

play

stop

Using these images we can now create a slightly better looking button than before:

button_with_image_icon_1

button_with_image_icon_2

Firstly we need to declare a variable to hold the images. This is done in the section before setup():

1 PImage img_stop, img_play;
3 In setup(), we then load the images into the variables:
4   img_stop = loadImage("stop.png");
5   img_play = loadImage("play.png");

Replace the code in listing 1 with the code to load the images:

1  // draw icon on button
2   imageMode(CORNERS);
3   if (bulb_on) {
4     image(img_stop, button_top_left_x + bevel_size + 5,
5     button_top_left_y + bevel_size + 5);
6   } else {
7     image(img_play, button_top_left_x + bevel_size + 5,
8     button_top_left_y + bevel_size + 5);
9   }
Using images for buttons

We could, of course, use only images for buttons. There is nothing new to doing this. Everything you need to know to do this has already been covered. The only changes we need to make to the code is to remove all the instructions which are used to draw the button. The button dimensions need to be adjusted to conform to that of the images we are using. The resulting code will actually be a little simpler than before. To make things slightly more interesting we will add a tint to the image when the mouse is hovering over the button.

01 int button_top_left_x = 10;
02 int button_top_left_y = 10;
03 int button_width;
04 int button_height;
05 boolean bulb_on = false;
06 PImage img_stop, img_play;
07 int gray = 255;
08 int alpha = 255;
10 void setup() {
11   size(300,300);
12   background(0xFF, 0xFF, 0xFF);
13   img_stop = loadImage("stop.png");
14   img_play = loadImage("play.png");
15   // Make sure both images have the same width and height when creating them
16   button_width = img_stop.width;
17   button_height = img_stop.height;
18 }
20 void draw() {
21   // draw icon on button
22   imageMode(CORNERS);
23   tint(gray, alpha);
24   if (bulb_on) {
25     image(img_stop, button_top_left_x + 5, button_top_left_y + 5);
26   } else {
27     image(img_play, button_top_left_x + 5 ,button_top_left_y + 5);
28   }
29  
30   // draw bulb
31   if (bulb_on) {
32     bulb_on();
33   } else {
34     bulb_off();
35   }
36 }
38 void bulb_on() {
39   bulb_on = true;
40   // draw the light bulb base
41   fill(0x40, 0x40, 0x40);
42   rectMode(CENTER);
43   rect(100,100,15,20);
44   fill(0xFF, 0xCC, 0x33); // an orange fill when the bulb is on
45   ellipseMode(CENTER);
46   ellipse(100,80,30,30);
47 }
49 void bulb_off() {
50   bulb_on = false;
51   // draw the light bulb base
52   fill(0x40, 0x40, 0x40);
53   rectMode(CENTER);
54   rect(100,100,15,20);
55   fill(0xFF, 0xFf, 0xFF); // a white fill when the bulb is off
56   ellipseMode(CENTER);
57   ellipse(100,80,30,30);
58 }
60 void mouseMoved() {
61   if (mouseX >= button_top_left_x &&
62     mouseX <= (button_top_left_x + button_width) &&
63     mouseY >= button_top_left_y &&
64     mouseY <= (button_top_left_y + button_height)) {
65       // Give the button a tint when the mouse is hovering over it
66       gray = color(0xFD, 0xD0, 0x17);
67       alpha =100;
68     } else {
69       gray = 255;
70       alpha = 255;
71     }
72 }
74 void mouseReleased() {
75   if (mouseX >= button_top_left_x &&
76     mouseX <= (button_top_left_x + button_width) &&
77     mouseY >= button_top_left_y &&
78     mouseY <= (button_top_left_y + button_height)) {
79       if (bulb_on) bulb_on = false; else bulb_on = true;
80   }
81 }

image_button_1

Illustration 7: Image button to switch light bulb on

image_button_2

Illustration 8: Image button with orange tint when mouse hovering

image_button_3

Illustration 9: Image button to switch light bulb off

image_button_4

Illustration 10: Image button with orange tint when mouse hovering

Adding tool tips

Tool tips are informative messages displayed when the mouse hovers over an item. These are usually used when additional information about the item, over which the mouse is hovering, needs to be conveyed to the user. The illustrations below show a tool tip being displayed when the mouse is hovering over the buttons:

tooltip_2 tooltip_1

To add the tool tips to our previous program, add the following pieces of code. Firstly declare a string variable before setup() to hold the text for the tool tip:

1 String tooltip = "";
2 PFont font;

Remember that you need to generate a font if you haven't done so yet. Then add these lines to the setup() method:

1  font = loadFont("Verdana-10.vlw");
2   textFont(font);
3   textMode(SCREEN);

Add the following line as the first line in draw(). This clears the tool tip when the mouse is moved off the button area:

code> 1 background(0x8B, 0xB3, 0x81);

Add the next chunk of code to the end of draw(). If the tooltip string is empty then the code does nothing. If a tool tip is set then a rectangle containing the tool tip is drawn below the button.

01  // Tooltip
02   if (tooltip.equals("")) {
03     //
04   } else {
05     fill(0xFF, 0xF8, 0xC6);
06     rectMode(CORNER);
07     rect(button_top_left_x + 3, button_top_left_y + button_height + 5, 100, 10);
08     textAlign(LEFT, TOP);
09     fill(0x00, 0x00, 0x00);
10     text(tooltip, button_top_left_x + 5, button_top_left_y + button_height + 6);
11   }

Amend the mouse events as follows. The added code is displayed in bold. If the bulb is switched on the tool tip is set to “Switch bulb off” but if the bulb is switched off the tool tip is set to “Switch bulb on”.

01 void mouseMoved() {
02   if (mouseX >= button_top_left_x &&
03     mouseX <= (button_top_left_x + button_width) &&
04     mouseY >= button_top_left_y &&
05     mouseY <= (button_top_left_y + button_height)) {
06       gray = color(0xFD, 0xD0, 0x17);
07       alpha =100;
08       if (bulb_on) {
09         tooltip = "Switch bulb off";
10       } else {
11         tooltip = "Switch bulb on";
12       }
13     } else {
14       tooltip = "";
15       gray = 255;
16       alpha = 255;
17     }
18 }
20 void mouseReleased() {
21   if (mouseX >= button_top_left_x &&
22     mouseX <= (button_top_left_x + button_width) &&
23     mouseY >= button_top_left_y &&
24     mouseY <= (button_top_left_y + button_height)) {
25       // Give the button a tint when the mouse is hovering over it   
26       if (bulb_on) bulb_on = false; else bulb_on = true;
27       if (bulb_on) {
28         tooltip = "Switch bulb off";
29       } else {
30         tooltip = "Switch bulb on";
31       }
32   } else {
33    
34   }

Using combinations of the techniques we have covered in chapter 83 and 84 you should now be able to create very attractive user interfaces with buttons. You will find though, that the code can once again get very complex if you have to draw each button individually. So at this point it would make sense to start using objects which are re-usable. The next chapter will cover this in more detail.

1http://itweek.deviantart.com/art/Knob-Buttons-Toolbar-icons-73463960