USE java.util.HashMap
USE java.util.TreeSet
rem 'Obtain the instance of the BBjAPI object
let myAPI!=BBjAPI()
rem 'Open the SysGui device
SYSGUI=UNT
OPEN (SYSGUI)"X0"
rem 'Obtain the instance of the BBjSysGui object
let mySysGui!=myAPI!.getSysGui()
rem 'Set addWindow param values
X=200
Y=200
WIDTH=350
HEIGHT=250
TITLE$="Birthday Finder"
rem 'Set the current context
mySysGui!.setContext(0)
rem 'Create a window
myWindow! = mySysGui!.addWindow(X,Y,WIDTH,HEIGHT,TITLE$,$00010083$)
rem 'All our dates are in 2006
startDate = JUL(2006, 1, 1)
endDate = JUL(2006, 12, 31)
rem 'Mask in numeric precedence order
myDateMask$ = "%Y-%Mz-%Dz"
rem 'Create date range for data.
myLowDate! = myWindow!.addInputDSpinner(101, 10, 10, 100, 25, $$, myDateMask$)
if (myLowDate!.getMinimumDate() <> startDate)
myLowDate!.setMinimumDate(startDate)
endif
if (myLowDate!.getMaximumDate() <> endDate)
myLowDate!.setMaximumDate(endDate)
endif
myLowDate!.setValue(startDate)
if (myLowDate!.getSpinField() <> myLowDate!.MONTH)
myLowDate!.setSpinField(myLowDate!.MONTH)
endif
myHighDate! = myWindow!.addInputDSpinner(102, 120, 10, 100, 25, $$, myDateMask$)
if (myLowDate!.getMinimumDate() <> startDate)
myLowDate!.setMinimumDate(startDate)
endif
if (myLowDate!.getMaximumDate() <> endDate)
myLowDate!.setMaximumDate(endDate)
endif
myHighDate!.setValue(endDate)
if (myHighDate!.getSpinField() <> myHighDate!.MONTH)
myHighDate!.setSpinField(myHighDate!.MONTH)
endif
rem 'Create date of event
myEventDate! = myWindow!.addInputD(103, 10, 45, 100, 25, $$, myDateMask$)
myEventDate!.setText(" ")
rem 'Create edit box for event name
myEditBox! = myWindow!.addEditBox(104, 120, 45, 120, 25, $$)
rem 'Create list box for the list of valid events
myList! = myWindow!.addListBox(105, 10, 80, 140, 100, $$)
rem 'Create buttons for date range
mySqueeze! = myWindow!.addButton(106, 250, 10, 90, 25, "Squeeze")
myExpand! = myWindow!.addButton(107, 250, 45, 90, 25, "Expand")
rem 'Set callbacks
myWindow!.setCallback(myWindow!.ON_CLOSE,"APP_CLOSE")
myLowDate!.setCallback(myLowDate!.ON_SPIN, "LOW_SPIN")
myHighDate!.setCallback(myHighDate!.ON_SPIN, "HIGH_SPIN")
myList!.setCallback(myList!.ON_LIST_DOUBLE_CLICK, "SELECT_EVENT")
mySqueeze!.setCallback(mySqueeze!.ON_BUTTON_PUSH, "SQUEEZE_RANGE")
myExpand!.setCallback(myExpand!.ON_BUTTON_PUSH, "EXPAND_RANGE")
rem 'Set callbacks for fast spin response
myAPI!.setCustomEventCallback("low_spin_started", "LOW_SPIN_STARTED")
myAPI!.setCustomEventCallback("high_spin_started", "HIGH_SPIN_STARTED")
rem 'Setup data structures for events
myEvents! = new TreeSet()
myEventDates! = new HashMap()
rem 'Populate data structures and myList!
GOSUB ADD_EVENTS
GOSUB DO_FILTER
lowSpin = 0
highSpin = 0
process_events
rem 'Callback for myLowDate! ON_SPIN
LOW_SPIN:
rem 'Get BBjSpinEvent
ev! = myAPI!.getLastEvent()
rem 'Get text and convert to date
date$ = ev!.getText()
lowDate = NUM(date$)
rem 'Set a new minimum for myHighDate! to be our current date.
myHighDate!.setMinimumDate(lowDate)
rem 'while receiving spin events, keep adding to the counter
lowSpin = lowSpin + 1
rem 'Post custom event, which will decrement the counter until 0
rem 'then it will update myList!
myAPI!.postCustomEvent("low_spin_started", NULL())
return
rem 'Callback for "low_spin_started"
LOW_SPIN_STARTED:
rem 'Decrement counter
lowSpin = lowSpin - 1
rem 'When it reaches zero, filter the list and reset the displayed values
if (lowSpin = 0)
GOSUB DO_FILTER
endif
return
rem 'Callback for myHighDate! ON_SPIN
HIGH_SPIN:
rem 'Get BBjSpinEvent
ev! = myAPI!.getLastEvent()
rem 'Get text and convert to date
date$ = ev!.getText()
highDate = NUM(date$)
rem 'Set a new maximum for myLowDate! to be our current date.
myLowDate!.setMaximumDate(highDate)
rem 'while receiving spin events, keep adding to the counter
highSpin = highSpin + 1
rem 'Post custom event, which will decrement the counter until 0
rem 'then it will update myList!
myAPI!.postCustomEvent("high_spin_started", NULL())
return
HIGH_SPIN_STARTED:
rem 'Decrement counter
highSpin = highSpin - 1
rem 'When it reaches zero, filter the list and reset the displayed values
if (highSpin = 0)
GOSUB DO_FILTER
endif
return
SELECT_EVENT:
rem 'Get the currently selected index
index = myList!.getSelectedIndex()
rem 'Get the event
eventName$ = myList!.getItemAt(index)
rem 'Get the time
myDate = myEventDates!.get(eventName$)
rem 'Show them in the "detail" fields
myEditBox!.setText(eventName$)
myEventDate!.setValue(myDate)
return
rem 'Callback for Squeeze button
SQUEEZE_RANGE:
rem 'Get the next and previous, and spin if there's room to spin.
nextLow = myLowDate!.getNextDate()
prevHigh = myHighDate!.getPreviousDate()
if (nextLow <> -1 AND prevHigh <> -1)
rem 'Prefer squeezing higher dates, if we can only move one.
if (nextLow < prevHigh)
myLowDate!.spin(1)
endif
myHighDate!.spin(0)
endif
rem 'spin doesn't cause event, so we have to manually filter
GOSUB DO_FILTER
return
rem 'Callback for Expand button
EXPAND_RANGE:
prevLow = myLowDate!.getPreviousDate()
nextHigh = myHighDate!.getNextDate()
if (prevLow <> -1)
myLowDate!.spin(0)
endif
if (nextHigh <> -1)
myHighDate!.spin(1)
endif
rem 'spin doesn't cause event, so we have to manually filter
GOSUB DO_FILTER
return
rem 'Callback for window close box
APP_CLOSE:
release
rem 'Subroutine to filter the contents of myList!
DO_FILTER:
rem 'Get the ends of the sequence.
lowDate = myLowDate!.getValue()
highDate = myHighDate!.getValue()
rem 'Use the TreeSet to filter the sequence by date.
eventsFiltered! = myEvents!.subSet(STR(lowDate:myNumMask$), STR(highDate + 1:myNumMask$))
rem 'Make a vector to set as the data for myList!
vec! = myAPI!.makeVector()
rem 'Iterate through and only add the events in the filtered list
iter! = eventsFiltered!.iterator()
maskLen = LEN(myNumMask$)
while (iter!.hasNext())
key$ = iter!.next()
rem 'Strip off the date part
key$ = key$(maskLen + 1)
vec!.add(key$)
wend
rem 'Remove all the existing events and set the new ones.
myList!.removeAllItems()
myList!.insertItems(0, vec!)
rem 'Don't forget to let go of the references
vec! = NULL()
return
rem 'Subroutine to set the initial events
ADD_EVENTS:
rem 'This mask will allow the julian to sort lexigraphically
myNumMask$ = "0000000000"
rem 'Add all the dates
dummy = fnAddEvent("Jim", JUL(2006, 1, 25))
dummy = fnAddEvent("Laura", JUL(2006, 2, 5))
dummy = fnAddEvent("Catherine", JUL(2006, 2, 28))
dummy = fnAddEvent("John", JUL(2006, 3, 10))
dummy = fnAddEvent("Ian", JUL(2006, 4, 13))
dummy = fnAddEvent("Bob", JUL(2006, 5, 7))
dummy = fnAddEvent("Stephen", JUL(2006, 6, 28))
dummy = fnAddEvent("Jason", JUL(2006, 7, 6))
dummy = fnAddEvent("Edna", JUL(2006, 8, 9))
dummy = fnAddEvent("Stephanie", JUL(2006, 9, 17))
dummy = fnAddEvent("Tara", JUL(2006, 10, 12))
dummy = fnAddEvent("Joe", JUL(2006, 12, 12))
return
rem 'Add a single event
DEF fnAddEvent(event$, date)
rem 'Add the events so they'll sort by date in the TreeSet
myEvents!.add(STR(date:myNumMask$) + event$)
rem 'To provide lookup by name, put the events in the eventDates! map
myEventDates!.put(event$, date)
return 0
FNEND
|