Description: This is a variation of the EditField class. It makes it so when the user begins to type in the editfield, Grayedit will attempt to "autofinish" what the user is typing. The new text is displayed in gray, just like autocomplete variables within the REALbasic IDE. Pressing tab or return fills in the full word in black. Typing more letters or deleting might change the autocomplete word being displayed.
In the picture above, a Grayedit field is finishing typing the name of a font for me.
To use Grayedit in your own projects, just drag the Grayedit class out of the demo project and into your own. Change an editField to Grayedit and make sure you check "styled" in the Grayedit's property window. You'll need to intialize the Grayedit's list of items array before use -- see the example project on how to do that. NOTE: as part of that initialization, you'll want to sort the array. Grayedit won't work correctly without the items being sorted. This is simple with REALbasic's "array.sort" command.
Download Grayedit: Grayedit (10K download, stuffed and binhexed)
Grayedit (9K download, ZIP file)
Type: Project (application)
Description: This is a silly program I did for fun, but it demonstrates several useful techniques, most obviously a terrific way to load and save preferences. The big problem I find with most techniques on saving preference files is that if you change something within the program -- add a new feature or delete something -- it can really mess up your pref system. If your program tries to read in data from an old version of the prefs file, it could cause serious errors.
My approach is label each piece of data with a unique name. Like "windowlocation," for instance. Then if you change the window location information your program saves (say you now want to save not only the size and location but the state, like which items were selected when the user closed the window), you can simply name the new version "windowlocs" or something. Then your program can handle both types of data (or ignore the one it doesn't understand).
Best of all, I include all the routines necessary to parse these types of files, making it a snap to implement prefs in your own programs. The procedure should be easy to understand when you see how I've implemented within this demo.
Best of all, the prefs files created by this system are ordinary text files. This makes them easy to view and edit. (You can, of course, change the type and creator codes used if you'd rather users didn't have the ability to edit your prefs file directly.)
For instance, here's the prefs file from my Z-Write application:
My routines automatically separate the label from the settings info. You simply add "case" statements for each label and then parse the setting data as needed. For instance, translate "false" by assigning false to a boolean variable.
Oh, and what does TacoCalculator do, you ask? It will memorize items and prices (storing them in a preferences file), and then tell you how many items a dollar value equals. For instance, if you tell it a taco costs 59 cents and your rent is $500 a month, TacoCalculator will tell you that your rent is 847 tacos!
It's not useful by any means, but it's fun new way to look at the world. As an experiment, see how many "tacos" you get paid per hour!
Download Tacocalculator: Tacocalculator (8K download, stuffed and binhexed)
Type: Module and Window (RB2)
Description: This provides you with a popup calendar where the user can select a date. I've modeled it after the popup calendar on the Palm Pilot. It handles years between 1500-2399. It's also set up with Constants for the month names, so it should be ready for easy localization.
To use this in your own projects, drag the CalendarModule and CalendarWindow items into your project. Then call the calendar with a CalendarWindow.showModal command. There's a global variable called "gReturnDate" (of type Date) that contains the date the user selects. If you set this date before you call the calendar, the calendar will open with that date selected.
This window is a tad slow, especially on slow machines. That's because I went the easy route and created the calendar with a button array. It would be faster to write a custom canvas that draws everything, but a lot more work. Even on a slow machine it just takes a second or so to switch between months. If anyone can figure out a way to speed it up, let me know!
This version is one I wrote before I realized that REALbasic would let you modify the date variable -- you just have to update it with a "d.totalSeconds = d.totalSeconds" command for changes to take effect. So the algorithm for finding the starting day of the month is entirely hard-coded. I later modified it by using REALbasic's date feature and it worked in just a few lines of code, but didn't seem any faster, and the accuracy seemed the same.
According to my tests, it's Y2K compliant, but there's always room for bugs, so let me know if you find any problems. This is especially true for international users.
Download Calendar Popup: Calendar Popup (11K download, stuffed and binhexed)
Listbox Column Resize
Type: Class (RB2)
Description: I like the new Headers feature of the Listboxes in REALbasic 2, but I wanted them to be resizable, like the Finder list views in Mac OS 8.5. So I created this custom Canvas Class which allows this (since only canvases accept mousedrags).
As you'll see in the example project, you make the canvas the exact same size as your listbox, and in the canvas's Open event, you must initialize the canvas by telling it which listbox you are linking it with. (There's no error-checking within the class: if the "theList" property is not defined [nil], the class will crash.) After that, it just works. It works with any number of columns. (You can modify the number of columns in the example to see how it works.)
There's one other property in the resizelistcolumn class you can set: the "liveResize" property. This will switch the class from resizing the columns as you drag to drawing a vertical resize line showing the new position of the column. In my example project there's a checkbox which sets this, so you can try it out and use whichever method you like better.
NEW 2.0 VERSION
This version incorporates a number of significant changes. First, it includes the updates that Guillaume Grenier sent me, to allow ResizeList to work with Percent values within the column widths. Second, I have made modifications to allow the user to change the order of the columns, similar to the way you can rearrange the column order in Finder 8.5!
This latter complicated things greatly, and there are still some obvious problems. Unfortunately, I will be very busy the next few days and so I won't have much time to work on this, but I thought some of you RBers might want to take a crack at mucking with my code. My brain hurts!
Another change, necessitated by the column rearrange feature, is to make it so that the user can't make the columns too big. This half-works right now (that is, it works in most cases, but occasionally does not). The problem deals with how RB handles column widths: if the total of your column is too big or too small, RB automatically shrinks/expands the rightmost column. This causes a problem because RB doesn't report the size as being different -- it just is visually. This causes a display bug, where the user drags a 1" wide column which on the screen looks like it's 3" wide. Since RB won't tell me the true size of the column, I'm attempting to take over this resize adjustment myself, with dubious results.
Here are the new changes.
- resizerZone property -- integer. Represents in pixels the width of resize column area.
- allowColumnDrag property -- boolean. If true, user can rearrange column order
- sortingOff property -- boolean. If true, clicks in headers don't register.
- dragDelay -- integer. Represents in ticks the delay after clicking in header before user gets a grabber hand and can rearrange column order. Default is 30 (half-second). Any mouseup in less than 30 ticks is passed on as a mousedown. (Has no effect unless allowColumnDrag is set to true.)
- returnHeader(string) as integer. Since the user can now shuffle your columns around, you need a way to find out which column is which. This routine accepts the name of a column (the column title) and returns the current number of that column. (This assumes all column names are different.)
(I've added a popup menu to the demo project, showing this in action. It has a list of column names in it. Choosing any column displays the number of that column. Rearrange the columns and see that the popup returns the new, correct column number.)
As this is a BETA, there are two routines in place:
The BETA routine is the one where I'm attempting to control the size of the columns (so the user can't make them too big). The SAFE routine works, but has the display bug mentioned above. You can use either one.
Download Listbox Column Resize: Listbox Column Resize (6K download, stuffed and binhexed)