#!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP #!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP

3D
3D Photo Gallery (Part 1)
3D Photo Gallery (Part 2)

Audio
Poor Man's MIDI
Make A Metronome
iPod Tricks (Part 1)
iPod Tricks (Part 2)
iPod Tricks (Part 3)
Laugh Track Machine
Audio Player with Reverb
Shepard Melody
RB Phone Home
Build a Drum Machine

Custom Controls and Windows
Double Click Listbox
Draggable Metal Window
Double Click Canvas
Custom Buttons
Custom Buttons Part II
iTunes-style Listboxes
Custom Controls


General RB
Scrolling Windows
Using Mesage Dialogs
Case-Sensitive Word Finder
Introduction to Stacks
Wiggle Window
JPEG in PDF
Listbox Checkboxes
Background Applications
Listbox Auto-Find
Virtual Volumes
Time Tracker
Software Distribution (Part 1)
Software Distribution (Part 2)
Software Distribution (Part 3)
Software Distribution (Part 4)
Exceptions
Tips and Tricks
Text Clippings Made Easy

Graphics
Drawing a Simple Gradient
The SpriteSurface: Space Game
Image Spinner
Cropping Graphics (Part 1)
Cropping Graphics (Part 2)
Cropping Graphics (Part 3)
Cropping Graphics (Part 4)
Shimmer Graphics
Lissajous Figures
Simple Screen Capture
Vector Graphics
Kaleidoscope Images
Stegonography
Spirals!
Image Table
RB Magnifying Lens
Screen Capture
Color Picker Tutorial

Hacks
Ghost Grab
Speedy Mouse Extension
iTunes Plugins
iTunes Skinner

Mac OS X
Global Hot Key Event (Carbon Events)
Login Welcomer (Carbon Events)
Add/Remove Buttons
Resizable Sheets
Mac OS X Preferences Window
Using Sheets in REALbasic
Build a Bundle (Part 1)
Build a Bundle (Part 2)
Dock Your Passwords
Mac OS X Debugging
REALbasic Mac OS X Icon Tutorial
Animate Your Dock
RB and the Command Line

Menus
Window Menu
Templates Menu
Listbox Menu

Novelty
Guessing Game
Calendar Trivia
Tile Mixer
Zip Code Finder
Happy Valentine's Day
Merlin Simulator (Part 1)
Merlin Simulator (Part 2)
Merlin Simulator (Part 3)
Buzzword Machine
AppleSoft BASIC

Printing
Print to PDF

Registration
Registration Code Validation
Network Registration Codes

Resources
Picture Extractor (Part 1)
Picture Extractor (Part 2)

Serial
Caller ID (Part 1)
Caller ID (Part 2)
Caller ID (Part 3)

Speech
Speech Recognition

Socket Communication
Easy Peer-to-Peer File Sharing
MacPAD Version Checking
Display Web Image In Canvas
HTML IMG Tags
Version Tracking
Even Smarter Instant Messaging
Web Tiler
JavaScript and REALbasic
Stock Ticker (Part I)
Stock Ticker (Part 2)
AIM Mate

XML Manipulation
Simple XML Introduction

Video
Big Brother Video Capture

Note: All articles without a byline were written by Erick Tejkowski. When cleaning the site I removed them because the code differed from page to page, and I have yet to put them back in.

resexc2.gif (20k)




REALbasic for Dummies
by Erick Tejkowski

$19.99 @ Amazon





Files are in Stuffit 6.5 or earlier, or ZIP format.
Download Stuffit Expander

Tell us about a bad link.

Custom Pushbuttons by Seth Willits
09-03-03




Hi everyone! I can't express how excited I am about having this position on the ResExcellence site. Writing about and helping others learn REALbasic has always been something I like to do, so I hope this turns out to be a blast!Now, normally there would be only a news update today, but I'm going to change things around a little and start off with the first half of this week's tutorial. Yes, you read that correctly; the first half. Contrary to what Erick has done in the past, I will be writing a lot of tutorials of varying length instead of "feature explainers." In doing this, I hope that you and new readers alike will find the information helpful and practical.This two-part tutorial will explain and demonstrate creating custom buttons with the Canvas control. Part 1 will cover how to create a simple rectangular button (like a bevel button) which behaves in the same manner as any standard OS button.The button we're going to build will be built as a customized canvas subclass. (If you don't know anything about objects and classes, I'm sorry. Seriously though, knowledge of object-oriented programming is pretty much a prerequesite for most, if not all, of the tutorials.)Analyzing the logic of a button, these are the things we want to accomplish:
  • User clicks within button - image changes to depressed state
  • User releases mouse within button - image changes to normal "up" state, and action event is fired
  • User moves mouse outside of button while the mouse is down - button's image and state return to "up"
  • User moves mouse back inside of button while the mouse is down - button's image and state return to "down"
These are the four basic components of a button.So let's begin by creating a new project and canvas subclass named "CButton". Lets add a "Draw" method and a few new properties: "mState as string", "mDownImage as picture", and "mUpImage as picture". The Draw method will solely be used to draw our button's image. What happens is the Paint event will actually call the Draw method in addition to when we call it directly from other events such as MouseDown. mState will be used to keep track of whether the button is "up" or "down". (In the next part of this tutorial you'll understand why I'm using a string.) The two image properties are self explanitory.The Draw method's purpose is to simply check which state the button is in (via the mState property) and draw the appropriate picture property. However, we also need to make sure that we don't attempt to use a picture that's currently "nil", so we'll need to test for that. Although unlikely to happen, the user (yourself), can forget to set the image properties, so instead of crashing, lets just gracefully handle the error by not drawing anything. In code, this looks like:



Also don't forget we need to draw something when the Paint event is fired, so we call the Draw method.



One important thing to note is that we need to set the mState property to have an initial value of "up". If we don't set the state, then nothing will be drawn! Also, we need to set which images to use for the up and down appearances of the button. Assuming we have two pictures dropped into our project window named "PicButtonDown" and "PicButtonUp", the code for the Open event of the CButton class will be:



You can go ahead and download these two images and use them in your project as we go. They're already named appropriately, so just drag them into your project.

    


Let's test what we have so far, shall we? Go ahead and drag the CButton class from the project window into the Window Editor for the window in our project. This creates an instance of the CButton class named CButton1 in the window. Unfortuantely REALbasic doesn't have a feature to do it for us, so you'll have to do it manually, but resize the CButton1 control to be the same width and height of the button images dropped in the project. For the images above, this will be 120 wide and 40 high. Once you've done that, go ahead and hit Cmd-R, Ctr-R for you Windows users, and when the project's done compiling you'll our button! The obvious thing missing is that it's not clickable, so let's work on that now.Go back to the CButton class, and create a new event named "Action". This is the event that will be used in the instance to handle clicks on the button. In the MouseDown event we're going to need to return "true" to signal that we want a MouseUp event to fire when the mouse button is released. However, we also want to set the button's state to "down" and redraw the button so it appears pressed. The code:



So far this completes objective 1 of our tutorial: When the button is clicked, it appears in a depressed state. Objective 2 is to return the state to "up" and fire the Action event when the mouse button is released within the button. To do that, we'll use -- go ahead and guess -- the MouseUp event. Since we want to test whether the cursor was inside the button when the mouse button was released, we're going to test the x and y parameters to the MouseUp event against 0 which is the value for the left side and top sides of the button, and Width and Height, the width and height of the button. For example, if x < 0 then the mouse's x position was outside of the button to the left. If x > Width, then the mouse's x position was outside of the button to the right. Thus we conclude that if x > 0 and x < Width, then the mouse's X position is within the bounds. We also need to test whether the Y position is in the bounds and we do it the same way:



Now what we want to do is add to that comment the action that applies to it. If the mouse is inside the button, we call the Action event. Note that regardless of the position of the mouse when the mouse button is released, we'll always want to set the state to "up" and redraw the button. Although the Action event isn't called if the mouse was outside of the button, it'd be very strange behavior if it also stayed down! The final code for the MouseUp event is:



Let's test our work so far. Travel back to the window containing the CButton instance, open it up, and add "beep" inside the now-existent Action event of the button. Go ahead and run the project and click on the button. It beeps! Take notice that it goes down and returns to its original state. Now click the button, and, while holding the mouse button down, move the cursor outside of the button. You'll notice that that the button's state doesn't switch to "up". If you release the mouse button, you'll notice that the program, correctly, does not beep.So how do we set the button's state based on where the cursor position is while the mouse button is down? We do this in the MouseDrag event using the same test to determine the cursor's position as in the MouseUp event. Although the test is the same, what we do with either result of the test (inside or outside) is different. This time we'll only want to draw the button in the "up" state if the cursor is *outside* of the button, not everytime and certainly not when it's inside. Conversely, we draw the button in the "down" state everytime the cursor is inside the button. The code for the MouseDrag event would therefore be this:



Once you've typed that in, go ahead and run the project again. Now you have a completely working customized push button which behaves in the same manner as standard operating system buttons.Next time we'll explore how to create buttons with the "toggle" and "sticky" behaviors and apply these to buttons such as a custom checkbox or radio button. Plus, we'll discuss how to optimize the code I've presented. Think you know what's "wrong" with it? If you do, email me and I'll give honorable mention to the first person to answer correctly. I really hope you've found this first part of the tutorial and my career here at ResExcellence informative and just at the right level of explaining how it works. If you have any suggestions or comments, please don't hesitate to email me.You can download the REALbasic 5.2 project for this part of the tutorial here. See you next time!






Please support ResExcellence by Visiting our Sponsors. One click makes a difference.


Download REALbasic and create your own software!

#!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP #!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP