Module 13: Drag and Drop
Copyright: C Wragg 2000

Unfinished business

Before we discuss the way in which we save using a traditional save window, we must first complete the response to clicks on buttons in the main window. The '|<' and '>|' symbols are meant to represent 'go to the first record' and 'go to the last record', which provides a little extra help in moving through the records. Suggested as an exercise in module 9, we simply list the appropriate coding for you here.

Firstly, in PROCclick and the main% loop we need to add two more options:

WHEN 7: PROCbegin

and

WHEN 10: PROClast

The two procedures should now be inserted, the first before DEFPROCback, and the second after the ENDPROC of DEFPROCnext.

DEFPROCbegin
IFn%=1 ENDPROC
n%=1
PROCreset
ENDPROC

DEFPROClast
IFn%>=50 ENDPROC
n%=50
PROCreset
ENDPROC

button functions
Completing the button functions

Saving to a filer directory

This process is very much a Wimp-related one, and has little to add to our knowledge of how to use Basic. It is made complicated by the need to use the Wimp message system to communicate with the filer itself. We also have to define a new type of icon that can actually be dragged around the screen. In order to 'hear' the messages from the Wimp, we must include additional reason codes in the wimp poll loop. To do this, add the line

WHEN 17,18:PROCreceive

to the polling loop. Notice here that we can include more than one option in the WHEN statement. Both reason codes will be responded to in this case and handled by the same procedure, PROCreceive.

To keep matters tidy as we go along, now add DEFPROCreceive as a new procedure definition immediately following the ENDPROC of DEFPROCmenuselect.

DEFPROCreceive
CASE block%!16 OF
    WHEN 0:quit%=TRUE
ENDCASE
ENDPROC

Strictly speaking, every program should contain this code, since otherwise it will always ignore messages sent to it by the Wimp. The code 0 picked up by this routine tells the program that it is being shut down, and it may be that you would want to take some action before it happens. quit% = TRUE makes the program leave the poll loop and end.

The order of events will be as follows.

1. A standard save-type window will be opened, and the user will type in a suitable name for the file, and then drag the icon to a filer directory.

2. When the icon in the save box is clicked on, PROCclick responds by sending the program to a procedure that drags the icon in response to movement of the mouse.

3. When the mouse button is released, a message is sent back from the Wimp to the program. This is picked up in the wimp poll loop as reason code 7 which directs the program to PROCstartsave. This procedure works out where the pointer is, and sends a message to the Wimp to ask for the details of the directory.

4. The poll routine picks up the reply through reason code 17 and goes to PROCreceive so that the information can be interpreted and acted upon. It carries with it an action code 2 enabling the procedure to pick out the necessary response by directing to PROCdatasave. This procedure acknowledges the information by sending back action code 3, and finally the wimp sends back a message to say all is complete.

5. The actual saving process now begins with PROCmanualsave.

We make no further attempt to explain the finer details of the required code, but some of it is complex and must be copied with care.

The save window

Insert the following at the end of PROCinit.

REM Save box window

DIM savespr% 8,savetext% 255,saveval% 5
$saveval%="R2A~ ":$savespr%="file_ffd":$savetext%="SecretData"
save%=FNcreate_window(604,336,280,180,0,0,&86000012,2,2,&19,"Save as:",3,0)
a%=FNcreate_icon(save%,100,-92,68,68,&6102,"",savespr%,1,9)
a%=FNcreate_icon(save%,8,-156,192,48,&700F12D,"",savetext%,saveval%,256)
a%=FNcreate_icon(save%,208,-156,64,48,&C701913D,"",ok%,R5%,3)

The code in saveval% will control what characters can be entered in the pathname of the file, thus preventing disallowed characters. Note the use of 'file_ffd' to define the icon type to appear in the window. This is the standard data icon. Note also the button type for this icon that makes it dragable.

Save window
The save window is easily recognisable

In PROCclick, we need to add yet another option in order to open this window, but remember that this window opens in response to 'Enter filename' in the check code window. The following lines must therefore be added in the savecheck section within PROCclick, between the lines 'PROCautosave' and 'ENDCASE'.

WHEN 4:
    !block%=savecheck%
    SYS"Wimp_CloseWindow",,block%
    !block%=save%
    SYS"Wimp_GetWindowState",,block%
    block%!28=-1
    SYS"Wimp_OpenWindow",,block%
    PROCcaret(save%,1)

Dragging the icon

When we click on the icon to drag it, PROCclick needs to respond. Add the following code to the end of PROCclick.

WHEN save%
    CASE block%!16 OF
        WHEN 0:REM Click on dragable icon
            IF block%!8 AND 64 PROCdragbox
        WHEN 2:REM Click on OK
            IF block%!8 AND 5 PROCquicksave
    ENDCASE

Dragging
What is happening as we drag a file?

We are ignoring the click on the OK button at the moment, but we must now write PROCdragbox. Copy it with care! Place it before DEFPROCautosave.

DEFPROCdragbox
!block%=save%
SYS "Wimp_GetWindowState",,block%
vx%=block%!4-block%!20
vy%=block%!16-block%!24
block%!4=0
SYS "Wimp_GetIconState",,block%
sprite$="file_ffd"
IF spritedrag% THEN
    !block%=block%!8+vx%
    block%!4=vy%+block%!12
    block%!8=block%!16+vx%
    block%!12=vy%+block%!20
    SYS "DragASprite_Start",%11000101,1,sprite$,block%
ELSE
    block%!4=5:block%!8=vx%+block%!8
    block%!12=vy%+block%!12
    block%!16=vx%+block%!16
    block%!20=vy%+block%!20
    block%!24=0:block%!28=0
    block%!32=&7FFFFFFF
    block%!36=&7FFFFFFF
    SYS "Wimp_DragBox",,block%
ENDIF
ENDPROC

This procedure might have been better placed in the Library but it does contain two specific items to this program. Firstly it again specifies the data sprite in the eight line. Secondly it uses a variable called spritedrag% which we must now define at the start of PROCinit. The purpose of this is to enable solid drags if the OS in use is capable of doing so. The code to check this and set spritedrag% accordingly is as follows, and should be inserted immediately after the ON ERROR statement at the beginning of PROCinit.

SYS "OS_Byte",161,28 TO ,,val%
spritedrag%=((val% AND 2)=2)

spritedrag% is TRUE if solid drags are supported.

Exchanging messages

When the mouse button is released, the Wimp passes a reason code of 7, as so begins the exchange of messages. In the Poll loop, add the response

WHEN 7:PROCstartsave

Now add DEFPROCstartsave immediately following DEFPROCdragbox.

DEFPROCstartsave
IFspritedrag% SYS"DragASprite_Stop"
fsize%=2000:type%=&FFD
SYS "Wimp_GetPointerInfo",,block%
block%!20=block%!12:block%!24=block%!16
block%!28=!block%:block%!32=block%!4
block%!36=fsize%
!block%=64:block%!12=0
block%!16=1:block%!40=type%
$(block%+44)=FNgetleaf($savetext%)
SYS "Wimp_SendMessage",18,block%,block%!20,block%!24
saveref%=block%!8
ENDPROC

This process receives a reply through the line 'WHEN 17,18:PROCreceive', but to handle this we must now add a second option to the choices within PROCreceive:

WHEN 2:PROCdatasave

Add DEFPROCdatasave after the startsave procedure:

DEFPROCdatasave
$savetext%=FNstring(block%+44)
!block%=save%
block%!12=block%!8
block%!16=3:!block%=256
SYS "Wimp_SendMessage",18,block%,block%!20,block%!24
PROCmanualsave
altered%=FALSE
ENDPROC

and follow on with PROCmanualsave:

DEFPROCmanualsave
!block%=save%
SYS"Wimp_CloseWindow",,block%
code2$=FNstring(code%)
$code%=STRING$(8,CHR$0)
IF code$<>code2$ PROCreport("Codes do not match",1):ENDPROC
PROCencode
path$=FNstring(savetext%)
$path%=path$
PROCsave
FORX%=1TO50
    secret$(0,X%)=""
    desc$(0,X%)=""
NEXT
ENDPROC

Note that this is very similar to autosave. We are back on more familiar ground. Finally, for completeness, go on and add PROCquicksave which enables you to save by clicking on the OK icon.

DEFPROCquicksave
IF INSTR($savetext%,".") THEN
    PROCmanualsave
    altered%=FALSE
ELSE
    PROCreport("To save, drag the icon to a directory viewer",1)
ENDIF
ENDPROC

Notice how we change the value of altered% in these routines to register that the current data has been saved. This is not exploited in the program yet, but could be with little further code.

You were warned that this would be complex. To know more about this you are referred to Lee Calcraft and Alan Wrigley's book 'Wimp Programming for All' or other similar texts. Meanwhile, you could of course have copied most of this code from the Freeware version, but would you have learnt as much?

Return to the Module Index