286 lines
9.8 KiB
Rexx
Executable File
286 lines
9.8 KiB
Rexx
Executable File
/*----------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
|
|
/* Copyright (c) 2005-2014 Rexx Language Association. All rights reserved. */
|
|
/* */
|
|
/* This program and the accompanying materials are made available under */
|
|
/* the terms of the Common Public License v1.0 which accompanies this */
|
|
/* distribution. A copy is also available at the following address: */
|
|
/* https://www.oorexx.org/license.html */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or */
|
|
/* without modification, are permitted provided that the following */
|
|
/* conditions are met: */
|
|
/* */
|
|
/* Redistributions of source code must retain the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer. */
|
|
/* Redistributions in binary form must reproduce the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer in */
|
|
/* the documentation and/or other materials provided with the distribution. */
|
|
/* */
|
|
/* Neither the name of Rexx Language Association nor the names */
|
|
/* of its contributors may be used to endorse or promote products */
|
|
/* derived from this software without specific prior written permission. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
|
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
|
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
|
|
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
|
|
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
|
|
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
|
|
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
|
/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
|
|
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
|
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* oowalker.rex Animation demonstration (using a .rc file for the dialog
|
|
* template.)
|
|
*
|
|
* The only real difference between this sample and the oowalk2.rex sample is
|
|
* the way the bitmaps for the animation are loaded. Look at the initDialog()
|
|
* method of the .WalkerDialog to see this difference.
|
|
*
|
|
* An animated button is used to simulate a man walking across the dialog. The
|
|
* user can adjust the pace of the waling by setting the amount the man is
|
|
* moved each time the button is redrawn and the delay between redrawing the
|
|
* button. The button is drawn using a sequence of bitmaps that show the man
|
|
* with different leg and arm positions. The user can also set how the man
|
|
* 'walking' off the edge of the dialog is handled, smoothly or bouncy, by
|
|
* using the "smooth corner wrap" check box.
|
|
*
|
|
* A 'got cha' point (!!!) is periodically drawn and if the man is close enough
|
|
* to this 'danger,' the man is 'gotten' and the animation is stopped. Each
|
|
* time the button is drawn, the !!! is over-drawn, so the !!! is only seen
|
|
* as a flicker.
|
|
*
|
|
* Normally the dialog ends when the walker is gotten. However there is a
|
|
* check box that allows the user to cancel this behavior and then restart the
|
|
* animation.
|
|
*/
|
|
|
|
srcDir = locate()
|
|
|
|
.application~useGlobalConstDir('O', srcDir"rc\walker.h")
|
|
dlg = .WalkerDialog~new(srcDir"rc\walker.rc", , data.)
|
|
|
|
if dlg~initCode \= 0 then do
|
|
return 99
|
|
end
|
|
dlg~execute("SHOWTOP")
|
|
|
|
return 0
|
|
|
|
/*---------------------------- requires -----------------------------*/
|
|
|
|
::requires "ooDialog.cls"
|
|
::requires "samplesSetup.rex" -- For sound path
|
|
|
|
/*---------------------------- walker dialog ------------------------*/
|
|
|
|
::class 'WalkerDialog' subclass RcDialog
|
|
|
|
::method initDialog
|
|
expose bitmaps spriteButton quitCheckBox restartButton okButton
|
|
|
|
-- Make button 105 a bitmap button. Bitmap buttons are owner-drawn and
|
|
-- ooDialog will manage the 'drawing' of the button by painting a series of
|
|
-- bitmaps on the button, using the AnimatedButton class.
|
|
self~installBitmapButton(105, '', 0);
|
|
|
|
-- Load the bitmaps from the bitmap files into an array.
|
|
bitmaps = .array~new(8)
|
|
do i= 1 to 8
|
|
bitmaps[i] = self~loadBitmap(.application~srcDir"bmp\wlkfig"i".bmp")
|
|
end
|
|
|
|
-- Create the animated button class and pass the array of bitmaps.
|
|
spriteButton = .WalkButton~new(105, bitmaps, 0, 10, 2, 70, 120, 60, 10, 10, self)
|
|
|
|
-- Use 'bouncy' operation when hitting edges.
|
|
spriteButton~setSmooth(.false)
|
|
|
|
-- Get things set up.
|
|
self~connectButtonEvent(107, "CLICKED", onRestart)
|
|
quitCheckBox = self~newCheckBox(106)
|
|
restartButton = self~newPushButton(107)
|
|
okButton = self~newPushButton(IDOK)
|
|
quitCheckBox~check
|
|
spriteButton~fillData(data.)
|
|
spriteButton~suspendGotCha(.false)
|
|
self~setDataStem(data.)
|
|
ret = Play("tada.wav", n)
|
|
|
|
-- Animate the button.
|
|
spriteButton~run
|
|
|
|
::method doDataStemGet unguarded
|
|
use strict arg data.
|
|
self~getDataStem(data.)
|
|
|
|
::method doDataStemSet unguarded
|
|
use strict arg data.
|
|
self~setDataStem(data.)
|
|
|
|
::method onGotCha
|
|
expose okButton
|
|
use strict arg animatedButton, x, y
|
|
okButton~disable
|
|
self~writetoButton(105, x, y, "Got-cha", "Arial", 28, "BOLD")
|
|
ret = play('gotcha.wav')
|
|
animatedButton~stop
|
|
call msSleep 1000
|
|
|
|
::method maybeQuit
|
|
expose quitCheckBox restartButton okButton
|
|
if quitCheckBox~checked then return self~ok
|
|
|
|
restartButton~enable
|
|
okButton~enable
|
|
|
|
::method onRestart
|
|
expose spriteButton restartButton
|
|
restartButton~disable
|
|
spriteButton~stopped = .false
|
|
|
|
-- Suspend the 'GotCha' before we start the animated button. Otherwise the
|
|
-- walker will be 'gotten' as soon as he starts.
|
|
spriteButton~suspendGotCha(.true)
|
|
spriteButton~run
|
|
|
|
-- Give the walker time to 'walk' out of the danger zone before reactivating
|
|
-- the 'GotCha.'
|
|
delay = self~newEdit(103)~getText
|
|
j = msSleep(2 * delay)
|
|
spriteButton~suspendGotCha(.false)
|
|
|
|
::method ok
|
|
self~stopAnimation
|
|
return self~ok:super
|
|
|
|
::method cancel
|
|
self~stopAnimation
|
|
return self~cancel:super
|
|
|
|
::method stopAnimation private
|
|
expose bitmaps spriteButton
|
|
spriteButton~stop
|
|
|
|
-- Wait until the animation sequence is finished.
|
|
do while spriteButton~isRunning
|
|
j = msSleep(30)
|
|
end
|
|
|
|
-- Now it is safe to delete the bitmaps.
|
|
if bitmaps \== .nil then do i= 1 to 8
|
|
self~removeBitmap(bitmaps[i])
|
|
end
|
|
|
|
-- Be sure we don't free the bitmaps twice. The WalkButton will invoke
|
|
-- maybeQuit() which can cause stopAnimation() to be invoked twice.
|
|
bitmaps = .nil
|
|
|
|
|
|
/*------------------------------ animated button --------------------*/
|
|
|
|
::class 'WalkButton' subclass AnimatedButton
|
|
|
|
::method run
|
|
expose xDanger yDanger running
|
|
xDanger = 300; yDanger = 70; running = .true
|
|
|
|
reply 0
|
|
|
|
do until(self~stopped = 1) | (self~parentStopped = 1)
|
|
self~doAnimatedSequence
|
|
end
|
|
|
|
-- Have the walker do one more sequence, gives the appearance of walking 'in
|
|
-- in place.'
|
|
self~doAnimatedSequence
|
|
|
|
-- We are no longer running, tell the parent dialog to maybe quit.
|
|
running = .false
|
|
self~parentDlg~maybeQuit
|
|
|
|
::method doAnimatedSequence private
|
|
expose xDanger yDanger
|
|
|
|
self~moveseq
|
|
self~parentDlg~doDataStemGet(data.)
|
|
do k over data.
|
|
if data.k~datatype('N') = 0 then data.k = 0
|
|
end
|
|
self~setmove(data.101, data.102)
|
|
self~setdelay(data.103)
|
|
self~setsmooth(data.104)
|
|
if self~stopped = 0 then
|
|
self~parentDlg~writetoButton(105,xDanger,yDanger,"!!!","Arial",20,"BOLD")
|
|
|
|
::method isRunning unguarded
|
|
expose running
|
|
return running
|
|
|
|
::method suspendGotCha unguarded
|
|
expose gotCha
|
|
use strict arg suspend
|
|
if suspend then gotCha = .false
|
|
else gotCha = .true
|
|
|
|
::method hitright
|
|
ret = play('ding.wav', 'YES')
|
|
return 1
|
|
|
|
::method hitleft
|
|
ret = play('ding.wav', 'YESY')
|
|
return 1
|
|
|
|
::method hitbottom
|
|
self~getsprite(s.)
|
|
ret = play('chord.wav', 'YES')
|
|
s.movey = -s.movey
|
|
self~setsprite(s.)
|
|
self~fillData(data.)
|
|
self~parentDlg~doDataStemSet(data.)
|
|
return 0
|
|
|
|
::method hittop
|
|
expose sprite.
|
|
self~getsprite(s.)
|
|
ret = play('chimes.wav', 'YES')
|
|
s.movey = -s.movey
|
|
self~setsprite(s.)
|
|
self~fillData(data.)
|
|
self~parentDlg~doDataStemSet(data.)
|
|
return 0
|
|
|
|
::method fillData
|
|
expose quitCheckBox
|
|
use arg data.
|
|
if \ quitCheckBox~isA(.CheckBox) then quitCheckBox = self~parentDlg~newCheckBox(106)
|
|
self~getSprite(msprite.)
|
|
data.101 = msprite.movex
|
|
data.102 = msprite.movey
|
|
data.103 = msprite.delay
|
|
data.104 = msprite.smooth
|
|
|
|
if quitCheckBox~checked then data.106 = 1
|
|
else data.106 = 0
|
|
|
|
::method movepos
|
|
use arg px, py
|
|
if self~stopped=0 then do
|
|
self~movepos:super(px,py)
|
|
self~checkDanger
|
|
end
|
|
|
|
::method checkDanger
|
|
expose xDanger yDanger gotCha
|
|
self~getpos(cur.)
|
|
if abs(cur.x+10-xDanger) <= 10 & abs(cur.y+55-yDanger) <= 30 then do
|
|
if gotCha then self~parentDlg~onGotCha(self, xDanger-50, yDanger)
|
|
end
|