/*----------------------------------------------------------------------------*/ /* */ /* 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. */ /* */ /*----------------------------------------------------------------------------*/ /** * oowalk2.rex Animation demonstration (using a compiled binary resource * for the dialog template. A DLL file.) * * The only real difference between this sample and the oowalker.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~setDefaults('O', srcDir'rc\walker.h', .false) dlg = .WalkerDialog~new(srcDir'res\oowalk2.dll', IDD_WALKER) if dlg~initCode \= 0 then do mgr~goBack return 99 end dlg~execute("SHOWTOP") return /*---------------------------- requires -----------------------------*/ ::requires "ooDialog.cls" ::requires "samplesSetup.rex" /*---------------------------- walker dialog ------------------------*/ ::class 'WalkerDialog' subclass ResDialog ::method initDialog expose bitmaps spriteButton quitCheckBox restartButton okButton -- Make button IDC_DRAW_BUTTON 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(IDC_DRAW_BUTTON, '', 0); -- The bitmaps are loaded from the resource DLL by specifying their resouce -- IDs in the DLL file, res\oowalk2.dll. -- -- We use symbolic IDs for the bitmaps, and we assigned the IDs in order. -- In the new() method, the 2nd arg is the first bitmap ID and the 3rd is the -- last bitmap ID and they are assumed to be in order. The AnimatedButton -- class was never updated to accept symbolic IDs, so we need to convert the -- IDs to numeric IDs bmpFirst = .constDir[ID_BMP_FIG1] bmpLast = .constDir[ID_BMP_FIG8] spriteButton = .WalkButton~new(IDC_DRAW_BUTTON, bmpFirst, bmpLast, 10, 2, 70, 120, 60, 10, 10, self) -- Use 'bouncy' operation when hitting edges. spriteButton~setSmooth(.false) -- Size of the step through the bitmap IDs. spriteButton~setstep(1) -- Get things set up. self~connectButtonEvent(IDC_PB_RESTART, "CLICKED", onRestart) quitCheckBox = self~newCheckBox(IDC_CB_GOTCHA) restartButton = self~newPushButton(IDC_PB_RESTART) okButton = self~newPushButton(IDOK) quitCheckBox~check spriteButton~fillData(data.) spriteButton~suspendGotCha(.false) self~doValueStemSet(data.) ret = Play(srcDir"tada.wav", n) -- TODO not playing in Win7 -- Animate the button. spriteButton~run ::method doValueStemGet unguarded use strict arg data. data.IDC_EDIT_MOVEX = self~newEdit(IDC_EDIT_MOVEX)~getText data.IDC_EDIT_MOVEY = self~newEdit(IDC_EDIT_MOVEY)~getText data.IDC_EDIT_DELAY = self~newEdit(IDC_EDIT_DELAY)~getText if self~newCheckBox(IDC_CB_SMOOTH)~checked then data.IDC_CB_SMOOTH = 1 else data.IDC_CB_SMOOTH = 0 ::method doValueStemSet unguarded use strict arg data. self~newEdit(IDC_EDIT_MOVEX)~setText(data.IDC_EDIT_MOVEX) self~newEdit(IDC_EDIT_MOVEY)~setText(data.IDC_EDIT_MOVEY) self~newEdit(IDC_EDIT_DELAY)~setText(data.IDC_EDIT_DELAY) if data.IDC_CB_SMOOTH == 1 then self~newCheckBox(IDC_CB_SMOOTH)~check else self~newCheckBox(IDC_CB_SMOOTH)~uncheck ::method onGotCha expose okButton use strict arg animatedButton, x, y okButton~disable self~writetoButton(IDC_DRAW_BUTTON, 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(IDC_EDIT_DELAY)~getText j = msSleep(2 * delay) spriteButton~suspendGotCha(.false) ::method ok unguarded self~stopAnimation return self~ok:super ::method cancel unguarded 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 /*------------------------------ animated button --------------------*/ ::class 'WalkButton' subclass AnimatedButton ::method run unguarded expose xDanger yDanger running xDanger = 300; yDanger = 70; running = .true reply 0 do until self~stopped | self~parentStopped self~doAnimatedSequence end -- Have the walker do one more sequence, gives the appearance of walking 'in -- place.' self~doAnimatedSequence -- We are no longer running, tell the parent dialog to maybe quit. running = .false self~parentDlg~maybeQuit ::method doAnimatedSequence private unguarded expose xDanger yDanger self~parentDlg~doValueStemGet(data.) do k over data. if \ data.k~datatype('N') then data.k = 0 end self~moveseq self~setmove(data.IDC_EDIT_MOVEX, data.IDC_EDIT_MOVEY) self~setdelay(data.IDC_EDIT_DELAY) self~setsmooth(data.IDC_CB_SMOOTH) if \ self~stopped then self~parentDlg~writetoButton(IDC_DRAW_BUTTON,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~doValueStemSet(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~doValueStemSet(data.) return 0 ::method fillData expose quitCheckBox use arg data. if \ quitCheckBox~isA(.CheckBox) then quitCheckBox = self~parentDlg~newCheckBox(IDC_CB_GOTCHA) self~getSprite(msprite.) data.IDC_EDIT_MOVEX = msprite.movex data.IDC_EDIT_MOVEY = msprite.movey data.IDC_EDIT_DELAY = msprite.delay data.IDC_CB_SMOOTH = msprite.smooth if quitCheckBox~checked then data.IDC_CB_GOTCHA = 1 else data.IDC_CB_GOTCHA = 0 ::method movepos use arg px, py if \ self~stopped 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