C for Yourself - part 30

Steve Mumford discovers that programming the WIMP's a drag

One of the crucial differences between RISC OS and other graphical user interfaces that exist lies in the way that file transfer is accomplished - we take saving and loading data from applications, or even between programs, very much for granted. In Acornland, all we have to do is drag an icon - if we want to save or load something to or from disc, we use the standard filer windows. RAM transfer is equally simple - just drag the file over another icon on the icon bar.

We're lucky. On certain other platforms I could mention, each application ends up with its own file interface, needing a hefty amount of code and producing a situation where no two file transfer dialogue boxes are the same. The approach that Acorn followed means that the programmer just has to provide one or two functions and the WIMP will do most of the hard work - your program doesn't need to know the difference between a floppy disc, an IDE drive or a magneto-optical device; all it has to do is write data to a filename that the WIMP provides.

This month, I've inluded the preliminary tools necessary for file saving in the example application - loading it from the cover disc, opening the Save window and dragging the icon will provide you with a dotted box that you can happily move around the screen. That's all it does for now, but we'll get on to the actual task of saving soon.

In order to make an icon draggable using the Acorn User library, you should first set its icon button type to be 'click and drag' (type 6). Whenever the user tries to perform a drag operation on the icon now, your task is passed the number of the mouse button used (Adjust is 1, Menu is 2 and Select is 4) multiplied by 16, to indicate the fact that the icon is being dragged.

You should then listen out for any Mouse_Click events occurring within Wimp_Poll that match the appropriate window handle and icon number - all you need to do then is call au_dragbox() with the appropriate values. Everything else is taken care of - AULib interrogates the icon and its window to discover the exact position of its bounding box on screen, then Wimp_DragBox is called to handle the familiar rotating dashed line. Here's the snippet of code from the example application that starts the procedure, all within the mouse_click() function:

if ((au_bytetoword(poll_block, 12) == win_data[2].win_handle) && (clk == 4*16))
  icon_num = au_bytetoword(poll_block, 16);
  if (icon_num == SAVE_ICON)
    au_dragbox(au_bytetoword(poll_block, 12), icon_num);

The first line checks that we're dealing with the correct window, and the drag operation has been started with Select. After that, we grab the target icon's number from the poll block and check it to see whether it's our save icon. If it is, we perform a function to start the usual drag box, and return to our polling loop.

After that, all we do is sit and wait for a User_Drag_Box event (type 7) to be reported to us via Wimp_Poll - this indicates that the dragging operation has finished and all buttons on the mouse have been released. At this stage in the procedure of saving a file, we would call Wimp_GetPointerInfo to discover which window the pointer was over at the moment when the drag operation ended.

From there, we can send a message to the File using that information and supplying a file name, type and approximate size - this allows the Filer to check whether the operation is feasible. Once our application receives a DataSaveAck message, we can get down to the low-level process of writing the file. The message-passing procedure might seem a little convoluted, but it means that saving between applications can be handled very simply using the Wimp$Scrap directory.

Data loading follows the same general scheme, although we don't have to go to the trouble of drawing the drag box, as someone else will be doing that for us - again, we listen for User_Drag_Box and check to see whether the file was dropped on our icon bar icon. I'll fill in the code necessary for these functions next month.

Source: Acorn User - 174 - November 1996
Publication: Acorn User
Contributor: Steve Mumford