Hi, all.
Well, I stared at the sacred ETH Gadgets scripts long enough and
enlightenment finally arrived. I'd like to outline what and how I
got a little gadgets thing working so as to 1) share my observations
about some things hidden in the manuals that ought to be in bold-face
28 point type, and 2) make sure I'm doing this right.
As I mentioned in an earlier post, I'm trying to make a gadget that
represents a viewable window onto an array of 8-bit pixels comprising
and image. Since the array is bigger (usually) than the window, I wanted
to have some attributes for the gadget showing the position of the
origin of the window relative to the underlying array, and wanted to
connect these attributes to some scroll bars. Finally, I wanted to be
able to have other modules load, process, and save the array of pixels
displayed by this module, and cause the display to be updated.
Here's what I did:
1. Changed the name of the Skeleton.Mod module to Images.Mod, and
named the New function "Images.NewImage". The record is augmented
with, among other things, a Screen.Image which contains a pointer
to an array of chars that Screen can blit to the screen display in
a portable way with Screen.Display(Image, etc), but that's another
story.
2. Set up some integer attributes with support in the Attr handler
function, including the "enum" section so it they can be seen
using the Inspector. These include XScroll & YScroll.
3. Set up the Restore function to call Screen.Display to display
the section of the array in the window using these attributes to
decide the origin of the window vs. the pixel array.
4. Now everything displayed fine, and playing with the attributes using
Gadgets.ChangeAttr worked just fine. So I made a couple of scroll
bars, set the ranges and positions appropriately for the gadget,
and started to set the command to manipulate the Image scrolling
attributes. Amazingly enough, how to do this isn't really detailed
in the section on how to use macros to *get* the values of other
widgets, nor anywhere in the programming reference. In the back of
the Gadgets Guide lives a tiny, unassuming one-liner:
Gadgets.Set Library.Object.Attribute Value
where Library can be omitted for things in the same context. This
turns out to work for things on the same panel; I assume this is
what's meant by that, more or less.
I think this is a pretty basic bit of information that should be
more predominately displayed, IMHO.
Anyway, so the scroll bars' commands now read something like:
Gadgets.Set .ImageWindow.XScroll #Value
and this works quite well.
5. Now, to somehow process this image. I didn't want to put all the
processing into the Images gadget module, as that seemed kind of
a crude way to do things. After some perusal I found (and I'm
trying to remember this from memory here)
Gadgets.FindObj(Name:ARRAY OF CHAR):Objects.Object
where Name is of the form Library.Object where Library can be omitted
for things in the same context. So I wrote another module called
Process with a procedure Load:
PROCEDURE Load*;
VAR
F : Objects.Object;
Gadget, Filename : ARRAY 255 OF CHAR;
BEGIN
In.Open;
In.String(Gadget);
In.String(Filename);
IF In.Done THEN
F := Gadgets.FindObj(Gadget);
IF F IS Images.Image THEN
WITH F:Images.Image THEN
(* using F, load the image, process it, whatever *)
Gadgets.Update(F); (* or something like this,
to send a redisplay message *)
END;
END;
END;
END Load;
Now I have some button take the value of a text field and
call Process.Load in its command field:
Process.Load .Window &.TF.Value
or something like that. I can make other commands, even using
other modules, that can also look up this gadget by name, get
its data, process it, and cause it to be redisplayed.
---
Anyway, I'd like some feedback. Given that I can't have ETH ring
me up and tell me how brilliantly I've mastered the concepts here,
what I'd like to ask is:
1) Am I doing this right?
2) Is there a better way to do this?
3) Why isn't this programming methodology discussed
to any extent in the documents, if it works? Or
am I just reading the wrong documents?
I've only seen from ETH two examples of programming Gadgets: Skeleton.Mod
and its relatives, and CAFE.Mod, a program that, while impressive, is
so huge that SPARC Oberon won't even compile the module, and it's not
a trivial program to read in any sense. Can we get some intermediate
complexity examples of real-world Gadgets applications using multiple
intercommunicating gadgets? I for one would like to see such a thing.
If there is interest, I will see if I can contribute the code for the
image-displaying window to an ftp site somewhere. I have code to read
sunraster files and straight pixel maps, and some simple IP filters I
can share; once you've seen the code, extending it is pretty easy. But
again, I'd like to make sure I'm doing this right. Oh, and the code
has only been tested on DOS and SPARC Oberon.
Well, sorry about the length of this. Gadgets has got me pretty
enthusiastic about using it as a serious programming tool, but I'd
like to be sure I'm not missing something big before writing a few
kilolines of code for my next project...
Well, back to deciphering the sacred scrolls... :-)
Best wishes...
-greg
---
Greg DeLozier/Senior Scientific Analyst, L{*filter*}Defense Systems