Wednesday 4 November 2009

Chunk 85 - Advanced Buttons 2 (Part 5)

...... Using our button class we have the ability to create buttons of any size, set the colour and the text of the button. We can also have buttons that display an image rather than text, and to set a colour and change of image for the button if the mouse is over the button. One remaining feature that is used in applications, primarily with image buttons, is a tooltip. This is a piece of descriptive text that appears at the position of the mouse pointer, once the mouse pointer has been over a button for a period of time. This tooltip disappears after a set period, or when the mouse pointer is moved off the button.

In the final section of Advanced Buttons 2 we will add tooltip functionality to our button class.

First we need to add an instance variable to our button class in which we can hold the text of the tooltip, and we will also add a couple of instance variables to help us with the timing of the tooltip display. The constructor method will have to be changed to set the initial values for these instance
variables.

String  btnTooltip;      // Button tooltip text
int btnStartTooltip; // Countdown to displaying the tooltip
int btnStopTooltip; // Countdown to removing the tooltip

// The button constructor is called to create a new button
// and stores the position and size information provided
// in the instance variables of the object creaetd
Button (int X, int Y, int W, int H)
{
.
.
.
this.btnTooltip = ""; // Default tooltip text
this.btnStartTooltip = 0; // Display started
this.btnStopTooltip = 0; // Dispaly stopped
}

A new setter method is required in order to set the value of the tooltip text for a button.

// Set the Button tooltip
public void setButtonTooltip(String tooltipText)
{
this.btnTooltip = tooltipText;
}

Changes are required in the checkMouse() method in order to start the countdowns to the display and removal of the tooltip for a button once the mouse pointer is over the button.

// Check the location of the mouse in relation to the
// button and set instance variables accordingly
private void checkMouse()
{
// Check if the mouse is over the button
boolean mOver = this.isMouseOver();

// If the mouse is over the current button
if (mOver == true)
{
// If the mouse was not already over the button
// set the start and stop counters for the
// tooltip, if we have a tooltip defined
if (this.mouseOver == false)
{
if (!this.btnTooltip.equals(""))
{
this.btnStartTooltip = 100;
this.btnStopTooltip = 500;
}
}
else
{
// The mouse pointer was already over this button so
// provided we have a tooltip defined we should be
// counting down to tooltip counters
if (!this.btnTooltip.equals(""))
{
// Provided the counter is greather than zero
// subtract one from the counter
if (this.btnStartTooltip > 0) {this.btnStartTooltip--;}
if (this.btnStopTooltip > 0) {this.btnStopTooltip--;}
}
}
}
else
{
// The mouse pointer was over this button but it is not
// now so provided we have a tooltip defined we should
// reset the tooltip counters
if (this.mouseOver == true && !this.btnTooltip.equals(""))
{
this.btnStartTooltip = 0;
this.btnStopTooltip = 0;
}
}

// Mark the button to indicate if the mouse is over it
this.mouseOver = mOver;

// If the mouse is over the button and we have a mouse over
// image defined, set the button image accordingly.
// Otherwise set to the standard image
if (this.mouseOver && this.moverImage != null)
{
this.btnImage = this.moverImage;
}
else
{
this.btnImage = this.stdImage;
}

// If the mouse is over the button and we have a mouse over
// colour defined, set the button colour accordingly.
// Otherwise set to the standard colour
if (this.mouseOver && this.moverColour != -1)
{
this.btnColour = this.moverColour;
}
else
{
this.btnColour = this.stdColour;
}
}

We need to create a new method within the button class that will draw the tooltip for a button is required, we will call this method for each button at the end of the draw() function so that the tooltip is displayed on the top of the display.

// Check if this button should have a tooltip displayed
// for it and display accordingly
private void tooltip()
{
int textWidth;
// If the mouse is over this button, and the tooltip is not
// an empty string, and the tooltip start countdown is zero
// and the tooltip stop countdown is not zero we should
// display the tooltip
if (this.mouseOver == true && ! this.tooltip.equals("") &&
this.tooltipStart == 0 && this.tooltipStop != 0)
{
// Select the font we will use for tooltips
textFont(tooltipFont,9);

// Calculate the width of the text we want to display
float textW = textWidth(this.tooltip) + 10;

// Choose the pale yellow background colour for the tooltip
fill(241,253,191);

// Draw the rectangle in which to display the tooltip text
rect( mouseX + 10, mouseY - 20, textW, 20);

// Change the colour to black
fill(0);

// Calculate the X and Y position to ensure the tooltip text is
// aligned in the centre of the tooltip rectangle
float textX = (mouseX + 10 + (textW / 2));
textX = textX - (textWidth(this.tooltip) / 2);
float textY = (mouseY - 20 + 10 ) + 4.5;

// Display the tooltip text
text(this.tooltip, textX, textY);
}
}

You will notice that we are using a new font size for the tooltip, and the code for this will need to be added to the setup() function along with a call to the setter method to set a tooltip for one of the buttons, and we will have to change the draw() function to call our tooltip() method for each button.

Button btn1;         // On Button
Button btn2; // Off Button
Button btn3; // Image Button

PFont btnFont; // Button Label Font
PFont tooltipFont; // Tooltip Font

void setup() {
size(400,400); // Set screen size
smooth(); // Anti-aliased (smooth) edges

// Load the font we want to use on the buttons
btnFont=loadFont("Verdana-Bold-12.vlw");
tooltipFont=loadFont("Verdana-9.vlw");

// Create a new button and set the colour and label
btn1 = new Button(10,365,100,25);
btn1.setButtonColour(color(128,128,255));
btn1.setMouseOverColour(color(128,128,128));
btn1.setButtonLabel("On");

// Create a new button and set the colour and label
btn2 = new Button(120,365,100,25);
btn2.setButtonColour(color(128,128,255));
btn2.setMouseOverColour(color(128,128,128));
btn2.setButtonLabel("Off");

// Create a new button and set the colour and image
btn3 = new Button(230,359,17,33);
btn3.setButtonColour(color(128,128,255));
btn3.setButtonImage("tab-unsel-menu.gif");
btn3.setMouseOverImage("tab-sel-menu.gif");
btn3.setButtonTooltip("Select Menu");

}

void draw () {

// Clear the background and set the background colour
background(128,128,128);

// Process button one
btn1.checkMouse();
btn1.drawButton();

// Process button two
btn2.checkMouse();
btn2.drawButton();

// Process button three
btn3.checkMouse();
btn3.drawButton();

// Process the tooltips for each button
btn1.tooltip();
btn2.tooltip();
btn3.tooltip();

}

Now when we run our final version of the program and place our mouse over the menu button, after a few seconds we get the display shown in figure 5.0.

Figure 5.0 Mouse Over Tooltip




// Button Class
// Development of a button class - Final Stage
// 2009 Nigel Parker

Button btn1; // On Button
Button btn2; // Off Button
Button btn3; // Image Button

PFont btnFont; // Button Label Font
PFont tooltipFont; // Tooltip Font

void setup() {
size(400,400); // Set screen size
smooth(); // Anti-aliased (smooth) edges

// Load the font we want to use on the buttons
btnFont=loadFont("Verdana-Bold-12.vlw");
tooltipFont=loadFont("Verdana-9.vlw");

// Create a new button and set the colour and label
btn1 = new Button(10,365,100,25);
btn1.setButtonColour(color(128,128,255));
btn1.setMouseOverColour(color(128,128,128));
btn1.setButtonLabel("On");

// Create a new button and set the colour and label
btn2 = new Button(120,365,100,25);
btn2.setButtonColour(color(128,128,255));
btn2.setMouseOverColour(color(128,128,128));
btn2.setButtonLabel("Off");

// Create a new button and set the colour and image
btn3 = new Button(230,359,17,33);
btn3.setButtonColour(color(128,128,255));
btn3.setButtonImage("tab-unsel-menu.gif");
btn3.setMouseOverImage("tab-sel-menu.gif");
btn3.setButtonTooltip("Select Menu");

}

void draw () {

// Clear the background and set the background colour
background(128,128,128);

// Process button one
btn1.checkMouse();
btn1.drawButton();

// Process button two
btn2.checkMouse();
btn2.drawButton();

// Process button three
btn3.checkMouse();
btn3.drawButton();

// Process the tooltips for each button
btn1.tooltip();
btn2.tooltip();
btn3.tooltip();

}

// Definition of a Button class that will allow us to
// create and use buttons within our processing code
class Button {

// Button Position and Size Properties
int btnTopX; // Button Top X Coordinate
int btnTopY; // Button Top Y Coordinate
int btnWidth; // Button Width
int btnHeight; // Button Height
color btnColour; // Button Colour
String btnText; // Button Label Text
PImage btnImage; // Button Image
boolean mouseOver; // Is mouse over button

color stdColour; // Standard Button Colour
color moverColour; // Mouse Over Button Colour
PImage stdImage; // Standard Button Image
PImage moverImage; // Mouse Over Button Image

String btnTooltip; // Button tooltip text
int btnStartTooltip; // Countdown to displaying the tooltip
int btnStopTooltip; // Countdown to removing the tooltip

// The button constructor is called to create a new button
// and stores the position and size information provided
// in the instance variables of the object creaetd
Button (int X, int Y, int W, int H)
{
this.btnTopX = X; // Set Button Top X Coordinate
this.btnTopY = Y; // Set Button Top Y Coordinate
this.btnWidth = W; // Set Button Width
this.btnHeight = H; // Set Button Height
this.btnColour = -1; // Button Colour
this.btnText = ""; // Default Button Label Text
this.btnImage = null; // Button Image
this.mouseOver = false; // Mouse over button?
this.stdColour = 128; // Standard Button Colour
this.moverColour = -1; // Mouse Over Button Colour
this.stdImage = null; // Standard Button Image
this.moverImage = null; // Mouse Over Button Image
this.btnTooltip = ""; // Default tooltip text
this.btnStartTooltip = 0; // Display started
this.btnStopTooltip = 0; // Dispaly stopped
}

// Setter Methods - Methods that can be used by an
// application to set instance variables within an
// instance of the button class

// Set the Button Label Text
public void setButtonLabel(String labelText)
{
this.btnText = labelText;
}

// Set the Button Colour
public void setButtonColour(int colourValue)
{
this.stdColour = colourValue;
this.btnColour = colourValue;
}

// Set the Button Image
public void setButtonImage(String imageValue)
{
this.stdImage = loadImage(imageValue);
this.btnImage = this.stdImage;
}

// Set the MouseOver Button Colour
public void setMouseOverColour(int colourValue)
{
this.moverColour = colourValue;
}

// Set the MouseOver Button Image
public void setMouseOverImage(String imageValue)
{
this.moverImage = loadImage(imageValue);
}

// Set the Button tooltip
public void setButtonTooltip(String tooltipText)
{
this.btnTooltip = tooltipText;
}

// Draw the button on the screen
public void drawButton()
{
// Set the button colour
fill(this.btnColour);

// Draw the button
rect(this.btnTopX, this.btnTopY, this.btnWidth, this.btnHeight);

// Draw the button image
if (this.btnImage != null)
{
image(this.btnImage, this.btnTopX, this.btnTopY);
}

// Draw the button label if the text is defined (not blank)
if (! this.btnText.equals(""))
{
// Select the font for the text
textFont(btnFont,12);

// Set the colour to white
fill(255);

// Calculate the horizontal centre of the button, then subtract half
// the width of the button label to find the starting position
float textX = (this.btnTopX + this.btnWidth / 2) - (textWidth(this.btnText) / 2);

// Calculate the vertical centre of the button
float textY = (this.btnTopY + this.btnHeight / 2) + 6;

// Output the text
text(this.btnText, textX, textY);
}
}

// Check if the mouse is currently positioned over the button
private boolean isMouseOver() {
if (mouseX >= this.btnTopX && mouseX <= this.btnTopX + this.btnWidth &&
mouseY >= this.btnTopY && mouseY <= this.btnTopY + this.btnHeight) {
return true;
}
else {
return false;
}
}

// Check the location of the mouse in relation to the
// button and set instance variables accordingly
private void checkMouse()
{
// Check if the mouse is over the button
boolean mOver = this.isMouseOver();

// If the mouse is over the current button
if (mOver == true)
{
// If the mouse was not already over the button
// set the start and stop counters for the
// tooltip, if we have a tooltip defined
if (this.mouseOver == false)
{
if (!this.btnTooltip.equals(""))
{
this.btnStartTooltip = 100;
this.btnStopTooltip = 500;
}
}
else
{
// The mouse pointer was already over this button so
// provided we have a tooltip defined we should be
// counting down to tooltip counters
if (!this.btnTooltip.equals(""))
{
// Provided the counter is greather than zero
// subtract one from the counter
if (this.btnStartTooltip > 0) {this.btnStartTooltip--;}
if (this.btnStopTooltip > 0) {this.btnStopTooltip--;}
}
}
}
else
{
// The mouse pointer was over this button but it is not
// now so provided we have a tooltip defined we should
// reset the tooltip counters
if (this.mouseOver == true && !this.btnTooltip.equals(""))
{
this.btnStartTooltip = 0;
this.btnStopTooltip = 0;
}
}

// Mark the button to indicate if the mouse is over it
this.mouseOver = mOver;

// If the mouse is over the button and we have a mouse over
// image defined, set the button image accordingly.
// Otherwise set to the standard image
if (this.mouseOver && this.moverImage != null)
{
this.btnImage = this.moverImage;
}
else
{
this.btnImage = this.stdImage;
}

// If the mouse is over the button and we have a mouse over
// colour defined, set the button colour accordingly.
// Otherwise set to the standard colour
if (this.mouseOver && this.moverColour != -1)
{
this.btnColour = this.moverColour;
}
else
{
this.btnColour = this.stdColour;
}

}

// Check if this button should have a tooltip displayed
// for it and display accordingly
private void tooltip()
{
int textWidth;
// If the mouse is over this button, and the tooltip is not
// an empty string, and the tooltip start countdown is zero
// and the tooltip stop countdown is not zero we should
// display the tooltip
if (this.mouseOver == true && ! this.btnTooltip.equals("") &&
this.btnStartTooltip == 0 && this.btnStopTooltip != 0)
{
// Select the font we will use for tooltips
textFont(tooltipFont,9);

// Calculate the width of the text we want to display
float textW = textWidth(this.btnTooltip) + 10;

// Choose the pale yellow background colour for the tooltip
fill(241,253,191);

// Draw the rectangle in which to display the tooltip text
rect( mouseX + 10, mouseY - 20, textW, 20);

// Change the colour to black
fill(0);

// Calculate the X and Y position to ensure the tooltip text is
// aligned in the centre of the tooltip rectangle
float textX = (mouseX + 10 + (textW / 2));
textX = textX - (textWidth(this.btnTooltip) / 2);
float textY = (mouseY - 20 + 10 ) + 4.5;

// Display the tooltip text
text(this.btnTooltip, textX, textY);
}
}

}

No comments:

Post a Comment